diff --git a/src/aabb.cpp b/src/aabb.cpp new file mode 100644 index 0000000..d50ee56 --- /dev/null +++ b/src/aabb.cpp @@ -0,0 +1,44 @@ +/* + * @file + * @author Benny Bobaganoosh + * @section LICENSE + * + * Copyright (C) 2014 Benny Bobaganoosh + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "aabb.h" + +IntersectData AABB::IntersectAABB(const AABB& other) const +{ + //The distance between the AABB's on the X, Y, and Z axis. + //Computed twice because there are two possible valid distances, depending + //on the location of the AABB's. + Vector3f distances1 = other.GetMinExtents() - m_maxExtents; + Vector3f distances2 = m_minExtents - other.GetMaxExtents(); + + //The correct distances will be whichever distance is larger for that + //particular axis. + Vector3f distances = Vector3f(distances1.Max(distances2)); + + float maxDistance = distances.Max(); + + //If there is any distance between the two AABB's, then max distance will + //be greather than or equal to 0. If there is distance between the two + //AABBs, then they aren't intersecting. + // + //Therefore, if the AABBs are intersecting, then the distance between them + //must be less than zero. + return IntersectData(maxDistance < 0, maxDistance); +} diff --git a/src/aabb.h b/src/aabb.h new file mode 100644 index 0000000..9fcea4e --- /dev/null +++ b/src/aabb.h @@ -0,0 +1,63 @@ +/* + * @file + * @author Benny Bobaganoosh + * @section LICENSE + * + * Copyright (C) 2014 Benny Bobaganoosh + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AABB_INCLUDED_H +#define AABB_INCLUDED_H + +#include "math3d.h" +#include "intersectData.h" + +/** + * The AABB class represents an Axis Aligned Bounding Box that can be used as + * a collider in a physics engine. + */ +class AABB +{ +public: + /** + * Creates an AABB in a usable state. + * + * @param minExtents The corner of the AABB with the smallest coordinates. + * @param maxExtents The corner of the AABB with the largest coordinates. + */ + AABB(const Vector3f& minExtents, const Vector3f& maxExtents) : + m_minExtents(minExtents), + m_maxExtents(maxExtents) {} + + /** + * Computes information about if this AABB intersects another AABB. + * + * @param other The AABB that's being tested for intersection with this + * AABB. + */ + IntersectData IntersectAABB(const AABB& other) const; + + /** Basic getter for the min extents */ + inline const Vector3f& GetMinExtents() const { return m_minExtents; } + /** Basic getter for the max extents */ + inline const Vector3f& GetMaxExtents() const { return m_maxExtents; } +private: + /** The corner of the AABB with the smallest coordinates */ + const Vector3f m_minExtents; + /** The corner of the AABB with the largest coordinates */ + const Vector3f m_maxExtents; +}; + +#endif diff --git a/src/boundingSphere.cpp b/src/boundingSphere.cpp index b376f24..872cfe3 100644 --- a/src/boundingSphere.cpp +++ b/src/boundingSphere.cpp @@ -1,10 +1,41 @@ +/* + * @file + * @author Benny Bobaganoosh + * @section LICENSE + * + * Copyright (C) 2014 Benny Bobaganoosh + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include "boundingSphere.h" -IntersectData BoundingSphere::IntersectBoundingSphere(const BoundingSphere& other) +IntersectData BoundingSphere::IntersectBoundingSphere(const BoundingSphere& other) const { + //The radius is the distance from any point on the sphere to the center. + // + //Therefore, by adding the radius of two spheres together, the result is + //the distance between the centers of the spheres when they are touching. float radiusDistance = m_radius + other.GetRadius(); float centerDistance = (other.GetCenter() - m_center).Length(); + + //Since the radiusDistance is the distance bwteen the centers of the + //spheres are when they're touching, you can subtract that from the + //distance between the centers of the spheres to get the actual distance + //between the two spheres. float distance = centerDistance - radiusDistance; - return IntersectData(centerDistance < radiusDistance, distance); + //Spheres can only be intersecting if the distance between them is less + //than 0. + return IntersectData(distance < 0, distance); } diff --git a/src/boundingSphere.h b/src/boundingSphere.h index e7effea..4c934f5 100644 --- a/src/boundingSphere.h +++ b/src/boundingSphere.h @@ -1,22 +1,62 @@ +/* + * @file + * @author Benny Bobaganoosh + * @section LICENSE + * + * Copyright (C) 2014 Benny Bobaganoosh + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef BOUNDING_SPHERE_INCLUDED_H #define BOUNDING_SPHERE_INCLUDED_H #include "math3d.h" #include "intersectData.h" +/** + * The BoundingSphere class represents an sphere that can be used as a + * collider in a physics engine. + */ class BoundingSphere { public: + /** + * Creates a BoundingSphere in a usable state. + * + * @param center The center point of the sphere. + * @param radius The distance from any point on the sphere to the center. + */ BoundingSphere(const Vector3f& center, float radius) : m_center(center), m_radius(radius) {} - IntersectData IntersectBoundingSphere(const BoundingSphere& other); + /** + * Computes information about if this sphere intersects another aphere. + * + * @param other The sphere that's being tested for intersection with this + * sphere. + */ + IntersectData IntersectBoundingSphere(const BoundingSphere& other) const; + /** Basic getter for the center */ inline const Vector3f& GetCenter() const { return m_center; } + /** Basic getter for the radius */ inline float GetRadius() const { return m_radius; } private: + /** The center point of the sphere */ const Vector3f m_center; + /** The distance from any point on the sphere to the center */ const float m_radius; }; diff --git a/src/intersectData.h b/src/intersectData.h index eb4601a..f2e7fee 100644 --- a/src/intersectData.h +++ b/src/intersectData.h @@ -1,17 +1,50 @@ +/* + * @file + * @author Benny Bobaganoosh + * @section LICENSE + * + * Copyright (C) 2014 Benny Bobaganoosh + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef INTERSECT_DATA_INCLUDED_H #define INTERSECT_DATA_INCLUDED_H +/** + * The IntersectData class stores information about two intersecting objects. + */ class IntersectData { public: + /** + * Creates Intersect Data in a usable state. + * + * @param doesIntersect Whether or not the objects are intersecting. + * @param distance The distance between the two objects + */ IntersectData(const bool doesIntersect, const float distance) : m_doesIntersect(doesIntersect), m_distance(distance) {} + /** Basic getter for m_doesIntersect */ inline bool GetDoesIntersect() const { return m_doesIntersect; } + /** Basic getter for m_distance */ inline float GetDistance() const { return m_distance; } private: + /** Whether or not the objects are intersecting */ const bool m_doesIntersect; + /** The distance between the two objects */ const float m_distance; }; diff --git a/src/main.cpp b/src/main.cpp index 03c27dd..25d24f3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -77,6 +77,7 @@ void TestGame::Init(const Window& window) } #include "boundingSphere.h" +#include "aabb.h" #include int main() @@ -97,6 +98,31 @@ int main() std::cout << "Sphere1 intersect Sphere4: " << sphere1IntersectSphere4.GetDoesIntersect() << ", Distance: " << sphere1IntersectSphere4.GetDistance() << std::endl; + std::cout << std::endl; + + AABB aabb1(Vector3f(0.0f, 0.0f, 0.0f), Vector3f(1.0f, 1.0f, 1.0f)); + AABB aabb2(Vector3f(1.0f, 1.0f, 1.0f), Vector3f(2.0f, 2.0f, 2.0f)); + AABB aabb3(Vector3f(1.0f, 0.0f, 0.0f), Vector3f(2.0f, 1.0f, 1.0f)); + AABB aabb4(Vector3f(0.0f, 0.0f, -2.0f), Vector3f(1.0f, 1.0f, -1.0f)); + AABB aabb5(Vector3f(0.0f, 0.5f, 0.0f), Vector3f(1.0f, 1.5f, 1.0f)); + + IntersectData aabb1Intersectaabb2 = aabb1.IntersectAABB(aabb2); + IntersectData aabb1Intersectaabb3 = aabb1.IntersectAABB(aabb3); + IntersectData aabb1Intersectaabb4 = aabb1.IntersectAABB(aabb4); + IntersectData aabb1Intersectaabb5 = aabb1.IntersectAABB(aabb5); + + std::cout << "AABB1 intersect AABB2: " << aabb1Intersectaabb2.GetDoesIntersect() + << ", Distance: " << aabb1Intersectaabb2.GetDistance() << std::endl; + + std::cout << "AABB1 intersect AABB3: " << aabb1Intersectaabb3.GetDoesIntersect() + << ", Distance: " << aabb1Intersectaabb3.GetDistance() << std::endl; + + std::cout << "AABB1 intersect AABB4: " << aabb1Intersectaabb4.GetDoesIntersect() + << ", Distance: " << aabb1Intersectaabb4.GetDistance() << std::endl; + + std::cout << "AABB1 intersect AABB5: " << aabb1Intersectaabb5.GetDoesIntersect() + << ", Distance: " << aabb1Intersectaabb5.GetDistance() << std::endl; + // TestGame game; // Window window(800, 600, "3D Game Engine"); diff --git a/src/math3d.h b/src/math3d.h index 157b8e3..ca120a1 100644 --- a/src/math3d.h +++ b/src/math3d.h @@ -57,6 +57,17 @@ class Vector return result; } + inline Vector Max(const Vector& r) const + { + Vector result; + for(unsigned int i = 0; i < D; i++) + { + result[i] = values[i] > r[i] ? values[i] : r[i]; + } + + return result; + } + inline T Max() const { T maxVal = (*this)[0];