diff --git a/CMakeLists.txt b/CMakeLists.txt index ee484a6a..40362d23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,6 +76,10 @@ SET (REACTPHYSICS3D_SOURCES "src/collision/narrowphase/ConcaveVsConvexAlgorithm.cpp" "src/collision/shapes/AABB.h" "src/collision/shapes/AABB.cpp" + "src/collision/shapes/ConvexShape.h" + "src/collision/shapes/ConvexShape.cpp" + "src/collision/shapes/ConcaveShape.h" + "src/collision/shapes/ConcaveShape.cpp" "src/collision/shapes/BoxShape.h" "src/collision/shapes/BoxShape.cpp" "src/collision/shapes/CapsuleShape.h" diff --git a/src/collision/narrowphase/DefaultCollisionDispatch.cpp b/src/collision/narrowphase/DefaultCollisionDispatch.cpp index d7997c19..a6e47025 100644 --- a/src/collision/narrowphase/DefaultCollisionDispatch.cpp +++ b/src/collision/narrowphase/DefaultCollisionDispatch.cpp @@ -51,8 +51,8 @@ void DefaultCollisionDispatch::init(MemoryAllocator* memoryAllocator) { NarrowPhaseAlgorithm* DefaultCollisionDispatch::selectAlgorithm(int shape1Type, int shape2Type) { - // Sphere vs Sphere algorithm - if (shape1Type == SPHERE && shape2Type == SPHERE) { + + if (shape1Type == SPHERE && shape2Type == SPHERE) { // Sphere vs Sphere algorithm return &mSphereVsSphereAlgorithm; } else { // GJK algorithm diff --git a/src/collision/shapes/BoxShape.h b/src/collision/shapes/BoxShape.h index de7e1540..5ef775af 100644 --- a/src/collision/shapes/BoxShape.h +++ b/src/collision/shapes/BoxShape.h @@ -28,7 +28,7 @@ // Libraries #include -#include "CollisionShape.h" +#include "ConvexShape.h" #include "body/CollisionBody.h" #include "mathematics/mathematics.h" @@ -50,7 +50,7 @@ namespace reactphysics3d { * constructor of the box shape. Otherwise, it is recommended to use the * default margin distance by not using the "margin" parameter in the constructor. */ -class BoxShape : public CollisionShape { +class BoxShape : public ConvexShape { protected : @@ -165,6 +165,9 @@ inline Vector3 BoxShape::getLocalSupportPointWithoutMargin(const Vector3& direct // Test equality between two box shapes inline bool BoxShape::isEqualTo(const CollisionShape& otherCollisionShape) const { + + if (!ConvexShape::isEqualTo(otherCollisionShape)) return false; + const BoxShape& otherShape = dynamic_cast(otherCollisionShape); return (mExtent == otherShape.mExtent); } diff --git a/src/collision/shapes/CapsuleShape.h b/src/collision/shapes/CapsuleShape.h index f4cc2625..caec2075 100644 --- a/src/collision/shapes/CapsuleShape.h +++ b/src/collision/shapes/CapsuleShape.h @@ -27,7 +27,7 @@ #define REACTPHYSICS3D_CAPSULE_SHAPE_H // Libraries -#include "CollisionShape.h" +#include "ConvexShape.h" #include "body/CollisionBody.h" #include "mathematics/mathematics.h" @@ -44,7 +44,7 @@ namespace reactphysics3d { * and height of the shape. Therefore, no need to specify an object margin for a * capsule shape. */ -class CapsuleShape : public CollisionShape { +class CapsuleShape : public ConvexShape { protected : @@ -115,7 +115,7 @@ class CapsuleShape : public CollisionShape { virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const; }; -/// Allocate and return a copy of the object +// Allocate and return a copy of the object inline CapsuleShape* CapsuleShape::clone(void* allocatedMemory) const { return new (allocatedMemory) CapsuleShape(*this); } @@ -162,6 +162,9 @@ inline void CapsuleShape::getLocalBounds(Vector3& min, Vector3& max) const { // Test equality between two capsule shapes inline bool CapsuleShape::isEqualTo(const CollisionShape& otherCollisionShape) const { + + if (!ConvexShape::isEqualTo(otherCollisionShape)) return false; + const CapsuleShape& otherShape = dynamic_cast(otherCollisionShape); return (mRadius == otherShape.mRadius && mHalfHeight == otherShape.mHalfHeight); } diff --git a/src/collision/shapes/CollisionShape.cpp b/src/collision/shapes/CollisionShape.cpp index 843f1c84..e6dc0a49 100644 --- a/src/collision/shapes/CollisionShape.cpp +++ b/src/collision/shapes/CollisionShape.cpp @@ -32,15 +32,14 @@ using namespace reactphysics3d; // Constructor -CollisionShape::CollisionShape(CollisionShapeType type, decimal margin) - : mType(type), mNbSimilarCreatedShapes(0), mMargin(margin) { +CollisionShape::CollisionShape(CollisionShapeType type) + : mType(type), mNbSimilarCreatedShapes(0) { } // Private copy-constructor CollisionShape::CollisionShape(const CollisionShape& shape) - : mType(shape.mType), mNbSimilarCreatedShapes(shape.mNbSimilarCreatedShapes), - mMargin(shape.mMargin) { + : mType(shape.mType), mNbSimilarCreatedShapes(shape.mNbSimilarCreatedShapes) { } diff --git a/src/collision/shapes/CollisionShape.h b/src/collision/shapes/CollisionShape.h index 5e3663bf..04fb4536 100644 --- a/src/collision/shapes/CollisionShape.h +++ b/src/collision/shapes/CollisionShape.h @@ -63,9 +63,6 @@ class CollisionShape { /// Current number of similar created shapes uint mNbSimilarCreatedShapes; - - /// Margin used for the GJK collision detection algorithm - decimal mMargin; // -------------------- Methods -------------------- // @@ -75,14 +72,6 @@ class CollisionShape { /// Private assignment operator CollisionShape& operator=(const CollisionShape& shape); - // Return a local support point in a given direction with the object margin - virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction, - void** cachedCollisionData) const=0; - - /// Return a local support point in a given direction without the object margin - virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction, - void** cachedCollisionData) const=0; - /// Return true if a point is inside the collision shape virtual bool testPointInside(const Vector3& worldPoint, ProxyShape* proxyShape) const=0; @@ -109,7 +98,7 @@ class CollisionShape { // -------------------- Methods -------------------- // /// Constructor - CollisionShape(CollisionShapeType type, decimal margin); + CollisionShape(CollisionShapeType type); /// Destructor virtual ~CollisionShape(); @@ -117,8 +106,8 @@ class CollisionShape { /// Return the type of the collision shapes CollisionShapeType getType() const; - /// Return the current object margin - decimal getMargin() const; + /// Return true if the collision shape is convex, false if it is concave + virtual bool isConvex() const=0; /// Return the local bounds of the shape in x, y and z directions virtual void getLocalBounds(Vector3& min, Vector3& max) const=0; @@ -141,9 +130,6 @@ class CollisionShape { friend class CollisionWorld; }; - - - // Return the type of the collision shape /** * @return The type of the collision shape (box, sphere, cylinder, ...) @@ -157,14 +143,6 @@ inline uint CollisionShape::getNbSimilarCreatedShapes() const { return mNbSimilarCreatedShapes; } -// Return the current collision shape margin -/** - * @return The margin (in meters) around the collision shape - */ -inline decimal CollisionShape::getMargin() const { - return mMargin; -} - // Increment the number of similar allocated collision shapes inline void CollisionShape::incrementNbSimilarCreatedShapes() { mNbSimilarCreatedShapes++; @@ -186,8 +164,6 @@ inline bool CollisionShape::operator==(const CollisionShape& otherCollisionShape assert(typeid(*this) == typeid(otherCollisionShape)); - if (mMargin != otherCollisionShape.mMargin) return false; - // Check if the two shapes are equal return otherCollisionShape.isEqualTo(*this); } diff --git a/src/collision/shapes/ConcaveMeshShape.h b/src/collision/shapes/ConcaveMeshShape.h index a9deb29e..77d23513 100644 --- a/src/collision/shapes/ConcaveMeshShape.h +++ b/src/collision/shapes/ConcaveMeshShape.h @@ -26,6 +26,9 @@ #ifndef REACTPHYSICS3D_CONCAVE_MESH_SHAPE_H #define REACTPHYSICS3D_CONCAVE_MESH_SHAPE_H +// Libraries +#include "ConcaveShape.h" + namespace reactphysics3d { // TODO : Implement raycasting with this collision shape @@ -36,7 +39,7 @@ namespace reactphysics3d { * with a concave mesh shape can be very expensive. You should use only use * this shape for a static mesh. */ -class ConcaveMeshShape : public CollisionShape { +class ConcaveMeshShape : public ConcaveShape { protected: @@ -76,6 +79,9 @@ class ConcaveMeshShape : public CollisionShape { /// Destructor ~ConcaveMeshShape(); + /// Return true if the collision shape is convex, false if it is concave + virtual bool isConvex() const; + /// Return the local bounds of the shape in x, y and z directions. virtual void getLocalBounds(Vector3& min, Vector3& max) const; @@ -89,7 +95,12 @@ class ConcaveMeshShape : public CollisionShape { virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const; }; -/// Allocate and return a copy of the object +// Return true if the collision shape is convex, false if it is concave +virtual bool isConvex() const { + return false; +} + +// Allocate and return a copy of the object inline ConcaveMeshShape* ConcaveMeshShape::clone(void* allocatedMemory) const { return new (allocatedMemory) ConcaveMeshShape(*this); } diff --git a/src/collision/shapes/ConcaveShape.cpp b/src/collision/shapes/ConcaveShape.cpp new file mode 100644 index 00000000..2a8811fe --- /dev/null +++ b/src/collision/shapes/ConcaveShape.cpp @@ -0,0 +1,46 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "ConcaveShape.h" + + +// We want to use the ReactPhysics3D namespace +using namespace reactphysics3d; + +// Constructor +ConcaveShape::ConcaveShape(CollisionShapeType type) : CollisionShape(type) { + +} + +// Private copy-constructor +ConcaveShape::ConcaveShape(const CollisionShape& shape) : CollisionShape(shape) { + +} + +// Destructor +ConcaveShape::~ConcaveShape() { + +} diff --git a/src/collision/shapes/ConcaveShape.h b/src/collision/shapes/ConcaveShape.h new file mode 100644 index 00000000..ef8c155b --- /dev/null +++ b/src/collision/shapes/ConcaveShape.h @@ -0,0 +1,134 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef REACTPHYSICS3D_CONCAVE_SHAPE_H +#define REACTPHYSICS3D_CONCAVE_SHAPE_H + +// Libraries +#include "CollisionShape.h" + +/// ReactPhysics3D namespace +namespace reactphysics3d { + +// Class ConcaveShape +/** + * This abstract class represents a concave collision shape associated with a + * body that is used during the narrow-phase collision detection. + */ +class ConcaveShape : public CollisionShape { + + protected : + + // -------------------- Attributes -------------------- // + + + + // -------------------- Methods -------------------- // + + /// Private copy-constructor + ConcaveShape(const ConcaveShape& shape); + + /// Private assignment operator + ConcaveShape& operator=(const ConcaveShape& shape); + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + ConcaveShape(CollisionShapeType type); + + /// Destructor + virtual ~ConcaveShape(); + + /// Return true if the collision shape is convex, false if it is concave + virtual bool isConvex() const; + + /// Test equality between two shapes + virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const; +}; + +/// Return true if the collision shape is convex, false if it is concave +inline bool ConcaveShape::isConvex() const { + return false; +} + +// Return the type of the collision shape +/** + * @return The type of the collision shape (box, sphere, cylinder, ...) + */ +inline CollisionShapeType CollisionShape::getType() const { + return mType; +} + +// Return the number of similar created shapes +inline uint CollisionShape::getNbSimilarCreatedShapes() const { + return mNbSimilarCreatedShapes; +} + +// Return the current collision shape margin +/** + * @return The margin (in meters) around the collision shape + */ +inline decimal CollisionShape::getMargin() const { + return mMargin; +} + +// Increment the number of similar allocated collision shapes +inline void CollisionShape::incrementNbSimilarCreatedShapes() { + mNbSimilarCreatedShapes++; +} + +// Decrement the number of similar allocated collision shapes +inline void CollisionShape::decrementNbSimilarCreatedShapes() { + mNbSimilarCreatedShapes--; +} + +// Equality operator between two collision shapes. +/// This methods returns true only if the two collision shapes are of the same type and +/// of the same dimensions. +inline bool CollisionShape::operator==(const CollisionShape& otherCollisionShape) const { + + // If the two collisions shapes are not of the same type (same derived classes) + // we return false + if (mType != otherCollisionShape.mType) return false; + + assert(typeid(*this) == typeid(otherCollisionShape)); + + if (mMargin != otherCollisionShape.mMargin) return false; + + // Check if the two shapes are equal + return otherCollisionShape.isEqualTo(*this); +} + +// Test equality between two shapes +inline bool ConcaveShape::isEqualTo(const CollisionShape& otherCollisionShape) const { + return true; +} + +} + +#endif + diff --git a/src/collision/shapes/ConeShape.h b/src/collision/shapes/ConeShape.h index 9d0d9db3..7c1e07cf 100644 --- a/src/collision/shapes/ConeShape.h +++ b/src/collision/shapes/ConeShape.h @@ -27,7 +27,7 @@ #define REACTPHYSICS3D_CONE_SHAPE_H // Libraries -#include "CollisionShape.h" +#include "ConvexShape.h" #include "body/CollisionBody.h" #include "mathematics/mathematics.h" @@ -49,7 +49,7 @@ namespace reactphysics3d { * constructor of the cone shape. Otherwise, it is recommended to use the * default margin distance by not using the "margin" parameter in the constructor. */ -class ConeShape : public CollisionShape { +class ConeShape : public ConvexShape { protected : @@ -178,6 +178,9 @@ inline void ConeShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass // Test equality between two cone shapes inline bool ConeShape::isEqualTo(const CollisionShape& otherCollisionShape) const { + + if (!ConvexShape::isEqualTo(otherCollisionShape)) return false; + const ConeShape& otherShape = dynamic_cast(otherCollisionShape); return (mRadius == otherShape.mRadius && mHalfHeight == otherShape.mHalfHeight); } diff --git a/src/collision/shapes/ConvexMeshShape.cpp b/src/collision/shapes/ConvexMeshShape.cpp index aa4cf81e..02237cc9 100644 --- a/src/collision/shapes/ConvexMeshShape.cpp +++ b/src/collision/shapes/ConvexMeshShape.cpp @@ -211,6 +211,9 @@ void ConvexMeshShape::recalculateBounds() { // Test equality between two cone shapes bool ConvexMeshShape::isEqualTo(const CollisionShape& otherCollisionShape) const { + + if (!ConvexShape::isEqualTo(otherCollisionShape)) return false; + const ConvexMeshShape& otherShape = dynamic_cast(otherCollisionShape); assert(mNbVertices == mVertices.size()); diff --git a/src/collision/shapes/ConvexMeshShape.h b/src/collision/shapes/ConvexMeshShape.h index 7245255b..80d5cbcb 100644 --- a/src/collision/shapes/ConvexMeshShape.h +++ b/src/collision/shapes/ConvexMeshShape.h @@ -27,7 +27,7 @@ #define REACTPHYSICS3D_CONVEX_MESH_SHAPE_H // Libraries -#include "CollisionShape.h" +#include "ConvexShape.h" #include "engine/CollisionWorld.h" #include "mathematics/mathematics.h" #include "collision/narrowphase/GJK/GJKAlgorithm.h" @@ -60,7 +60,7 @@ class CollisionWorld; * with the addEdge() method. Then, you must use the setIsEdgesInformationUsed(true) method * in order to use the edges information for collision detection. */ -class ConvexMeshShape : public CollisionShape { +class ConvexMeshShape : public ConvexShape { protected : diff --git a/src/collision/shapes/ConvexShape.cpp b/src/collision/shapes/ConvexShape.cpp new file mode 100644 index 00000000..1d27ad27 --- /dev/null +++ b/src/collision/shapes/ConvexShape.cpp @@ -0,0 +1,48 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "ConvexShape.h" + + +// We want to use the ReactPhysics3D namespace +using namespace reactphysics3d; + +// Constructor +ConvexShape::ConvexShape(CollisionShapeType type, decimal margin) + : CollisionShape(type), mMargin(margin) { + +} + +// Private copy-constructor +ConvexShape::ConvexShape(const CollisionShape& shape) + : CollisionShape(shape), mMargin(shape.mMargin) { + +} + +// Destructor +ConvexShape::~ConvexShape() { + +} diff --git a/src/collision/shapes/ConvexShape.h b/src/collision/shapes/ConvexShape.h new file mode 100644 index 00000000..16be7065 --- /dev/null +++ b/src/collision/shapes/ConvexShape.h @@ -0,0 +1,142 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef REACTPHYSICS3D_CONVEX_SHAPE_H +#define REACTPHYSICS3D_CONVEX_SHAPE_H + +// Libraries +#include "CollisionShape.h" + +/// ReactPhysics3D namespace +namespace reactphysics3d { + +// Class ConvexShape +/** + * This abstract class represents a convex collision shape associated with a + * body that is used during the narrow-phase collision detection. + */ +class ConvexShape : public CollisionShape { + + protected : + + // -------------------- Attributes -------------------- // + + /// Margin used for the GJK collision detection algorithm + decimal mMargin; + + // -------------------- Methods -------------------- // + + /// Private copy-constructor + ConvexShape(const ConvexShape& shape); + + /// Private assignment operator + ConvexShape& operator=(const ConvexShape& shape); + + // Return a local support point in a given direction with the object margin + virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction, + void** cachedCollisionData) const=0; + + /// Return a local support point in a given direction without the object margin + virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction, + void** cachedCollisionData) const=0; + + /// Return true if a point is inside the collision shape + virtual bool testPointInside(const Vector3& worldPoint, ProxyShape* proxyShape) const=0; + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + ConvexShape(CollisionShapeType type, decimal margin); + + /// Destructor + virtual ~ConvexShape(); + + /// Return the current object margin + decimal getMargin() const; + + /// Return true if the collision shape is convex, false if it is concave + virtual bool isConvex() const; + + /// Test equality between two shapes + virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const; +}; + +/// Return true if the collision shape is convex, false if it is concave +inline bool ConvexShape::isConvex() const { + return true; +} + +// Return the current collision shape margin +/** + * @return The margin (in meters) around the collision shape + */ +inline decimal CollisionShape::getMargin() const { + return mMargin; +} + +// Return the type of the collision shape +/** + * @return The type of the collision shape (box, sphere, cylinder, ...) + */ +inline CollisionShapeType CollisionShape::getType() const { + return mType; +} + +// Return the number of similar created shapes +inline uint CollisionShape::getNbSimilarCreatedShapes() const { + return mNbSimilarCreatedShapes; +} + +// Return the current collision shape margin +/** + * @return The margin (in meters) around the collision shape + */ +inline decimal CollisionShape::getMargin() const { + return mMargin; +} + +// Increment the number of similar allocated collision shapes +inline void CollisionShape::incrementNbSimilarCreatedShapes() { + mNbSimilarCreatedShapes++; +} + +// Decrement the number of similar allocated collision shapes +inline void CollisionShape::decrementNbSimilarCreatedShapes() { + mNbSimilarCreatedShapes--; +} + +// Test equality between two shapes +inline bool ConvexShape::isEqualTo(const CollisionShape& otherCollisionShape) const { + + const ConvexShape& otherShape = static_cast(otherCollisionShape); + return (mMargin == otherShape.mMargin); +} + +} + +#endif + diff --git a/src/collision/shapes/CylinderShape.h b/src/collision/shapes/CylinderShape.h index 0e193d39..73266ad4 100644 --- a/src/collision/shapes/CylinderShape.h +++ b/src/collision/shapes/CylinderShape.h @@ -27,7 +27,7 @@ #define REACTPHYSICS3D_CYLINDER_SHAPE_H // Libraries -#include "CollisionShape.h" +#include "ConvexShape.h" #include "body/CollisionBody.h" #include "mathematics/mathematics.h" @@ -49,7 +49,7 @@ namespace reactphysics3d { * constructor of the cylinder shape. Otherwise, it is recommended to use the * default margin distance by not using the "margin" parameter in the constructor. */ -class CylinderShape : public CollisionShape { +class CylinderShape : public ConvexShape { protected : @@ -115,7 +115,7 @@ class CylinderShape : public CollisionShape { virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const; }; -/// Allocate and return a copy of the object +// Allocate and return a copy of the object inline CylinderShape* CylinderShape::clone(void* allocatedMemory) const { return new (allocatedMemory) CylinderShape(*this); } @@ -175,6 +175,9 @@ inline void CylinderShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal // Test equality between two cylinder shapes inline bool CylinderShape::isEqualTo(const CollisionShape& otherCollisionShape) const { + + if (!ConvexShape::isEqualTo(otherCollisionShape)) return false; + const CylinderShape& otherShape = dynamic_cast(otherCollisionShape); return (mRadius == otherShape.mRadius && mHalfHeight == otherShape.mHalfHeight); } diff --git a/src/collision/shapes/SphereShape.h b/src/collision/shapes/SphereShape.h index ac3e3cf2..911d487d 100644 --- a/src/collision/shapes/SphereShape.h +++ b/src/collision/shapes/SphereShape.h @@ -27,7 +27,7 @@ #define REACTPHYSICS3D_SPHERE_SHAPE_H // Libraries -#include "CollisionShape.h" +#include "ConvexShape.h" #include "body/CollisionBody.h" #include "mathematics/mathematics.h" @@ -42,7 +42,7 @@ namespace reactphysics3d { * radius of the sphere. Therefore, no need to specify an object margin * for a sphere shape. */ -class SphereShape : public CollisionShape { +class SphereShape : public ConvexShape { protected : @@ -105,7 +105,7 @@ class SphereShape : public CollisionShape { virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const; }; -/// Allocate and return a copy of the object +// Allocate and return a copy of the object inline SphereShape* SphereShape::clone(void* allocatedMemory) const { return new (allocatedMemory) SphereShape(*this); } @@ -197,6 +197,9 @@ inline void SphereShape::computeAABB(AABB& aabb, const Transform& transform) { // Test equality between two sphere shapes inline bool SphereShape::isEqualTo(const CollisionShape& otherCollisionShape) const { + + if (!ConvexShape::isEqualTo(otherCollisionShape)) return false; + const SphereShape& otherShape = dynamic_cast(otherCollisionShape); return (mRadius == otherShape.mRadius); } diff --git a/src/collision/shapes/TriangleShape.h b/src/collision/shapes/TriangleShape.h index f56158f1..fee38302 100644 --- a/src/collision/shapes/TriangleShape.h +++ b/src/collision/shapes/TriangleShape.h @@ -28,7 +28,7 @@ // Libraries #include "mathematics/mathematics.h" -#include "CollisionShape.h" +#include "ConvexShape.h" /// ReactPhysics3D namespace namespace reactphysics3d { @@ -38,7 +38,7 @@ namespace reactphysics3d { * This class represents a triangle collision shape that is centered * at the origin and defined three points. */ -class TriangleShape : public CollisionShape { +class TriangleShape : public ConvexShape { protected: @@ -99,7 +99,7 @@ class TriangleShape : public CollisionShape { virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const; }; -/// Allocate and return a copy of the object +// Allocate and return a copy of the object inline TriangleShape* TriangleShape::clone(void* allocatedMemory) const { return new (allocatedMemory) TriangleShape(*this); } @@ -121,7 +121,7 @@ inline Vector3 TriangleShape::getLocalSupportPointWithMargin(const Vector3& dire // Return a local support point in a given direction without the object margin inline Vector3 TriangleShape::getLocalSupportPointWithoutMargin(const Vector3& direction, void** cachedCollisionData) const { - Vector3 dotProducts(direction.dot(mPoints[0]), direction.dot(mPoints[1], direction.dot(mPoints[2]))); + Vector3 dotProducts(direction.dot(mPoints[0]), direction.dot(mPoints[1]), direction.dot(mPoints[2])); return mPoints[dotProducts.getMaxAxis()]; } @@ -133,12 +133,11 @@ inline Vector3 TriangleShape::getLocalSupportPointWithoutMargin(const Vector3& d */ inline void TriangleShape::getLocalBounds(Vector3& min, Vector3& max) const { - // TODO :This code is wrong const Vector3 xAxis(worldPoint1.X, worldPoint2.X, worldPoint3.X); const Vector3 yAxis(worldPoint1.Y, worldPoint2.Y, worldPoint3.Y); const Vector3 zAxis(worldPoint1.Z, worldPoint2.Z, worldPoint3.Z); - min.setAllValues(xAxis.getMinAxis(), yAxis.getMinAxis(), zAxis.getMinAxis()); - max.setAllValues(xAxis.getMaxAxis(), yAxis.getMaxAxis(), zAxis.getMaxAxis()); + min.setAllValues(xAxis.getMinValue(), yAxis.getMinValue(), zAxis.getMinValue()); + max.setAllValues(xAxis.getMaxValue(), yAxis.getMaxValue(), zAxis.getMaxValue()); } // Return the local inertia tensor of the triangle shape @@ -159,8 +158,6 @@ inline void TriangleShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal */ inline void TriangleShape::computeAABB(AABB& aabb, const Transform& transform) { - // TODO :This code is wrong - const Vector3 worldPoint1 = transform * mPoints[0]; const Vector3 worldPoint2 = transform * mPoints[1]; const Vector3 worldPoint3 = transform * mPoints[2]; @@ -168,12 +165,15 @@ inline void TriangleShape::computeAABB(AABB& aabb, const Transform& transform) { const Vector3 xAxis(worldPoint1.X, worldPoint2.X, worldPoint3.X); const Vector3 yAxis(worldPoint1.Y, worldPoint2.Y, worldPoint3.Y); const Vector3 zAxis(worldPoint1.Z, worldPoint2.Z, worldPoint3.Z); - aabb.setMin(Vector3(xAxis.getMinAxis(), yAxis.getMinAxis(), zAxis.getMinAxis())); - aabb.setMax(Vector3(xAxis.getMaxAxis(), yAxis.getMaxAxis(), zAxis.getMaxAxis())); + aabb.setMin(Vector3(xAxis.getMinValue(), yAxis.getMinValue(), zAxis.getMinValue())); + aabb.setMax(Vector3(xAxis.getMaxValue(), yAxis.getMaxValue(), zAxis.getMaxValue())); } // Test equality between two triangle shapes inline bool TriangleShape::isEqualTo(const CollisionShape& otherCollisionShape) const { + + if (!ConvexShape::isEqualTo(otherCollisionShape)) return false; + const TriangleShape& otherShape = dynamic_cast(otherCollisionShape); return (mPoints[0] == otherShape.mPoints[0] && mPoints[1] == otherShape.mPoints[1] && diff --git a/src/mathematics/Vector3.h b/src/mathematics/Vector3.h index f8ffb77f..e7374435 100644 --- a/src/mathematics/Vector3.h +++ b/src/mathematics/Vector3.h @@ -111,6 +111,12 @@ struct Vector3 { /// Return the axis with the maximal value int getMaxAxis() const; + /// Return the minimum value among the three components of a vector + decimal getMinValue() const; + + /// Return the maximum value among the three components of a vector + decimal getMaxValue() const; + /// Overloaded operator for the equality condition bool operator== (const Vector3& vector) const; @@ -334,6 +340,16 @@ inline Vector3 Vector3::max(const Vector3& vector1, const Vector3& vector2) { std::max(vector1.z, vector2.z)); } +// Return the minimum value among the three components of a vector +inline decimal Vector3::getMinValue() const { + return std::min(std::min(x, y), z); +} + +// Return the maximum value among the three components of a vector +inline decimal Vector3::getMaxValue() const { + return std::max(std::max(x, y), z); +} + } #endif diff --git a/src/mathematics/mathematics_functions.h b/src/mathematics/mathematics_functions.h index 5b89e98f..d88ed46a 100644 --- a/src/mathematics/mathematics_functions.h +++ b/src/mathematics/mathematics_functions.h @@ -28,18 +28,20 @@ // Libraries #include "configuration.h" +#include "mathematics/Vector3.h" #include "decimal.h" #include /// ReactPhysics3D namespace namespace reactphysics3d { +struct Vector3; + // ---------- Mathematics functions ---------- // /// Function to test if two real numbers are (almost) equal /// We test if two numbers a and b are such that (a-b) are in [-EPSILON; EPSILON] inline bool approxEqual(decimal a, decimal b, decimal epsilon = MACHINE_EPSILON) { - decimal difference = a - b; return (difference < epsilon && difference > -epsilon); } @@ -51,8 +53,16 @@ inline decimal clamp(decimal value, decimal lowerLimit, decimal upperLimit) { return std::min(std::max(value, lowerLimit), upperLimit); } +/// Return the minimum value among three values +inline decimal min3(decimal a, decimal b, decimal c) { + return std::min(std::min(a, b), c); } +/// Return the maximum value among three values +inline decimal max3(decimal a, decimal b, decimal c) { + return std::max(std::max(a, b), c); +} +} #endif