diff --git a/src/body/CollisionBody.cpp b/src/body/CollisionBody.cpp index 2297157a..5d87eeb3 100644 --- a/src/body/CollisionBody.cpp +++ b/src/body/CollisionBody.cpp @@ -197,15 +197,22 @@ void CollisionBody::updateBroadPhaseState() const { // For all the proxy collision shapes of the body for (ProxyShape* shape = mProxyCollisionShapes; shape != NULL; shape = shape->mNext) { - // Recompute the world-space AABB of the collision shape - AABB aabb; - shape->getCollisionShape()->computeAABB(aabb, mTransform *shape->getLocalToBodyTransform()); - - // Update the broad-phase state for the proxy collision shape - mWorld.mCollisionDetection.updateProxyCollisionShape(shape, aabb); + // Update the proxy + updateProxyShapeInBroadPhase(shape); } } +// Update the broad-phase state of a proxy collision shape of the body +void CollisionBody::updateProxyShapeInBroadPhase(ProxyShape* proxyShape) const { + + // Recompute the world-space AABB of the collision shape + AABB aabb; + proxyShape->getCollisionShape()->computeAABB(aabb, mTransform * proxyShape->getLocalToBodyTransform()); + + // Update the broad-phase state for the proxy collision shape + mWorld.mCollisionDetection.updateProxyCollisionShape(proxyShape, aabb); +} + // Set whether or not the body is active /** * @param isActive True if you want to activate the body diff --git a/src/body/CollisionBody.h b/src/body/CollisionBody.h index 85a423cf..89837b82 100644 --- a/src/body/CollisionBody.h +++ b/src/body/CollisionBody.h @@ -102,6 +102,9 @@ class CollisionBody : public Body { /// Update the broad-phase state for this body (because it has moved for instance) virtual void updateBroadPhaseState() const; + /// Update the broad-phase state of a proxy collision shape of the body + void updateProxyShapeInBroadPhase(ProxyShape* proxyShape) const; + /// Ask the broad-phase to test again the collision shapes of the body for collision /// (as if the body has moved). void askForBroadPhaseCollisionCheck() const; diff --git a/src/collision/CollisionDetection.cpp b/src/collision/CollisionDetection.cpp index 7ebfa4bc..2fcf6888 100644 --- a/src/collision/CollisionDetection.cpp +++ b/src/collision/CollisionDetection.cpp @@ -335,9 +335,11 @@ void CollisionDetection::computeNarrowPhaseBetweenShapes(CollisionCallback* call CollisionShapeInfo shape2Info(shape2, shape2->getCollisionShape(), shape2->getLocalToWorldTransform(), pair, shape2->getCachedCollisionData()); + TestCollisionBetweenShapesCallback narrowPhaseCallback(callback); + // Use the narrow-phase collision detection algorithm to check // if there really is a collision - narrowPhaseAlgorithm->testCollision(shape1Info, shape2Info, this); + narrowPhaseAlgorithm->testCollision(shape1Info, shape2Info, &narrowPhaseCallback); } // Add all the contact manifolds (between colliding bodies) to the bodies @@ -518,3 +520,9 @@ EventListener* CollisionDetection::getWorldEventListener() { MemoryAllocator& CollisionDetection::getWorldMemoryAllocator() { return mWorld->mMemoryAllocator; } + +// Called by a narrow-phase collision algorithm when a new contact has been found +void TestCollisionBetweenShapesCallback::notifyContact(OverlappingPair* overlappingPair, + const ContactPointInfo& contactInfo) { + mCollisionCallback->notifyContact(contactInfo); +} diff --git a/src/collision/CollisionDetection.h b/src/collision/CollisionDetection.h index 3140a5f8..535e1015 100644 --- a/src/collision/CollisionDetection.h +++ b/src/collision/CollisionDetection.h @@ -47,6 +47,26 @@ class BroadPhaseAlgorithm; class CollisionWorld; class CollisionCallback; +// Class TestCollisionBetweenShapesCallback +class TestCollisionBetweenShapesCallback : public NarrowPhaseCallback { + + private: + + CollisionCallback* mCollisionCallback; + + public: + + // Constructor + TestCollisionBetweenShapesCallback(CollisionCallback* callback) + : mCollisionCallback(callback) { + + } + + // Called by a narrow-phase collision algorithm when a new contact has been found + virtual void notifyContact(OverlappingPair* overlappingPair, + const ContactPointInfo& contactInfo); +}; + // Class CollisionDetection /** * This class computes the collision detection algorithms. We first diff --git a/src/collision/ProxyShape.h b/src/collision/ProxyShape.h index 7f6e7dbc..334fbcf1 100644 --- a/src/collision/ProxyShape.h +++ b/src/collision/ProxyShape.h @@ -152,6 +152,12 @@ class ProxyShape { /// Return the pointer to the cached collision data void** getCachedCollisionData(); + /// Return the scaling vector of the collision shape + Vector3 getScaling() const; + + /// Set the scaling vector of the collision shape + virtual void setScaling(const Vector3& scaling); + // -------------------- Friendship -------------------- // friend class OverlappingPair; @@ -293,6 +299,21 @@ inline void ProxyShape::setCollideWithMaskBits(unsigned short collideWithMaskBit mCollideWithMaskBits = collideWithMaskBits; } +// Return the scaling vector of the collision shape +inline Vector3 ProxyShape::getScaling() const { + return mCollisionShape->getScaling(); +} + +// Set the scaling vector of the collision shape +inline void ProxyShape::setScaling(const Vector3& scaling) { + + // Set the local scaling of the collision shape + mCollisionShape->setLocalScaling(scaling); + + // Notify the body that the proxy shape has to be updated in the broad-phase + mBody->updateProxyShapeInBroadPhase(this); +} + } #endif diff --git a/src/collision/broadphase/DynamicAABBTree.cpp b/src/collision/broadphase/DynamicAABBTree.cpp index dd2446cf..4f72c6a7 100644 --- a/src/collision/broadphase/DynamicAABBTree.cpp +++ b/src/collision/broadphase/DynamicAABBTree.cpp @@ -37,6 +37,19 @@ const int TreeNode::NULL_TREE_NODE = -1; // Constructor DynamicAABBTree::DynamicAABBTree(decimal extraAABBGap) : mExtraAABBGap(extraAABBGap) { + init(); +} + +// Destructor +DynamicAABBTree::~DynamicAABBTree() { + + // Free the allocated memory for the nodes + free(mNodes); +} + +// Initialize the tree +void DynamicAABBTree::init() { + mRootNodeID = TreeNode::NULL_TREE_NODE; mNbNodes = 0; mNbAllocatedNodes = 8; @@ -56,11 +69,14 @@ DynamicAABBTree::DynamicAABBTree(decimal extraAABBGap) : mExtraAABBGap(extraAABB mFreeNodeID = 0; } -// Destructor -DynamicAABBTree::~DynamicAABBTree() { +// Clear all the nodes and reset the tree +void DynamicAABBTree::reset() { // Free the allocated memory for the nodes free(mNodes); + + // Initialize the tree + init(); } // Allocate and return a new node in the tree diff --git a/src/collision/broadphase/DynamicAABBTree.h b/src/collision/broadphase/DynamicAABBTree.h index ec530e94..8f2c6255 100644 --- a/src/collision/broadphase/DynamicAABBTree.h +++ b/src/collision/broadphase/DynamicAABBTree.h @@ -159,6 +159,9 @@ class DynamicAABBTree { /// Internally add an object into the tree int addObjectInternal(const AABB& aabb); + /// Initialize the tree + void init(); + #ifndef NDEBUG /// Check if the tree structure is valid (for debugging purpose) @@ -214,6 +217,9 @@ class DynamicAABBTree { /// Return the root AABB of the tree AABB getRootAABB() const; + + /// Clear all the nodes and reset the tree + void reset(); }; // Return true if the node is a leaf of the tree diff --git a/src/collision/narrowphase/ConcaveVsConvexAlgorithm.cpp b/src/collision/narrowphase/ConcaveVsConvexAlgorithm.cpp index e1a83147..bc55226b 100644 --- a/src/collision/narrowphase/ConcaveVsConvexAlgorithm.cpp +++ b/src/collision/narrowphase/ConcaveVsConvexAlgorithm.cpp @@ -86,7 +86,7 @@ void ConvexVsTriangleCallback::testTriangle(const Vector3* trianglePoints) { // Create a triangle collision shape // TODO : Do we need to use a collision margin for a triangle ? - TriangleShape triangleShape(trianglePoints[0], trianglePoints[1], trianglePoints[2], 0.0); + TriangleShape triangleShape(trianglePoints[0], trianglePoints[1], trianglePoints[2]); // Select the collision algorithm to use between the triangle and the convex shape NarrowPhaseAlgorithm* algo = mCollisionDetection->getCollisionAlgorithm(triangleShape.getType(), diff --git a/src/collision/shapes/BoxShape.h b/src/collision/shapes/BoxShape.h index ec9a1c1f..927f69c2 100644 --- a/src/collision/shapes/BoxShape.h +++ b/src/collision/shapes/BoxShape.h @@ -97,6 +97,9 @@ class BoxShape : public ConvexShape { /// Return the extents of the box Vector3 getExtent() const; + /// Set the scaling vector of the collision shape + virtual void setLocalScaling(const Vector3& scaling); + /// Return the local bounds of the shape in x, y and z directions virtual void getLocalBounds(Vector3& min, Vector3& max) const; @@ -112,6 +115,14 @@ inline Vector3 BoxShape::getExtent() const { return mExtent + Vector3(mMargin, mMargin, mMargin); } +// Set the scaling vector of the collision shape +inline void BoxShape::setLocalScaling(const Vector3& scaling) { + + mExtent = (mExtent / mScaling) * scaling; + + CollisionShape::setLocalScaling(scaling); +} + // Return the local bounds of the shape in x, y and z directions /// This method is used to compute the AABB of the box /** diff --git a/src/collision/shapes/CapsuleShape.h b/src/collision/shapes/CapsuleShape.h index 480b185d..fb2270a8 100644 --- a/src/collision/shapes/CapsuleShape.h +++ b/src/collision/shapes/CapsuleShape.h @@ -102,6 +102,9 @@ class CapsuleShape : public ConvexShape { /// Return the height of the capsule decimal getHeight() const; + /// Set the scaling vector of the collision shape + virtual void setLocalScaling(const Vector3& scaling); + /// Return the local bounds of the shape in x, y and z directions virtual void getLocalBounds(Vector3& min, Vector3& max) const; @@ -125,6 +128,15 @@ inline decimal CapsuleShape::getHeight() const { return mHalfHeight + mHalfHeight; } +/// Set the scaling vector of the collision shape +inline void CapsuleShape::setLocalScaling(const Vector3& scaling) { + + mHalfHeight = (mHalfHeight / mScaling.y) * scaling.y; + mRadius = (mRadius / mScaling.x) * scaling.x; + + CollisionShape::setLocalScaling(scaling); +} + // Return the number of bytes used by the collision shape inline size_t CapsuleShape::getSizeInBytes() const { return sizeof(CapsuleShape); diff --git a/src/collision/shapes/CollisionShape.cpp b/src/collision/shapes/CollisionShape.cpp index e5825500..3685a832 100644 --- a/src/collision/shapes/CollisionShape.cpp +++ b/src/collision/shapes/CollisionShape.cpp @@ -32,7 +32,7 @@ using namespace reactphysics3d; // Constructor -CollisionShape::CollisionShape(CollisionShapeType type) : mType(type){ +CollisionShape::CollisionShape(CollisionShapeType type) : mType(type), mScaling(1.0, 1.0, 1.0) { } diff --git a/src/collision/shapes/CollisionShape.h b/src/collision/shapes/CollisionShape.h index fa198c18..0e041e0f 100644 --- a/src/collision/shapes/CollisionShape.h +++ b/src/collision/shapes/CollisionShape.h @@ -60,6 +60,9 @@ class CollisionShape { /// Type of the collision shape CollisionShapeType mType; + + /// Scaling vector of the collision shape + Vector3 mScaling; // -------------------- Methods -------------------- // @@ -97,6 +100,12 @@ class CollisionShape { /// Return the local bounds of the shape in x, y and z directions virtual void getLocalBounds(Vector3& min, Vector3& max) const=0; + /// Return the scaling vector of the collision shape + Vector3 getScaling() const; + + /// Set the local scaling vector of the collision shape + virtual void setLocalScaling(const Vector3& scaling); + /// Return the local inertia tensor of the collision shapes virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const=0; @@ -129,6 +138,16 @@ inline bool CollisionShape::isConvex(CollisionShapeType shapeType) { return shapeType != CONCAVE_MESH; } +// Return the scaling vector of the collision shape +inline Vector3 CollisionShape::getScaling() const { + return mScaling; +} + +// Set the scaling vector of the collision shape +inline void CollisionShape::setLocalScaling(const Vector3& scaling) { + mScaling = scaling; +} + // Return the maximum number of contact manifolds allowed in an overlapping // pair wit the given two collision shape types inline int CollisionShape::computeNbMaxContactManifolds(CollisionShapeType shapeType1, diff --git a/src/collision/shapes/ConcaveMeshShape.cpp b/src/collision/shapes/ConcaveMeshShape.cpp index 6cf152d8..61d0e402 100644 --- a/src/collision/shapes/ConcaveMeshShape.cpp +++ b/src/collision/shapes/ConcaveMeshShape.cpp @@ -80,15 +80,15 @@ void ConcaveMeshShape::initBVHTree() { // Get the vertices components of the triangle if (vertexType == TriangleVertexArray::VERTEX_FLOAT_TYPE) { const float* vertices = (float*)(verticesStart + vertexIndex * vertexStride); - trianglePoints[k][0] = decimal(vertices[0]); - trianglePoints[k][1] = decimal(vertices[1]); - trianglePoints[k][2] = decimal(vertices[2]); + trianglePoints[k][0] = decimal(vertices[0]) * mScaling.x; + trianglePoints[k][1] = decimal(vertices[1]) * mScaling.y; + trianglePoints[k][2] = decimal(vertices[2]) * mScaling.z; } else if (vertexType == TriangleVertexArray::VERTEX_DOUBLE_TYPE) { const double* vertices = (double*)(verticesStart + vertexIndex * vertexStride); - trianglePoints[k][0] = decimal(vertices[0]); - trianglePoints[k][1] = decimal(vertices[1]); - trianglePoints[k][2] = decimal(vertices[2]); + trianglePoints[k][0] = decimal(vertices[0]) * mScaling.x; + trianglePoints[k][1] = decimal(vertices[1]) * mScaling.y; + trianglePoints[k][2] = decimal(vertices[2]) * mScaling.z; } } @@ -133,15 +133,15 @@ void ConcaveMeshShape::getTriangleVerticesWithIndexPointer(int32 subPart, int32 // Get the vertices components of the triangle if (vertexType == TriangleVertexArray::VERTEX_FLOAT_TYPE) { const float* vertices = (float*)(verticesStart + vertexIndex * vertexStride); - outTriangleVertices[k][0] = decimal(vertices[0]); - outTriangleVertices[k][1] = decimal(vertices[1]); - outTriangleVertices[k][2] = decimal(vertices[2]); + outTriangleVertices[k][0] = decimal(vertices[0]) * mScaling.x; + outTriangleVertices[k][1] = decimal(vertices[1]) * mScaling.y; + outTriangleVertices[k][2] = decimal(vertices[2]) * mScaling.z; } else if (vertexType == TriangleVertexArray::VERTEX_DOUBLE_TYPE) { const double* vertices = (double*)(verticesStart + vertexIndex * vertexStride); - outTriangleVertices[k][0] = decimal(vertices[0]); - outTriangleVertices[k][1] = decimal(vertices[1]); - outTriangleVertices[k][2] = decimal(vertices[2]); + outTriangleVertices[k][0] = decimal(vertices[0]) * mScaling.x; + outTriangleVertices[k][1] = decimal(vertices[1]) * mScaling.y; + outTriangleVertices[k][2] = decimal(vertices[2]) * mScaling.z; } } } diff --git a/src/collision/shapes/ConcaveMeshShape.h b/src/collision/shapes/ConcaveMeshShape.h index c7154942..cd574a69 100644 --- a/src/collision/shapes/ConcaveMeshShape.h +++ b/src/collision/shapes/ConcaveMeshShape.h @@ -30,7 +30,6 @@ #include "ConcaveShape.h" #include "collision/broadphase/DynamicAABBTree.h" #include "collision/TriangleMesh.h" -#include namespace reactphysics3d { @@ -130,6 +129,9 @@ class ConcaveMeshShape : public ConcaveShape { /// Return the local bounds of the shape in x, y and z directions. virtual void getLocalBounds(Vector3& min, Vector3& max) const; + /// Set the local scaling vector of the collision shape + virtual void setLocalScaling(const Vector3& scaling); + /// Return the local inertia tensor of the collision shape virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const; @@ -150,14 +152,16 @@ inline size_t ConcaveMeshShape::getSizeInBytes() const { inline Vector3 ConcaveMeshShape::getLocalSupportPointWithMargin(const Vector3& direction, void** cachedCollisionData) const { - // TODO : Implement this + // Should not be used + assert(false); return Vector3(0, 0, 0); } // Return a local support point in a given direction without the object margin inline Vector3 ConcaveMeshShape::getLocalSupportPointWithoutMargin(const Vector3& direction, void** cachedCollisionData) const { - // TODO : Implement this + // Should not be used + assert(false); return Vector3(0.0, 0.0, 0.0); } @@ -176,6 +180,18 @@ inline void ConcaveMeshShape::getLocalBounds(Vector3& min, Vector3& max) const { max = treeAABB.getMax(); } +// Set the local scaling vector of the collision shape +inline void ConcaveMeshShape::setLocalScaling(const Vector3& scaling) { + + CollisionShape::setLocalScaling(scaling); + + // Reset the Dynamic AABB Tree + mDynamicAABBTree.reset(); + + // Rebuild Dynamic AABB Tree here + initBVHTree(); +} + // Return the local inertia tensor of the sphere /** * @param[out] tensor The 3x3 inertia tensor matrix of the shape in local-space @@ -213,9 +229,6 @@ inline void ConvexTriangleAABBOverlapCallback::notifyOverlappingNode(int nodeId) // Call the callback to test narrow-phase collision with this triangle mTriangleTestCallback.testTriangle(trianglePoints); - - // TODO : Delete this - std::cout << "Notify triangle test" << std::endl; } } diff --git a/src/collision/shapes/ConeShape.h b/src/collision/shapes/ConeShape.h index b17c4514..8fdcf6bd 100644 --- a/src/collision/shapes/ConeShape.h +++ b/src/collision/shapes/ConeShape.h @@ -105,6 +105,9 @@ class ConeShape : public ConvexShape { /// Return the height decimal getHeight() const; + /// Set the scaling vector of the collision shape + virtual void setLocalScaling(const Vector3& scaling); + /// Return the local bounds of the shape in x, y and z directions virtual void getLocalBounds(Vector3& min, Vector3& max) const; @@ -128,6 +131,15 @@ inline decimal ConeShape::getHeight() const { return decimal(2.0) * mHalfHeight; } +// Set the scaling vector of the collision shape +inline void ConeShape::setLocalScaling(const Vector3& scaling) { + + mHalfHeight = (mHalfHeight / mScaling.y) * scaling.y; + mRadius = (mRadius / mScaling.x) * scaling.x; + + CollisionShape::setLocalScaling(scaling); +} + // Return the number of bytes used by the collision shape inline size_t ConeShape::getSizeInBytes() const { return sizeof(ConeShape); diff --git a/src/collision/shapes/ConvexMeshShape.cpp b/src/collision/shapes/ConvexMeshShape.cpp index 0789e3c5..f33af857 100644 --- a/src/collision/shapes/ConvexMeshShape.cpp +++ b/src/collision/shapes/ConvexMeshShape.cpp @@ -148,7 +148,7 @@ Vector3 ConvexMeshShape::getLocalSupportPointWithoutMargin(const Vector3& direct *((int*)(*cachedCollisionData)) = maxVertex; // Return the support vertex - return mVertices[maxVertex]; + return mVertices[maxVertex] * mScaling; } else { // If the edges information is not used @@ -171,7 +171,7 @@ Vector3 ConvexMeshShape::getLocalSupportPointWithoutMargin(const Vector3& direct assert(maxDotProduct >= decimal(0.0)); // Return the vertex with the largest dot product in the support direction - return mVertices[indexMaxDotProduct]; + return mVertices[indexMaxDotProduct] * mScaling; } } diff --git a/src/collision/shapes/ConvexMeshShape.h b/src/collision/shapes/ConvexMeshShape.h index 3447c59f..94c1f7a9 100644 --- a/src/collision/shapes/ConvexMeshShape.h +++ b/src/collision/shapes/ConvexMeshShape.h @@ -44,7 +44,7 @@ class CollisionWorld; // TODO : Make possible to create a ConvexMeshShape using a TriangleMesh as for // the ConcaveMeshShape -// TODO : Make possible for the user to have a scaling factor on the mesh +// TODO : Check that scaling factor is working after the change of the previous TODO // Class ConvexMeshShape /** @@ -64,6 +64,8 @@ class CollisionWorld; */ class ConvexMeshShape : public ConvexShape { + // TODO : Implement method setLocalScaling() here + protected : // -------------------- Attributes -------------------- // diff --git a/src/collision/shapes/CylinderShape.h b/src/collision/shapes/CylinderShape.h index 546f87b2..02dfa8c5 100644 --- a/src/collision/shapes/CylinderShape.h +++ b/src/collision/shapes/CylinderShape.h @@ -102,6 +102,9 @@ class CylinderShape : public ConvexShape { /// Return the height decimal getHeight() const; + /// Set the scaling vector of the collision shape + virtual void setLocalScaling(const Vector3& scaling); + /// Return the local bounds of the shape in x, y and z directions virtual void getLocalBounds(Vector3& min, Vector3& max) const; @@ -125,6 +128,15 @@ inline decimal CylinderShape::getHeight() const { return mHalfHeight + mHalfHeight; } +// Set the scaling vector of the collision shape +inline void CylinderShape::setLocalScaling(const Vector3& scaling) { + + mHalfHeight = (mHalfHeight / mScaling.y) * scaling.y; + mRadius = (mRadius / mScaling.x) * scaling.x; + + CollisionShape::setLocalScaling(scaling); +} + // Return the number of bytes used by the collision shape inline size_t CylinderShape::getSizeInBytes() const { return sizeof(CylinderShape); diff --git a/src/collision/shapes/SphereShape.cpp b/src/collision/shapes/SphereShape.cpp index c1b119eb..9b231d0a 100644 --- a/src/collision/shapes/SphereShape.cpp +++ b/src/collision/shapes/SphereShape.cpp @@ -35,7 +35,7 @@ using namespace reactphysics3d; /** * @param radius Radius of the sphere (in meters) */ -SphereShape::SphereShape(decimal radius) : ConvexShape(SPHERE, radius), mRadius(radius) { +SphereShape::SphereShape(decimal radius) : ConvexShape(SPHERE, radius) { assert(radius > decimal(0.0)); } @@ -51,7 +51,7 @@ bool SphereShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* const Vector3 sphereCenter = proxyShape->getLocalToWorldTransform().getPosition(); const Vector3 m = ray.point1 - sphereCenter; - decimal c = m.dot(m) - mRadius * mRadius; + decimal c = m.dot(m) - mMargin * mMargin; // If the origin of the ray is inside the sphere, we return no intersection if (c < decimal(0.0)) return false; diff --git a/src/collision/shapes/SphereShape.h b/src/collision/shapes/SphereShape.h index 0928311c..58e3e1a0 100644 --- a/src/collision/shapes/SphereShape.h +++ b/src/collision/shapes/SphereShape.h @@ -48,8 +48,6 @@ class SphereShape : public ConvexShape { // -------------------- Attributes -------------------- // - /// Radius of the sphere - decimal mRadius; // -------------------- Methods -------------------- // @@ -89,6 +87,9 @@ class SphereShape : public ConvexShape { /// Return the radius of the sphere decimal getRadius() const; + /// Set the scaling vector of the collision shape + virtual void setLocalScaling(const Vector3& scaling); + /// Return the local bounds of the shape in x, y and z directions. virtual void getLocalBounds(Vector3& min, Vector3& max) const; @@ -104,7 +105,15 @@ class SphereShape : public ConvexShape { * @return Radius of the sphere (in meters) */ inline decimal SphereShape::getRadius() const { - return mRadius; + return mMargin; +} + +// Set the scaling vector of the collision shape +inline void SphereShape::setLocalScaling(const Vector3& scaling) { + + mMargin = (mMargin / mScaling.x) * scaling.x; + + CollisionShape::setLocalScaling(scaling); } // Return the number of bytes used by the collision shape @@ -145,12 +154,12 @@ inline Vector3 SphereShape::getLocalSupportPointWithoutMargin(const Vector3& dir inline void SphereShape::getLocalBounds(Vector3& min, Vector3& max) const { // Maximum bounds - max.x = mRadius; - max.y = mRadius; - max.z = mRadius; + max.x = mMargin; + max.y = mMargin; + max.z = mMargin; // Minimum bounds - min.x = -mRadius; + min.x = -mMargin; min.y = min.x; min.z = min.x; } @@ -162,7 +171,7 @@ inline void SphereShape::getLocalBounds(Vector3& min, Vector3& max) const { * @param mass Mass to use to compute the inertia tensor of the collision shape */ inline void SphereShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const { - decimal diag = decimal(0.4) * mass * mRadius * mRadius; + decimal diag = decimal(0.4) * mass * mMargin * mMargin; tensor.setAllValues(diag, 0.0, 0.0, 0.0, diag, 0.0, 0.0, 0.0, diag); @@ -177,7 +186,7 @@ inline void SphereShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal ma inline void SphereShape::computeAABB(AABB& aabb, const Transform& transform) { // Get the local extents in x,y and z direction - Vector3 extents(mRadius, mRadius, mRadius); + Vector3 extents(mMargin, mMargin, mMargin); // Update the AABB with the new minimum and maximum coordinates aabb.setMin(transform.getPosition() - extents); @@ -186,7 +195,7 @@ inline void SphereShape::computeAABB(AABB& aabb, const Transform& transform) { // Return true if a point is inside the collision shape inline bool SphereShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const { - return (localPoint.lengthSquare() < mRadius * mRadius); + return (localPoint.lengthSquare() < mMargin * mMargin); } } diff --git a/src/collision/shapes/TriangleShape.cpp b/src/collision/shapes/TriangleShape.cpp index c6c4323d..0a0d540c 100644 --- a/src/collision/shapes/TriangleShape.cpp +++ b/src/collision/shapes/TriangleShape.cpp @@ -38,9 +38,8 @@ using namespace reactphysics3d; * @param point3 Third point of the triangle * @param margin The collision margin (in meters) around the collision shape */ -TriangleShape::TriangleShape(const Vector3& point1, const Vector3& point2, - const Vector3& point3, decimal margin) - : ConvexShape(TRIANGLE, margin) { +TriangleShape::TriangleShape(const Vector3& point1, const Vector3& point2, const Vector3& point3) + : ConvexShape(TRIANGLE, 0) { mPoints[0] = point1; mPoints[1] = point2; mPoints[2] = point3; diff --git a/src/collision/shapes/TriangleShape.h b/src/collision/shapes/TriangleShape.h index 8309fc1f..7ffdd380 100644 --- a/src/collision/shapes/TriangleShape.h +++ b/src/collision/shapes/TriangleShape.h @@ -77,8 +77,7 @@ class TriangleShape : public ConvexShape { // -------------------- Methods -------------------- // /// Constructor - TriangleShape(const Vector3& point1, const Vector3& point2, - const Vector3& point3, decimal margin); + TriangleShape(const Vector3& point1, const Vector3& point2, const Vector3& point3); /// Destructor virtual ~TriangleShape(); @@ -86,6 +85,9 @@ class TriangleShape : public ConvexShape { /// Return the local bounds of the shape in x, y and z directions. virtual void getLocalBounds(Vector3& min, Vector3& max) const; + /// Set the local scaling vector of the collision shape + virtual void setLocalScaling(const Vector3& scaling); + /// Return the local inertia tensor of the collision shape virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const; @@ -102,8 +104,6 @@ inline size_t TriangleShape::getSizeInBytes() const { inline Vector3 TriangleShape::getLocalSupportPointWithMargin(const Vector3& direction, void** cachedCollisionData) const { - // TODO : Do we need to use margin for triangle support point ? - return getLocalSupportPointWithoutMargin(direction, cachedCollisionData); } @@ -129,6 +129,16 @@ inline void TriangleShape::getLocalBounds(Vector3& min, Vector3& max) const { max.setAllValues(xAxis.getMaxValue(), yAxis.getMaxValue(), zAxis.getMaxValue()); } +// Set the local scaling vector of the collision shape +inline void TriangleShape::setLocalScaling(const Vector3& scaling) { + + mPoints[0] = (mPoints[0] / mScaling) * scaling; + mPoints[1] = (mPoints[1] / mScaling) * scaling; + mPoints[2] = (mPoints[2] / mScaling) * scaling; + + CollisionShape::setLocalScaling(scaling); +} + // Return the local inertia tensor of the triangle shape /** * @param[out] tensor The 3x3 inertia tensor matrix of the shape in local-space diff --git a/src/mathematics/Vector2.h b/src/mathematics/Vector2.h index 1083d26a..ee0fe7bc 100644 --- a/src/mathematics/Vector2.h +++ b/src/mathematics/Vector2.h @@ -145,7 +145,9 @@ struct Vector2 { friend Vector2 operator-(const Vector2& vector); friend Vector2 operator*(const Vector2& vector, decimal number); friend Vector2 operator*(decimal number, const Vector2& vector); + friend Vector2 operator*(const Vector2& vector1, const Vector2& vector2); friend Vector2 operator/(const Vector2& vector, decimal number); + friend Vector2 operator/(const Vector2& vector1, const Vector2& vector2); }; // Set the vector to zero @@ -279,12 +281,24 @@ inline Vector2 operator*(const Vector2& vector, decimal number) { return Vector2(number * vector.x, number * vector.y); } +// Overloaded operator for multiplication of two vectors +inline Vector2 operator*(const Vector2& vector1, const Vector2& vector2) { + return Vector2(vector1.x * vector2.x, vector1.y * vector2.y); +} + // Overloaded operator for division by a number inline Vector2 operator/(const Vector2& vector, decimal number) { assert(number > MACHINE_EPSILON); return Vector2(vector.x / number, vector.y / number); } +// Overload operator for division between two vectors +inline Vector2 operator/(const Vector2& vector1, const Vector2& vector2) { + assert(vector2.x > MACHINE_EPSILON); + assert(vector2.y > MACHINE_EPSILON); + return Vector2(vector1.x / vector2.x, vector1.y / vector2.y); +} + // Overloaded operator for multiplication with a number inline Vector2 operator*(decimal number, const Vector2& vector) { return vector * number; diff --git a/src/mathematics/Vector3.h b/src/mathematics/Vector3.h index e7374435..d5a9fb97 100644 --- a/src/mathematics/Vector3.h +++ b/src/mathematics/Vector3.h @@ -157,7 +157,9 @@ struct Vector3 { friend Vector3 operator-(const Vector3& vector); friend Vector3 operator*(const Vector3& vector, decimal number); friend Vector3 operator*(decimal number, const Vector3& vector); + friend Vector3 operator*(const Vector3& vector1, const Vector3& vector2); friend Vector3 operator/(const Vector3& vector, decimal number); + friend Vector3 operator/(const Vector3& vector1, const Vector3& vector2); }; // Set the vector to zero @@ -311,11 +313,24 @@ inline Vector3 operator/(const Vector3& vector, decimal number) { return Vector3(vector.x / number, vector.y / number, vector.z / number); } +// Overload operator for division between two vectors +inline Vector3 operator/(const Vector3& vector1, const Vector3& vector2) { + assert(vector2.x > MACHINE_EPSILON); + assert(vector2.y > MACHINE_EPSILON); + assert(vector2.z > MACHINE_EPSILON); + return Vector3(vector1.x / vector2.x, vector1.y / vector2.y, vector1.z / vector2.z); +} + // Overloaded operator for multiplication with a number inline Vector3 operator*(decimal number, const Vector3& vector) { return vector * number; } +// Overload operator for multiplication between two vectors +inline Vector3 operator*(const Vector3& vector1, const Vector3& vector2) { + return Vector3(vector1.x * vector2.x, vector1.y * vector2.y, vector1.z * vector2.z); +} + // Assignment operator inline Vector3& Vector3::operator=(const Vector3& vector) { if (&vector != this) { diff --git a/test/tests/mathematics/TestVector2.h b/test/tests/mathematics/TestVector2.h index 7279f29d..314dd5b0 100644 --- a/test/tests/mathematics/TestVector2.h +++ b/test/tests/mathematics/TestVector2.h @@ -201,10 +201,17 @@ class TestVector2 : public Test { vector4 /= 3; test(vector3 == Vector2(60, 330)); test(vector4 == Vector2(5, 20)); + Vector2 vector5(21, 80); + Vector2 vector6(7, 10); + Vector2 vector7 = vector5 * vector6; + test(vector7 == Vector2(147, 800)); + Vector2 vector8 = vector5 / vector6; + test(approxEqual(vector8.x, 3)); + test(approxEqual(vector8.y, 8)); // Negative operator - Vector2 vector5(-34, 5); - Vector2 negative = -vector5; + Vector2 vector9(-34, 5); + Vector2 negative = -vector9; test(negative == Vector2(34, -5)); } }; diff --git a/test/tests/mathematics/TestVector3.h b/test/tests/mathematics/TestVector3.h index 4e6a5b70..c50545fc 100644 --- a/test/tests/mathematics/TestVector3.h +++ b/test/tests/mathematics/TestVector3.h @@ -225,10 +225,18 @@ class TestVector3 : public Test { vector4 /= 3; test(vector3 == Vector3(60, 330, 620)); test(vector4 == Vector3(5, 20, 11)); + Vector3 vector5(21, 80, 45); + Vector3 vector6(7, 10, 3); + Vector3 vector7 = vector5 * vector6; + test(vector7 == Vector3(147, 800, 135)); + Vector3 vector8 = vector5 / vector6; + test(approxEqual(vector8.x, 3)); + test(approxEqual(vector8.y, 8)); + test(approxEqual(vector8.z, 15)); // Negative operator - Vector3 vector5(-34, 5, 422); - Vector3 negative = -vector5; + Vector3 vector9(-34, 5, 422); + Vector3 negative = -vector9; test(negative == Vector3(34, -5, -422)); } };