diff --git a/CMakeLists.txt b/CMakeLists.txt index e162c26f..177b5e19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,8 @@ SET (REACTPHYSICS3D_SOURCES "src/collision/BroadPhasePair.h" "src/collision/BroadPhasePair.cpp" "src/collision/RaycastInfo.h" + "src/collision/ProxyShape.h" + "src/collision/ProxyShape.cpp" "src/collision/CollisionDetection.h" "src/collision/CollisionDetection.cpp" "src/constraint/BallAndSocketJoint.h" diff --git a/src/body/CollisionBody.cpp b/src/body/CollisionBody.cpp index fee4f84c..51b87e6f 100644 --- a/src/body/CollisionBody.cpp +++ b/src/body/CollisionBody.cpp @@ -62,14 +62,15 @@ CollisionBody::~CollisionBody() { /// This method will return a pointer to the proxy collision shape that links the body with /// the collision shape you have added. ProxyShape* CollisionBody::addCollisionShape(const CollisionShape& collisionShape, - const Transform& transform) { + const Transform& transform) { // Create an internal copy of the collision shape into the world (if it does not exist yet) CollisionShape* newCollisionShape = mWorld.createCollisionShape(collisionShape); // Create a new proxy collision shape to attach the collision shape to the body - ProxyShape* proxyShape = newCollisionShape->createProxyShape(mWorld.mMemoryAllocator, - this, transform, decimal(1.0)); + ProxyShape* proxyShape = new (mWorld.mMemoryAllocator.allocate( + sizeof(ProxyShape))) ProxyShape(this, newCollisionShape, + transform, decimal(1)); // Add it to the list of proxy collision shapes of the body if (mProxyCollisionShapes == NULL) { @@ -102,10 +103,9 @@ void CollisionBody::removeCollisionShape(const ProxyShape* proxyShape) { if (current == proxyShape) { mProxyCollisionShapes = current->mNext; mWorld.mCollisionDetection.removeProxyCollisionShape(current); - mWorld.removeCollisionShape(proxyShape->getInternalCollisionShape()); - size_t sizeBytes = current->getSizeInBytes(); + mWorld.removeCollisionShape(proxyShape->mCollisionShape); current->ProxyShape::~ProxyShape(); - mWorld.mMemoryAllocator.release(current, sizeBytes); + mWorld.mMemoryAllocator.release(current, sizeof(ProxyShape)); mNbCollisionShapes--; return; } @@ -120,10 +120,9 @@ void CollisionBody::removeCollisionShape(const ProxyShape* proxyShape) { ProxyShape* elementToRemove = current->mNext; current->mNext = elementToRemove->mNext; mWorld.mCollisionDetection.removeProxyCollisionShape(elementToRemove); - mWorld.removeCollisionShape(proxyShape->getInternalCollisionShape()); - size_t sizeBytes = elementToRemove->getSizeInBytes(); + mWorld.removeCollisionShape(proxyShape->mCollisionShape); elementToRemove->ProxyShape::~ProxyShape(); - mWorld.mMemoryAllocator.release(elementToRemove, sizeBytes); + mWorld.mMemoryAllocator.release(elementToRemove, sizeof(ProxyShape)); mNbCollisionShapes--; return; } @@ -146,7 +145,7 @@ void CollisionBody::removeAllCollisionShapes() { // Remove the proxy collision shape ProxyShape* nextElement = current->mNext; mWorld.mCollisionDetection.removeProxyCollisionShape(current); - mWorld.removeCollisionShape(current->getInternalCollisionShape()); + mWorld.removeCollisionShape(current->mCollisionShape); current->ProxyShape::~ProxyShape(); mWorld.mMemoryAllocator.release(current, sizeof(ProxyShape)); @@ -212,3 +211,15 @@ bool CollisionBody::testPointInside(const Vector3& worldPoint) const { return false; } + +// Raycast method +bool CollisionBody::raycast(const Ray& ray, decimal distance) { + // TODO : Implement this method + return false; +} + +// Raycast method with feedback information +bool CollisionBody::raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal distance) { + // TODO : Implement this method + return false; +} diff --git a/src/body/CollisionBody.h b/src/body/CollisionBody.h index 296f4d78..b66bf0e7 100644 --- a/src/body/CollisionBody.h +++ b/src/body/CollisionBody.h @@ -166,13 +166,11 @@ class CollisionBody : public Body { bool testPointInside(const Vector3& worldPoint) const; /// Raycast method - // TODO : Implement this method - bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const; + bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE); /// Raycast method with feedback information - // TODO : Implement this method bool raycast(const Ray& ray, RaycastInfo& raycastInfo, - decimal distance = RAYCAST_INFINITY_DISTANCE) const; + decimal distance = RAYCAST_INFINITY_DISTANCE); // -------------------- Friendship -------------------- // diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index f890e410..9c02030d 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -184,8 +184,9 @@ ProxyShape* RigidBody::addCollisionShape(const CollisionShape& collisionShape, CollisionShape* newCollisionShape = mWorld.createCollisionShape(collisionShape); // Create a new proxy collision shape to attach the collision shape to the body - ProxyShape* proxyShape = newCollisionShape->createProxyShape(mWorld.mMemoryAllocator, - this, transform, mass); + ProxyShape* proxyShape = new (mWorld.mMemoryAllocator.allocate( + sizeof(ProxyShape))) ProxyShape(this, newCollisionShape, + transform, mass); // Add it to the list of proxy collision shapes of the body if (mProxyCollisionShapes == NULL) { diff --git a/src/collision/ProxyShape.cpp b/src/collision/ProxyShape.cpp new file mode 100644 index 00000000..299f6423 --- /dev/null +++ b/src/collision/ProxyShape.cpp @@ -0,0 +1,30 @@ + +// Libraries +#include "ProxyShape.h" + +using namespace reactphysics3d; + +// Constructor +ProxyShape::ProxyShape(CollisionBody* body, CollisionShape* shape, const Transform& transform, + decimal mass) + :mBody(body), mCollisionShape(shape), mLocalToBodyTransform(transform), mMass(mass), + mNext(NULL), mBroadPhaseID(-1), mCachedCollisionData(NULL) { + +} + +// Destructor +ProxyShape::~ProxyShape() { + + // Release the cached collision data memory + if (mCachedCollisionData != NULL) { + free(mCachedCollisionData); + } +} + +// Return true if a point is inside the collision shape +bool ProxyShape::testPointInside(const Vector3& worldPoint) { + const Transform localToWorld = mBody->getTransform() * mLocalToBodyTransform; + const Vector3 localPoint = localToWorld.getInverse() * worldPoint; + return mCollisionShape->testPointInside(localPoint); +} + diff --git a/src/collision/ProxyShape.h b/src/collision/ProxyShape.h new file mode 100644 index 00000000..3d989140 --- /dev/null +++ b/src/collision/ProxyShape.h @@ -0,0 +1,156 @@ +#ifndef REACTPHYSICS3D_PROXY_SHAPE_H +#define REACTPHYSICS3D_PROXY_SHAPE_H + +// Libraries +#include "body/CollisionBody.h" +#include "shapes/CollisionShape.h" + +namespace reactphysics3d { + +// Class ProxyShape +/** + * The CollisionShape instances are supposed to be unique for memory optimization. For instance, + * consider two rigid bodies with the same sphere collision shape. In this situation, we will have + * a unique instance of SphereShape but we need to differentiate between the two instances during + * the collision detection. They do not have the same position in the world and they do not + * belong to the same rigid body. The ProxyShape class is used for that purpose by attaching a + * rigid body with one of its collision shape. A body can have multiple proxy shapes (one for + * each collision shape attached to the body). + */ +class ProxyShape { + + protected: + + // -------------------- Attributes -------------------- // + + /// Pointer to the parent body + CollisionBody* mBody; + + /// Internal collision shape + CollisionShape* mCollisionShape; + + /// Local-space to parent body-space transform (does not change over time) + const Transform mLocalToBodyTransform; + + /// Mass (in kilogramms) of the corresponding collision shape + decimal mMass; + + /// Pointer to the next proxy shape of the body (linked list) + ProxyShape* mNext; + + /// Broad-phase ID (node ID in the dynamic AABB tree) + int mBroadPhaseID; + + /// Cached collision data + void* mCachedCollisionData; + + // -------------------- Methods -------------------- // + + /// Private copy-constructor + ProxyShape(const ProxyShape& proxyShape); + + /// Private assignment operator + ProxyShape& operator=(const ProxyShape& proxyShape); + + // Return a local support point in a given direction with the object margin + Vector3 getLocalSupportPointWithMargin(const Vector3& direction); + + /// Return a local support point in a given direction without the object margin. + Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction); + + /// Return the collision shape margin + decimal getMargin() const; + + public: + + // -------------------- Methods -------------------- // + + /// Constructor + ProxyShape(CollisionBody* body, CollisionShape* shape, + const Transform& transform, decimal mass); + + /// Destructor + ~ProxyShape(); + + /// Return the collision shape + const CollisionShape* getCollisionShape() const; + + /// Return the parent body + CollisionBody* getBody() const; + + /// Return the mass of the collision shape + decimal getMass() const; + + /// Return the local to parent body transform + const Transform& getLocalToBodyTransform() const; + + /// Return true if a point is inside the collision shape + bool testPointInside(const Vector3& worldPoint); + + /// Raycast method + bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE); + + /// Raycast method with feedback information + bool raycast(const Ray& ray, RaycastInfo& raycastInfo, + decimal distance = RAYCAST_INFINITY_DISTANCE); + + // -------------------- Friendship -------------------- // + + friend class OverlappingPair; + friend class CollisionBody; + friend class RigidBody; + friend class BroadPhaseAlgorithm; + friend class DynamicAABBTree; + friend class CollisionDetection; + friend class EPAAlgorithm; + friend class GJKAlgorithm; +}; + +/// Return the collision shape +inline const CollisionShape* ProxyShape::getCollisionShape() const { + return mCollisionShape; +} + +// Return the parent body +inline CollisionBody* ProxyShape::getBody() const { + return mBody; +} + +// Return the mass of the collision shape +inline decimal ProxyShape::getMass() const { + return mMass; +} + +// Return the local to parent body transform +inline const Transform& ProxyShape::getLocalToBodyTransform() const { + return mLocalToBodyTransform; +} + +// Return a local support point in a given direction with the object margin +inline Vector3 ProxyShape::getLocalSupportPointWithMargin(const Vector3& direction) { + return mCollisionShape->getLocalSupportPointWithMargin(direction, &mCachedCollisionData); +} + +// Return a local support point in a given direction without the object margin. +inline Vector3 ProxyShape::getLocalSupportPointWithoutMargin(const Vector3& direction) { + return mCollisionShape->getLocalSupportPointWithoutMargin(direction, &mCachedCollisionData); +} + +// Return the collision shape margin +inline decimal ProxyShape::getMargin() const { + return mCollisionShape->getMargin(); +} + +// Raycast method +inline bool ProxyShape::raycast(const Ray& ray, decimal distance) { + return mCollisionShape->raycast(ray, distance); +} + +// Raycast method with feedback information +inline bool ProxyShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal distance) { + return mCollisionShape->raycast(ray, raycastInfo, distance); +} + +} + +#endif diff --git a/src/collision/broadphase/BroadPhaseAlgorithm.h b/src/collision/broadphase/BroadPhaseAlgorithm.h index 0a27fd32..75830a91 100644 --- a/src/collision/broadphase/BroadPhaseAlgorithm.h +++ b/src/collision/broadphase/BroadPhaseAlgorithm.h @@ -29,6 +29,7 @@ // Libraries #include #include "../../body/CollisionBody.h" +#include "collision/ProxyShape.h" #include "DynamicAABBTree.h" /// Namespace ReactPhysics3D diff --git a/src/collision/shapes/BoxShape.cpp b/src/collision/shapes/BoxShape.cpp index 4c8ccdaf..4fd5f7c4 100644 --- a/src/collision/shapes/BoxShape.cpp +++ b/src/collision/shapes/BoxShape.cpp @@ -37,7 +37,6 @@ BoxShape::BoxShape(const Vector3& extent, decimal margin) assert(extent.x > decimal(0.0) && extent.x > margin); assert(extent.y > decimal(0.0) && extent.y > margin); assert(extent.z > decimal(0.0) && extent.z > margin); - assert(margin > decimal(0.0)); } // Private copy-constructor @@ -79,27 +78,3 @@ bool BoxShape::testPointInside(const Vector3& localPoint) const { // TODO : Implement this method return false; } - -// Constructor -ProxyBoxShape::ProxyBoxShape(BoxShape* shape, CollisionBody* body, - const Transform& transform, decimal mass) - :ProxyShape(body, transform, mass), mCollisionShape(shape){ - -} - -// Destructor -ProxyBoxShape::~ProxyBoxShape() { - -} - -// Raycast method -bool ProxyBoxShape::raycast(const Ray& ray, decimal distance) const { - // TODO : Implement this method - return false; -} - -// Raycast method with feedback information -bool ProxyBoxShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal distance) const { - // TODO : Implement this method - return false; -} diff --git a/src/collision/shapes/BoxShape.h b/src/collision/shapes/BoxShape.h index 1f8ea740..bee7397a 100644 --- a/src/collision/shapes/BoxShape.h +++ b/src/collision/shapes/BoxShape.h @@ -67,8 +67,16 @@ class BoxShape : public CollisionShape { /// Private assignment operator BoxShape& operator=(const BoxShape& shape); + /// Return a local support point in a given direction with the object margin + virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction, + void** cachedCollisionData) const; + + /// Return a local support point in a given direction without the object margin + virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction, + void** cachedCollisionData) const; + /// Return true if a point is inside the collision shape - bool testPointInside(const Vector3& localPoint) const; + virtual bool testPointInside(const Vector3& localPoint) const; public : @@ -92,94 +100,18 @@ class BoxShape : public CollisionShape { /// Return the number of bytes used by the collision shape virtual size_t getSizeInBytes() const; - /// Return a local support point in a given direction with the object margin - virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const; - - /// Return a local support point in a given direction without the object margin - virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const; - /// Return the local inertia tensor of the collision shape virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const; /// Test equality between two box shapes virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const; - /// Create a proxy collision shape for the collision shape - virtual ProxyShape* createProxyShape(MemoryAllocator& allocator, CollisionBody* body, - const Transform& transform, decimal mass); - /// Raycast method virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const; /// Raycast method with feedback information virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - // -------------------- Friendship -------------------- // - - friend class ProxyBoxShape; -}; - -// Class ProxyBoxShape -/** - * The proxy collision shape for a box shape. - */ -class ProxyBoxShape : public ProxyShape { - - private: - - // -------------------- Attributes -------------------- // - - /// Pointer to the actual collision shape - BoxShape* mCollisionShape; - - - // -------------------- Methods -------------------- // - - /// Private copy-constructor - ProxyBoxShape(const ProxyBoxShape& proxyShape); - - /// Private assignment operator - ProxyBoxShape& operator=(const ProxyBoxShape& proxyShape); - - /// Return the non-const collision shape - virtual CollisionShape* getInternalCollisionShape() const; - - public: - - // -------------------- Methods -------------------- // - - /// Constructor - ProxyBoxShape(BoxShape* shape, CollisionBody* body, - const Transform& transform, decimal mass); - - /// Destructor - ~ProxyBoxShape(); - - /// Return the collision shape - virtual const CollisionShape* getCollisionShape() const; - - /// Return the number of bytes used by the proxy collision shape - virtual size_t getSizeInBytes() const; - - /// Return a local support point in a given direction with the object margin - virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction); - - /// Return a local support point in a given direction without the object margin - virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction); - - /// Return the current collision shape margin - virtual decimal getMargin() const; - - /// Raycast method - virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - /// Raycast method with feedback information - virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, - decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - /// Return true if a point is inside the collision shape - virtual bool testPointInside(const Vector3& worldPoint); }; // Allocate and return a copy of the object @@ -209,7 +141,8 @@ inline size_t BoxShape::getSizeInBytes() const { } // Return a local support point in a given direction with the object margin -inline Vector3 BoxShape::getLocalSupportPointWithMargin(const Vector3& direction) const { +inline Vector3 BoxShape::getLocalSupportPointWithMargin(const Vector3& direction, + void** cachedCollisionData) const { assert(mMargin > 0.0); @@ -219,7 +152,8 @@ inline Vector3 BoxShape::getLocalSupportPointWithMargin(const Vector3& direction } // Return a local support point in a given direction without the objec margin -inline Vector3 BoxShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const { +inline Vector3 BoxShape::getLocalSupportPointWithoutMargin(const Vector3& direction, + void** cachedCollisionData) const { return Vector3(direction.x < 0.0 ? -mExtent.x : mExtent.x, direction.y < 0.0 ? -mExtent.y : mExtent.y, @@ -232,50 +166,6 @@ inline bool BoxShape::isEqualTo(const CollisionShape& otherCollisionShape) const return (mExtent == otherShape.mExtent); } -// Create a proxy collision shape for the collision shape -inline ProxyShape* BoxShape::createProxyShape(MemoryAllocator& allocator, CollisionBody* body, - const Transform& transform, decimal mass) { - return new (allocator.allocate(sizeof(ProxyBoxShape))) ProxyBoxShape(this, body, - transform, mass); -} - -// Return the non-const collision shape -inline CollisionShape* ProxyBoxShape::getInternalCollisionShape() const { - return mCollisionShape; -} - -// Return the collision shape -inline const CollisionShape* ProxyBoxShape::getCollisionShape() const { - return mCollisionShape; -} - -// Return the number of bytes used by the proxy collision shape -inline size_t ProxyBoxShape::getSizeInBytes() const { - return sizeof(ProxyBoxShape); -} - -// Return a local support point in a given direction with the object margin -inline Vector3 ProxyBoxShape::getLocalSupportPointWithMargin(const Vector3& direction) { - return mCollisionShape->getLocalSupportPointWithMargin(direction); -} - -// Return a local support point in a given direction without the object margin -inline Vector3 ProxyBoxShape::getLocalSupportPointWithoutMargin(const Vector3& direction) { - return mCollisionShape->getLocalSupportPointWithoutMargin(direction); -} - -// Return the current object margin -inline decimal ProxyBoxShape::getMargin() const { - return mCollisionShape->getMargin(); -} - -// Return true if a point is inside the collision shape -inline bool ProxyBoxShape::testPointInside(const Vector3& worldPoint) { - const Transform localToWorld = mBody->getTransform() * mLocalToBodyTransform; - const Vector3 localPoint = localToWorld.getInverse() * worldPoint; - return mCollisionShape->testPointInside(localPoint); -} - } #endif diff --git a/src/collision/shapes/CapsuleShape.cpp b/src/collision/shapes/CapsuleShape.cpp index 5867c536..22202c8d 100644 --- a/src/collision/shapes/CapsuleShape.cpp +++ b/src/collision/shapes/CapsuleShape.cpp @@ -55,7 +55,8 @@ CapsuleShape::~CapsuleShape() { /// Therefore, in this method, we compute the support points of both top and bottom spheres of /// the capsule and return the point with the maximum dot product with the direction vector. Note /// that the object margin is implicitly the radius and height of the capsule. -Vector3 CapsuleShape::getLocalSupportPointWithMargin(const Vector3& direction) const { +Vector3 CapsuleShape::getLocalSupportPointWithMargin(const Vector3& direction, + void** cachedCollisionData) const { // If the direction vector is not the zero vector if (direction.lengthSquare() >= MACHINE_EPSILON * MACHINE_EPSILON) { @@ -87,7 +88,8 @@ Vector3 CapsuleShape::getLocalSupportPointWithMargin(const Vector3& direction) c } // Return a local support point in a given direction without the object margin. -Vector3 CapsuleShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const { +Vector3 CapsuleShape::getLocalSupportPointWithoutMargin(const Vector3& direction, + void** cachedCollisionData) const { // If the dot product of the direction and the local Y axis (dotProduct = direction.y) // is positive @@ -141,27 +143,3 @@ bool CapsuleShape::testPointInside(const Vector3& localPoint) const { // TODO : Implement this method return false; } - -// Constructor -ProxyCapsuleShape::ProxyCapsuleShape(CapsuleShape* shape, CollisionBody* body, - const Transform& transform, decimal mass) - :ProxyShape(body, transform, mass), mCollisionShape(shape){ - -} - -// Destructor -ProxyCapsuleShape::~ProxyCapsuleShape() { - -} - -// Raycast method -bool ProxyCapsuleShape::raycast(const Ray& ray, decimal distance) const { - // TODO : Implement this method - return false; -} - -// Raycast method with feedback information -bool ProxyCapsuleShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal distance) const { - // TODO : Implement this method - return false; -} diff --git a/src/collision/shapes/CapsuleShape.h b/src/collision/shapes/CapsuleShape.h index d40eef01..e36a56aa 100644 --- a/src/collision/shapes/CapsuleShape.h +++ b/src/collision/shapes/CapsuleShape.h @@ -64,8 +64,16 @@ class CapsuleShape : public CollisionShape { /// Private assignment operator CapsuleShape& operator=(const CapsuleShape& shape); + /// Return a local support point in a given direction with the object margin. + virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction, + void** cachedCollisionData) const; + + /// Return a local support point in a given direction without the object margin + virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction, + void** cachedCollisionData) const; + /// Return true if a point is inside the collision shape - bool testPointInside(const Vector3& localPoint) const; + virtual bool testPointInside(const Vector3& localPoint) const; public : @@ -89,12 +97,6 @@ class CapsuleShape : public CollisionShape { /// Return the number of bytes used by the collision shape virtual size_t getSizeInBytes() const; - /// Return a local support point in a given direction with the object margin. - virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const; - - /// Return a local support point in a given direction without the object margin - virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const; - /// Return the local bounds of the shape in x, y and z directions virtual void getLocalBounds(Vector3& min, Vector3& max) const; @@ -104,82 +106,12 @@ class CapsuleShape : public CollisionShape { /// Test equality between two capsule shapes virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const; - /// Create a proxy collision shape for the collision shape - virtual ProxyShape* createProxyShape(MemoryAllocator& allocator, CollisionBody* body, - const Transform& transform, decimal mass); - /// Raycast method virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const; /// Raycast method with feedback information virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - // -------------------- Friendship -------------------- // - - friend class ProxyCapsuleShape; -}; - -// Class ProxyCapsuleShape -/** - * The proxy collision shape for a capsule shape. - */ -class ProxyCapsuleShape : public ProxyShape { - - private: - - // -------------------- Attributes -------------------- // - - /// Pointer to the actual collision shape - CapsuleShape* mCollisionShape; - - - // -------------------- Methods -------------------- // - - /// Private copy-constructor - ProxyCapsuleShape(const ProxyCapsuleShape& proxyShape); - - /// Private assignment operator - ProxyCapsuleShape& operator=(const ProxyCapsuleShape& proxyShape); - - /// Return the non-const collision shape - virtual CollisionShape* getInternalCollisionShape() const; - - public: - - // -------------------- Methods -------------------- // - - /// Constructor - ProxyCapsuleShape(CapsuleShape* shape, CollisionBody* body, - const Transform& transform, decimal mass); - - /// Destructor - ~ProxyCapsuleShape(); - - /// Return the collision shape - virtual const CollisionShape* getCollisionShape() const; - - /// Return the number of bytes used by the proxy collision shape - virtual size_t getSizeInBytes() const; - - /// Return a local support point in a given direction with the object margin - virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction); - - /// Return a local support point in a given direction without the object margin - virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction); - - /// Return the current collision shape margin - virtual decimal getMargin() const; - - /// Raycast method - virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - /// Raycast method with feedback information - virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, - decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - /// Return true if a point is inside the collision shape - virtual bool testPointInside(const Vector3& worldPoint); }; /// Allocate and return a copy of the object @@ -223,50 +155,6 @@ inline bool CapsuleShape::isEqualTo(const CollisionShape& otherCollisionShape) c return (mRadius == otherShape.mRadius && mHalfHeight == otherShape.mHalfHeight); } -// Create a proxy collision shape for the collision shape -inline ProxyShape* CapsuleShape::createProxyShape(MemoryAllocator& allocator, CollisionBody* body, - const Transform& transform, decimal mass) { - return new (allocator.allocate(sizeof(ProxyCapsuleShape))) ProxyCapsuleShape(this, body, - transform, mass); -} - -// Return the non-const collision shape -inline CollisionShape* ProxyCapsuleShape::getInternalCollisionShape() const { - return mCollisionShape; -} - -// Return the collision shape -inline const CollisionShape* ProxyCapsuleShape::getCollisionShape() const { - return mCollisionShape; -} - -// Return the number of bytes used by the proxy collision shape -inline size_t ProxyCapsuleShape::getSizeInBytes() const { - return sizeof(ProxyCapsuleShape); -} - -// Return a local support point in a given direction with the object margin -inline Vector3 ProxyCapsuleShape::getLocalSupportPointWithMargin(const Vector3& direction) { - return mCollisionShape->getLocalSupportPointWithMargin(direction); -} - -// Return a local support point in a given direction without the object margin -inline Vector3 ProxyCapsuleShape::getLocalSupportPointWithoutMargin(const Vector3& direction) { - return mCollisionShape->getLocalSupportPointWithoutMargin(direction); -} - -// Return the current object margin -inline decimal ProxyCapsuleShape::getMargin() const { - return mCollisionShape->getMargin(); -} - -// Return true if a point is inside the collision shape -inline bool ProxyCapsuleShape::testPointInside(const Vector3& worldPoint) { - const Transform localToWorld = mBody->getTransform() * mLocalToBodyTransform; - const Vector3 localPoint = localToWorld.getInverse() * worldPoint; - return mCollisionShape->testPointInside(localPoint); -} - } #endif diff --git a/src/collision/shapes/CollisionShape.cpp b/src/collision/shapes/CollisionShape.cpp index 89292370..5b001e71 100644 --- a/src/collision/shapes/CollisionShape.cpp +++ b/src/collision/shapes/CollisionShape.cpp @@ -26,6 +26,7 @@ // Libraries #include "CollisionShape.h" #include "../../engine/Profiler.h" +#include "body/CollisionBody.h" // We want to use the ReactPhysics3D namespace using namespace reactphysics3d; @@ -75,15 +76,3 @@ void CollisionShape::computeAABB(AABB& aabb, const Transform& transform) const { aabb.setMin(minCoordinates); aabb.setMax(maxCoordinates); } - -// Constructor -ProxyShape::ProxyShape(CollisionBody* body, const Transform& transform, decimal mass) - :mBody(body), mLocalToBodyTransform(transform), mMass(mass), mNext(NULL), - mBroadPhaseID(-1) { - -} - -// Destructor -ProxyShape::~ProxyShape() { - -} diff --git a/src/collision/shapes/CollisionShape.h b/src/collision/shapes/CollisionShape.h index 87b57a31..48faa881 100644 --- a/src/collision/shapes/CollisionShape.h +++ b/src/collision/shapes/CollisionShape.h @@ -43,8 +43,8 @@ namespace reactphysics3d { enum CollisionShapeType {BOX, SPHERE, CONE, CYLINDER, CAPSULE, CONVEX_MESH}; // Declarations -class CollisionBody; class ProxyShape; +class CollisionBody; // Class CollisionShape /** @@ -74,6 +74,24 @@ 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) const=0; + + /// Raycast method + virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const=0; + + /// Raycast method with feedback information + virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, + decimal distance = RAYCAST_INFINITY_DISTANCE) const=0; + public : // -------------------- Methods -------------------- // @@ -120,115 +138,14 @@ class CollisionShape { /// Test equality between two collision shapes of the same type (same derived classes). virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const=0; - /// Create a proxy collision shape for the collision shape - virtual ProxyShape* createProxyShape(MemoryAllocator& allocator, CollisionBody* body, - const Transform& transform, decimal mass)=0; - - /// Raycast method - virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const=0; - - /// Raycast method with feedback information - virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, - decimal distance = RAYCAST_INFINITY_DISTANCE) const=0; -}; - - -// Class ProxyShape -/** - * The CollisionShape instances are supposed to be unique for memory optimization. For instance, - * consider two rigid bodies with the same sphere collision shape. In this situation, we will have - * a unique instance of SphereShape but we need to differentiate between the two instances during - * the collision detection. They do not have the same position in the world and they do not - * belong to the same rigid body. The ProxyShape class is used for that purpose by attaching a - * rigid body with one of its collision shape. A body can have multiple proxy shapes (one for - * each collision shape attached to the body). - */ -class ProxyShape { - - protected: - - // -------------------- Attributes -------------------- // - - /// Pointer to the parent body - CollisionBody* mBody; - - /// Local-space to parent body-space transform (does not change over time) - const Transform mLocalToBodyTransform; - - /// Mass (in kilogramms) of the corresponding collision shape - decimal mMass; - - /// Pointer to the next proxy shape of the body (linked list) - ProxyShape* mNext; - - /// Broad-phase ID (node ID in the dynamic AABB tree) - int mBroadPhaseID; - - // -------------------- Methods -------------------- // - - /// Private copy-constructor - ProxyShape(const ProxyShape& proxyShape); - - /// Private assignment operator - ProxyShape& operator=(const ProxyShape& proxyShape); - - /// Return the non-const collision shape - virtual CollisionShape* getInternalCollisionShape() const=0; - - public: - - // -------------------- Methods -------------------- // - - /// Constructor - ProxyShape(CollisionBody* body, const Transform& transform, decimal mass); - - /// Destructor - ~ProxyShape(); - - /// Return the collision shape - virtual const CollisionShape* getCollisionShape() const=0; - - /// Return the number of bytes used by the proxy collision shape - virtual size_t getSizeInBytes() const=0; - - /// Return the parent body - CollisionBody* getBody() const; - - /// Return the mass of the collision shape - decimal getMass() const; - - /// Return the local to parent body transform - const Transform& getLocalToBodyTransform() const; - - /// Return a local support point in a given direction with the object margin - virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction)=0; - - /// Return a local support point in a given direction without the object margin - virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction)=0; - - /// Return the current object margin - virtual decimal getMargin() const=0; - - /// Return true if a point is inside the collision shape - virtual bool testPointInside(const Vector3& worldPoint)=0; - - /// Raycast method - virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const=0; - - /// Raycast method with feedback information - virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, - decimal distance = RAYCAST_INFINITY_DISTANCE) const=0; - // -------------------- Friendship -------------------- // - friend class OverlappingPair; - friend class CollisionBody; - friend class RigidBody; - friend class BroadPhaseAlgorithm; - friend class DynamicAABBTree; - friend class CollisionDetection; + friend class ProxyShape; }; + + + // Return the type of the collision shape inline CollisionShapeType CollisionShape::getType() const { return mType; @@ -271,21 +188,6 @@ inline bool CollisionShape::operator==(const CollisionShape& otherCollisionShape return otherCollisionShape.isEqualTo(*this); } -// Return the parent body -inline CollisionBody* ProxyShape::getBody() const { - return mBody; -} - -// Return the mass of the collision shape -inline decimal ProxyShape::getMass() const { - return mMass; -} - -// Return the local to parent body transform -inline const Transform& ProxyShape::getLocalToBodyTransform() const { - return mLocalToBodyTransform; -} - } #endif diff --git a/src/collision/shapes/ConeShape.cpp b/src/collision/shapes/ConeShape.cpp index e0d77914..cad743cc 100644 --- a/src/collision/shapes/ConeShape.cpp +++ b/src/collision/shapes/ConeShape.cpp @@ -35,7 +35,6 @@ ConeShape::ConeShape(decimal radius, decimal height, decimal margin) : CollisionShape(CONE, margin), mRadius(radius), mHalfHeight(height * decimal(0.5)) { assert(mRadius > decimal(0.0)); assert(mHalfHeight > decimal(0.0)); - assert(margin > decimal(0.0)); // Compute the sine of the semi-angle at the apex point mSinTheta = mRadius / (sqrt(mRadius * mRadius + height * height)); @@ -54,10 +53,11 @@ ConeShape::~ConeShape() { } // Return a local support point in a given direction with the object margin -Vector3 ConeShape::getLocalSupportPointWithMargin(const Vector3& direction) const { +Vector3 ConeShape::getLocalSupportPointWithMargin(const Vector3& direction, + void** cachedCollisionData) const { // Compute the support point without the margin - Vector3 supportPoint = getLocalSupportPointWithoutMargin(direction); + Vector3 supportPoint = getLocalSupportPointWithoutMargin(direction, cachedCollisionData); // Add the margin to the support point Vector3 unitVec(0.0, -1.0, 0.0); @@ -70,7 +70,8 @@ Vector3 ConeShape::getLocalSupportPointWithMargin(const Vector3& direction) cons } // Return a local support point in a given direction without the object margin -Vector3 ConeShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const { +Vector3 ConeShape::getLocalSupportPointWithoutMargin(const Vector3& direction, + void** cachedCollisionData) const { const Vector3& v = direction; decimal sinThetaTimesLengthV = mSinTheta * v.length(); @@ -110,27 +111,3 @@ bool ConeShape::testPointInside(const Vector3& localPoint) const { // TODO : Implement this method return false; } - -// Constructor -ProxyConeShape::ProxyConeShape(ConeShape* shape, CollisionBody* body, - const Transform& transform, decimal mass) - :ProxyShape(body, transform, mass), mCollisionShape(shape){ - -} - -// Destructor -ProxyConeShape::~ProxyConeShape() { - -} - -// Raycast method -bool ProxyConeShape::raycast(const Ray& ray, decimal distance) const { - // TODO : Implement this method - return false; -} - -// Raycast method with feedback information -bool ProxyConeShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal distance) const { - // TODO : Implement this method - return false; -} diff --git a/src/collision/shapes/ConeShape.h b/src/collision/shapes/ConeShape.h index cd68a23a..683ddb4c 100644 --- a/src/collision/shapes/ConeShape.h +++ b/src/collision/shapes/ConeShape.h @@ -72,8 +72,16 @@ class ConeShape : public CollisionShape { /// Private assignment operator ConeShape& operator=(const ConeShape& shape); + /// Return a local support point in a given direction with the object margin + virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction, + void** cachedCollisionData) const; + + /// Return a local support point in a given direction without the object margin + virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction, + void** cachedCollisionData) const; + /// Return true if a point is inside the collision shape - bool testPointInside(const Vector3& localPoint) const; + virtual bool testPointInside(const Vector3& localPoint) const; public : @@ -97,12 +105,6 @@ class ConeShape : public CollisionShape { /// Return the number of bytes used by the collision shape virtual size_t getSizeInBytes() const; - /// Return a local support point in a given direction with the object margin - virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const; - - /// Return a local support point in a given direction without the object margin - virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const; - /// Return the local bounds of the shape in x, y and z directions virtual void getLocalBounds(Vector3& min, Vector3& max) const; @@ -112,82 +114,12 @@ class ConeShape : public CollisionShape { /// Test equality between two cone shapes virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const; - /// Create a proxy collision shape for the collision shape - virtual ProxyShape* createProxyShape(MemoryAllocator& allocator, CollisionBody* body, - const Transform& transform, decimal mass); - /// Raycast method virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const; /// Raycast method with feedback information virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - // -------------------- Friendship -------------------- // - - friend class ProxyConeShape; -}; - -// Class ProxyConeShape -/** - * The proxy collision shape for a cone shape. - */ -class ProxyConeShape : public ProxyShape { - - private: - - // -------------------- Attributes -------------------- // - - /// Pointer to the actual collision shape - ConeShape* mCollisionShape; - - - // -------------------- Methods -------------------- // - - /// Private copy-constructor - ProxyConeShape(const ProxyConeShape& proxyShape); - - /// Private assignment operator - ProxyConeShape& operator=(const ProxyConeShape& proxyShape); - - /// Return the non-const collision shape - virtual CollisionShape* getInternalCollisionShape() const; - - public: - - // -------------------- Methods -------------------- // - - /// Constructor - ProxyConeShape(ConeShape* shape, CollisionBody* body, - const Transform& transform, decimal mass); - - /// Destructor - ~ProxyConeShape(); - - /// Return the collision shape - virtual const CollisionShape* getCollisionShape() const; - - /// Return the number of bytes used by the proxy collision shape - virtual size_t getSizeInBytes() const; - - /// Return a local support point in a given direction with the object margin - virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction); - - /// Return a local support point in a given direction without the object margin - virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction); - - /// Return the current collision shape margin - virtual decimal getMargin() const; - - /// Raycast method - virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - /// Raycast method with feedback information - virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, - decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - /// Return true if a point is inside the collision body - virtual bool testPointInside(const Vector3& worldPoint); }; // Allocate and return a copy of the object @@ -239,50 +171,6 @@ inline bool ConeShape::isEqualTo(const CollisionShape& otherCollisionShape) cons return (mRadius == otherShape.mRadius && mHalfHeight == otherShape.mHalfHeight); } -// Create a proxy collision shape for the collision shape -inline ProxyShape* ConeShape::createProxyShape(MemoryAllocator& allocator, CollisionBody* body, - const Transform& transform, decimal mass) { - return new (allocator.allocate(sizeof(ProxyConeShape))) ProxyConeShape(this, body, - transform, mass); -} - -// Return the non-const collision shape -inline CollisionShape* ProxyConeShape::getInternalCollisionShape() const { - return mCollisionShape; -} - -// Return the collision shape -inline const CollisionShape* ProxyConeShape::getCollisionShape() const { - return mCollisionShape; -} - -// Return the number of bytes used by the proxy collision shape -inline size_t ProxyConeShape::getSizeInBytes() const { - return sizeof(ProxyConeShape); -} - -// Return a local support point in a given direction with the object margin -inline Vector3 ProxyConeShape::getLocalSupportPointWithMargin(const Vector3& direction) { - return mCollisionShape->getLocalSupportPointWithMargin(direction); -} - -// Return a local support point in a given direction without the object margin -inline Vector3 ProxyConeShape::getLocalSupportPointWithoutMargin(const Vector3& direction) { - return mCollisionShape->getLocalSupportPointWithoutMargin(direction); -} - -// Return the current object margin -inline decimal ProxyConeShape::getMargin() const { - return mCollisionShape->getMargin(); -} - -// Return true if a point is inside the collision shape -inline bool ProxyConeShape::testPointInside(const Vector3& worldPoint) { - const Transform localToWorld = mBody->getTransform() * mLocalToBodyTransform; - const Vector3 localPoint = localToWorld.getInverse() * worldPoint; - return mCollisionShape->testPointInside(localPoint); -} - } #endif diff --git a/src/collision/shapes/ConvexMeshShape.cpp b/src/collision/shapes/ConvexMeshShape.cpp index 76578cee..86ca3b87 100644 --- a/src/collision/shapes/ConvexMeshShape.cpp +++ b/src/collision/shapes/ConvexMeshShape.cpp @@ -38,7 +38,6 @@ ConvexMeshShape::ConvexMeshShape(const decimal* arrayVertices, uint nbVertices, mMaxBounds(0, 0, 0), mIsEdgesInformationUsed(false) { assert(nbVertices > 0); assert(stride > 0); - assert(margin > decimal(0.0)); const unsigned char* vertexPointer = (const unsigned char*) arrayVertices; @@ -59,7 +58,7 @@ ConvexMeshShape::ConvexMeshShape(const decimal* arrayVertices, uint nbVertices, ConvexMeshShape::ConvexMeshShape(decimal margin) : CollisionShape(CONVEX_MESH, margin), mNbVertices(0), mMinBounds(0, 0, 0), mMaxBounds(0, 0, 0), mIsEdgesInformationUsed(false) { - assert(margin > decimal(0.0)); + } // Private copy-constructor @@ -79,10 +78,10 @@ ConvexMeshShape::~ConvexMeshShape() { // Return a local support point in a given direction with the object margin Vector3 ConvexMeshShape::getLocalSupportPointWithMargin(const Vector3& direction, - uint& cachedSupportVertex) const { + void** cachedCollisionData) const { // Get the support point without the margin - Vector3 supportPoint = getLocalSupportPointWithoutMargin(direction, cachedSupportVertex); + Vector3 supportPoint = getLocalSupportPointWithoutMargin(direction, cachedCollisionData); // Get the unit direction vector Vector3 unitDirection = direction; @@ -104,16 +103,23 @@ Vector3 ConvexMeshShape::getLocalSupportPointWithMargin(const Vector3& direction /// will be in most of the cases very close to the previous one. Using hill-climbing, this method /// runs in almost constant time. Vector3 ConvexMeshShape::getLocalSupportPointWithoutMargin(const Vector3& direction, - uint& cachedSupportVertex) const { + void** cachedCollisionData) const { assert(mNbVertices == mVertices.size()); + assert(cachedCollisionData != NULL); + + // Allocate memory for the cached collision data if not allocated yet + if ((*cachedCollisionData) == NULL) { + *cachedCollisionData = (int*) malloc(sizeof(int)); + *((int*)(*cachedCollisionData)) = 0; + } // If the edges information is used to speed up the collision detection if (mIsEdgesInformationUsed) { assert(mEdgesAdjacencyList.size() == mNbVertices); - uint maxVertex = cachedSupportVertex; + uint maxVertex = *((int*)(*cachedCollisionData)); decimal maxDotProduct = direction.dot(mVertices[maxVertex]); bool isOptimal; @@ -143,7 +149,7 @@ Vector3 ConvexMeshShape::getLocalSupportPointWithoutMargin(const Vector3& direct } while(!isOptimal); // Cache the support vertex - cachedSupportVertex = maxVertex; + *((int*)(*cachedCollisionData)) = maxVertex; // Return the support vertex return mVertices[maxVertex]; @@ -235,29 +241,3 @@ bool ConvexMeshShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal // TODO : Implement this method return false; } - -// Constructor -ProxyConvexMeshShape::ProxyConvexMeshShape(ConvexMeshShape* shape, CollisionBody* body, - const Transform& transform, decimal mass) - :ProxyShape(body, transform, mass), mCollisionShape(shape), - mCachedSupportVertex(0) { - -} - -// Destructor -ProxyConvexMeshShape::~ProxyConvexMeshShape() { - -} - -// Raycast method -bool ProxyConvexMeshShape::raycast(const Ray& ray, decimal distance) const { - // TODO : Implement this method - return false; -} - -// Raycast method with feedback information -bool ProxyConvexMeshShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, - decimal distance) const { - // TODO : Implement this method - return false; -} diff --git a/src/collision/shapes/ConvexMeshShape.h b/src/collision/shapes/ConvexMeshShape.h index 89cfce79..6dbc584d 100644 --- a/src/collision/shapes/ConvexMeshShape.h +++ b/src/collision/shapes/ConvexMeshShape.h @@ -93,6 +93,17 @@ class ConvexMeshShape : public CollisionShape { /// Recompute the bounds of the mesh void recalculateBounds(); + /// Return a local support point in a given direction with the object margin + virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction, + void** cachedCollisionData) const; + + /// Return a local support point in a given direction without the object margin. + virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction, + void** cachedCollisionData) const; + + /// Return true if a point is inside the collision shape + virtual bool testPointInside(const Vector3& localPoint) const; + public : // -------------------- Methods -------------------- // @@ -113,14 +124,6 @@ class ConvexMeshShape : public CollisionShape { /// Return the number of bytes used by the collision shape virtual size_t getSizeInBytes() const; - /// Return a local support point in a given direction with the object margin - virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction, - uint& cachedSupportVertex) const; - - /// Return a local support point in a given direction without the object margin. - virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction, - uint& cachedSupportVertex) const; - /// Return the local bounds of the shape in x, y and z directions virtual void getLocalBounds(Vector3& min, Vector3& max) const; @@ -143,85 +146,12 @@ class ConvexMeshShape : public CollisionShape { /// collision detection void setIsEdgesInformationUsed(bool isEdgesUsed); - /// Create a proxy collision shape for the collision shape - virtual ProxyShape* createProxyShape(MemoryAllocator& allocator, CollisionBody* body, - const Transform& transform, decimal mass); - /// Raycast method virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const; /// Raycast method with feedback information virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - // -------------------- Friendship -------------------- // - - friend class ProxyConvexMeshShape; -}; - - -// Class ProxyConvexMeshSphape -/** - * The proxy collision shape for a convex mesh shape. - */ -class ProxyConvexMeshShape : public ProxyShape { - - private: - - // -------------------- Attributes -------------------- // - - /// Pointer to the actual collision shape - ConvexMeshShape* mCollisionShape; - - /// Cached support vertex index (previous support vertex for hill-climbing) - uint mCachedSupportVertex; - - // -------------------- Methods -------------------- // - - /// Private copy-constructor - ProxyConvexMeshShape(const ProxyConvexMeshShape& proxyShape); - - /// Private assignment operator - ProxyConvexMeshShape& operator=(const ProxyConvexMeshShape& proxyShape); - - /// Return the non-const collision shape - virtual CollisionShape* getInternalCollisionShape() const; - - public: - - // -------------------- Methods -------------------- // - - /// Constructor - ProxyConvexMeshShape(ConvexMeshShape* shape, CollisionBody* body, - const Transform& transform, decimal mass); - - /// Destructor - ~ProxyConvexMeshShape(); - - /// Return the collision shape - virtual const CollisionShape* getCollisionShape() const; - - /// Return the number of bytes used by the proxy collision shape - virtual size_t getSizeInBytes() const; - - /// Return a local support point in a given direction with the object margin - virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction); - - /// Return a local support point in a given direction without the object margin - virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction); - - /// Return the current collision shape margin - virtual decimal getMargin() const; - - /// Raycast method - virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - /// Raycast method with feedback information - virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, - decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - /// Return true if a point is inside the collision shape - virtual bool testPointInside(const Vector3& worldPoint); }; // Allocate and return a copy of the object @@ -306,48 +236,10 @@ inline void ConvexMeshShape::setIsEdgesInformationUsed(bool isEdgesUsed) { mIsEdgesInformationUsed = isEdgesUsed; } -// Create a proxy collision shape for the collision shape -inline ProxyShape* ConvexMeshShape::createProxyShape(MemoryAllocator& allocator, - CollisionBody* body, - const Transform& transform, - decimal mass) { - return new (allocator.allocate(sizeof(ProxyConvexMeshShape))) ProxyConvexMeshShape(this, body, - transform, mass); -} - -// Return the non-const collision shape -inline CollisionShape* ProxyConvexMeshShape::getInternalCollisionShape() const { - return mCollisionShape; -} - -// Return the collision shape -inline const CollisionShape* ProxyConvexMeshShape::getCollisionShape() const { - return mCollisionShape; -} - -// Return the number of bytes used by the proxy collision shape -inline size_t ProxyConvexMeshShape::getSizeInBytes() const { - return sizeof(ProxyConvexMeshShape); -} - -// Return a local support point in a given direction with the object margin -inline Vector3 ProxyConvexMeshShape::getLocalSupportPointWithMargin(const Vector3& direction) { - return mCollisionShape->getLocalSupportPointWithMargin(direction, mCachedSupportVertex); -} - -// Return a local support point in a given direction without the object margin -inline Vector3 ProxyConvexMeshShape::getLocalSupportPointWithoutMargin(const Vector3& direction) { - return mCollisionShape->getLocalSupportPointWithoutMargin(direction, mCachedSupportVertex); -} - -// Return the current object margin -inline decimal ProxyConvexMeshShape::getMargin() const { - return mCollisionShape->getMargin(); -} - // Return true if a point is inside the collision shape -inline bool ProxyConvexMeshShape::testPointInside(const Vector3& worldPoint) { - return mBody->mWorld.mCollisionDetection.mNarrowPhaseGJKAlgorithm.testPointInside(worldPoint,this); +inline bool ConvexMeshShape::testPointInside(const Vector3& localPoint) const { + // TODO : Implement this + return false; } } diff --git a/src/collision/shapes/CylinderShape.cpp b/src/collision/shapes/CylinderShape.cpp index 78cfa9e2..3218914d 100644 --- a/src/collision/shapes/CylinderShape.cpp +++ b/src/collision/shapes/CylinderShape.cpp @@ -35,7 +35,6 @@ CylinderShape::CylinderShape(decimal radius, decimal height, decimal margin) mHalfHeight(height/decimal(2.0)) { assert(radius > decimal(0.0)); assert(height > decimal(0.0)); - assert(margin > decimal(0.0)); } // Private copy-constructor @@ -50,10 +49,11 @@ CylinderShape::~CylinderShape() { } // Return a local support point in a given direction with the object margin -Vector3 CylinderShape::getLocalSupportPointWithMargin(const Vector3& direction) const { +Vector3 CylinderShape::getLocalSupportPointWithMargin(const Vector3& direction, + void** cachedCollisionData) const { // Compute the support point without the margin - Vector3 supportPoint = getLocalSupportPointWithoutMargin(direction); + Vector3 supportPoint = getLocalSupportPointWithoutMargin(direction, NULL); // Add the margin to the support point Vector3 unitVec(0.0, 1.0, 0.0); @@ -66,7 +66,8 @@ Vector3 CylinderShape::getLocalSupportPointWithMargin(const Vector3& direction) } // Return a local support point in a given direction without the object margin -Vector3 CylinderShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const { +Vector3 CylinderShape::getLocalSupportPointWithoutMargin(const Vector3& direction, + void** cachedCollisionData) const { Vector3 supportPoint(0.0, 0.0, 0.0); decimal uDotv = direction.y; @@ -103,27 +104,3 @@ bool CylinderShape::testPointInside(const Vector3& localPoint) const { // TODO : Implement this method return false; } - -// Constructor -ProxyCylinderShape::ProxyCylinderShape(CylinderShape* cylinderShape, CollisionBody* body, - const Transform& transform, decimal mass) - :ProxyShape(body, transform, mass), mCollisionShape(cylinderShape){ - -} - -// Destructor -ProxyCylinderShape::~ProxyCylinderShape() { - -} - -// Raycast method -bool ProxyCylinderShape::raycast(const Ray& ray, decimal distance) const { - // TODO : Implement this method - return false; -} - -// Raycast method with feedback information -bool ProxyCylinderShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal distance) const { - // TODO : Implement this method - return false; -} diff --git a/src/collision/shapes/CylinderShape.h b/src/collision/shapes/CylinderShape.h index d89fc992..ab0ccd64 100644 --- a/src/collision/shapes/CylinderShape.h +++ b/src/collision/shapes/CylinderShape.h @@ -69,8 +69,16 @@ class CylinderShape : public CollisionShape { /// Private assignment operator CylinderShape& operator=(const CylinderShape& shape); + /// Return a local support point in a given direction with the object margin + virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction, + void** cachedCollisionData) const; + + /// Return a local support point in a given direction without the object margin + virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction, + void** cachedCollisionData) const; + /// Return true if a point is inside the collision shape - bool testPointInside(const Vector3& localPoint) const; + virtual bool testPointInside(const Vector3& localPoint) const; public : @@ -94,12 +102,6 @@ class CylinderShape : public CollisionShape { /// Return the number of bytes used by the collision shape virtual size_t getSizeInBytes() const; - /// Return a local support point in a given direction with the object margin - virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const; - - /// Return a local support point in a given direction without the object margin - virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const; - /// Return the local bounds of the shape in x, y and z directions virtual void getLocalBounds(Vector3& min, Vector3& max) const; @@ -109,81 +111,12 @@ class CylinderShape : public CollisionShape { /// Test equality between two cylinder shapes virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const; - /// Create a proxy collision shape for the collision shape - virtual ProxyShape* createProxyShape(MemoryAllocator& allocator, CollisionBody* body, - const Transform& transform, decimal mass); - /// Raycast method virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const; /// Raycast method with feedback information virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - // -------------------- Friendship -------------------- // - - friend class ProxyCylinderShape; -}; - -// Class ProxyCylinderShape -/** - * The proxy collision shape for a cylinder shape. - */ -class ProxyCylinderShape : public ProxyShape { - - private: - - // -------------------- Attributes -------------------- // - - /// Pointer to the actual collision shape - CylinderShape* mCollisionShape; - - // -------------------- Methods -------------------- // - - /// Private copy-constructor - ProxyCylinderShape(const ProxyCylinderShape& proxyShape); - - /// Private assignment operator - ProxyCylinderShape& operator=(const ProxyCylinderShape& proxyShape); - - /// Return the non-const collision shape - virtual CollisionShape* getInternalCollisionShape() const; - - public: - - // -------------------- Methods -------------------- // - - /// Constructor - ProxyCylinderShape(CylinderShape* cylinderShape, CollisionBody* body, - const Transform& transform, decimal mass); - - /// Destructor - ~ProxyCylinderShape(); - - /// Return the collision shape - virtual const CollisionShape* getCollisionShape() const; - - /// Return the number of bytes used by the proxy collision shape - virtual size_t getSizeInBytes() const; - - /// Return a local support point in a given direction with the object margin - virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction); - - /// Return a local support point in a given direction without the object margin - virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction); - - /// Return the current collision shape margin - virtual decimal getMargin() const; - - /// Raycast method - virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - /// Raycast method with feedback information - virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, - decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - /// Return true if a point is inside the collision shape - virtual bool testPointInside(const Vector3& worldPoint); }; /// Allocate and return a copy of the object @@ -235,49 +168,6 @@ inline bool CylinderShape::isEqualTo(const CollisionShape& otherCollisionShape) return (mRadius == otherShape.mRadius && mHalfHeight == otherShape.mHalfHeight); } -// Create a proxy collision shape for the collision shape -inline ProxyShape* CylinderShape::createProxyShape(MemoryAllocator& allocator, CollisionBody* body, - const Transform& transform, decimal mass) { - return new (allocator.allocate(sizeof(ProxyCylinderShape))) ProxyCylinderShape(this, body, - transform, mass); -} - -// Return the non-const collision shape -inline CollisionShape* ProxyCylinderShape::getInternalCollisionShape() const { - return mCollisionShape; -} - -// Return the collision shape -inline const CollisionShape* ProxyCylinderShape::getCollisionShape() const { - return mCollisionShape; -} - -// Return the number of bytes used by the proxy collision shape -inline size_t ProxyCylinderShape::getSizeInBytes() const { - return sizeof(ProxyCylinderShape); -} - -// Return a local support point in a given direction with the object margin -inline Vector3 ProxyCylinderShape::getLocalSupportPointWithMargin(const Vector3& direction) { - return mCollisionShape->getLocalSupportPointWithMargin(direction); -} - -// Return a local support point in a given direction without the object margin -inline Vector3 ProxyCylinderShape::getLocalSupportPointWithoutMargin(const Vector3& direction) { - return mCollisionShape->getLocalSupportPointWithoutMargin(direction); -} - -// Return the current object margin -inline decimal ProxyCylinderShape::getMargin() const { - return mCollisionShape->getMargin(); -} - -// Return true if a point is inside the collision shape -inline bool ProxyCylinderShape::testPointInside(const Vector3& worldPoint) { - const Transform localToWorld = mBody->getTransform() * mLocalToBodyTransform; - const Vector3 localPoint = localToWorld.getInverse() * worldPoint; - return mCollisionShape->testPointInside(localPoint); -} } diff --git a/src/collision/shapes/SphereShape.cpp b/src/collision/shapes/SphereShape.cpp index f01dd463..cb12e6c2 100644 --- a/src/collision/shapes/SphereShape.cpp +++ b/src/collision/shapes/SphereShape.cpp @@ -63,27 +63,3 @@ bool SphereShape::testPointInside(const Vector3& localPoint) const { // TODO : Implement this method return false; } - -// Constructor -ProxySphereShape::ProxySphereShape(SphereShape* shape, CollisionBody* body, - const Transform& transform, decimal mass) - :ProxyShape(body, transform, mass), mCollisionShape(shape){ - -} - -// Destructor -ProxySphereShape::~ProxySphereShape() { - -} - -// Raycast method -bool ProxySphereShape::raycast(const Ray& ray, decimal distance) const { - // TODO : Implement this method - return false; -} - -// Raycast method with feedback information -bool ProxySphereShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal distance) const { - // TODO : Implement this method - return false; -} diff --git a/src/collision/shapes/SphereShape.h b/src/collision/shapes/SphereShape.h index 374a8a92..8517c287 100644 --- a/src/collision/shapes/SphereShape.h +++ b/src/collision/shapes/SphereShape.h @@ -59,8 +59,16 @@ class SphereShape : public CollisionShape { /// Private assignment operator SphereShape& operator=(const SphereShape& shape); + /// Return a local support point in a given direction with the object margin + virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction, + void** cachedCollisionData) const; + + /// Return a local support point in a given direction without the object margin + virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction, + void** cachedCollisionData) const; + /// Return true if a point is inside the collision shape - bool testPointInside(const Vector3& localPoint) const; + virtual bool testPointInside(const Vector3& localPoint) const; public : @@ -81,12 +89,6 @@ class SphereShape : public CollisionShape { /// Return the number of bytes used by the collision shape virtual size_t getSizeInBytes() const; - /// Return a local support point in a given direction with the object margin - virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const; - - /// Return a local support point in a given direction without the object margin - virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const; - /// Return the local bounds of the shape in x, y and z directions. virtual void getLocalBounds(Vector3& min, Vector3& max) const; @@ -99,83 +101,12 @@ class SphereShape : public CollisionShape { /// Test equality between two sphere shapes virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const; - /// Create a proxy collision shape for the collision shape - virtual ProxyShape* createProxyShape(MemoryAllocator& allocator, CollisionBody* body, - const Transform& transform, decimal mass); - /// Raycast method virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const; /// Raycast method with feedback information virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - // -------------------- Friendship -------------------- // - - friend class ProxySphereShape; -}; - - -// Class ProxySphereShape -/** - * The proxy collision shape for a sphere shape. - */ -class ProxySphereShape : public ProxyShape { - - private: - - // -------------------- Attributes -------------------- // - - /// Pointer to the actual collision shape - SphereShape* mCollisionShape; - - - // -------------------- Methods -------------------- // - - /// Private copy-constructor - ProxySphereShape(const ProxySphereShape& proxyShape); - - /// Private assignment operator - ProxySphereShape& operator=(const ProxySphereShape& proxyShape); - - /// Return the non-const collision shape - virtual CollisionShape* getInternalCollisionShape() const; - - public: - - // -------------------- Methods -------------------- // - - /// Constructor - ProxySphereShape(SphereShape* shape, CollisionBody* body, - const Transform& transform, decimal mass); - - /// Destructor - ~ProxySphereShape(); - - /// Return the collision shape - virtual const CollisionShape* getCollisionShape() const; - - /// Return the number of bytes used by the proxy collision shape - virtual size_t getSizeInBytes() const; - - /// Return a local support point in a given direction with the object margin - virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction); - - /// Return a local support point in a given direction without the object margin - virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction); - - /// Return the current collision shape margin - virtual decimal getMargin() const; - - /// Raycast method - virtual bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - /// Raycast method with feedback information - virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, - decimal distance = RAYCAST_INFINITY_DISTANCE) const; - - /// Return true if a point is inside the collision shape - virtual bool testPointInside(const Vector3& worldPoint); }; /// Allocate and return a copy of the object @@ -194,7 +125,8 @@ inline size_t SphereShape::getSizeInBytes() const { } // Return a local support point in a given direction with the object margin -inline Vector3 SphereShape::getLocalSupportPointWithMargin(const Vector3& direction) const { +inline Vector3 SphereShape::getLocalSupportPointWithMargin(const Vector3& direction, + void** cachedCollisionData) const { // If the direction vector is not the zero vector if (direction.lengthSquare() >= MACHINE_EPSILON * MACHINE_EPSILON) { @@ -209,7 +141,8 @@ inline Vector3 SphereShape::getLocalSupportPointWithMargin(const Vector3& direct } // Return a local support point in a given direction without the object margin -inline Vector3 SphereShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const { +inline Vector3 SphereShape::getLocalSupportPointWithoutMargin(const Vector3& direction, + void** cachedCollisionData) const { // Return the center of the sphere (the radius is taken into account in the object margin) return Vector3(0.0, 0.0, 0.0); @@ -255,50 +188,6 @@ inline bool SphereShape::isEqualTo(const CollisionShape& otherCollisionShape) co return (mRadius == otherShape.mRadius); } -// Create a proxy collision shape for the collision shape -inline ProxyShape* SphereShape::createProxyShape(MemoryAllocator& allocator, CollisionBody* body, - const Transform& transform, decimal mass) { - return new (allocator.allocate(sizeof(ProxySphereShape))) ProxySphereShape(this, body, - transform, mass); -} - -// Return the non-const collision shape -inline CollisionShape* ProxySphereShape::getInternalCollisionShape() const { - return mCollisionShape; -} - -// Return the collision shape -inline const CollisionShape* ProxySphereShape::getCollisionShape() const { - return mCollisionShape; -} - -// Return the number of bytes used by the proxy collision shape -inline size_t ProxySphereShape::getSizeInBytes() const { - return sizeof(ProxySphereShape); -} - -// Return a local support point in a given direction with the object margin -inline Vector3 ProxySphereShape::getLocalSupportPointWithMargin(const Vector3& direction) { - return mCollisionShape->getLocalSupportPointWithMargin(direction); -} - -// Return a local support point in a given direction without the object margin -inline Vector3 ProxySphereShape::getLocalSupportPointWithoutMargin(const Vector3& direction) { - return mCollisionShape->getLocalSupportPointWithoutMargin(direction); -} - -// Return the current object margin -inline decimal ProxySphereShape::getMargin() const { - return mCollisionShape->getMargin(); -} - -// Return true if a point is inside the collision shape -inline bool ProxySphereShape::testPointInside(const Vector3& worldPoint) { - const Transform localToWorld = mBody->getTransform() * mLocalToBodyTransform; - const Vector3 localPoint = localToWorld.getInverse() * worldPoint; - return mCollisionShape->testPointInside(localPoint); -} - } #endif diff --git a/src/constraint/ContactPoint.cpp b/src/constraint/ContactPoint.cpp index c4ad1d9c..be1e74cf 100644 --- a/src/constraint/ContactPoint.cpp +++ b/src/constraint/ContactPoint.cpp @@ -25,6 +25,7 @@ // Libraries #include "ContactPoint.h" +#include "collision/ProxyShape.h" using namespace reactphysics3d; using namespace std; diff --git a/src/engine/CollisionWorld.cpp b/src/engine/CollisionWorld.cpp index c15f70d1..bf0ea54e 100644 --- a/src/engine/CollisionWorld.cpp +++ b/src/engine/CollisionWorld.cpp @@ -166,4 +166,16 @@ void CollisionWorld::removeCollisionShape(CollisionShape* collisionShape) { } } +/// Raycast method +bool CollisionWorld::raycast(const Ray& ray, decimal distance) { + // TODO : Implement this method + return false; +} + +/// Raycast method with feedback information +bool CollisionWorld::raycast(const Ray& ray, RaycastInfo& raycastInfo, decimal distance) { + // TODO : Implement this method + return false; +} + diff --git a/src/engine/CollisionWorld.h b/src/engine/CollisionWorld.h index 59f62c9b..7a52845e 100644 --- a/src/engine/CollisionWorld.h +++ b/src/engine/CollisionWorld.h @@ -121,13 +121,11 @@ class CollisionWorld { void destroyCollisionBody(CollisionBody* collisionBody); /// Raycast method - // TODO : Implement this method - bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE) const; + bool raycast(const Ray& ray, decimal distance = RAYCAST_INFINITY_DISTANCE); /// Raycast method with feedback information - // TODO : Implement this method bool raycast(const Ray& ray, RaycastInfo& raycastInfo, - decimal distance = RAYCAST_INFINITY_DISTANCE) const; + decimal distance = RAYCAST_INFINITY_DISTANCE); // -------------------- Friendship -------------------- // diff --git a/src/engine/OverlappingPair.h b/src/engine/OverlappingPair.h index 4a3e7b17..578f1e43 100644 --- a/src/engine/OverlappingPair.h +++ b/src/engine/OverlappingPair.h @@ -28,6 +28,7 @@ // Libraries #include "ContactManifold.h" +#include "collision/ProxyShape.h" #include "../collision/shapes/CollisionShape.h" /// ReactPhysics3D namespace diff --git a/test/tests/collision/TestPointInside.h b/test/tests/collision/TestPointInside.h index abb87a2f..e0805733 100644 --- a/test/tests/collision/TestPointInside.h +++ b/test/tests/collision/TestPointInside.h @@ -68,13 +68,13 @@ class TestPointInside : public Test { Transform mLocalShape2ToWorld; // Collision Shapes - ProxyBoxShape* mBoxShape; - ProxySphereShape* mSphereShape; - ProxyCapsuleShape* mCapsuleShape; - ProxyConeShape* mConeShape; - ProxyConvexMeshShape* mConvexMeshShape; - ProxyConvexMeshShape* mConvexMeshShapeEdgesInfo; - ProxyCylinderShape* mCylinderShape; + ProxyShape* mBoxShape; + ProxyShape* mSphereShape; + ProxyShape* mCapsuleShape; + ProxyShape* mConeShape; + ProxyShape* mConvexMeshShape; + ProxyShape* mConvexMeshShapeEdgesInfo; + ProxyShape* mCylinderShape; public : @@ -130,7 +130,7 @@ class TestPointInside : public Test { convexMeshShape.addVertex(Vector3(2, 3, 4)); convexMeshShape.addVertex(Vector3(-2, 3, -4)); convexMeshShape.addVertex(Vector3(2, 3, -4)); - mConvexMeshShape = mConvexMeshBody->addCollisionShape(convexMeshShape, shapeTransform); + mConvexMeshShape = mConvexMeshBody->addCollisionShape(convexMeshShape, mShapeTransform); ConvexMeshShape convexMeshShapeEdgesInfo(0); convexMeshShapeEdgesInfo.addVertex(Vector3(-2, -3, 4)); @@ -158,14 +158,14 @@ class TestPointInside : public Test { convexMeshShapeEdgesInfo); CylinderShape cylinderShape(3, 8, 0); - mCylinderShape = mCylinderBody->addCollisionShape(cylinderShape, shapeTransform); + mCylinderShape = mCylinderBody->addCollisionShape(cylinderShape, mShapeTransform); // Compound shape is a cylinder and a sphere Vector3 positionShape2(Vector3(4, 2, -3)); Quaternion orientationShape2(-3 *PI / 8, 1.5 * PI/ 3, PI / 13); Transform shapeTransform2(positionShape2, orientationShape2); mLocalShape2ToWorld = mBodyTransform * shapeTransform2; - mCompoundBody->addCollisionShape(cylinderShape, shapeTransform); + mCompoundBody->addCollisionShape(cylinderShape, mShapeTransform); mCompoundBody->addCollisionShape(sphereShape, shapeTransform2); } diff --git a/test/tests/collision/TestRaycast.h b/test/tests/collision/TestRaycast.h index e6bd5806..c164f048 100644 --- a/test/tests/collision/TestRaycast.h +++ b/test/tests/collision/TestRaycast.h @@ -28,14 +28,14 @@ // Libraries #include "../../Test.h" -#include "../../src/engine/CollisionWorld.h" -#include "../../src/body/CollisionBody.h" -#include "../../src/collision/shapes/BoxShape.h" -#include "../../src/collision/shapes/SphereShape.h" -#include "../../src/collision/shapes/CapsuleShape.h" -#include "../../src/collision/shapes/ConeShape.h" -#include "../../src/collision/shapes/ConvexMeshShape.h" -#include "../../src/collision/shapes/CylinderShape.h" +#include "engine/CollisionWorld.h" +#include "body/CollisionBody.h" +#include "collision/shapes/BoxShape.h" +#include "collision/shapes/SphereShape.h" +#include "collision/shapes/CapsuleShape.h" +#include "collision/shapes/ConeShape.h" +#include "collision/shapes/ConvexMeshShape.h" +#include "collision/shapes/CylinderShape.h" /// Reactphysics3D namespace namespace reactphysics3d { @@ -51,7 +51,7 @@ class TestRaycast : public Test { // ---------- Atributes ---------- // // Physics world - DynamicsWorld* mWorld; + CollisionWorld* mWorld; // Bodies CollisionBody* mBoxBody; @@ -70,13 +70,13 @@ class TestRaycast : public Test { Transform mLocalShape2ToWorld; // Collision Shapes - ProxyBoxShape* mBoxShape; - ProxySphereShape* mSphereShape; - ProxyCapsuleShape* mCapsuleShape; - ProxyConeShape* mConeShape; - ProxyConvexMeshShape* mConvexMeshShape; - ProxyConvexMeshShape* mConvexMeshShapeEdgesInfo; - ProxyCylinderShape* mCylinderShape; + ProxyShape* mBoxShape; + ProxyShape* mSphereShape; + ProxyShape* mCapsuleShape; + ProxyShape* mConeShape; + ProxyShape* mConvexMeshShape; + ProxyShape* mConvexMeshShapeEdgesInfo; + ProxyShape* mCylinderShape; public : @@ -86,7 +86,7 @@ class TestRaycast : public Test { TestRaycast() { // Create the world - mWorld = new rp3d::CollisionWorld(); + mWorld = new CollisionWorld(); // Body transform Vector3 position(-3, 2, 7); @@ -94,13 +94,13 @@ class TestRaycast : public Test { mBodyTransform = Transform(position, orientation); // Create the bodies - mBoxBody = mWorld->createCollisionBody(bodyTransform); - mSphereBody = mWorld->createCollisionBody(bodyTransform); - mCapsuleBody = mWorld->createCollisionBody(bodyTransform); - mConeBody = mWorld->createCollisionBody(bodyTransform); - mConvexMeshBody = mWorld->createCollisionBody(bodyTransform); - mConvexMeshBodyEdgesInfo = mWorld->createCollisionBody(bodyTransform); - mCylinderBody = mWorld->createCollisionBody(bodyTransform); + mBoxBody = mWorld->createCollisionBody(mBodyTransform); + mSphereBody = mWorld->createCollisionBody(mBodyTransform); + mCapsuleBody = mWorld->createCollisionBody(mBodyTransform); + mConeBody = mWorld->createCollisionBody(mBodyTransform); + mConvexMeshBody = mWorld->createCollisionBody(mBodyTransform); + mConvexMeshBodyEdgesInfo = mWorld->createCollisionBody(mBodyTransform); + mCylinderBody = mWorld->createCollisionBody(mBodyTransform); // Collision shape transform Vector3 shapePosition(1, -4, -3); @@ -112,16 +112,16 @@ class TestRaycast : public Test { // Create collision shapes BoxShape boxShape(Vector3(2, 3, 4), 0); - mBoxShape = mBoxBody->addCollisionShape(boxShape, shapeTransform); + mBoxShape = mBoxBody->addCollisionShape(boxShape, mShapeTransform); SphereShape sphereShape(3); - mSphereShape = mSphereBody->addCollisionShape(sphereShape, shapeTransform); + mSphereShape = mSphereBody->addCollisionShape(sphereShape, mShapeTransform); CapsuleShape capsuleShape(2, 5); - mCapsuleShape = mCapsuleBody->addCollisionShape(capsuleShape, shapeTransform); + mCapsuleShape = mCapsuleBody->addCollisionShape(capsuleShape, mShapeTransform); ConeShape coneShape(2, 6, 0); - mConeShape = mConeBody->addCollisionShape(coneShape, shapeTransform); + mConeShape = mConeBody->addCollisionShape(coneShape, mShapeTransform); ConvexMeshShape convexMeshShape(0); // Box of dimension (2, 3, 4) convexMeshShape.addVertex(Vector3(-2, -3, 4)); @@ -132,7 +132,7 @@ class TestRaycast : public Test { convexMeshShape.addVertex(Vector3(2, 3, 4)); convexMeshShape.addVertex(Vector3(-2, 3, -4)); convexMeshShape.addVertex(Vector3(2, 3, -4)); - mConvexMeshShape = mConvexMeshBody->addCollisionShape(convexMeshShape, shapeTransform); + mConvexMeshShape = mConvexMeshBody->addCollisionShape(convexMeshShape, mShapeTransform); ConvexMeshShape convexMeshShapeEdgesInfo(0); convexMeshShapeEdgesInfo.addVertex(Vector3(-2, -3, 4)); @@ -160,14 +160,14 @@ class TestRaycast : public Test { convexMeshShapeEdgesInfo); CylinderShape cylinderShape(2, 5, 0); - mCylinderShape = mCylinderBody->addCollisionShape(cylinderShape, shapeTransform); + mCylinderShape = mCylinderBody->addCollisionShape(cylinderShape, mShapeTransform); // Compound shape is a cylinder and a sphere - Vector3 (Vector3(4, 2, -3)); + Vector3 positionShape2(Vector3(4, 2, -3)); Quaternion orientationShape2(-3 *PI / 8, 1.5 * PI/ 3, PI / 13); Transform shapeTransform2(positionShape2, orientationShape2); mLocalShape2ToWorld = mBodyTransform * shapeTransform2; - mCompoundBody->addCollisionShape(cylinderShape, shapeTransform); + mCompoundBody->addCollisionShape(cylinderShape, mShapeTransform); mCompoundBody->addCollisionShape(sphereShape, shapeTransform2); } @@ -674,8 +674,8 @@ class TestRaycast : public Test { // CollisionBody::raycast() RaycastInfo raycastInfo2; test(mConeBody->raycast(ray, raycastInfo2)); - test(raycastInfo2.body == mConeShape); - test(raycastInfo2.proxyShape == mBoxShape); + test(raycastInfo2.body == mConeBody); + test(raycastInfo2.proxyShape == mConeShape); test(approxEqual(raycastInfo2.distance, 6)); test(approxEqual(raycastInfo2.worldPoint.x, hitPoint.x)); test(approxEqual(raycastInfo2.worldPoint.y, hitPoint.y)); @@ -1174,6 +1174,9 @@ class TestRaycast : public Test { /// CollisionWorld::raycast() methods. void testCompound() { + // ----- Test feedback data ----- // + const Matrix3x3 mLocalToWorldMatrix = mLocalShapeToWorld.getOrientation().getMatrix(); + // Raycast hit agains the sphere shape Ray ray1(mLocalShape2ToWorld * Vector3(4, 1, 2), mLocalToWorldMatrix * Vector3(-4, 0, 0)); Ray ray2(mLocalShape2ToWorld * Vector3(1, 4, -1), mLocalToWorldMatrix * Vector3(0, -3, 0)); @@ -1182,34 +1185,35 @@ class TestRaycast : public Test { Ray ray5(mLocalShape2ToWorld * Vector3(0, -4, 1), mLocalToWorldMatrix * Vector3(0, 3, 0)); Ray ray6(mLocalShape2ToWorld * Vector3(-1, 2, -11), mLocalToWorldMatrix * Vector3(0, 0, 8)); - test(mCompoundBody->raycast(ray1, raycastInfo3)); - test(mWorld->raycast(ray1, raycastInfo3)); - test(mWorld->raycast(ray1, raycastInfo3, 2)); + RaycastInfo raycastInfo; + test(mCompoundBody->raycast(ray1, raycastInfo)); + test(mWorld->raycast(ray1, raycastInfo)); + test(mWorld->raycast(ray1, raycastInfo, 2)); test(mWorld->raycast(ray1)); - test(mCompoundBody->raycast(ray2, raycastInfo3)); - test(mWorld->raycast(ray2, raycastInfo3)); - test(mWorld->raycast(ray2, raycastInfo3, 2)); + test(mCompoundBody->raycast(ray2, raycastInfo)); + test(mWorld->raycast(ray2, raycastInfo)); + test(mWorld->raycast(ray2, raycastInfo, 2)); test(mWorld->raycast(ray2)); - test(mCompoundBody->raycast(ray3, raycastInfo3)); - test(mWorld->raycast(ray3, raycastInfo3)); - test(mWorld->raycast(ray3, raycastInfo3, 2)); + test(mCompoundBody->raycast(ray3, raycastInfo)); + test(mWorld->raycast(ray3, raycastInfo)); + test(mWorld->raycast(ray3, raycastInfo, 2)); test(mWorld->raycast(ray3)); - test(mCompoundBody->raycast(ray4, raycastInfo3)); - test(mWorld->raycast(ray4, raycastInfo3)); - test(mWorld->raycast(ray4, raycastInfo3, 2)); + test(mCompoundBody->raycast(ray4, raycastInfo)); + test(mWorld->raycast(ray4, raycastInfo)); + test(mWorld->raycast(ray4, raycastInfo, 2)); test(mWorld->raycast(ray4)); - test(mCompoundBody->raycast(ray5, raycastInfo3)); - test(mWorld->raycast(ray5, raycastInfo3)); - test(mWorld->raycast(ray5, raycastInfo3, 2)); + test(mCompoundBody->raycast(ray5, raycastInfo)); + test(mWorld->raycast(ray5, raycastInfo)); + test(mWorld->raycast(ray5, raycastInfo, 2)); test(mWorld->raycast(ray5)); - test(mCompoundBody->raycast(ray6, raycastInfo3)); - test(mWorld->raycast(ray6, raycastInfo3)); - test(mWorld->raycast(ray6, raycastInfo3, 4)); + test(mCompoundBody->raycast(ray6, raycastInfo)); + test(mWorld->raycast(ray6, raycastInfo)); + test(mWorld->raycast(ray6, raycastInfo, 4)); test(mWorld->raycast(ray6)); // Raycast hit agains the cylinder shape @@ -1220,34 +1224,34 @@ class TestRaycast : public Test { Ray ray15(mLocalShapeToWorld * Vector3(0, -9, 1), mLocalToWorldMatrix * Vector3(0, 3, 0)); Ray ray16(mLocalShapeToWorld * Vector3(-1, 2, -7), mLocalToWorldMatrix * Vector3(0, 0, 8)); - test(mCompoundBody->raycast(ray11, raycastInfo3)); - test(mWorld->raycast(ray11, raycastInfo3)); - test(mWorld->raycast(ray11, raycastInfo3, 2)); + test(mCompoundBody->raycast(ray11, raycastInfo)); + test(mWorld->raycast(ray11, raycastInfo)); + test(mWorld->raycast(ray11, raycastInfo, 2)); test(mWorld->raycast(ray11)); - test(mCompoundBody->raycast(ray12, raycastInfo3)); - test(mWorld->raycast(ray12, raycastInfo3)); - test(mWorld->raycast(ray12, raycastInfo3, 2)); + test(mCompoundBody->raycast(ray12, raycastInfo)); + test(mWorld->raycast(ray12, raycastInfo)); + test(mWorld->raycast(ray12, raycastInfo, 2)); test(mWorld->raycast(ray12)); - test(mCompoundBody->raycast(ray13, raycastInfo3)); - test(mWorld->raycast(ray13, raycastInfo3)); - test(mWorld->raycast(ray13, raycastInfo3, 2)); + test(mCompoundBody->raycast(ray13, raycastInfo)); + test(mWorld->raycast(ray13, raycastInfo)); + test(mWorld->raycast(ray13, raycastInfo, 2)); test(mWorld->raycast(ray13)); - test(mCompoundBody->raycast(ray14, raycastInfo3)); - test(mWorld->raycast(ray14, raycastInfo3)); - test(mWorld->raycast(ray14, raycastInfo3, 2)); + test(mCompoundBody->raycast(ray14, raycastInfo)); + test(mWorld->raycast(ray14, raycastInfo)); + test(mWorld->raycast(ray14, raycastInfo, 2)); test(mWorld->raycast(ray14)); - test(mCompoundBody->raycast(ray15, raycastInfo3)); - test(mWorld->raycast(ray15, raycastInfo3)); - test(mWorld->raycast(ray15, raycastInfo3, 2)); + test(mCompoundBody->raycast(ray15, raycastInfo)); + test(mWorld->raycast(ray15, raycastInfo)); + test(mWorld->raycast(ray15, raycastInfo, 2)); test(mWorld->raycast(ray15)); - test(mCompoundBody->raycast(ray16, raycastInfo3)); - test(mWorld->raycast(ray16, raycastInfo3)); - test(mWorld->raycast(ray16, raycastInfo3, 4)); + test(mCompoundBody->raycast(ray16, raycastInfo)); + test(mWorld->raycast(ray16, raycastInfo)); + test(mWorld->raycast(ray16, raycastInfo, 4)); test(mWorld->raycast(ray16)); } };