Modify the way the collision shapes are created (we don't make an internal copy anymore)

This commit is contained in:
Daniel Chappuis 2015-09-04 19:56:27 +02:00
parent ae122f07d6
commit cd808fcf62
55 changed files with 819 additions and 1204 deletions

View File

@ -51,30 +51,27 @@ CollisionBody::~CollisionBody() {
removeAllCollisionShapes(); removeAllCollisionShapes();
} }
// Add a collision shape to the body. // Add a collision shape to the body. Note that you can share a collision
/// When you add a collision shape to the body, an internal copy of this // shape between several bodies using the same collision shape instance to
/// collision shape will be created internally. Therefore, you can delete it // when you add the shape to the different bodies. Do not forget to delete
/// right after calling this method or use it later to add it to another body. // the collision shape you have created at the end of your program.
/// This method will return a pointer to a new proxy shape. A proxy shape is /// This method will return a pointer to a new proxy shape. A proxy shape is
/// an object that links a collision shape and a given body. You can use the /// an object that links a collision shape and a given body. You can use the
/// returned proxy shape to get and set information about the corresponding /// returned proxy shape to get and set information about the corresponding
/// collision shape for that body. /// collision shape for that body.
/** /**
* @param collisionShape The collision shape you want to add to the body * @param collisionShape A pointer to the collision shape you want to add to the body
* @param transform The transformation of the collision shape that transforms the * @param transform The transformation of the collision shape that transforms the
* local-space of the collision shape into the local-space of the body * local-space of the collision shape into the local-space of the body
* @return A pointer to the proxy shape that has been created to link the body to * @return A pointer to the proxy shape that has been created to link the body to
* the new collision shape you have added. * the new collision shape you have added.
*/ */
ProxyShape* CollisionBody::addCollisionShape(const CollisionShape& collisionShape, ProxyShape* CollisionBody::addCollisionShape(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 // Create a new proxy collision shape to attach the collision shape to the body
ProxyShape* proxyShape = new (mWorld.mMemoryAllocator.allocate( ProxyShape* proxyShape = new (mWorld.mMemoryAllocator.allocate(
sizeof(ProxyShape))) ProxyShape(this, newCollisionShape, sizeof(ProxyShape))) ProxyShape(this, collisionShape,
transform, decimal(1)); transform, decimal(1));
// Add it to the list of proxy collision shapes of the body // Add it to the list of proxy collision shapes of the body
@ -88,7 +85,7 @@ ProxyShape* CollisionBody::addCollisionShape(const CollisionShape& collisionShap
// Compute the world-space AABB of the new collision shape // Compute the world-space AABB of the new collision shape
AABB aabb; AABB aabb;
newCollisionShape->computeAABB(aabb, mTransform * transform); collisionShape->computeAABB(aabb, mTransform * transform);
// Notify the collision detection about this new collision shape // Notify the collision detection about this new collision shape
mWorld.mCollisionDetection.addProxyCollisionShape(proxyShape, aabb); mWorld.mCollisionDetection.addProxyCollisionShape(proxyShape, aabb);
@ -118,7 +115,6 @@ void CollisionBody::removeCollisionShape(const ProxyShape* proxyShape) {
mWorld.mCollisionDetection.removeProxyCollisionShape(current); mWorld.mCollisionDetection.removeProxyCollisionShape(current);
} }
mWorld.removeCollisionShape(proxyShape->mCollisionShape);
current->~ProxyShape(); current->~ProxyShape();
mWorld.mMemoryAllocator.release(current, sizeof(ProxyShape)); mWorld.mMemoryAllocator.release(current, sizeof(ProxyShape));
mNbCollisionShapes--; mNbCollisionShapes--;
@ -140,7 +136,6 @@ void CollisionBody::removeCollisionShape(const ProxyShape* proxyShape) {
mWorld.mCollisionDetection.removeProxyCollisionShape(elementToRemove); mWorld.mCollisionDetection.removeProxyCollisionShape(elementToRemove);
} }
mWorld.removeCollisionShape(proxyShape->mCollisionShape);
elementToRemove->~ProxyShape(); elementToRemove->~ProxyShape();
mWorld.mMemoryAllocator.release(elementToRemove, sizeof(ProxyShape)); mWorld.mMemoryAllocator.release(elementToRemove, sizeof(ProxyShape));
mNbCollisionShapes--; mNbCollisionShapes--;
@ -169,7 +164,6 @@ void CollisionBody::removeAllCollisionShapes() {
mWorld.mCollisionDetection.removeProxyCollisionShape(current); mWorld.mCollisionDetection.removeProxyCollisionShape(current);
} }
mWorld.removeCollisionShape(current->mCollisionShape);
current->~ProxyShape(); current->~ProxyShape();
mWorld.mMemoryAllocator.release(current, sizeof(ProxyShape)); mWorld.mMemoryAllocator.release(current, sizeof(ProxyShape));

View File

@ -135,8 +135,8 @@ class CollisionBody : public Body {
virtual void setTransform(const Transform& transform); virtual void setTransform(const Transform& transform);
/// Add a collision shape to the body. /// Add a collision shape to the body.
virtual ProxyShape* addCollisionShape(const CollisionShape& collisionShape, virtual ProxyShape* addCollisionShape(CollisionShape* collisionShape,
const Transform& transform); const Transform& transform);
/// Remove a collision shape from the body /// Remove a collision shape from the body
virtual void removeCollisionShape(const ProxyShape* proxyShape); virtual void removeCollisionShape(const ProxyShape* proxyShape);

View File

@ -209,18 +209,15 @@ void RigidBody::removeJointFromJointsList(MemoryAllocator& memoryAllocator, cons
* @return A pointer to the proxy shape that has been created to link the body to * @return A pointer to the proxy shape that has been created to link the body to
* the new collision shape you have added. * the new collision shape you have added.
*/ */
ProxyShape* RigidBody::addCollisionShape(const CollisionShape& collisionShape, ProxyShape* RigidBody::addCollisionShape(CollisionShape* collisionShape,
const Transform& transform, const Transform& transform,
decimal mass) { decimal mass) {
assert(mass > decimal(0.0)); assert(mass > decimal(0.0));
// Create an internal copy of the collision shape into the world if it is not there yet
CollisionShape* newCollisionShape = mWorld.createCollisionShape(collisionShape);
// Create a new proxy collision shape to attach the collision shape to the body // Create a new proxy collision shape to attach the collision shape to the body
ProxyShape* proxyShape = new (mWorld.mMemoryAllocator.allocate( ProxyShape* proxyShape = new (mWorld.mMemoryAllocator.allocate(
sizeof(ProxyShape))) ProxyShape(this, newCollisionShape, sizeof(ProxyShape))) ProxyShape(this, collisionShape,
transform, mass); transform, mass);
// Add it to the list of proxy collision shapes of the body // Add it to the list of proxy collision shapes of the body
@ -234,7 +231,7 @@ ProxyShape* RigidBody::addCollisionShape(const CollisionShape& collisionShape,
// Compute the world-space AABB of the new collision shape // Compute the world-space AABB of the new collision shape
AABB aabb; AABB aabb;
newCollisionShape->computeAABB(aabb, mTransform * transform); collisionShape->computeAABB(aabb, mTransform * transform);
// Notify the collision detection about this new collision shape // Notify the collision detection about this new collision shape
mWorld.mCollisionDetection.addProxyCollisionShape(proxyShape, aabb); mWorld.mCollisionDetection.addProxyCollisionShape(proxyShape, aabb);

View File

@ -210,7 +210,7 @@ class RigidBody : public CollisionBody {
void applyTorque(const Vector3& torque); void applyTorque(const Vector3& torque);
/// Add a collision shape to the body. /// Add a collision shape to the body.
virtual ProxyShape* addCollisionShape(const CollisionShape& collisionShape, virtual ProxyShape* addCollisionShape(CollisionShape* collisionShape,
const Transform& transform, const Transform& transform,
decimal mass); decimal mass);

View File

@ -35,8 +35,7 @@ using namespace reactphysics3d;
* @param transform Transformation from collision shape local-space to body local-space * @param transform Transformation from collision shape local-space to body local-space
* @param mass Mass of the collision shape (in kilograms) * @param mass Mass of the collision shape (in kilograms)
*/ */
ProxyShape::ProxyShape(CollisionBody* body, CollisionShape* shape, const Transform& transform, ProxyShape::ProxyShape(CollisionBody* body, CollisionShape* shape, const Transform& transform, decimal mass)
decimal mass)
:mBody(body), mCollisionShape(shape), mLocalToBodyTransform(transform), mMass(mass), :mBody(body), mCollisionShape(shape), mLocalToBodyTransform(transform), mMass(mass),
mNext(NULL), mBroadPhaseID(-1), mCachedCollisionData(NULL), mUserData(NULL), mNext(NULL), mBroadPhaseID(-1), mCachedCollisionData(NULL), mUserData(NULL),
mCollisionCategoryBits(0x0001), mCollideWithMaskBits(0xFFFF) { mCollisionCategoryBits(0x0001), mCollideWithMaskBits(0xFFFF) {

View File

@ -93,14 +93,8 @@ class ProxyShape {
/// Private assignment operator /// Private assignment operator
ProxyShape& operator=(const ProxyShape& proxyShape); ProxyShape& operator=(const ProxyShape& proxyShape);
// Return a local support point in a given direction with the object margin /// Return the pointer to the cached collision data
Vector3 getLocalSupportPointWithMargin(const Vector3& direction); void** getCachedCollisionData();
/// 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: public:
@ -173,7 +167,12 @@ class ProxyShape {
friend class ConvexMeshShape; friend class ConvexMeshShape;
}; };
/// Return the collision shape // Return the pointer to the cached collision data
inline void** ProxyShape::getCachedCollisionData() {
return &mCachedCollisionData;
}
// Return the collision shape
/** /**
* @return Pointer to the internal collision shape * @return Pointer to the internal collision shape
*/ */
@ -231,21 +230,6 @@ inline const Transform ProxyShape::getLocalToWorldTransform() const {
return mBody->mTransform * mLocalToBodyTransform; return mBody->mTransform * 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 with feedback information // Raycast method with feedback information
/** /**
* @param ray Ray to use for the raycasting * @param ray Ray to use for the raycasting

View File

@ -28,6 +28,7 @@
// Libraries // Libraries
#include <vector> #include <vector>
#include <cassert>
#include "TriangleVertexArray.h" #include "TriangleVertexArray.h"
namespace reactphysics3d { namespace reactphysics3d {

View File

@ -27,6 +27,7 @@
#define REACTPHYSICS3D_TRIANGLE_VERTEX_ARRAY_H #define REACTPHYSICS3D_TRIANGLE_VERTEX_ARRAY_H
// Libraries // Libraries
#include "configuration.h"
namespace reactphysics3d { namespace reactphysics3d {

View File

@ -27,6 +27,7 @@
#define REACTPHYSICS3D_CONCAVE_VS_CONVEX_ALGORITHM_H #define REACTPHYSICS3D_CONCAVE_VS_CONVEX_ALGORITHM_H
// Libraries // Libraries
#include "NarrowPhaseAlgorithm.h"
/// Namespace ReactPhysics3D /// Namespace ReactPhysics3D
namespace reactphysics3d { namespace reactphysics3d {

View File

@ -82,12 +82,21 @@ int EPAAlgorithm::isOriginInTetrahedron(const Vector3& p1, const Vector3& p2,
/// GJK algorithm. The EPA Algorithm will extend this simplex polytope to find /// GJK algorithm. The EPA Algorithm will extend this simplex polytope to find
/// the correct penetration depth /// the correct penetration depth
bool EPAAlgorithm::computePenetrationDepthAndContactPoints(const Simplex& simplex, bool EPAAlgorithm::computePenetrationDepthAndContactPoints(const Simplex& simplex,
ProxyShape* collisionShape1, ProxyShape* proxyShape1,
const Transform& transform1, const Transform& transform1,
ProxyShape* collisionShape2, ProxyShape* proxyShape2,
const Transform& transform2, const Transform& transform2,
Vector3& v, ContactPointInfo*& contactInfo) { Vector3& v, ContactPointInfo*& contactInfo) {
assert(proxyShape1->getCollisionShape()->isConvex());
assert(proxyShape2->getCollisionShape()->isConvex());
const ConvexShape* shape1 = static_cast<const ConvexShape*>(proxyShape1->getCollisionShape());
const ConvexShape* shape2 = static_cast<const ConvexShape*>(proxyShape2->getCollisionShape());
void** shape1CachedCollisionData = proxyShape1->getCachedCollisionData();
void** shape2CachedCollisionData = proxyShape2->getCachedCollisionData();
Vector3 suppPointsA[MAX_SUPPORT_POINTS]; // Support points of object A in local coordinates Vector3 suppPointsA[MAX_SUPPORT_POINTS]; // Support points of object A in local coordinates
Vector3 suppPointsB[MAX_SUPPORT_POINTS]; // Support points of object B in local coordinates Vector3 suppPointsB[MAX_SUPPORT_POINTS]; // Support points of object B in local coordinates
Vector3 points[MAX_SUPPORT_POINTS]; // Current points Vector3 points[MAX_SUPPORT_POINTS]; // Current points
@ -154,21 +163,21 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(const Simplex& simple
Vector3 v3 = rotationQuat * v2; Vector3 v3 = rotationQuat * v2;
// Compute the support point in the direction of v1 // Compute the support point in the direction of v1
suppPointsA[2] = collisionShape1->getLocalSupportPointWithMargin(v1); suppPointsA[2] = shape1->getLocalSupportPointWithMargin(v1, shape1CachedCollisionData);
suppPointsB[2] = body2Tobody1 * suppPointsB[2] = body2Tobody1 *
collisionShape2->getLocalSupportPointWithMargin(rotateToBody2 * (-v1)); shape2->getLocalSupportPointWithMargin(rotateToBody2 * (-v1), shape2CachedCollisionData);
points[2] = suppPointsA[2] - suppPointsB[2]; points[2] = suppPointsA[2] - suppPointsB[2];
// Compute the support point in the direction of v2 // Compute the support point in the direction of v2
suppPointsA[3] = collisionShape1->getLocalSupportPointWithMargin(v2); suppPointsA[3] = shape1->getLocalSupportPointWithMargin(v2, shape1CachedCollisionData);
suppPointsB[3] = body2Tobody1 * suppPointsB[3] = body2Tobody1 *
collisionShape2->getLocalSupportPointWithMargin(rotateToBody2 * (-v2)); shape2->getLocalSupportPointWithMargin(rotateToBody2 * (-v2), shape2CachedCollisionData);
points[3] = suppPointsA[3] - suppPointsB[3]; points[3] = suppPointsA[3] - suppPointsB[3];
// Compute the support point in the direction of v3 // Compute the support point in the direction of v3
suppPointsA[4] = collisionShape1->getLocalSupportPointWithMargin(v3); suppPointsA[4] = shape1->getLocalSupportPointWithMargin(v3, shape1CachedCollisionData);
suppPointsB[4] = body2Tobody1 * suppPointsB[4] = body2Tobody1 *
collisionShape2->getLocalSupportPointWithMargin(rotateToBody2 * (-v3)); shape2->getLocalSupportPointWithMargin(rotateToBody2 * (-v3), shape2CachedCollisionData);
points[4] = suppPointsA[4] - suppPointsB[4]; points[4] = suppPointsA[4] - suppPointsB[4];
// Now we have an hexahedron (two tetrahedron glued together). We can simply keep the // Now we have an hexahedron (two tetrahedron glued together). We can simply keep the
@ -267,13 +276,13 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(const Simplex& simple
Vector3 n = v1.cross(v2); Vector3 n = v1.cross(v2);
// Compute the two new vertices to obtain a hexahedron // Compute the two new vertices to obtain a hexahedron
suppPointsA[3] = collisionShape1->getLocalSupportPointWithMargin(n); suppPointsA[3] = shape1->getLocalSupportPointWithMargin(n, shape1CachedCollisionData);
suppPointsB[3] = body2Tobody1 * suppPointsB[3] = body2Tobody1 *
collisionShape2->getLocalSupportPointWithMargin(rotateToBody2 * (-n)); shape2->getLocalSupportPointWithMargin(rotateToBody2 * (-n), shape2CachedCollisionData);
points[3] = suppPointsA[3] - suppPointsB[3]; points[3] = suppPointsA[3] - suppPointsB[3];
suppPointsA[4] = collisionShape1->getLocalSupportPointWithMargin(-n); suppPointsA[4] = shape1->getLocalSupportPointWithMargin(-n, shape1CachedCollisionData);
suppPointsB[4] = body2Tobody1 * suppPointsB[4] = body2Tobody1 *
collisionShape2->getLocalSupportPointWithMargin(rotateToBody2 * n); shape2->getLocalSupportPointWithMargin(rotateToBody2 * n, shape2CachedCollisionData);
points[4] = suppPointsA[4] - suppPointsB[4]; points[4] = suppPointsA[4] - suppPointsB[4];
TriangleEPA* face0 = NULL; TriangleEPA* face0 = NULL;
@ -363,11 +372,11 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(const Simplex& simple
// Compute the support point of the Minkowski // Compute the support point of the Minkowski
// difference (A-B) in the closest point direction // difference (A-B) in the closest point direction
suppPointsA[nbVertices] = collisionShape1->getLocalSupportPointWithMargin( suppPointsA[nbVertices] = shape1->getLocalSupportPointWithMargin(
triangle->getClosestPoint()); triangle->getClosestPoint(), shape1CachedCollisionData);
suppPointsB[nbVertices] = body2Tobody1 * suppPointsB[nbVertices] = body2Tobody1 *
collisionShape2->getLocalSupportPointWithMargin(rotateToBody2 * shape2->getLocalSupportPointWithMargin(rotateToBody2 *
(-triangle->getClosestPoint())); (-triangle->getClosestPoint()), shape2CachedCollisionData);
points[nbVertices] = suppPointsA[nbVertices] - suppPointsB[nbVertices]; points[nbVertices] = suppPointsA[nbVertices] - suppPointsB[nbVertices];
int indexNewVertex = nbVertices; int indexNewVertex = nbVertices;
@ -418,7 +427,7 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(const Simplex& simple
// Create the contact info object // Create the contact info object
contactInfo = new (mMemoryAllocator->allocate(sizeof(ContactPointInfo))) contactInfo = new (mMemoryAllocator->allocate(sizeof(ContactPointInfo)))
ContactPointInfo(collisionShape1, collisionShape2, normal, ContactPointInfo(proxyShape1, proxyShape2, normal,
penetrationDepth, pALocal, pBLocal); penetrationDepth, pALocal, pBLocal);
return true; return true;

View File

@ -122,9 +122,9 @@ class EPAAlgorithm {
/// Compute the penetration depth with EPA algorithm. /// Compute the penetration depth with EPA algorithm.
bool computePenetrationDepthAndContactPoints(const Simplex& simplex, bool computePenetrationDepthAndContactPoints(const Simplex& simplex,
ProxyShape* collisionShape1, ProxyShape* proxyShape1,
const Transform& transform1, const Transform& transform1,
ProxyShape* collisionShape2, ProxyShape* proxyShape2,
const Transform& transform2, const Transform& transform2,
Vector3& v, ContactPointInfo*& contactInfo); Vector3& v, ContactPointInfo*& contactInfo);
}; };

View File

@ -56,7 +56,7 @@ GJKAlgorithm::~GJKAlgorithm() {
/// algorithm on the enlarged object to obtain a simplex polytope that contains the /// algorithm on the enlarged object to obtain a simplex polytope that contains the
/// origin, they we give that simplex polytope to the EPA algorithm which will compute /// origin, they we give that simplex polytope to the EPA algorithm which will compute
/// the correct penetration depth and contact points between the enlarged objects. /// the correct penetration depth and contact points between the enlarged objects.
bool GJKAlgorithm::testCollision(ProxyShape* collisionShape1, ProxyShape* collisionShape2, bool GJKAlgorithm::testCollision(ProxyShape* proxyShape1, ProxyShape* proxyShape2,
ContactPointInfo*& contactInfo) { ContactPointInfo*& contactInfo) {
Vector3 suppA; // Support point of object A Vector3 suppA; // Support point of object A
@ -67,11 +67,20 @@ bool GJKAlgorithm::testCollision(ProxyShape* collisionShape1, ProxyShape* collis
decimal vDotw; decimal vDotw;
decimal prevDistSquare; decimal prevDistSquare;
assert(proxyShape1->getCollisionShape()->isConvex());
assert(proxyShape2->getCollisionShape()->isConvex());
const ConvexShape* shape1 = static_cast<const ConvexShape*>(proxyShape1->getCollisionShape());
const ConvexShape* shape2 = static_cast<const ConvexShape*>(proxyShape2->getCollisionShape());
void** shape1CachedCollisionData = proxyShape1->getCachedCollisionData();
void** shape2CachedCollisionData = proxyShape2->getCachedCollisionData();
// Get the local-space to world-space transforms // Get the local-space to world-space transforms
const Transform transform1 = collisionShape1->getBody()->getTransform() * const Transform transform1 = proxyShape1->getBody()->getTransform() *
collisionShape1->getLocalToBodyTransform(); proxyShape1->getLocalToBodyTransform();
const Transform transform2 = collisionShape2->getBody()->getTransform() * const Transform transform2 = proxyShape2->getBody()->getTransform() *
collisionShape2->getLocalToBodyTransform(); proxyShape2->getLocalToBodyTransform();
// Transform a point from local space of body 2 to local // Transform a point from local space of body 2 to local
// space of body 1 (the GJK algorithm is done in local space of body 1) // space of body 1 (the GJK algorithm is done in local space of body 1)
@ -83,7 +92,7 @@ bool GJKAlgorithm::testCollision(ProxyShape* collisionShape1, ProxyShape* collis
transform1.getOrientation().getMatrix(); transform1.getOrientation().getMatrix();
// Initialize the margin (sum of margins of both objects) // Initialize the margin (sum of margins of both objects)
decimal margin = collisionShape1->getMargin() + collisionShape2->getMargin(); decimal margin = shape1->getMargin() + shape2->getMargin();
decimal marginSquare = margin * margin; decimal marginSquare = margin * margin;
assert(margin > 0.0); assert(margin > 0.0);
@ -99,9 +108,9 @@ bool GJKAlgorithm::testCollision(ProxyShape* collisionShape1, ProxyShape* collis
do { do {
// Compute the support points for original objects (without margins) A and B // Compute the support points for original objects (without margins) A and B
suppA = collisionShape1->getLocalSupportPointWithoutMargin(-v); suppA = shape1->getLocalSupportPointWithoutMargin(-v, shape1CachedCollisionData);
suppB = body2Tobody1 * suppB = body2Tobody1 *
collisionShape2->getLocalSupportPointWithoutMargin(rotateToBody2 * v); shape2->getLocalSupportPointWithoutMargin(rotateToBody2 * v, shape2CachedCollisionData);
// Compute the support point for the Minkowski difference A-B // Compute the support point for the Minkowski difference A-B
w = suppA - suppB; w = suppA - suppB;
@ -128,8 +137,8 @@ bool GJKAlgorithm::testCollision(ProxyShape* collisionShape1, ProxyShape* collis
// object with the margins // object with the margins
decimal dist = sqrt(distSquare); decimal dist = sqrt(distSquare);
assert(dist > 0.0); assert(dist > 0.0);
pA = (pA - (collisionShape1->getMargin() / dist) * v); pA = (pA - (shape1->getMargin() / dist) * v);
pB = body2Tobody1.getInverse() * (pB + (collisionShape2->getMargin() / dist) * v); pB = body2Tobody1.getInverse() * (pB + (shape2->getMargin() / dist) * v);
// Compute the contact info // Compute the contact info
Vector3 normal = transform1.getOrientation() * (-v.getUnit()); Vector3 normal = transform1.getOrientation() * (-v.getUnit());
@ -140,7 +149,7 @@ bool GJKAlgorithm::testCollision(ProxyShape* collisionShape1, ProxyShape* collis
// Create the contact info object // Create the contact info object
contactInfo = new (mMemoryAllocator->allocate(sizeof(ContactPointInfo))) contactInfo = new (mMemoryAllocator->allocate(sizeof(ContactPointInfo)))
ContactPointInfo(collisionShape1, collisionShape2, normal, ContactPointInfo(proxyShape1, proxyShape2, normal,
penetrationDepth, pA, pB); penetrationDepth, pA, pB);
// There is an intersection, therefore we return true // There is an intersection, therefore we return true
@ -160,8 +169,8 @@ bool GJKAlgorithm::testCollision(ProxyShape* collisionShape1, ProxyShape* collis
// object with the margins // object with the margins
decimal dist = sqrt(distSquare); decimal dist = sqrt(distSquare);
assert(dist > 0.0); assert(dist > 0.0);
pA = (pA - (collisionShape1->getMargin() / dist) * v); pA = (pA - (shape1->getMargin() / dist) * v);
pB = body2Tobody1.getInverse() * (pB + (collisionShape2->getMargin() / dist) * v); pB = body2Tobody1.getInverse() * (pB + (shape2->getMargin() / dist) * v);
// Compute the contact info // Compute the contact info
Vector3 normal = transform1.getOrientation() * (-v.getUnit()); Vector3 normal = transform1.getOrientation() * (-v.getUnit());
@ -172,7 +181,7 @@ bool GJKAlgorithm::testCollision(ProxyShape* collisionShape1, ProxyShape* collis
// Create the contact info object // Create the contact info object
contactInfo = new (mMemoryAllocator->allocate(sizeof(ContactPointInfo))) contactInfo = new (mMemoryAllocator->allocate(sizeof(ContactPointInfo)))
ContactPointInfo(collisionShape1, collisionShape2, normal, ContactPointInfo(proxyShape1, proxyShape2, normal,
penetrationDepth, pA, pB); penetrationDepth, pA, pB);
// There is an intersection, therefore we return true // There is an intersection, therefore we return true
@ -190,8 +199,8 @@ bool GJKAlgorithm::testCollision(ProxyShape* collisionShape1, ProxyShape* collis
// object with the margins // object with the margins
decimal dist = sqrt(distSquare); decimal dist = sqrt(distSquare);
assert(dist > 0.0); assert(dist > 0.0);
pA = (pA - (collisionShape1->getMargin() / dist) * v); pA = (pA - (shape1->getMargin() / dist) * v);
pB = body2Tobody1.getInverse() * (pB + (collisionShape2->getMargin() / dist) * v); pB = body2Tobody1.getInverse() * (pB + (shape2->getMargin() / dist) * v);
// Compute the contact info // Compute the contact info
Vector3 normal = transform1.getOrientation() * (-v.getUnit()); Vector3 normal = transform1.getOrientation() * (-v.getUnit());
@ -202,7 +211,7 @@ bool GJKAlgorithm::testCollision(ProxyShape* collisionShape1, ProxyShape* collis
// Create the contact info object // Create the contact info object
contactInfo = new (mMemoryAllocator->allocate(sizeof(ContactPointInfo))) contactInfo = new (mMemoryAllocator->allocate(sizeof(ContactPointInfo)))
ContactPointInfo(collisionShape1, collisionShape2, normal, ContactPointInfo(proxyShape1, proxyShape2, normal,
penetrationDepth, pA, pB); penetrationDepth, pA, pB);
// There is an intersection, therefore we return true // There is an intersection, therefore we return true
@ -227,8 +236,8 @@ bool GJKAlgorithm::testCollision(ProxyShape* collisionShape1, ProxyShape* collis
// object with the margins // object with the margins
decimal dist = sqrt(distSquare); decimal dist = sqrt(distSquare);
assert(dist > 0.0); assert(dist > 0.0);
pA = (pA - (collisionShape1->getMargin() / dist) * v); pA = (pA - (shape1->getMargin() / dist) * v);
pB = body2Tobody1.getInverse() * (pB + (collisionShape2->getMargin() / dist) * v); pB = body2Tobody1.getInverse() * (pB + (shape2->getMargin() / dist) * v);
// Compute the contact info // Compute the contact info
Vector3 normal = transform1.getOrientation() * (-v.getUnit()); Vector3 normal = transform1.getOrientation() * (-v.getUnit());
@ -239,7 +248,7 @@ bool GJKAlgorithm::testCollision(ProxyShape* collisionShape1, ProxyShape* collis
// Create the contact info object // Create the contact info object
contactInfo = new (mMemoryAllocator->allocate(sizeof(ContactPointInfo))) contactInfo = new (mMemoryAllocator->allocate(sizeof(ContactPointInfo)))
ContactPointInfo(collisionShape1, collisionShape2, normal, ContactPointInfo(proxyShape1, proxyShape2, normal,
penetrationDepth, pA, pB); penetrationDepth, pA, pB);
// There is an intersection, therefore we return true // There is an intersection, therefore we return true
@ -252,7 +261,7 @@ bool GJKAlgorithm::testCollision(ProxyShape* collisionShape1, ProxyShape* collis
// again but on the enlarged objects to compute a simplex polytope that contains // again but on the enlarged objects to compute a simplex polytope that contains
// the origin. Then, we give that simplex polytope to the EPA algorithm to compute // the origin. Then, we give that simplex polytope to the EPA algorithm to compute
// the correct penetration depth and contact points between the enlarged objects. // the correct penetration depth and contact points between the enlarged objects.
return computePenetrationDepthForEnlargedObjects(collisionShape1, transform1, collisionShape2, return computePenetrationDepthForEnlargedObjects(proxyShape1, transform1, proxyShape2,
transform2, contactInfo, v); transform2, contactInfo, v);
} }
@ -261,9 +270,9 @@ bool GJKAlgorithm::testCollision(ProxyShape* collisionShape1, ProxyShape* collis
/// assumed to intersect in the original objects (without margin). Therefore such /// assumed to intersect in the original objects (without margin). Therefore such
/// a polytope must exist. Then, we give that polytope to the EPA algorithm to /// a polytope must exist. Then, we give that polytope to the EPA algorithm to
/// compute the correct penetration depth and contact points of the enlarged objects. /// compute the correct penetration depth and contact points of the enlarged objects.
bool GJKAlgorithm::computePenetrationDepthForEnlargedObjects(ProxyShape* collisionShape1, bool GJKAlgorithm::computePenetrationDepthForEnlargedObjects(ProxyShape* proxyShape1,
const Transform& transform1, const Transform& transform1,
ProxyShape* collisionShape2, ProxyShape* proxyShape2,
const Transform& transform2, const Transform& transform2,
ContactPointInfo*& contactInfo, ContactPointInfo*& contactInfo,
Vector3& v) { Vector3& v) {
@ -275,6 +284,15 @@ bool GJKAlgorithm::computePenetrationDepthForEnlargedObjects(ProxyShape* collisi
decimal distSquare = DECIMAL_LARGEST; decimal distSquare = DECIMAL_LARGEST;
decimal prevDistSquare; decimal prevDistSquare;
assert(proxyShape1->getCollisionShape()->isConvex());
assert(proxyShape2->getCollisionShape()->isConvex());
const ConvexShape* shape1 = static_cast<const ConvexShape*>(proxyShape1->getCollisionShape());
const ConvexShape* shape2 = static_cast<const ConvexShape*>(proxyShape2->getCollisionShape());
void** shape1CachedCollisionData = proxyShape1->getCachedCollisionData();
void** shape2CachedCollisionData = proxyShape2->getCachedCollisionData();
// Transform a point from local space of body 2 to local space // Transform a point from local space of body 2 to local space
// of body 1 (the GJK algorithm is done in local space of body 1) // of body 1 (the GJK algorithm is done in local space of body 1)
Transform body2ToBody1 = transform1.getInverse() * transform2; Transform body2ToBody1 = transform1.getInverse() * transform2;
@ -285,8 +303,8 @@ bool GJKAlgorithm::computePenetrationDepthForEnlargedObjects(ProxyShape* collisi
do { do {
// Compute the support points for the enlarged object A and B // Compute the support points for the enlarged object A and B
suppA = collisionShape1->getLocalSupportPointWithMargin(-v); suppA = shape1->getLocalSupportPointWithMargin(-v, shape1CachedCollisionData);
suppB = body2ToBody1 * collisionShape2->getLocalSupportPointWithMargin(rotateToBody2 * v); suppB = body2ToBody1 * shape2->getLocalSupportPointWithMargin(rotateToBody2 * v, shape2CachedCollisionData);
// Compute the support point for the Minkowski difference A-B // Compute the support point for the Minkowski difference A-B
w = suppA - suppB; w = suppA - suppB;
@ -325,18 +343,24 @@ bool GJKAlgorithm::computePenetrationDepthForEnlargedObjects(ProxyShape* collisi
// Give the simplex computed with GJK algorithm to the EPA algorithm // Give the simplex computed with GJK algorithm to the EPA algorithm
// which will compute the correct penetration depth and contact points // which will compute the correct penetration depth and contact points
// between the two enlarged objects // between the two enlarged objects
return mAlgoEPA.computePenetrationDepthAndContactPoints(simplex, collisionShape1, return mAlgoEPA.computePenetrationDepthAndContactPoints(simplex, proxyShape1,
transform1, collisionShape2, transform2, transform1, proxyShape2, transform2,
v, contactInfo); v, contactInfo);
} }
// Use the GJK Algorithm to find if a point is inside a convex collision shape // Use the GJK Algorithm to find if a point is inside a convex collision shape
bool GJKAlgorithm::testPointInside(const Vector3& localPoint, ProxyShape* collisionShape) { bool GJKAlgorithm::testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) {
Vector3 suppA; // Support point of object A Vector3 suppA; // Support point of object A
Vector3 w; // Support point of Minkowski difference A-B Vector3 w; // Support point of Minkowski difference A-B
decimal prevDistSquare; decimal prevDistSquare;
assert(proxyShape->getCollisionShape()->isConvex());
const ConvexShape* shape = static_cast<const ConvexShape*>(proxyShape->getCollisionShape());
void** shapeCachedCollisionData = proxyShape->getCachedCollisionData();
// Support point of object B (object B is a single point) // Support point of object B (object B is a single point)
const Vector3 suppB(localPoint); const Vector3 suppB(localPoint);
@ -352,7 +376,7 @@ bool GJKAlgorithm::testPointInside(const Vector3& localPoint, ProxyShape* collis
do { do {
// Compute the support points for original objects (without margins) A and B // Compute the support points for original objects (without margins) A and B
suppA = collisionShape->getLocalSupportPointWithoutMargin(-v); suppA = shape->getLocalSupportPointWithoutMargin(-v, shapeCachedCollisionData);
// Compute the support point for the Minkowski difference A-B // Compute the support point for the Minkowski difference A-B
w = suppA - suppB; w = suppA - suppB;
@ -393,7 +417,13 @@ bool GJKAlgorithm::testPointInside(const Vector3& localPoint, ProxyShape* collis
// Ray casting algorithm agains a convex collision shape using the GJK Algorithm // Ray casting algorithm agains a convex collision shape using the GJK Algorithm
/// This method implements the GJK ray casting algorithm described by Gino Van Den Bergen in /// This method implements the GJK ray casting algorithm described by Gino Van Den Bergen in
/// "Ray Casting against General Convex Objects with Application to Continuous Collision Detection". /// "Ray Casting against General Convex Objects with Application to Continuous Collision Detection".
bool GJKAlgorithm::raycast(const Ray& ray, ProxyShape* collisionShape, RaycastInfo& raycastInfo) { bool GJKAlgorithm::raycast(const Ray& ray, ProxyShape* proxyShape, RaycastInfo& raycastInfo) {
assert(proxyShape->getCollisionShape()->isConvex());
const ConvexShape* shape = static_cast<const ConvexShape*>(proxyShape->getCollisionShape());
void** shapeCachedCollisionData = proxyShape->getCachedCollisionData();
Vector3 suppA; // Current lower bound point on the ray (starting at ray's origin) Vector3 suppA; // Current lower bound point on the ray (starting at ray's origin)
Vector3 suppB; // Support point on the collision shape Vector3 suppB; // Support point on the collision shape
@ -401,7 +431,7 @@ bool GJKAlgorithm::raycast(const Ray& ray, ProxyShape* collisionShape, RaycastIn
const decimal epsilon = decimal(0.0001); const decimal epsilon = decimal(0.0001);
// Convert the ray origin and direction into the local-space of the collision shape // Convert the ray origin and direction into the local-space of the collision shape
const Transform localToWorldTransform = collisionShape->getLocalToWorldTransform(); const Transform localToWorldTransform = proxyShape->getLocalToWorldTransform();
const Transform worldToLocalTransform = localToWorldTransform.getInverse(); const Transform worldToLocalTransform = localToWorldTransform.getInverse();
Vector3 point1 = worldToLocalTransform * ray.point1; Vector3 point1 = worldToLocalTransform * ray.point1;
Vector3 point2 = worldToLocalTransform * ray.point2; Vector3 point2 = worldToLocalTransform * ray.point2;
@ -418,7 +448,7 @@ bool GJKAlgorithm::raycast(const Ray& ray, ProxyShape* collisionShape, RaycastIn
Vector3 n(decimal(0.0), decimal(0.0), decimal(0.0)); Vector3 n(decimal(0.0), decimal(0.0), decimal(0.0));
decimal lambda = decimal(0.0); decimal lambda = decimal(0.0);
suppA = point1; // Current lower bound point on the ray (starting at ray's origin) suppA = point1; // Current lower bound point on the ray (starting at ray's origin)
suppB = collisionShape->getLocalSupportPointWithoutMargin(rayDirection); suppB = shape->getLocalSupportPointWithoutMargin(rayDirection, shapeCachedCollisionData);
Vector3 v = suppA - suppB; Vector3 v = suppA - suppB;
decimal vDotW, vDotR; decimal vDotW, vDotR;
decimal distSquare = v.lengthSquare(); decimal distSquare = v.lengthSquare();
@ -428,7 +458,7 @@ bool GJKAlgorithm::raycast(const Ray& ray, ProxyShape* collisionShape, RaycastIn
while (distSquare > epsilon && nbIterations < MAX_ITERATIONS_GJK_RAYCAST) { while (distSquare > epsilon && nbIterations < MAX_ITERATIONS_GJK_RAYCAST) {
// Compute the support points // Compute the support points
suppB = collisionShape->getLocalSupportPointWithoutMargin(v); suppB = shape->getLocalSupportPointWithoutMargin(v, shapeCachedCollisionData);
w = suppA - suppB; w = suppA - suppB;
vDotW = v.dot(w); vDotW = v.dot(w);
@ -481,8 +511,8 @@ bool GJKAlgorithm::raycast(const Ray& ray, ProxyShape* collisionShape, RaycastIn
// A raycast hit has been found, we fill in the raycast info // A raycast hit has been found, we fill in the raycast info
raycastInfo.hitFraction = lambda; raycastInfo.hitFraction = lambda;
raycastInfo.worldPoint = localToWorldTransform * pointB; raycastInfo.worldPoint = localToWorldTransform * pointB;
raycastInfo.body = collisionShape->getBody(); raycastInfo.body = proxyShape->getBody();
raycastInfo.proxyShape = collisionShape; raycastInfo.proxyShape = proxyShape;
if (n.lengthSquare() >= machineEpsilonSquare) { // The normal vector is valid if (n.lengthSquare() >= machineEpsilonSquare) { // The normal vector is valid
raycastInfo.worldNormal = localToWorldTransform.getOrientation() * n.getUnit(); raycastInfo.worldNormal = localToWorldTransform.getOrientation() * n.getUnit();

View File

@ -29,7 +29,7 @@
// Libraries // Libraries
#include "collision/narrowphase/NarrowPhaseAlgorithm.h" #include "collision/narrowphase/NarrowPhaseAlgorithm.h"
#include "constraint/ContactPoint.h" #include "constraint/ContactPoint.h"
#include "collision/shapes/CollisionShape.h" #include "collision/shapes/ConvexShape.h"
#include "collision/narrowphase/EPA/EPAAlgorithm.h" #include "collision/narrowphase/EPA/EPAAlgorithm.h"
@ -75,9 +75,9 @@ class GJKAlgorithm : public NarrowPhaseAlgorithm {
GJKAlgorithm& operator=(const GJKAlgorithm& algorithm); GJKAlgorithm& operator=(const GJKAlgorithm& algorithm);
/// Compute the penetration depth for enlarged objects. /// Compute the penetration depth for enlarged objects.
bool computePenetrationDepthForEnlargedObjects(ProxyShape* collisionShape1, bool computePenetrationDepthForEnlargedObjects(ProxyShape* proxyShape1,
const Transform& transform1, const Transform& transform1,
ProxyShape* collisionShape2, ProxyShape* proxyShape2,
const Transform& transform2, const Transform& transform2,
ContactPointInfo*& contactInfo, Vector3& v); ContactPointInfo*& contactInfo, Vector3& v);
@ -95,14 +95,14 @@ class GJKAlgorithm : public NarrowPhaseAlgorithm {
virtual void init(MemoryAllocator* memoryAllocator); virtual void init(MemoryAllocator* memoryAllocator);
/// Return true and compute a contact info if the two bounding volumes collide. /// Return true and compute a contact info if the two bounding volumes collide.
virtual bool testCollision(ProxyShape* collisionShape1, ProxyShape* collisionShape2, virtual bool testCollision(ProxyShape* proxyShape1, ProxyShape* proxyShape2,
ContactPointInfo*& contactInfo); ContactPointInfo*& contactInfo);
/// Use the GJK Algorithm to find if a point is inside a convex collision shape /// Use the GJK Algorithm to find if a point is inside a convex collision shape
bool testPointInside(const Vector3& localPoint, ProxyShape* collisionShape); bool testPointInside(const Vector3& localPoint, ProxyShape* proxyShape);
/// Ray casting algorithm agains a convex collision shape using the GJK Algorithm /// Ray casting algorithm agains a convex collision shape using the GJK Algorithm
bool raycast(const Ray& ray, ProxyShape* collisionShape, RaycastInfo& raycastInfo); bool raycast(const Ray& ray, ProxyShape* proxyShape, RaycastInfo& raycastInfo);
}; };
// Initalize the algorithm // Initalize the algorithm

View File

@ -38,18 +38,12 @@ using namespace reactphysics3d;
* @param margin The collision margin (in meters) around the collision shape * @param margin The collision margin (in meters) around the collision shape
*/ */
BoxShape::BoxShape(const Vector3& extent, decimal margin) BoxShape::BoxShape(const Vector3& extent, decimal margin)
: CollisionShape(BOX, margin), mExtent(extent - Vector3(margin, margin, margin)) { : ConvexShape(BOX, margin), mExtent(extent - Vector3(margin, margin, margin)) {
assert(extent.x > decimal(0.0) && extent.x > margin); assert(extent.x > decimal(0.0) && extent.x > margin);
assert(extent.y > decimal(0.0) && extent.y > margin); assert(extent.y > decimal(0.0) && extent.y > margin);
assert(extent.z > decimal(0.0) && extent.z > margin); assert(extent.z > decimal(0.0) && extent.z > margin);
} }
// Private copy-constructor
BoxShape::BoxShape(const BoxShape& shape) : CollisionShape(shape), mExtent(shape.mExtent) {
}
// Destructor // Destructor
BoxShape::~BoxShape() { BoxShape::~BoxShape() {

View File

@ -81,9 +81,6 @@ class BoxShape : public ConvexShape {
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const;
/// Allocate and return a copy of the object
virtual BoxShape* clone(void* allocatedMemory) const;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const; virtual size_t getSizeInBytes() const;
@ -105,16 +102,8 @@ class BoxShape : public ConvexShape {
/// Return the local inertia tensor of the collision shape /// Return the local inertia tensor of the collision shape
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const; virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
/// Test equality between two box shapes
virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const;
}; };
// Allocate and return a copy of the object
inline BoxShape* BoxShape::clone(void* allocatedMemory) const {
return new (allocatedMemory) BoxShape(*this);
}
// Return the extents of the box // Return the extents of the box
/** /**
* @return The vector with the three extents of the box shape (in meters) * @return The vector with the three extents of the box shape (in meters)
@ -163,15 +152,6 @@ inline Vector3 BoxShape::getLocalSupportPointWithoutMargin(const Vector3& direct
direction.z < 0.0 ? -mExtent.z : mExtent.z); direction.z < 0.0 ? -mExtent.z : mExtent.z);
} }
// Test equality between two box shapes
inline bool BoxShape::isEqualTo(const CollisionShape& otherCollisionShape) const {
if (!ConvexShape::isEqualTo(otherCollisionShape)) return false;
const BoxShape& otherShape = dynamic_cast<const BoxShape&>(otherCollisionShape);
return (mExtent == otherShape.mExtent);
}
// Return true if a point is inside the collision shape // Return true if a point is inside the collision shape
inline bool BoxShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const { inline bool BoxShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const {
return (localPoint.x < mExtent[0] && localPoint.x > -mExtent[0] && return (localPoint.x < mExtent[0] && localPoint.x > -mExtent[0] &&

View File

@ -37,17 +37,11 @@ using namespace reactphysics3d;
* @param height The height of the capsule (in meters) * @param height The height of the capsule (in meters)
*/ */
CapsuleShape::CapsuleShape(decimal radius, decimal height) CapsuleShape::CapsuleShape(decimal radius, decimal height)
: CollisionShape(CAPSULE, radius), mRadius(radius), mHalfHeight(height * decimal(0.5)) { : ConvexShape(CAPSULE, radius), mRadius(radius), mHalfHeight(height * decimal(0.5)) {
assert(radius > decimal(0.0)); assert(radius > decimal(0.0));
assert(height > decimal(0.0)); assert(height > decimal(0.0));
} }
// Private copy-constructor
CapsuleShape::CapsuleShape(const CapsuleShape& shape)
: CollisionShape(shape), mRadius(shape.mRadius), mHalfHeight(shape.mHalfHeight) {
}
// Destructor // Destructor
CapsuleShape::~CapsuleShape() { CapsuleShape::~CapsuleShape() {

View File

@ -83,9 +83,6 @@ class CapsuleShape : public ConvexShape {
const Vector3& sphereCenter, decimal maxFraction, const Vector3& sphereCenter, decimal maxFraction,
Vector3& hitLocalPoint, decimal& hitFraction) const; Vector3& hitLocalPoint, decimal& hitFraction) const;
/// Allocate and return a copy of the object
virtual CapsuleShape* clone(void* allocatedMemory) const;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const; virtual size_t getSizeInBytes() const;
@ -110,16 +107,8 @@ class CapsuleShape : public ConvexShape {
/// Return the local inertia tensor of the collision shape /// Return the local inertia tensor of the collision shape
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const; virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
/// Test equality between two capsule shapes
virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const;
}; };
// Allocate and return a copy of the object
inline CapsuleShape* CapsuleShape::clone(void* allocatedMemory) const {
return new (allocatedMemory) CapsuleShape(*this);
}
// Get the radius of the capsule // Get the radius of the capsule
/** /**
* @return The radius of the capsule shape (in meters) * @return The radius of the capsule shape (in meters)
@ -160,15 +149,6 @@ inline void CapsuleShape::getLocalBounds(Vector3& min, Vector3& max) const {
min.z = min.x; min.z = min.x;
} }
// Test equality between two capsule shapes
inline bool CapsuleShape::isEqualTo(const CollisionShape& otherCollisionShape) const {
if (!ConvexShape::isEqualTo(otherCollisionShape)) return false;
const CapsuleShape& otherShape = dynamic_cast<const CapsuleShape&>(otherCollisionShape);
return (mRadius == otherShape.mRadius && mHalfHeight == otherShape.mHalfHeight);
}
} }
#endif #endif

View File

@ -37,12 +37,6 @@ CollisionShape::CollisionShape(CollisionShapeType type)
} }
// Private copy-constructor
CollisionShape::CollisionShape(const CollisionShape& shape)
: mType(shape.mType), mNbSimilarCreatedShapes(shape.mNbSimilarCreatedShapes) {
}
// Destructor // Destructor
CollisionShape::~CollisionShape() { CollisionShape::~CollisionShape() {
assert(mNbSimilarCreatedShapes == 0); assert(mNbSimilarCreatedShapes == 0);

View File

@ -78,21 +78,9 @@ class CollisionShape {
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const=0; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const=0;
/// Return the number of similar created shapes
uint getNbSimilarCreatedShapes() const;
/// Allocate and return a copy of the object
virtual CollisionShape* clone(void* allocatedMemory) const=0;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const = 0; virtual size_t getSizeInBytes() const = 0;
/// Increment the number of similar allocated collision shapes
void incrementNbSimilarCreatedShapes();
/// Decrement the number of similar allocated collision shapes
void decrementNbSimilarCreatedShapes();
public : public :
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
@ -118,12 +106,6 @@ class CollisionShape {
/// Compute the world-space AABB of the collision shape given a transform /// Compute the world-space AABB of the collision shape given a transform
virtual void computeAABB(AABB& aabb, const Transform& transform) const; virtual void computeAABB(AABB& aabb, const Transform& transform) const;
/// Equality operator between two collision shapes.
bool operator==(const CollisionShape& otherCollisionShape) const;
/// Test equality between two collision shapes of the same type (same derived classes).
virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const=0;
// -------------------- Friendship -------------------- // // -------------------- Friendship -------------------- //
friend class ProxyShape; friend class ProxyShape;
@ -138,36 +120,6 @@ inline CollisionShapeType CollisionShape::getType() const {
return mType; return mType;
} }
// Return the number of similar created shapes
inline uint CollisionShape::getNbSimilarCreatedShapes() const {
return mNbSimilarCreatedShapes;
}
// Increment the number of similar allocated collision shapes
inline void CollisionShape::incrementNbSimilarCreatedShapes() {
mNbSimilarCreatedShapes++;
}
// Decrement the number of similar allocated collision shapes
inline void CollisionShape::decrementNbSimilarCreatedShapes() {
mNbSimilarCreatedShapes--;
}
// Equality operator between two collision shapes.
/// This methods returns true only if the two collision shapes are of the same type and
/// of the same dimensions.
inline bool CollisionShape::operator==(const CollisionShape& otherCollisionShape) const {
// If the two collisions shapes are not of the same type (same derived classes)
// we return false
if (mType != otherCollisionShape.mType) return false;
assert(typeid(*this) == typeid(otherCollisionShape));
// Check if the two shapes are equal
return otherCollisionShape.isEqualTo(*this);
}
} }
#endif #endif

View File

@ -29,7 +29,7 @@
using namespace reactphysics3d; using namespace reactphysics3d;
// Constructor // Constructor
ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh) { ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh) : ConcaveShape(CONCAVE_MESH) {
} }

View File

@ -28,6 +28,7 @@
// Libraries // Libraries
#include "ConcaveShape.h" #include "ConcaveShape.h"
#include "collision/TriangleMesh.h"
namespace reactphysics3d { namespace reactphysics3d {
@ -65,9 +66,6 @@ class ConcaveMeshShape : public ConcaveShape {
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const;
/// Allocate and return a copy of the object
virtual ConcaveMeshShape* clone(void* allocatedMemory) const;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const; virtual size_t getSizeInBytes() const;
@ -79,9 +77,6 @@ class ConcaveMeshShape : public ConcaveShape {
/// Destructor /// Destructor
~ConcaveMeshShape(); ~ConcaveMeshShape();
/// Return true if the collision shape is convex, false if it is concave
virtual bool isConvex() const;
/// Return the local bounds of the shape in x, y and z directions. /// Return the local bounds of the shape in x, y and z directions.
virtual void getLocalBounds(Vector3& min, Vector3& max) const; virtual void getLocalBounds(Vector3& min, Vector3& max) const;
@ -95,16 +90,6 @@ class ConcaveMeshShape : public ConcaveShape {
virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const; virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const;
}; };
// Return true if the collision shape is convex, false if it is concave
virtual bool isConvex() const {
return false;
}
// Allocate and return a copy of the object
inline ConcaveMeshShape* ConcaveMeshShape::clone(void* allocatedMemory) const {
return new (allocatedMemory) ConcaveMeshShape(*this);
}
// Return the number of bytes used by the collision shape // Return the number of bytes used by the collision shape
inline size_t ConcaveMeshShape::getSizeInBytes() const { inline size_t ConcaveMeshShape::getSizeInBytes() const {
return sizeof(ConcaveMeshShape); return sizeof(ConcaveMeshShape);
@ -145,10 +130,7 @@ inline void ConcaveMeshShape::getLocalBounds(Vector3& min, Vector3& max) const {
inline void ConcaveMeshShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const { inline void ConcaveMeshShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const {
// TODO : Implement this // TODO : Implement this
decimal diag = decimal(0.4) * mass * mRadius * mRadius; tensor.setToZero();
tensor.setAllValues(diag, 0.0, 0.0,
0.0, diag, 0.0,
0.0, 0.0, diag);
} }
// Update the AABB of a body using its collision shape // Update the AABB of a body using its collision shape
@ -162,15 +144,6 @@ inline void ConcaveMeshShape::computeAABB(AABB& aabb, const Transform& transform
// TODO : Implement this // TODO : Implement this
} }
// Test equality between two sphere shapes
inline bool ConcaveMeshShape::isEqualTo(const CollisionShape& otherCollisionShape) const {
const ConcaveMeshShape& otherShape = dynamic_cast<const ConcaveMeshShape&>(otherCollisionShape);
// TODO : Implement this
return false;
}
// Return true if a point is inside the collision shape // Return true if a point is inside the collision shape
inline bool ConcaveMeshShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const { inline bool ConcaveMeshShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const {

View File

@ -35,11 +35,6 @@ ConcaveShape::ConcaveShape(CollisionShapeType type) : CollisionShape(type) {
} }
// Private copy-constructor
ConcaveShape::ConcaveShape(const CollisionShape& shape) : CollisionShape(shape) {
}
// Destructor // Destructor
ConcaveShape::~ConcaveShape() { ConcaveShape::~ConcaveShape() {

View File

@ -65,9 +65,6 @@ class ConcaveShape : public CollisionShape {
/// Return true if the collision shape is convex, false if it is concave /// Return true if the collision shape is convex, false if it is concave
virtual bool isConvex() const; virtual bool isConvex() const;
/// Test equality between two shapes
virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const;
}; };
/// Return true if the collision shape is convex, false if it is concave /// Return true if the collision shape is convex, false if it is concave
@ -75,59 +72,6 @@ inline bool ConcaveShape::isConvex() const {
return false; return false;
} }
// Return the type of the collision shape
/**
* @return The type of the collision shape (box, sphere, cylinder, ...)
*/
inline CollisionShapeType CollisionShape::getType() const {
return mType;
}
// Return the number of similar created shapes
inline uint CollisionShape::getNbSimilarCreatedShapes() const {
return mNbSimilarCreatedShapes;
}
// Return the current collision shape margin
/**
* @return The margin (in meters) around the collision shape
*/
inline decimal CollisionShape::getMargin() const {
return mMargin;
}
// Increment the number of similar allocated collision shapes
inline void CollisionShape::incrementNbSimilarCreatedShapes() {
mNbSimilarCreatedShapes++;
}
// Decrement the number of similar allocated collision shapes
inline void CollisionShape::decrementNbSimilarCreatedShapes() {
mNbSimilarCreatedShapes--;
}
// Equality operator between two collision shapes.
/// This methods returns true only if the two collision shapes are of the same type and
/// of the same dimensions.
inline bool CollisionShape::operator==(const CollisionShape& otherCollisionShape) const {
// If the two collisions shapes are not of the same type (same derived classes)
// we return false
if (mType != otherCollisionShape.mType) return false;
assert(typeid(*this) == typeid(otherCollisionShape));
if (mMargin != otherCollisionShape.mMargin) return false;
// Check if the two shapes are equal
return otherCollisionShape.isEqualTo(*this);
}
// Test equality between two shapes
inline bool ConcaveShape::isEqualTo(const CollisionShape& otherCollisionShape) const {
return true;
}
} }
#endif #endif

View File

@ -38,7 +38,7 @@ using namespace reactphysics3d;
* @param margin Collision margin (in meters) around the collision shape * @param margin Collision margin (in meters) around the collision shape
*/ */
ConeShape::ConeShape(decimal radius, decimal height, decimal margin) ConeShape::ConeShape(decimal radius, decimal height, decimal margin)
: CollisionShape(CONE, margin), mRadius(radius), mHalfHeight(height * decimal(0.5)) { : ConvexShape(CONE, margin), mRadius(radius), mHalfHeight(height * decimal(0.5)) {
assert(mRadius > decimal(0.0)); assert(mRadius > decimal(0.0));
assert(mHalfHeight > decimal(0.0)); assert(mHalfHeight > decimal(0.0));
@ -46,13 +46,6 @@ ConeShape::ConeShape(decimal radius, decimal height, decimal margin)
mSinTheta = mRadius / (sqrt(mRadius * mRadius + height * height)); mSinTheta = mRadius / (sqrt(mRadius * mRadius + height * height));
} }
// Private copy-constructor
ConeShape::ConeShape(const ConeShape& shape)
: CollisionShape(shape), mRadius(shape.mRadius), mHalfHeight(shape.mHalfHeight),
mSinTheta(shape.mSinTheta){
}
// Destructor // Destructor
ConeShape::~ConeShape() { ConeShape::~ConeShape() {

View File

@ -86,9 +86,6 @@ class ConeShape : public ConvexShape {
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const;
/// Allocate and return a copy of the object
virtual ConeShape* clone(void* allocatedMemory) const;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const; virtual size_t getSizeInBytes() const;
@ -113,16 +110,8 @@ class ConeShape : public ConvexShape {
/// Return the local inertia tensor of the collision shape /// Return the local inertia tensor of the collision shape
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const; virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
/// Test equality between two cone shapes
virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const;
}; };
// Allocate and return a copy of the object
inline ConeShape* ConeShape::clone(void* allocatedMemory) const {
return new (allocatedMemory) ConeShape(*this);
}
// Return the radius // Return the radius
/** /**
* @return Radius of the cone (in meters) * @return Radius of the cone (in meters)
@ -176,15 +165,6 @@ inline void ConeShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass
0.0, 0.0, 0.0, diagXZ); 0.0, 0.0, 0.0, diagXZ);
} }
// Test equality between two cone shapes
inline bool ConeShape::isEqualTo(const CollisionShape& otherCollisionShape) const {
if (!ConvexShape::isEqualTo(otherCollisionShape)) return false;
const ConeShape& otherShape = dynamic_cast<const ConeShape&>(otherCollisionShape);
return (mRadius == otherShape.mRadius && mHalfHeight == otherShape.mHalfHeight);
}
// Return true if a point is inside the collision shape // Return true if a point is inside the collision shape
inline bool ConeShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const { inline bool ConeShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const {
const decimal radiusHeight = mRadius * (-localPoint.y + mHalfHeight) / const decimal radiusHeight = mRadius * (-localPoint.y + mHalfHeight) /

View File

@ -40,7 +40,7 @@ using namespace reactphysics3d;
*/ */
ConvexMeshShape::ConvexMeshShape(const decimal* arrayVertices, uint nbVertices, int stride, ConvexMeshShape::ConvexMeshShape(const decimal* arrayVertices, uint nbVertices, int stride,
decimal margin) decimal margin)
: CollisionShape(CONVEX_MESH, margin), mNbVertices(nbVertices), mMinBounds(0, 0, 0), : ConvexShape(CONVEX_MESH, margin), mNbVertices(nbVertices), mMinBounds(0, 0, 0),
mMaxBounds(0, 0, 0), mIsEdgesInformationUsed(false) { mMaxBounds(0, 0, 0), mIsEdgesInformationUsed(false) {
assert(nbVertices > 0); assert(nbVertices > 0);
assert(stride > 0); assert(stride > 0);
@ -62,21 +62,11 @@ ConvexMeshShape::ConvexMeshShape(const decimal* arrayVertices, uint nbVertices,
/// If you use this constructor, you will need to set the vertices manually one by one using /// If you use this constructor, you will need to set the vertices manually one by one using
/// the addVertex() method. /// the addVertex() method.
ConvexMeshShape::ConvexMeshShape(decimal margin) ConvexMeshShape::ConvexMeshShape(decimal margin)
: CollisionShape(CONVEX_MESH, margin), mNbVertices(0), mMinBounds(0, 0, 0), : ConvexShape(CONVEX_MESH, margin), mNbVertices(0), mMinBounds(0, 0, 0),
mMaxBounds(0, 0, 0), mIsEdgesInformationUsed(false) { mMaxBounds(0, 0, 0), mIsEdgesInformationUsed(false) {
} }
// Private copy-constructor
ConvexMeshShape::ConvexMeshShape(const ConvexMeshShape& shape)
: CollisionShape(shape), mVertices(shape.mVertices), mNbVertices(shape.mNbVertices),
mMinBounds(shape.mMinBounds), mMaxBounds(shape.mMaxBounds),
mIsEdgesInformationUsed(shape.mIsEdgesInformationUsed),
mEdgesAdjacencyList(shape.mEdgesAdjacencyList) {
assert(mNbVertices == mVertices.size());
}
// Destructor // Destructor
ConvexMeshShape::~ConvexMeshShape() { ConvexMeshShape::~ConvexMeshShape() {
@ -209,36 +199,6 @@ void ConvexMeshShape::recalculateBounds() {
mMinBounds -= Vector3(mMargin, mMargin, mMargin); mMinBounds -= Vector3(mMargin, mMargin, mMargin);
} }
// Test equality between two cone shapes
bool ConvexMeshShape::isEqualTo(const CollisionShape& otherCollisionShape) const {
if (!ConvexShape::isEqualTo(otherCollisionShape)) return false;
const ConvexMeshShape& otherShape = dynamic_cast<const ConvexMeshShape&>(otherCollisionShape);
assert(mNbVertices == mVertices.size());
if (mNbVertices != otherShape.mNbVertices) return false;
if (mIsEdgesInformationUsed != otherShape.mIsEdgesInformationUsed) return false;
if (mEdgesAdjacencyList.size() != otherShape.mEdgesAdjacencyList.size()) return false;
// Check that the vertices are the same
for (uint i=0; i<mNbVertices; i++) {
if (mVertices[i] != otherShape.mVertices[i]) return false;
}
// Check that the edges are the same
for (uint i=0; i<mEdgesAdjacencyList.size(); i++) {
assert(otherShape.mEdgesAdjacencyList.count(i) == 1);
if (mEdgesAdjacencyList.at(i) != otherShape.mEdgesAdjacencyList.at(i)) return false;
}
return true;
}
// Raycast method with feedback information // Raycast method with feedback information
bool ConvexMeshShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const { bool ConvexMeshShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const {
return proxyShape->mBody->mWorld.mCollisionDetection.mNarrowPhaseGJKAlgorithm.raycast( return proxyShape->mBody->mWorld.mCollisionDetection.mNarrowPhaseGJKAlgorithm.raycast(

View File

@ -110,9 +110,6 @@ class ConvexMeshShape : public ConvexShape {
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const;
/// Allocate and return a copy of the object
virtual ConvexMeshShape* clone(void* allocatedMemory) const;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const; virtual size_t getSizeInBytes() const;
@ -136,9 +133,6 @@ class ConvexMeshShape : public ConvexShape {
/// Return the local inertia tensor of the collision shape. /// Return the local inertia tensor of the collision shape.
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const; virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
/// Test equality between two collision shapes
virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const;
/// Add a vertex into the convex mesh /// Add a vertex into the convex mesh
void addVertex(const Vector3& vertex); void addVertex(const Vector3& vertex);
@ -153,11 +147,6 @@ class ConvexMeshShape : public ConvexShape {
void setIsEdgesInformationUsed(bool isEdgesUsed); void setIsEdgesInformationUsed(bool isEdgesUsed);
}; };
// Allocate and return a copy of the object
inline ConvexMeshShape* ConvexMeshShape::clone(void* allocatedMemory) const {
return new (allocatedMemory) ConvexMeshShape(*this);
}
// Return the number of bytes used by the collision shape // Return the number of bytes used by the collision shape
inline size_t ConvexMeshShape::getSizeInBytes() const { inline size_t ConvexMeshShape::getSizeInBytes() const {
return sizeof(ConvexMeshShape); return sizeof(ConvexMeshShape);

View File

@ -32,13 +32,7 @@ using namespace reactphysics3d;
// Constructor // Constructor
ConvexShape::ConvexShape(CollisionShapeType type, decimal margin) ConvexShape::ConvexShape(CollisionShapeType type, decimal margin)
: CollisionShape(type), mMargin(margin) { : CollisionShape(type), mMargin(margin) {
}
// Private copy-constructor
ConvexShape::ConvexShape(const CollisionShape& shape)
: CollisionShape(shape), mMargin(shape.mMargin) {
} }

View File

@ -81,8 +81,10 @@ class ConvexShape : public CollisionShape {
/// Return true if the collision shape is convex, false if it is concave /// Return true if the collision shape is convex, false if it is concave
virtual bool isConvex() const; virtual bool isConvex() const;
/// Test equality between two shapes // -------------------- Friendship -------------------- //
virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const;
friend class GJKAlgorithm;
friend class EPAAlgorithm;
}; };
/// Return true if the collision shape is convex, false if it is concave /// Return true if the collision shape is convex, false if it is concave
@ -94,48 +96,10 @@ inline bool ConvexShape::isConvex() const {
/** /**
* @return The margin (in meters) around the collision shape * @return The margin (in meters) around the collision shape
*/ */
inline decimal CollisionShape::getMargin() const { inline decimal ConvexShape::getMargin() const {
return mMargin; return mMargin;
} }
// Return the type of the collision shape
/**
* @return The type of the collision shape (box, sphere, cylinder, ...)
*/
inline CollisionShapeType CollisionShape::getType() const {
return mType;
}
// Return the number of similar created shapes
inline uint CollisionShape::getNbSimilarCreatedShapes() const {
return mNbSimilarCreatedShapes;
}
// Return the current collision shape margin
/**
* @return The margin (in meters) around the collision shape
*/
inline decimal CollisionShape::getMargin() const {
return mMargin;
}
// Increment the number of similar allocated collision shapes
inline void CollisionShape::incrementNbSimilarCreatedShapes() {
mNbSimilarCreatedShapes++;
}
// Decrement the number of similar allocated collision shapes
inline void CollisionShape::decrementNbSimilarCreatedShapes() {
mNbSimilarCreatedShapes--;
}
// Test equality between two shapes
inline bool ConvexShape::isEqualTo(const CollisionShape& otherCollisionShape) const {
const ConvexShape& otherShape = static_cast<const ConvexShape&>(otherCollisionShape);
return (mMargin == otherShape.mMargin);
}
} }
#endif #endif

View File

@ -37,18 +37,12 @@ using namespace reactphysics3d;
* @param margin Collision margin (in meters) around the collision shape * @param margin Collision margin (in meters) around the collision shape
*/ */
CylinderShape::CylinderShape(decimal radius, decimal height, decimal margin) CylinderShape::CylinderShape(decimal radius, decimal height, decimal margin)
: CollisionShape(CYLINDER, margin), mRadius(radius), : ConvexShape(CYLINDER, margin), mRadius(radius),
mHalfHeight(height/decimal(2.0)) { mHalfHeight(height/decimal(2.0)) {
assert(radius > decimal(0.0)); assert(radius > decimal(0.0));
assert(height > decimal(0.0)); assert(height > decimal(0.0));
} }
// Private copy-constructor
CylinderShape::CylinderShape(const CylinderShape& shape)
: CollisionShape(shape), mRadius(shape.mRadius), mHalfHeight(shape.mHalfHeight) {
}
// Destructor // Destructor
CylinderShape::~CylinderShape() { CylinderShape::~CylinderShape() {

View File

@ -83,9 +83,6 @@ class CylinderShape : public ConvexShape {
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const;
/// Allocate and return a copy of the object
virtual CylinderShape* clone(void* allocatedMemory) const;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const; virtual size_t getSizeInBytes() const;
@ -110,16 +107,8 @@ class CylinderShape : public ConvexShape {
/// Return the local inertia tensor of the collision shape /// Return the local inertia tensor of the collision shape
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const; virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
/// Test equality between two cylinder shapes
virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const;
}; };
// Allocate and return a copy of the object
inline CylinderShape* CylinderShape::clone(void* allocatedMemory) const {
return new (allocatedMemory) CylinderShape(*this);
}
// Return the radius // Return the radius
/** /**
* @return Radius of the cylinder (in meters) * @return Radius of the cylinder (in meters)
@ -173,15 +162,6 @@ inline void CylinderShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal
0.0, 0.0, diag); 0.0, 0.0, diag);
} }
// Test equality between two cylinder shapes
inline bool CylinderShape::isEqualTo(const CollisionShape& otherCollisionShape) const {
if (!ConvexShape::isEqualTo(otherCollisionShape)) return false;
const CylinderShape& otherShape = dynamic_cast<const CylinderShape&>(otherCollisionShape);
return (mRadius == otherShape.mRadius && mHalfHeight == otherShape.mHalfHeight);
}
// Return true if a point is inside the collision shape // Return true if a point is inside the collision shape
inline bool CylinderShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const{ inline bool CylinderShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const{
return ((localPoint.x * localPoint.x + localPoint.z * localPoint.z) < mRadius * mRadius && return ((localPoint.x * localPoint.x + localPoint.z * localPoint.z) < mRadius * mRadius &&

View File

@ -35,16 +35,10 @@ using namespace reactphysics3d;
/** /**
* @param radius Radius of the sphere (in meters) * @param radius Radius of the sphere (in meters)
*/ */
SphereShape::SphereShape(decimal radius) : CollisionShape(SPHERE, radius), mRadius(radius) { SphereShape::SphereShape(decimal radius) : ConvexShape(SPHERE, radius), mRadius(radius) {
assert(radius > decimal(0.0)); assert(radius > decimal(0.0));
} }
// Private copy-constructor
SphereShape::SphereShape(const SphereShape& shape)
: CollisionShape(shape), mRadius(shape.mRadius) {
}
// Destructor // Destructor
SphereShape::~SphereShape() { SphereShape::~SphereShape() {

View File

@ -73,9 +73,6 @@ class SphereShape : public ConvexShape {
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const;
/// Allocate and return a copy of the object
virtual SphereShape* clone(void* allocatedMemory) const;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const; virtual size_t getSizeInBytes() const;
@ -100,16 +97,8 @@ class SphereShape : public ConvexShape {
/// Update the AABB of a body using its collision shape /// Update the AABB of a body using its collision shape
virtual void computeAABB(AABB& aabb, const Transform& transform); virtual void computeAABB(AABB& aabb, const Transform& transform);
/// Test equality between two sphere shapes
virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const;
}; };
// Allocate and return a copy of the object
inline SphereShape* SphereShape::clone(void* allocatedMemory) const {
return new (allocatedMemory) SphereShape(*this);
}
// Get the radius of the sphere // Get the radius of the sphere
/** /**
* @return Radius of the sphere (in meters) * @return Radius of the sphere (in meters)
@ -195,15 +184,6 @@ inline void SphereShape::computeAABB(AABB& aabb, const Transform& transform) {
aabb.setMax(transform.getPosition() + extents); aabb.setMax(transform.getPosition() + extents);
} }
// Test equality between two sphere shapes
inline bool SphereShape::isEqualTo(const CollisionShape& otherCollisionShape) const {
if (!ConvexShape::isEqualTo(otherCollisionShape)) return false;
const SphereShape& otherShape = dynamic_cast<const SphereShape&>(otherCollisionShape);
return (mRadius == otherShape.mRadius);
}
// Return true if a point is inside the collision shape // Return true if a point is inside the collision shape
inline bool SphereShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const { inline bool SphereShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const {
return (localPoint.lengthSquare() < mRadius * mRadius); return (localPoint.lengthSquare() < mRadius * mRadius);

View File

@ -40,20 +40,12 @@ using namespace reactphysics3d;
*/ */
TriangleShape::TriangleShape(const Vector3& point1, const Vector3& point2, TriangleShape::TriangleShape(const Vector3& point1, const Vector3& point2,
const Vector3& point3, decimal margin) const Vector3& point3, decimal margin)
: CollisionShape(TRIANGLE, margin) { : ConvexShape(TRIANGLE, margin) {
mPoints[0] = point1; mPoints[0] = point1;
mPoints[1] = point2; mPoints[1] = point2;
mPoints[2] = point3; mPoints[2] = point3;
} }
// Private copy-constructor
TriangleShape::TriangleShape(const TriangleShape& shape)
: CollisionShape(shape) {
mPoints[0] = shape.mPoints[0];
mPoints[1] = shape.mPoints[1];
mPoints[2] = shape.mPoints[2];
}
// Destructor // Destructor
TriangleShape::~TriangleShape() { TriangleShape::~TriangleShape() {

View File

@ -69,9 +69,6 @@ class TriangleShape : public ConvexShape {
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const;
/// Allocate and return a copy of the object
virtual TriangleShape* clone(void* allocatedMemory) const;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const; virtual size_t getSizeInBytes() const;
@ -94,16 +91,8 @@ class TriangleShape : public ConvexShape {
/// Update the AABB of a body using its collision shape /// Update the AABB of a body using its collision shape
virtual void computeAABB(AABB& aabb, const Transform& transform); virtual void computeAABB(AABB& aabb, const Transform& transform);
/// Test equality between two triangle shapes
virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const;
}; };
// Allocate and return a copy of the object
inline TriangleShape* TriangleShape::clone(void* allocatedMemory) const {
return new (allocatedMemory) TriangleShape(*this);
}
// Return the number of bytes used by the collision shape // Return the number of bytes used by the collision shape
inline size_t TriangleShape::getSizeInBytes() const { inline size_t TriangleShape::getSizeInBytes() const {
return sizeof(TriangleShape); return sizeof(TriangleShape);
@ -133,9 +122,9 @@ inline Vector3 TriangleShape::getLocalSupportPointWithoutMargin(const Vector3& d
*/ */
inline void TriangleShape::getLocalBounds(Vector3& min, Vector3& max) const { inline void TriangleShape::getLocalBounds(Vector3& min, Vector3& max) const {
const Vector3 xAxis(worldPoint1.X, worldPoint2.X, worldPoint3.X); const Vector3 xAxis(mPoints[0].x, mPoints[1].x, mPoints[2].x);
const Vector3 yAxis(worldPoint1.Y, worldPoint2.Y, worldPoint3.Y); const Vector3 yAxis(mPoints[0].y, mPoints[1].y, mPoints[2].y);
const Vector3 zAxis(worldPoint1.Z, worldPoint2.Z, worldPoint3.Z); const Vector3 zAxis(mPoints[0].z, mPoints[1].z, mPoints[2].z);
min.setAllValues(xAxis.getMinValue(), yAxis.getMinValue(), zAxis.getMinValue()); min.setAllValues(xAxis.getMinValue(), yAxis.getMinValue(), zAxis.getMinValue());
max.setAllValues(xAxis.getMaxValue(), yAxis.getMaxValue(), zAxis.getMaxValue()); max.setAllValues(xAxis.getMaxValue(), yAxis.getMaxValue(), zAxis.getMaxValue());
} }
@ -162,24 +151,13 @@ inline void TriangleShape::computeAABB(AABB& aabb, const Transform& transform) {
const Vector3 worldPoint2 = transform * mPoints[1]; const Vector3 worldPoint2 = transform * mPoints[1];
const Vector3 worldPoint3 = transform * mPoints[2]; const Vector3 worldPoint3 = transform * mPoints[2];
const Vector3 xAxis(worldPoint1.X, worldPoint2.X, worldPoint3.X); const Vector3 xAxis(worldPoint1.x, worldPoint2.x, worldPoint3.x);
const Vector3 yAxis(worldPoint1.Y, worldPoint2.Y, worldPoint3.Y); const Vector3 yAxis(worldPoint1.y, worldPoint2.y, worldPoint3.y);
const Vector3 zAxis(worldPoint1.Z, worldPoint2.Z, worldPoint3.Z); const Vector3 zAxis(worldPoint1.z, worldPoint2.z, worldPoint3.z);
aabb.setMin(Vector3(xAxis.getMinValue(), yAxis.getMinValue(), zAxis.getMinValue())); aabb.setMin(Vector3(xAxis.getMinValue(), yAxis.getMinValue(), zAxis.getMinValue()));
aabb.setMax(Vector3(xAxis.getMaxValue(), yAxis.getMaxValue(), zAxis.getMaxValue())); aabb.setMax(Vector3(xAxis.getMaxValue(), yAxis.getMaxValue(), zAxis.getMaxValue()));
} }
// Test equality between two triangle shapes
inline bool TriangleShape::isEqualTo(const CollisionShape& otherCollisionShape) const {
if (!ConvexShape::isEqualTo(otherCollisionShape)) return false;
const TriangleShape& otherShape = dynamic_cast<const TriangleShape&>(otherCollisionShape);
return (mPoints[0] == otherShape.mPoints[0] &&
mPoints[1] == otherShape.mPoints[1] &&
mPoints[2] == otherShape.mPoints[2]);
}
// Return true if a point is inside the collision shape // Return true if a point is inside the collision shape
inline bool TriangleShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const { inline bool TriangleShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const {
return false; return false;

View File

@ -49,7 +49,6 @@ CollisionWorld::~CollisionWorld() {
destroyCollisionBody(*itToRemove); destroyCollisionBody(*itToRemove);
} }
assert(mCollisionShapes.empty());
assert(mBodies.empty()); assert(mBodies.empty());
} }
@ -118,70 +117,6 @@ bodyindex CollisionWorld::computeNextAvailableBodyID() {
return bodyID; return bodyID;
} }
// Create a new collision shape in the world.
/// First, this methods checks that the new collision shape does not exist yet in the
/// world. If it already exists, we do not allocate memory for a new one but instead
/// we reuse the existing one. The goal is to only allocate memory for a single
/// collision shape if this one is used for several bodies in the world. To allocate
/// memory for a new collision shape, we use the memory allocator.
CollisionShape* CollisionWorld::createCollisionShape(const CollisionShape& collisionShape) {
// Check if there is already a similar collision shape in the world
std::list<CollisionShape*>::iterator it;
for (it = mCollisionShapes.begin(); it != mCollisionShapes.end(); ++it) {
if (collisionShape == (*(*it))) {
// Increment the number of similar created shapes
(*it)->incrementNbSimilarCreatedShapes();
// A similar collision shape already exists in the world, so we do not
// create a new one but we simply return a pointer to the existing one
return (*it);
}
}
// A similar collision shape does not already exist in the world, so we create a
// new one and add it to the world
void* allocatedMemory = mMemoryAllocator.allocate(collisionShape.getSizeInBytes());
CollisionShape* newCollisionShape = collisionShape.clone(allocatedMemory);
mCollisionShapes.push_back(newCollisionShape);
newCollisionShape->incrementNbSimilarCreatedShapes();
// Return a pointer to the new collision shape
return newCollisionShape;
}
// Remove a collision shape.
/// First, we check if another body is still using the same collision shape. If so,
/// we keep the allocated collision shape. If it is not the case, we can deallocate
/// the memory associated with the collision shape.
void CollisionWorld::removeCollisionShape(CollisionShape* collisionShape) {
assert(collisionShape->getNbSimilarCreatedShapes() != 0);
// Decrement the number of bodies using the same collision shape
collisionShape->decrementNbSimilarCreatedShapes();
// If no other body is using the collision shape in the world
if (collisionShape->getNbSimilarCreatedShapes() == 0) {
// Remove the shape from the set of shapes in the world
mCollisionShapes.remove(collisionShape);
// Compute the size (in bytes) of the collision shape
size_t nbBytesShape = collisionShape->getSizeInBytes();
// Call the destructor of the collision shape
collisionShape->~CollisionShape();
// Deallocate the memory used by the collision shape
mMemoryAllocator.release(collisionShape, nbBytesShape);
}
}
// Reset all the contact manifolds linked list of each body // Reset all the contact manifolds linked list of each body
void CollisionWorld::resetContactManifoldListsOfBodies() { void CollisionWorld::resetContactManifoldListsOfBodies() {

View File

@ -66,9 +66,6 @@ class CollisionWorld {
/// All the bodies (rigid and soft) of the world /// All the bodies (rigid and soft) of the world
std::set<CollisionBody*> mBodies; std::set<CollisionBody*> mBodies;
/// All the collision shapes of the world
std::list<CollisionShape*> mCollisionShapes;
/// Current body ID /// Current body ID
bodyindex mCurrentBodyID; bodyindex mCurrentBodyID;
@ -92,12 +89,6 @@ class CollisionWorld {
/// Return the next available body ID /// Return the next available body ID
bodyindex computeNextAvailableBodyID(); bodyindex computeNextAvailableBodyID();
/// Remove a collision shape.
void removeCollisionShape(CollisionShape* collisionShape);
/// Create a new collision shape in the world.
CollisionShape* createCollisionShape(const CollisionShape& collisionShape);
/// Reset all the contact manifolds linked list of each body /// Reset all the contact manifolds linked list of each body
void resetContactManifoldListsOfBodies(); void resetContactManifoldListsOfBodies();

View File

@ -28,7 +28,6 @@
// Libraries // Libraries
#include "configuration.h" #include "configuration.h"
#include "mathematics/Vector3.h"
#include "decimal.h" #include "decimal.h"
#include <algorithm> #include <algorithm>

View File

@ -112,11 +112,16 @@ class TestCollisionWorld : public Test {
CollisionBody* mSphere2Body; CollisionBody* mSphere2Body;
CollisionBody* mCylinderBody; CollisionBody* mCylinderBody;
// Shapes // Collision shapes
ProxyShape* mBoxShape; BoxShape* mBoxShape;
ProxyShape* mSphere1Shape; SphereShape* mSphereShape;
ProxyShape* mSphere2Shape; CylinderShape* mCylinderShape;
ProxyShape* mCylinderShape;
// Proxy shapes
ProxyShape* mBoxProxyShape;
ProxyShape* mSphere1ProxyShape;
ProxyShape* mSphere2ProxyShape;
ProxyShape* mCylinderProxyShape;
// Collision callback class // Collision callback class
WorldCollisionCallback mCollisionCallback; WorldCollisionCallback mCollisionCallback;
@ -134,28 +139,28 @@ class TestCollisionWorld : public Test {
// Create the bodies // Create the bodies
Transform boxTransform(Vector3(10, 0, 0), Quaternion::identity()); Transform boxTransform(Vector3(10, 0, 0), Quaternion::identity());
mBoxBody = mWorld->createCollisionBody(boxTransform); mBoxBody = mWorld->createCollisionBody(boxTransform);
BoxShape boxShape(Vector3(3, 3, 3)); mBoxShape = new BoxShape(Vector3(3, 3, 3));
mBoxShape = mBoxBody->addCollisionShape(boxShape, Transform::identity()); mBoxProxyShape = mBoxBody->addCollisionShape(mBoxShape, Transform::identity());
SphereShape sphereShape(3.0); mSphereShape = new SphereShape(3.0);
Transform sphere1Transform(Vector3(10,5, 0), Quaternion::identity()); Transform sphere1Transform(Vector3(10,5, 0), Quaternion::identity());
mSphere1Body = mWorld->createCollisionBody(sphere1Transform); mSphere1Body = mWorld->createCollisionBody(sphere1Transform);
mSphere1Shape = mSphere1Body->addCollisionShape(sphereShape, Transform::identity()); mSphere1ProxyShape = mSphere1Body->addCollisionShape(mSphereShape, Transform::identity());
Transform sphere2Transform(Vector3(30, 10, 10), Quaternion::identity()); Transform sphere2Transform(Vector3(30, 10, 10), Quaternion::identity());
mSphere2Body = mWorld->createCollisionBody(sphere2Transform); mSphere2Body = mWorld->createCollisionBody(sphere2Transform);
mSphere2Shape = mSphere2Body->addCollisionShape(sphereShape, Transform::identity()); mSphere2ProxyShape = mSphere2Body->addCollisionShape(mSphereShape, Transform::identity());
Transform cylinderTransform(Vector3(10, -5, 0), Quaternion::identity()); Transform cylinderTransform(Vector3(10, -5, 0), Quaternion::identity());
mCylinderBody = mWorld->createCollisionBody(cylinderTransform); mCylinderBody = mWorld->createCollisionBody(cylinderTransform);
CylinderShape cylinderShape(2, 5); mCylinderShape = new CylinderShape(2, 5);
mCylinderShape = mCylinderBody->addCollisionShape(cylinderShape, Transform::identity()); mCylinderProxyShape = mCylinderBody->addCollisionShape(mCylinderShape, Transform::identity());
// Assign collision categories to proxy shapes // Assign collision categories to proxy shapes
mBoxShape->setCollisionCategoryBits(CATEGORY_1); mBoxProxyShape->setCollisionCategoryBits(CATEGORY_1);
mSphere1Shape->setCollisionCategoryBits(CATEGORY_1); mSphere1ProxyShape->setCollisionCategoryBits(CATEGORY_1);
mSphere2Shape->setCollisionCategoryBits(CATEGORY_2); mSphere2ProxyShape->setCollisionCategoryBits(CATEGORY_2);
mCylinderShape->setCollisionCategoryBits(CATEGORY_3); mCylinderProxyShape->setCollisionCategoryBits(CATEGORY_3);
mCollisionCallback.boxBody = mBoxBody; mCollisionCallback.boxBody = mBoxBody;
mCollisionCallback.sphere1Body = mSphere1Body; mCollisionCallback.sphere1Body = mSphere1Body;
@ -163,6 +168,13 @@ class TestCollisionWorld : public Test {
mCollisionCallback.cylinderBody = mCylinderBody; mCollisionCallback.cylinderBody = mCylinderBody;
} }
/// Destructor
~TestCollisionWorld() {
delete mBoxShape;
delete mSphereShape;
delete mCylinderShape;
}
/// Run the tests /// Run the tests
void run() { void run() {
@ -183,10 +195,10 @@ class TestCollisionWorld : public Test {
test(!mWorld->testAABBOverlap(mSphere1Body, mCylinderBody)); test(!mWorld->testAABBOverlap(mSphere1Body, mCylinderBody));
test(!mWorld->testAABBOverlap(mSphere1Body, mSphere2Body)); test(!mWorld->testAABBOverlap(mSphere1Body, mSphere2Body));
test(mWorld->testAABBOverlap(mBoxShape, mSphere1Shape)); test(mWorld->testAABBOverlap(mBoxProxyShape, mSphere1ProxyShape));
test(mWorld->testAABBOverlap(mBoxShape, mCylinderShape)); test(mWorld->testAABBOverlap(mBoxProxyShape, mCylinderProxyShape));
test(!mWorld->testAABBOverlap(mSphere1Shape, mCylinderShape)); test(!mWorld->testAABBOverlap(mSphere1ProxyShape, mCylinderProxyShape));
test(!mWorld->testAABBOverlap(mSphere1Shape, mSphere2Shape)); test(!mWorld->testAABBOverlap(mSphere1ProxyShape, mSphere2ProxyShape));
mCollisionCallback.reset(); mCollisionCallback.reset();
mWorld->testCollision(mCylinderBody, &mCollisionCallback); mWorld->testCollision(mCylinderBody, &mCollisionCallback);
@ -210,14 +222,14 @@ class TestCollisionWorld : public Test {
test(!mCollisionCallback.sphere1CollideWithSphere2); test(!mCollisionCallback.sphere1CollideWithSphere2);
mCollisionCallback.reset(); mCollisionCallback.reset();
mWorld->testCollision(mCylinderShape, &mCollisionCallback); mWorld->testCollision(mCylinderProxyShape, &mCollisionCallback);
test(!mCollisionCallback.boxCollideWithSphere1); test(!mCollisionCallback.boxCollideWithSphere1);
test(mCollisionCallback.boxCollideWithCylinder); test(mCollisionCallback.boxCollideWithCylinder);
test(!mCollisionCallback.sphere1CollideWithCylinder); test(!mCollisionCallback.sphere1CollideWithCylinder);
test(!mCollisionCallback.sphere1CollideWithSphere2); test(!mCollisionCallback.sphere1CollideWithSphere2);
mCollisionCallback.reset(); mCollisionCallback.reset();
mWorld->testCollision(mBoxShape, mCylinderShape, &mCollisionCallback); mWorld->testCollision(mBoxProxyShape, mCylinderProxyShape, &mCollisionCallback);
test(!mCollisionCallback.boxCollideWithSphere1); test(!mCollisionCallback.boxCollideWithSphere1);
test(mCollisionCallback.boxCollideWithCylinder); test(mCollisionCallback.boxCollideWithCylinder);
test(!mCollisionCallback.sphere1CollideWithCylinder); test(!mCollisionCallback.sphere1CollideWithCylinder);
@ -268,10 +280,10 @@ class TestCollisionWorld : public Test {
test(!mWorld->testAABBOverlap(mSphere1Body, mCylinderBody)); test(!mWorld->testAABBOverlap(mSphere1Body, mCylinderBody));
test(!mWorld->testAABBOverlap(mSphere1Body, mSphere2Body)); test(!mWorld->testAABBOverlap(mSphere1Body, mSphere2Body));
test(!mWorld->testAABBOverlap(mBoxShape, mSphere1Shape)); test(!mWorld->testAABBOverlap(mBoxProxyShape, mSphere1ProxyShape));
test(!mWorld->testAABBOverlap(mBoxShape, mCylinderShape)); test(!mWorld->testAABBOverlap(mBoxProxyShape, mCylinderProxyShape));
test(!mWorld->testAABBOverlap(mSphere1Shape, mCylinderShape)); test(!mWorld->testAABBOverlap(mSphere1ProxyShape, mCylinderProxyShape));
test(!mWorld->testAABBOverlap(mSphere1Shape, mSphere2Shape)); test(!mWorld->testAABBOverlap(mSphere1ProxyShape, mSphere2ProxyShape));
mBoxBody->setIsActive(true); mBoxBody->setIsActive(true);
mCylinderBody->setIsActive(true); mCylinderBody->setIsActive(true);
@ -280,10 +292,10 @@ class TestCollisionWorld : public Test {
// --------- Test collision with collision filtering -------- // // --------- Test collision with collision filtering -------- //
mBoxShape->setCollideWithMaskBits(CATEGORY_1 | CATEGORY_3); mBoxProxyShape->setCollideWithMaskBits(CATEGORY_1 | CATEGORY_3);
mSphere1Shape->setCollideWithMaskBits(CATEGORY_1 | CATEGORY_2); mSphere1ProxyShape->setCollideWithMaskBits(CATEGORY_1 | CATEGORY_2);
mSphere2Shape->setCollideWithMaskBits(CATEGORY_1); mSphere2ProxyShape->setCollideWithMaskBits(CATEGORY_1);
mCylinderShape->setCollideWithMaskBits(CATEGORY_1); mCylinderProxyShape->setCollideWithMaskBits(CATEGORY_1);
mCollisionCallback.reset(); mCollisionCallback.reset();
mWorld->testCollision(&mCollisionCallback); mWorld->testCollision(&mCollisionCallback);
@ -302,10 +314,10 @@ class TestCollisionWorld : public Test {
test(!mCollisionCallback.sphere1CollideWithCylinder); test(!mCollisionCallback.sphere1CollideWithCylinder);
test(mCollisionCallback.sphere1CollideWithSphere2); test(mCollisionCallback.sphere1CollideWithSphere2);
mBoxShape->setCollideWithMaskBits(CATEGORY_2); mBoxProxyShape->setCollideWithMaskBits(CATEGORY_2);
mSphere1Shape->setCollideWithMaskBits(CATEGORY_2); mSphere1ProxyShape->setCollideWithMaskBits(CATEGORY_2);
mSphere2Shape->setCollideWithMaskBits(CATEGORY_3); mSphere2ProxyShape->setCollideWithMaskBits(CATEGORY_3);
mCylinderShape->setCollideWithMaskBits(CATEGORY_1); mCylinderProxyShape->setCollideWithMaskBits(CATEGORY_1);
mCollisionCallback.reset(); mCollisionCallback.reset();
mWorld->testCollision(&mCollisionCallback); mWorld->testCollision(&mCollisionCallback);
@ -317,10 +329,10 @@ class TestCollisionWorld : public Test {
// Move sphere 1 to collide with box // Move sphere 1 to collide with box
mSphere1Body->setTransform(Transform(Vector3(10, 5, 0), Quaternion::identity())); mSphere1Body->setTransform(Transform(Vector3(10, 5, 0), Quaternion::identity()));
mBoxShape->setCollideWithMaskBits(0xFFFF); mBoxProxyShape->setCollideWithMaskBits(0xFFFF);
mSphere1Shape->setCollideWithMaskBits(0xFFFF); mSphere1ProxyShape->setCollideWithMaskBits(0xFFFF);
mSphere2Shape->setCollideWithMaskBits(0xFFFF); mSphere2ProxyShape->setCollideWithMaskBits(0xFFFF);
mCylinderShape->setCollideWithMaskBits(0xFFFF); mCylinderProxyShape->setCollideWithMaskBits(0xFFFF);
} }
}; };

View File

@ -61,20 +61,29 @@ class TestPointInside : public Test {
CollisionBody* mCylinderBody; CollisionBody* mCylinderBody;
CollisionBody* mCompoundBody; CollisionBody* mCompoundBody;
// Collision shapes
BoxShape* mBoxShape;
SphereShape* mSphereShape;
CapsuleShape* mCapsuleShape;
ConeShape* mConeShape;
ConvexMeshShape* mConvexMeshShape;
ConvexMeshShape* mConvexMeshShapeBodyEdgesInfo;
CylinderShape* mCylinderShape;
// Transform // Transform
Transform mBodyTransform; Transform mBodyTransform;
Transform mShapeTransform; Transform mShapeTransform;
Transform mLocalShapeToWorld; Transform mLocalShapeToWorld;
Transform mLocalShape2ToWorld; Transform mLocalShape2ToWorld;
// Collision Shapes // Proxy Shapes
ProxyShape* mBoxShape; ProxyShape* mBoxProxyShape;
ProxyShape* mSphereShape; ProxyShape* mSphereProxyShape;
ProxyShape* mCapsuleShape; ProxyShape* mCapsuleProxyShape;
ProxyShape* mConeShape; ProxyShape* mConeProxyShape;
ProxyShape* mConvexMeshShape; ProxyShape* mConvexMeshProxyShape;
ProxyShape* mConvexMeshShapeEdgesInfo; ProxyShape* mConvexMeshProxyShapeEdgesInfo;
ProxyShape* mCylinderShape; ProxyShape* mCylinderProxyShape;
public : public :
@ -110,65 +119,76 @@ class TestPointInside : public Test {
mLocalShapeToWorld = mBodyTransform * mShapeTransform; mLocalShapeToWorld = mBodyTransform * mShapeTransform;
// Create collision shapes // Create collision shapes
BoxShape boxShape(Vector3(2, 3, 4), 0); mBoxShape = new BoxShape(Vector3(2, 3, 4), 0);
mBoxShape = mBoxBody->addCollisionShape(boxShape, mShapeTransform); mBoxProxyShape = mBoxBody->addCollisionShape(mBoxShape, mShapeTransform);
SphereShape sphereShape(3); mSphereShape = new SphereShape(3);
mSphereShape = mSphereBody->addCollisionShape(sphereShape, mShapeTransform); mSphereProxyShape = mSphereBody->addCollisionShape(mSphereShape, mShapeTransform);
CapsuleShape capsuleShape(2, 10); mCapsuleShape = new CapsuleShape(2, 10);
mCapsuleShape = mCapsuleBody->addCollisionShape(capsuleShape, mShapeTransform); mCapsuleProxyShape = mCapsuleBody->addCollisionShape(mCapsuleShape, mShapeTransform);
ConeShape coneShape(2, 6, 0); mConeShape = new ConeShape(2, 6, 0);
mConeShape = mConeBody->addCollisionShape(coneShape, mShapeTransform); mConeProxyShape = mConeBody->addCollisionShape(mConeShape, mShapeTransform);
ConvexMeshShape convexMeshShape(0); // Box of dimension (2, 3, 4) mConvexMeshShape = new ConvexMeshShape(0); // Box of dimension (2, 3, 4)
convexMeshShape.addVertex(Vector3(-2, -3, -4)); mConvexMeshShape->addVertex(Vector3(-2, -3, -4));
convexMeshShape.addVertex(Vector3(2, -3, -4)); mConvexMeshShape->addVertex(Vector3(2, -3, -4));
convexMeshShape.addVertex(Vector3(2, -3, 4)); mConvexMeshShape->addVertex(Vector3(2, -3, 4));
convexMeshShape.addVertex(Vector3(-2, -3, 4)); mConvexMeshShape->addVertex(Vector3(-2, -3, 4));
convexMeshShape.addVertex(Vector3(-2, 3, -4)); mConvexMeshShape->addVertex(Vector3(-2, 3, -4));
convexMeshShape.addVertex(Vector3(2, 3, -4)); mConvexMeshShape->addVertex(Vector3(2, 3, -4));
convexMeshShape.addVertex(Vector3(2, 3, 4)); mConvexMeshShape->addVertex(Vector3(2, 3, 4));
convexMeshShape.addVertex(Vector3(-2, 3, 4)); mConvexMeshShape->addVertex(Vector3(-2, 3, 4));
mConvexMeshShape = mConvexMeshBody->addCollisionShape(convexMeshShape, mShapeTransform); mConvexMeshProxyShape = mConvexMeshBody->addCollisionShape(mConvexMeshShape, mShapeTransform);
ConvexMeshShape convexMeshShapeEdgesInfo(0); mConvexMeshShapeBodyEdgesInfo = new ConvexMeshShape(0);
convexMeshShapeEdgesInfo.addVertex(Vector3(-2, -3, -4)); mConvexMeshShapeBodyEdgesInfo->addVertex(Vector3(-2, -3, -4));
convexMeshShapeEdgesInfo.addVertex(Vector3(2, -3, -4)); mConvexMeshShapeBodyEdgesInfo->addVertex(Vector3(2, -3, -4));
convexMeshShapeEdgesInfo.addVertex(Vector3(2, -3, 4)); mConvexMeshShapeBodyEdgesInfo->addVertex(Vector3(2, -3, 4));
convexMeshShapeEdgesInfo.addVertex(Vector3(-2, -3, 4)); mConvexMeshShapeBodyEdgesInfo->addVertex(Vector3(-2, -3, 4));
convexMeshShapeEdgesInfo.addVertex(Vector3(-2, 3, -4)); mConvexMeshShapeBodyEdgesInfo->addVertex(Vector3(-2, 3, -4));
convexMeshShapeEdgesInfo.addVertex(Vector3(2, 3, -4)); mConvexMeshShapeBodyEdgesInfo->addVertex(Vector3(2, 3, -4));
convexMeshShapeEdgesInfo.addVertex(Vector3(2, 3, 4)); mConvexMeshShapeBodyEdgesInfo->addVertex(Vector3(2, 3, 4));
convexMeshShapeEdgesInfo.addVertex(Vector3(-2, 3, 4)); mConvexMeshShapeBodyEdgesInfo->addVertex(Vector3(-2, 3, 4));
convexMeshShapeEdgesInfo.addEdge(0, 1); mConvexMeshShapeBodyEdgesInfo->addEdge(0, 1);
convexMeshShapeEdgesInfo.addEdge(1, 2); mConvexMeshShapeBodyEdgesInfo->addEdge(1, 2);
convexMeshShapeEdgesInfo.addEdge(2, 3); mConvexMeshShapeBodyEdgesInfo->addEdge(2, 3);
convexMeshShapeEdgesInfo.addEdge(0, 3); mConvexMeshShapeBodyEdgesInfo->addEdge(0, 3);
convexMeshShapeEdgesInfo.addEdge(4, 5); mConvexMeshShapeBodyEdgesInfo->addEdge(4, 5);
convexMeshShapeEdgesInfo.addEdge(5, 6); mConvexMeshShapeBodyEdgesInfo->addEdge(5, 6);
convexMeshShapeEdgesInfo.addEdge(6, 7); mConvexMeshShapeBodyEdgesInfo->addEdge(6, 7);
convexMeshShapeEdgesInfo.addEdge(4, 7); mConvexMeshShapeBodyEdgesInfo->addEdge(4, 7);
convexMeshShapeEdgesInfo.addEdge(0, 4); mConvexMeshShapeBodyEdgesInfo->addEdge(0, 4);
convexMeshShapeEdgesInfo.addEdge(1, 5); mConvexMeshShapeBodyEdgesInfo->addEdge(1, 5);
convexMeshShapeEdgesInfo.addEdge(2, 6); mConvexMeshShapeBodyEdgesInfo->addEdge(2, 6);
convexMeshShapeEdgesInfo.addEdge(3, 7); mConvexMeshShapeBodyEdgesInfo->addEdge(3, 7);
convexMeshShapeEdgesInfo.setIsEdgesInformationUsed(true); mConvexMeshShapeBodyEdgesInfo->setIsEdgesInformationUsed(true);
mConvexMeshShapeEdgesInfo = mConvexMeshBodyEdgesInfo->addCollisionShape( mConvexMeshProxyShapeEdgesInfo = mConvexMeshBodyEdgesInfo->addCollisionShape(
convexMeshShapeEdgesInfo, mConvexMeshShapeBodyEdgesInfo,
mShapeTransform); mShapeTransform);
CylinderShape cylinderShape(3, 8, 0); mCylinderShape = new CylinderShape(3, 8, 0);
mCylinderShape = mCylinderBody->addCollisionShape(cylinderShape, mShapeTransform); mCylinderProxyShape = mCylinderBody->addCollisionShape(mCylinderShape, mShapeTransform);
// Compound shape is a cylinder and a sphere // Compound shape is a cylinder and a sphere
Vector3 positionShape2(Vector3(4, 2, -3)); Vector3 positionShape2(Vector3(4, 2, -3));
Quaternion orientationShape2(-3 *PI / 8, 1.5 * PI/ 3, PI / 13); Quaternion orientationShape2(-3 *PI / 8, 1.5 * PI/ 3, PI / 13);
Transform shapeTransform2(positionShape2, orientationShape2); Transform shapeTransform2(positionShape2, orientationShape2);
mLocalShape2ToWorld = mBodyTransform * shapeTransform2; mLocalShape2ToWorld = mBodyTransform * shapeTransform2;
mCompoundBody->addCollisionShape(cylinderShape, mShapeTransform); mCompoundBody->addCollisionShape(mCylinderShape, mShapeTransform);
mCompoundBody->addCollisionShape(sphereShape, shapeTransform2); mCompoundBody->addCollisionShape(mSphereShape, shapeTransform2);
}
/// Destructor
~TestPointInside() {
delete mBoxShape;
delete mSphereShape;
delete mCapsuleShape;
delete mConeShape;
delete mConvexMeshShape;
delete mConvexMeshShapeBodyEdgesInfo;
delete mCylinderShape;
} }
/// Run the tests /// Run the tests
@ -213,30 +233,30 @@ class TestPointInside : public Test {
test(!mBoxBody->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 4.5))); test(!mBoxBody->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 4.5)));
// Tests with ProxyBoxShape // Tests with ProxyBoxShape
test(mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0))); test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0)));
test(mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(-1.9, 0, 0))); test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.9, 0, 0)));
test(mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(1.9, 0, 0))); test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.9, 0, 0)));
test(mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, 0))); test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, 0)));
test(mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(0, 2.9, 0))); test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 2.9, 0)));
test(mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -3.9))); test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -3.9)));
test(mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 3.9))); test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 3.9)));
test(mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(-1.9, -2.9, -3.9))); test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.9, -2.9, -3.9)));
test(mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(1.9, 2.9, 3.9))); test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.9, 2.9, 3.9)));
test(mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(-1, -2, -1.5))); test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1, -2, -1.5)));
test(mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(-1, 2, -2.5))); test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1, 2, -2.5)));
test(mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 3.5))); test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 3.5)));
test(!mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(-2.1, 0, 0))); test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.1, 0, 0)));
test(!mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(2.1, 0, 0))); test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.1, 0, 0)));
test(!mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.1, 0))); test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.1, 0)));
test(!mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.1, 0))); test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.1, 0)));
test(!mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -4.1))); test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -4.1)));
test(!mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 4.1))); test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 4.1)));
test(!mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(-2.1, -3.1, -4.1))); test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.1, -3.1, -4.1)));
test(!mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(2.1, 3.1, 4.1))); test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.1, 3.1, 4.1)));
test(!mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(-10, -2, -1.5))); test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-10, -2, -1.5)));
test(!mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(-1, 4, -2.5))); test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1, 4, -2.5)));
test(!mBoxShape->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 4.5))); test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 4.5)));
} }
/// Test the ProxySphereShape::testPointInside() and /// Test the ProxySphereShape::testPointInside() and
@ -266,26 +286,26 @@ class TestPointInside : public Test {
test(!mSphereBody->testPointInside(mLocalShapeToWorld * Vector3(1.5, -2, 2.5))); test(!mSphereBody->testPointInside(mLocalShapeToWorld * Vector3(1.5, -2, 2.5)));
// Tests with ProxySphereShape // Tests with ProxySphereShape
test(mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0))); test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0)));
test(mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(2.9, 0, 0))); test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.9, 0, 0)));
test(mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(-2.9, 0, 0))); test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.9, 0, 0)));
test(mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(0, 2.9, 0))); test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 2.9, 0)));
test(mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, 0))); test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, 0)));
test(mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 2.9))); test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 2.9)));
test(mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 2.9))); test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 2.9)));
test(mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(-1, -2, -1.5))); test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1, -2, -1.5)));
test(mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(-1, 2, -1.5))); test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1, 2, -1.5)));
test(mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 1.5))); test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 1.5)));
test(!mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(3.1, 0, 0))); test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(3.1, 0, 0)));
test(!mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(-3.1, 0, 0))); test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-3.1, 0, 0)));
test(!mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.1, 0))); test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.1, 0)));
test(!mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.1, 0))); test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.1, 0)));
test(!mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 3.1))); test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 3.1)));
test(!mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -3.1))); test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -3.1)));
test(!mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(-2, -2, -2))); test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2, -2, -2)));
test(!mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(-2, 2, -1.5))); test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2, 2, -1.5)));
test(!mSphereShape->testPointInside(mLocalShapeToWorld * Vector3(1.5, -2, 2.5))); test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.5, -2, 2.5)));
} }
/// Test the ProxyCapsuleShape::testPointInside() and /// Test the ProxyCapsuleShape::testPointInside() and
@ -340,51 +360,51 @@ class TestPointInside : public Test {
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * Vector3(1.5, -5, -1.7))); test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * Vector3(1.5, -5, -1.7)));
// Tests with ProxyCapsuleShape // Tests with ProxyCapsuleShape
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, 5, 0))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 5, 0)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, -5, 0))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -5, 0)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, -6.9, 0))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -6.9, 0)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, 6.9, 0))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 6.9, 0)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 1.9))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 1.9)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -1.9))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -1.9)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(1.9, 0, 0))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.9, 0, 0)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(-1.9, 0, 0))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.9, 0, 0)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0.9, 0, 0.9))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0.9, 0, 0.9)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0.9, 0, -0.9))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0.9, 0, -0.9)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, 5, 1.9))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 5, 1.9)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, 5, -1.9))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 5, -1.9)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(1.9, 5, 0))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.9, 5, 0)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(-1.9, 5, 0))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.9, 5, 0)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0.9, 5, 0.9))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0.9, 5, 0.9)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0.9, 5, -0.9))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0.9, 5, -0.9)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, -5, 1.9))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -5, 1.9)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, -5, -1.9))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -5, -1.9)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(1.9, -5, 0))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.9, -5, 0)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(-1.9, -5, 0))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.9, -5, 0)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0.9, -5, 0.9))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0.9, -5, 0.9)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0.9, -5, -0.9))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0.9, -5, -0.9)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(-1.7, -4, -0.9))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.7, -4, -0.9)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(-1, 2, 0.4))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1, 2, 0.4)));
test(mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(1.3, 1, 1.5))); test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.3, 1, 1.5)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, -7.1, 0))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -7.1, 0)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, 7.1, 0))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 7.1, 0)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 2.1))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 2.1)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -2.1))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -2.1)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(2.1, 0, 0))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.1, 0, 0)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(-2.1, 0, 0))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.1, 0, 0)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, 5, 2.1))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 5, 2.1)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, 5, -2.1))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 5, -2.1)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(2.1, 5, 0))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.1, 5, 0)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(-2.1, 5, 0))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.1, 5, 0)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(1.5, 5, 1.6))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.5, 5, 1.6)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(1.5, 5, -1.7))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.5, 5, -1.7)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, -5, 2.1))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -5, 2.1)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(0, -5, -2.1))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -5, -2.1)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(2.1, -5, 0))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.1, -5, 0)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(-2.1, -5, 0))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.1, -5, 0)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(1.5, -5, 1.6))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.5, -5, 1.6)));
test(!mCapsuleShape->testPointInside(mLocalShapeToWorld * Vector3(1.5, -5, -1.7))); test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.5, -5, -1.7)));
} }
/// Test the ProxyConeShape::testPointInside() and /// Test the ProxyConeShape::testPointInside() and
@ -428,40 +448,40 @@ class TestPointInside : public Test {
test(!mConeBody->testPointInside(mLocalShapeToWorld * Vector3(-1.5, -2.9, 1.5))); test(!mConeBody->testPointInside(mLocalShapeToWorld * Vector3(-1.5, -2.9, 1.5)));
// Tests with ProxyConeShape // Tests with ProxyConeShape
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0.9, 0, 0))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0.9, 0, 0)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(-0.9, 0, 0))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-0.9, 0, 0)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0.9))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0.9)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -0.9))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -0.9)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0.6, 0, -0.7))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0.6, 0, -0.7)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0.6, 0, 0.7))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0.6, 0, 0.7)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(-0.6, 0, -0.7))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-0.6, 0, -0.7)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(-0.6, 0, 0.7))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-0.6, 0, 0.7)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0, 2.9, 0))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 2.9, 0)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, 0))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, 0)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(1.96, -2.9, 0))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.96, -2.9, 0)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(-1.96, -2.9, 0))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.96, -2.9, 0)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, 1.96))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, 1.96)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, -1.96))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, -1.96)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(1.3, -2.9, -1.4))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.3, -2.9, -1.4)));
test(mConeShape->testPointInside(mLocalShapeToWorld * Vector3(-1.3, -2.9, 1.4))); test(mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.3, -2.9, 1.4)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(1.1, 0, 0))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.1, 0, 0)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(-1.1, 0, 0))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.1, 0, 0)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 1.1))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 1.1)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -1.1))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -1.1)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0.8, 0, -0.8))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0.8, 0, -0.8)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0.8, 0, 0.8))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0.8, 0, 0.8)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(-0.8, 0, -0.8))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-0.8, 0, -0.8)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(-0.8, 0, 0.8))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-0.8, 0, 0.8)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.1, 0))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.1, 0)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.1, 0))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.1, 0)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(1.97, -2.9, 0))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.97, -2.9, 0)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(-1.97, -2.9, 0))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.97, -2.9, 0)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, 1.97))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, 1.97)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, -1.97))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, -1.97)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(1.5, -2.9, -1.5))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.5, -2.9, -1.5)));
test(!mConeShape->testPointInside(mLocalShapeToWorld * Vector3(-1.5, -2.9, 1.5))); test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.5, -2.9, 1.5)));
} }
/// Test the ProxyConvexMeshShape::testPointInside() and /// Test the ProxyConvexMeshShape::testPointInside() and
@ -497,30 +517,30 @@ class TestPointInside : public Test {
test(!mConvexMeshBody->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 4.5))); test(!mConvexMeshBody->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 4.5)));
// Tests with ProxyConvexMeshShape // Tests with ProxyConvexMeshShape
test(mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0))); test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0)));
test(mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(-1.9, 0, 0))); test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.9, 0, 0)));
test(mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(1.9, 0, 0))); test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.9, 0, 0)));
test(mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, 0))); test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, 0)));
test(mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(0, 2.9, 0))); test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 2.9, 0)));
test(mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -3.9))); test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -3.9)));
test(mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 3.9))); test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 3.9)));
test(mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(-1.9, -2.9, -3.9))); test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.9, -2.9, -3.9)));
test(mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(1.9, 2.9, 3.9))); test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.9, 2.9, 3.9)));
test(mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(-1, -2, -1.5))); test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1, -2, -1.5)));
test(mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(-1, 2, -2.5))); test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1, 2, -2.5)));
test(mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 3.5))); test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 3.5)));
test(!mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(-2.1, 0, 0))); test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.1, 0, 0)));
test(!mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(2.1, 0, 0))); test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.1, 0, 0)));
test(!mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.1, 0))); test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.1, 0)));
test(!mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.1, 0))); test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.1, 0)));
test(!mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -4.1))); test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -4.1)));
test(!mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 4.1))); test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 4.1)));
test(!mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(-2.1, -3.1, -4.1))); test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.1, -3.1, -4.1)));
test(!mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(2.1, 3.1, 4.1))); test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.1, 3.1, 4.1)));
test(!mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(-10, -2, -1.5))); test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-10, -2, -1.5)));
test(!mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(-1, 4, -2.5))); test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1, 4, -2.5)));
test(!mConvexMeshShape->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 4.5))); test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 4.5)));
// ----- Tests using edges information ----- // // ----- Tests using edges information ----- //
@ -551,30 +571,30 @@ class TestPointInside : public Test {
test(!mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 4.5))); test(!mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 4.5)));
// Tests with ProxyConvexMeshShape // Tests with ProxyConvexMeshShape
test(mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0))); test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0)));
test(mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-1.9, 0, 0))); test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-1.9, 0, 0)));
test(mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(1.9, 0, 0))); test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(1.9, 0, 0)));
test(mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, 0))); test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, -2.9, 0)));
test(mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, 2.9, 0))); test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, 2.9, 0)));
test(mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -3.9))); test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -3.9)));
test(mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 3.9))); test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 3.9)));
test(mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-1.9, -2.9, -3.9))); test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-1.9, -2.9, -3.9)));
test(mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(1.9, 2.9, 3.9))); test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(1.9, 2.9, 3.9)));
test(mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-1, -2, -1.5))); test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-1, -2, -1.5)));
test(mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-1, 2, -2.5))); test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-1, 2, -2.5)));
test(mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 3.5))); test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 3.5)));
test(!mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-2.1, 0, 0))); test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-2.1, 0, 0)));
test(!mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(2.1, 0, 0))); test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(2.1, 0, 0)));
test(!mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, -3.1, 0))); test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, -3.1, 0)));
test(!mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, 3.1, 0))); test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, 3.1, 0)));
test(!mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -4.1))); test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -4.1)));
test(!mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 4.1))); test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 4.1)));
test(!mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-2.1, -3.1, -4.1))); test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-2.1, -3.1, -4.1)));
test(!mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(2.1, 3.1, 4.1))); test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(2.1, 3.1, 4.1)));
test(!mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-10, -2, -1.5))); test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-10, -2, -1.5)));
test(!mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-1, 4, -2.5))); test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(-1, 4, -2.5)));
test(!mConvexMeshShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 4.5))); test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * Vector3(1, -2, 4.5)));
} }
/// Test the ProxyCylinderShape::testPointInside() and /// Test the ProxyCylinderShape::testPointInside() and
@ -638,60 +658,60 @@ class TestPointInside : public Test {
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * Vector3(-2.2, -3.9, 2.2))); test(!mCylinderBody->testPointInside(mLocalShapeToWorld * Vector3(-2.2, -3.9, 2.2)));
// Tests with ProxyCylinderShape // Tests with ProxyCylinderShape
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 0)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.9, 0))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.9, 0)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.9, 0))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.9, 0)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(2.9, 0, 0))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.9, 0, 0)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-2.9, 0, 0))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.9, 0, 0)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 2.9))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 2.9)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -2.9))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -2.9)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(1.7, 0, 1.7))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.7, 0, 1.7)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(1.7, 0, -1.7))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.7, 0, -1.7)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-1.7, 0, -1.7))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.7, 0, -1.7)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-1.7, 0, 1.7))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.7, 0, 1.7)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(2.9, 3.9, 0))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.9, 3.9, 0)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-2.9, 3.9, 0))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.9, 3.9, 0)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.9, 2.9))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.9, 2.9)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.9, -2.9))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.9, -2.9)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(1.7, 3.9, 1.7))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.7, 3.9, 1.7)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(1.7, 3.9, -1.7))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.7, 3.9, -1.7)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-1.7, 3.9, -1.7))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.7, 3.9, -1.7)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-1.7, 3.9, 1.7))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.7, 3.9, 1.7)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(2.9, -3.9, 0))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.9, -3.9, 0)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-2.9, -3.9, 0))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.9, -3.9, 0)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.9, 2.9))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.9, 2.9)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.9, -2.9))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.9, -2.9)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(1.7, -3.9, 1.7))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.7, -3.9, 1.7)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(1.7, -3.9, -1.7))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(1.7, -3.9, -1.7)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-1.7, -3.9, -1.7))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.7, -3.9, -1.7)));
test(mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-1.7, -3.9, 1.7))); test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.7, -3.9, 1.7)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, 4.1, 0))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 4.1, 0)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, -4.1, 0))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -4.1, 0)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(3.1, 0, 0))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(3.1, 0, 0)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-3.1, 0, 0))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-3.1, 0, 0)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 3.1))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, 3.1)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -3.1))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 0, -3.1)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(2.2, 0, 2.2))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.2, 0, 2.2)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(2.2, 0, -2.2))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.2, 0, -2.2)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-2.2, 0, -2.2))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.2, 0, -2.2)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-1.3, 0, 2.8))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-1.3, 0, 2.8)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(3.1, 3.9, 0))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(3.1, 3.9, 0)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-3.1, 3.9, 0))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-3.1, 3.9, 0)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.9, 3.1))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.9, 3.1)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.9, -3.1))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, 3.9, -3.1)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(2.2, 3.9, 2.2))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.2, 3.9, 2.2)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(2.2, 3.9, -2.2))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.2, 3.9, -2.2)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-2.2, 3.9, -2.2))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.2, 3.9, -2.2)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-2.2, 3.9, 2.2))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.2, 3.9, 2.2)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(3.1, -3.9, 0))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(3.1, -3.9, 0)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-3.1, -3.9, 0))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-3.1, -3.9, 0)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.9, 3.1))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.9, 3.1)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.9, -3.1))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(0, -3.9, -3.1)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(2.2, -3.9, 2.2))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.2, -3.9, 2.2)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(2.2, -3.9, -2.2))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(2.2, -3.9, -2.2)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-2.2, -3.9, -2.2))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.2, -3.9, -2.2)));
test(!mCylinderShape->testPointInside(mLocalShapeToWorld * Vector3(-2.2, -3.9, 2.2))); test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * Vector3(-2.2, -3.9, 2.2)));
} }
/// Test the CollisionBody::testPointInside() method /// Test the CollisionBody::testPointInside() method

File diff suppressed because it is too large Load Diff

View File

@ -132,7 +132,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
// Create the collision shape for the rigid body (box shape) // Create the collision shape for the rigid body (box shape)
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
const rp3d::BoxShape collisionShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); mboxCollisionShape = new rp3d::BoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2]));
// Initial position and orientation of the rigid body // Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z); rp3d::Vector3 initPosition(position.x, position.y, position.z);
@ -145,7 +145,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
mBody = world->createCollisionBody(transform); mBody = world->createCollisionBody(transform);
// Add the collision shape to the body // Add the collision shape to the body
mBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mBody->addCollisionShape(mboxCollisionShape, rp3d::Transform::identity());
// If the Vertex Buffer object has not been created yet // If the Vertex Buffer object has not been created yet
if (totalNbBoxes == 0) { if (totalNbBoxes == 0) {
@ -181,7 +181,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3& p
// Create the collision shape for the rigid body (box shape) // Create the collision shape for the rigid body (box shape)
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
const rp3d::BoxShape collisionShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); mboxCollisionShape = new rp3d::BoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2]));
// Initial position and orientation of the rigid body // Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z); rp3d::Vector3 initPosition(position.x, position.y, position.z);
@ -194,7 +194,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3& p
rp3d::RigidBody* body = world->createRigidBody(transform); rp3d::RigidBody* body = world->createRigidBody(transform);
// Add the collision shape to the body // Add the collision shape to the body
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); body->addCollisionShape(mboxCollisionShape, rp3d::Transform::identity(), mass);
mBody = body; mBody = body;
@ -220,7 +220,7 @@ Box::~Box() {
mVBONormals.destroy(); mVBONormals.destroy();
mVAO.destroy(); mVAO.destroy();
} }
delete mboxCollisionShape;
totalNbBoxes--; totalNbBoxes--;
} }

View File

@ -41,6 +41,8 @@ class Box : public openglframework::Object3D, public PhysicsObject {
/// Size of each side of the box /// Size of each side of the box
float mSize[3]; float mSize[3];
rp3d::BoxShape* mboxCollisionShape;
/// Scaling matrix (applied to a cube to obtain the correct box dimensions) /// Scaling matrix (applied to a cube to obtain the correct box dimensions)
openglframework::Matrix4 mScalingMatrix; openglframework::Matrix4 mScalingMatrix;

View File

@ -57,7 +57,7 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
// Create the collision shape for the rigid body (sphere shape) // Create the collision shape for the rigid body (sphere shape)
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
const rp3d::CapsuleShape collisionShape(mRadius, mHeight); mCollisionShape = new rp3d::CapsuleShape(mRadius, mHeight);
// Initial position and orientation of the rigid body // Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z); rp3d::Vector3 initPosition(position.x, position.y, position.z);
@ -70,7 +70,7 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
mBody = world->createCollisionBody(transform); mBody = world->createCollisionBody(transform);
// Add a collision shape to the body and specify the mass of the shape // Add a collision shape to the body and specify the mass of the shape
mBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity());
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
@ -106,7 +106,7 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
// Create the collision shape for the rigid body (sphere shape) // Create the collision shape for the rigid body (sphere shape)
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
const rp3d::CapsuleShape collisionShape(mRadius, mHeight); mCollisionShape = new rp3d::CapsuleShape(mRadius, mHeight);
// Initial position and orientation of the rigid body // Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z); rp3d::Vector3 initPosition(position.x, position.y, position.z);
@ -117,7 +117,7 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform);
// Add a collision shape to the body and specify the mass of the shape // Add a collision shape to the body and specify the mass of the shape
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass);
mBody = body; mBody = body;
@ -146,7 +146,7 @@ Capsule::~Capsule() {
mVBOTextureCoords.destroy(); mVBOTextureCoords.destroy();
mVAO.destroy(); mVAO.destroy();
} }
delete mCollisionShape;
totalNbCapsules--; totalNbCapsules--;
} }

View File

@ -44,6 +44,9 @@ class Capsule : public openglframework::Mesh, public PhysicsObject {
/// Height of the capsule /// Height of the capsule
float mHeight; float mHeight;
/// Collision shape
rp3d::CapsuleShape* mCollisionShape;
/// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions)
openglframework::Matrix4 mScalingMatrix; openglframework::Matrix4 mScalingMatrix;

View File

@ -54,10 +54,9 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
// Initialize the position where the cone will be rendered // Initialize the position where the cone will be rendered
translateWorld(position); translateWorld(position);
// Create the collision shape for the rigid body (cone shape) // Create the collision shape for the rigid body (cone shape) and do
// ReactPhysics3D will clone this object to create an internal one. Therefore, // not forget to delete it at the end
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() mCollisionShape = new rp3d::ConeShape(mRadius, mHeight);
const rp3d::ConeShape collisionShape(mRadius, mHeight);
// Initial position and orientation of the rigid body // Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z); rp3d::Vector3 initPosition(position.x, position.y, position.z);
@ -70,7 +69,7 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
mBody = world->createCollisionBody(transform); mBody = world->createCollisionBody(transform);
// Add a collision shape to the body and specify the mass of the shape // Add a collision shape to the body and specify the mass of the shape
mBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity());
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
@ -103,10 +102,9 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
// Initialize the position where the cone will be rendered // Initialize the position where the cone will be rendered
translateWorld(position); translateWorld(position);
// Create the collision shape for the rigid body (cone shape) // Create the collision shape for the rigid body (cone shape) and do not
// ReactPhysics3D will clone this object to create an internal one. Therefore, // forget to delete it at the end
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() mCollisionShape = new rp3d::ConeShape(mRadius, mHeight);
const rp3d::ConeShape collisionShape(mRadius, mHeight);
// Initial position and orientation of the rigid body // Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z); rp3d::Vector3 initPosition(position.x, position.y, position.z);
@ -117,7 +115,7 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform);
// Add a collision shape to the body and specify the mass of the shape // Add a collision shape to the body and specify the mass of the shape
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass);
mBody = body; mBody = body;
@ -145,7 +143,7 @@ Cone::~Cone() {
mVBOTextureCoords.destroy(); mVBOTextureCoords.destroy();
mVAO.destroy(); mVAO.destroy();
} }
delete mCollisionShape;
totalNbCones--; totalNbCones--;
} }

View File

@ -44,6 +44,9 @@ class Cone : public openglframework::Mesh, public PhysicsObject {
/// Height of the cone /// Height of the cone
float mHeight; float mHeight;
/// Collision shape
rp3d::ConeShape* mCollisionShape;
/// Scaling matrix (applied to a sphere to obtain the correct cone dimensions) /// Scaling matrix (applied to a sphere to obtain the correct cone dimensions)
openglframework::Matrix4 mScalingMatrix; openglframework::Matrix4 mScalingMatrix;

View File

@ -51,11 +51,9 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position,
vertices[3 * i + 2] = static_cast<rp3d::decimal>(mVertices[i].z); vertices[3 * i + 2] = static_cast<rp3d::decimal>(mVertices[i].z);
} }
// Create the collision shape for the rigid body (convex mesh shape) // Create the collision shape for the rigid body (convex mesh shape) and
// ReactPhysics3D will clone this object to create an internal one. Therefore, // do not forget to delete it at the end
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() mCollisionShape = new rp3d::ConvexMeshShape(vertices, mVertices.size(), 3 * sizeof(rp3d::decimal));
rp3d::ConvexMeshShape collisionShape(vertices, mVertices.size(), 3 * sizeof(rp3d::decimal));
delete[] vertices; delete[] vertices;
@ -70,11 +68,11 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position,
unsigned int v3 = getVertexIndexInFace(i, 2); unsigned int v3 = getVertexIndexInFace(i, 2);
// Add the three edges into the collision shape // Add the three edges into the collision shape
collisionShape.addEdge(v1, v2); mCollisionShape->addEdge(v1, v2);
collisionShape.addEdge(v1, v3); mCollisionShape->addEdge(v1, v3);
collisionShape.addEdge(v2, v3); mCollisionShape->addEdge(v2, v3);
} }
collisionShape.setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges mCollisionShape->setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges
// Initial position and orientation of the rigid body // Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z); rp3d::Vector3 initPosition(position.x, position.y, position.z);
@ -87,7 +85,7 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position,
mBody = world->createCollisionBody(transform); mBody = world->createCollisionBody(transform);
// Add a collision shape to the body and specify the mass of the collision shape // Add a collision shape to the body and specify the mass of the collision shape
mBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity());
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(); createVBOAndVAO();
@ -118,10 +116,9 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass,
vertices[3 * i + 2] = static_cast<rp3d::decimal>(mVertices[i].z); vertices[3 * i + 2] = static_cast<rp3d::decimal>(mVertices[i].z);
} }
// Create the collision shape for the rigid body (convex mesh shape) // Create the collision shape for the rigid body (convex mesh shape) and do
// ReactPhysics3D will clone this object to create an internal one. Therefore, // not forget to delete it at the end
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() mCollisionShape = new rp3d::ConvexMeshShape(vertices, mVertices.size(), 3 * sizeof(rp3d::decimal));
rp3d::ConvexMeshShape collisionShape(vertices, mVertices.size(), 3 * sizeof(rp3d::decimal));
delete[] vertices; delete[] vertices;
@ -136,11 +133,11 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass,
unsigned int v3 = getVertexIndexInFace(i, 2); unsigned int v3 = getVertexIndexInFace(i, 2);
// Add the three edges into the collision shape // Add the three edges into the collision shape
collisionShape.addEdge(v1, v2); mCollisionShape->addEdge(v1, v2);
collisionShape.addEdge(v1, v3); mCollisionShape->addEdge(v1, v3);
collisionShape.addEdge(v2, v3); mCollisionShape->addEdge(v2, v3);
} }
collisionShape.setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges mCollisionShape->setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges
// Initial position and orientation of the rigid body // Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z); rp3d::Vector3 initPosition(position.x, position.y, position.z);
@ -151,7 +148,7 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass,
rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform);
// Add a collision shape to the body and specify the mass of the collision shape // Add a collision shape to the body and specify the mass of the collision shape
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass);
mBody = body; mBody = body;
@ -171,6 +168,8 @@ ConvexMesh::~ConvexMesh() {
mVBONormals.destroy(); mVBONormals.destroy();
mVBOTextureCoords.destroy(); mVBOTextureCoords.destroy();
mVAO.destroy(); mVAO.destroy();
delete mCollisionShape;
} }
// Render the sphere at the correct position and with the correct orientation // Render the sphere at the correct position and with the correct orientation

View File

@ -41,6 +41,9 @@ class ConvexMesh : public openglframework::Mesh, public PhysicsObject {
/// Previous transform (for interpolation) /// Previous transform (for interpolation)
rp3d::Transform mPreviousTransform; rp3d::Transform mPreviousTransform;
/// Collision shape
rp3d::ConvexMeshShape* mCollisionShape;
/// Vertex Buffer Object for the vertices data /// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices; openglframework::VertexBufferObject mVBOVertices;

View File

@ -54,10 +54,9 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
// Initialize the position where the cylinder will be rendered // Initialize the position where the cylinder will be rendered
translateWorld(position); translateWorld(position);
// Create the collision shape for the rigid body (cylinder shape) // Create the collision shape for the rigid body (cylinder shape) and do not
// ReactPhysics3D will clone this object to create an internal one. Therefore, // forget to delete it at the end
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() mCollisionShape = new rp3d::CylinderShape(mRadius, mHeight);
const rp3d::CylinderShape collisionShape(mRadius, mHeight);
// Initial position and orientation of the rigid body // Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z); rp3d::Vector3 initPosition(position.x, position.y, position.z);
@ -70,7 +69,7 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
mBody = world->createCollisionBody(transform); mBody = world->createCollisionBody(transform);
// Add a collision shape to the body and specify the mass of the shape // Add a collision shape to the body and specify the mass of the shape
mBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity());
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
@ -103,10 +102,9 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
// Initialize the position where the cylinder will be rendered // Initialize the position where the cylinder will be rendered
translateWorld(position); translateWorld(position);
// Create the collision shape for the rigid body (cylinder shape) // Create the collision shape for the rigid body (cylinder shape) and do
// ReactPhysics3D will clone this object to create an internal one. Therefore, // not forget to delete it at the end
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() mCollisionShape = new rp3d::CylinderShape(mRadius, mHeight);
const rp3d::CylinderShape collisionShape(mRadius, mHeight);
// Initial position and orientation of the rigid body // Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z); rp3d::Vector3 initPosition(position.x, position.y, position.z);
@ -117,7 +115,7 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform);
// Add a collision shape to the body and specify the mass of the shape // Add a collision shape to the body and specify the mass of the shape
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass);
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
@ -146,7 +144,7 @@ Cylinder::~Cylinder() {
mVBOTextureCoords.destroy(); mVBOTextureCoords.destroy();
mVAO.destroy(); mVAO.destroy();
} }
delete mCollisionShape;
totalNbCylinders--; totalNbCylinders--;
} }

View File

@ -50,6 +50,9 @@ class Cylinder : public openglframework::Mesh, public PhysicsObject {
/// Previous transform (for interpolation) /// Previous transform (for interpolation)
rp3d::Transform mPreviousTransform; rp3d::Transform mPreviousTransform;
/// Collision shape
rp3d::CylinderShape* mCollisionShape;
/// Vertex Buffer Object for the vertices data /// Vertex Buffer Object for the vertices data
static openglframework::VertexBufferObject mVBOVertices; static openglframework::VertexBufferObject mVBOVertices;

View File

@ -55,7 +55,7 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
const rp3d::decimal radiusSphere = rp3d::decimal(1.5); const rp3d::decimal radiusSphere = rp3d::decimal(1.5);
const rp3d::decimal massSphere = rp3d::decimal(2.0); const rp3d::decimal massSphere = rp3d::decimal(2.0);
const rp3d::SphereShape sphereCollisionShape(radiusSphere); mSphereShape = new rp3d::SphereShape(radiusSphere);
// Create a cylinder collision shape for the middle of the dumbbell // Create a cylinder collision shape for the middle of the dumbbell
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
@ -63,7 +63,7 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
const rp3d::decimal radiusCylinder = rp3d::decimal(0.5); const rp3d::decimal radiusCylinder = rp3d::decimal(0.5);
const rp3d::decimal heightCylinder = rp3d::decimal(8.0); const rp3d::decimal heightCylinder = rp3d::decimal(8.0);
const rp3d::decimal massCylinder = rp3d::decimal(1.0); const rp3d::decimal massCylinder = rp3d::decimal(1.0);
const rp3d::CylinderShape cylinderCollisionShape(radiusCylinder, heightCylinder); mCylinderShape = new rp3d::CylinderShape(radiusCylinder, heightCylinder);
// Initial position and orientation of the rigid body // Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z); rp3d::Vector3 initPosition(position.x, position.y, position.z);
@ -86,9 +86,9 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transformBody); rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transformBody);
// Add the three collision shapes to the body and specify the mass and transform of the shapes // Add the three collision shapes to the body and specify the mass and transform of the shapes
body->addCollisionShape(sphereCollisionShape, transformSphereShape1, massSphere); body->addCollisionShape(mSphereShape, transformSphereShape1, massSphere);
body->addCollisionShape(sphereCollisionShape, transformSphereShape2, massSphere); body->addCollisionShape(mSphereShape, transformSphereShape2, massSphere);
body->addCollisionShape(cylinderCollisionShape, transformCylinderShape, massCylinder); body->addCollisionShape(mCylinderShape, transformCylinderShape, massCylinder);
mBody = body; mBody = body;
@ -123,14 +123,14 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
const rp3d::decimal radiusSphere = rp3d::decimal(1.5); const rp3d::decimal radiusSphere = rp3d::decimal(1.5);
const rp3d::SphereShape sphereCollisionShape(radiusSphere); mSphereShape = new rp3d::SphereShape(radiusSphere);
// Create a cylinder collision shape for the middle of the dumbbell // Create a cylinder collision shape for the middle of the dumbbell
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
const rp3d::decimal radiusCylinder = rp3d::decimal(0.5); const rp3d::decimal radiusCylinder = rp3d::decimal(0.5);
const rp3d::decimal heightCylinder = rp3d::decimal(8.0); const rp3d::decimal heightCylinder = rp3d::decimal(8.0);
const rp3d::CylinderShape cylinderCollisionShape(radiusCylinder, heightCylinder); mCylinderShape = new rp3d::CylinderShape(radiusCylinder, heightCylinder);
// Initial position and orientation of the rigid body // Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z); rp3d::Vector3 initPosition(position.x, position.y, position.z);
@ -151,9 +151,9 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
mBody = world->createCollisionBody(transformBody); mBody = world->createCollisionBody(transformBody);
// Add the three collision shapes to the body and specify the mass and transform of the shapes // Add the three collision shapes to the body and specify the mass and transform of the shapes
mBody->addCollisionShape(sphereCollisionShape, transformSphereShape1); mBody->addCollisionShape(mSphereShape, transformSphereShape1);
mBody->addCollisionShape(sphereCollisionShape, transformSphereShape2); mBody->addCollisionShape(mSphereShape, transformSphereShape2);
mBody->addCollisionShape(cylinderCollisionShape, transformCylinderShape); mBody->addCollisionShape(mCylinderShape, transformCylinderShape);
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
@ -180,7 +180,8 @@ Dumbbell::~Dumbbell() {
mVBOTextureCoords.destroy(); mVBOTextureCoords.destroy();
mVAO.destroy(); mVAO.destroy();
} }
delete mSphereShape;
delete mCylinderShape;
totalNbDumbbells--; totalNbDumbbells--;
} }

View File

@ -41,6 +41,10 @@ class Dumbbell : public openglframework::Mesh, public PhysicsObject {
/// Radius of the spheres /// Radius of the spheres
float mRadius; float mRadius;
/// Collision shapes
rp3d::CylinderShape* mCylinderShape;
rp3d::SphereShape* mSphereShape;
/// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions)
openglframework::Matrix4 mScalingMatrix; openglframework::Matrix4 mScalingMatrix;

View File

@ -57,7 +57,7 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
// Create the collision shape for the rigid body (sphere shape) // Create the collision shape for the rigid body (sphere shape)
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
const rp3d::SphereShape collisionShape(mRadius); mCollisionShape = new rp3d::SphereShape(mRadius);
// Initial position and orientation of the rigid body // Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z); rp3d::Vector3 initPosition(position.x, position.y, position.z);
@ -70,7 +70,7 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
mBody = world->createCollisionBody(transform); mBody = world->createCollisionBody(transform);
// Add a collision shape to the body and specify the mass of the shape // Add a collision shape to the body and specify the mass of the shape
mBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity());
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
@ -106,7 +106,7 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
// Create the collision shape for the rigid body (sphere shape) // Create the collision shape for the rigid body (sphere shape)
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
const rp3d::SphereShape collisionShape(mRadius); mCollisionShape = new rp3d::SphereShape(mRadius);
// Initial position and orientation of the rigid body // Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z); rp3d::Vector3 initPosition(position.x, position.y, position.z);
@ -117,7 +117,7 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
rp3d::RigidBody* body = world->createRigidBody(transform); rp3d::RigidBody* body = world->createRigidBody(transform);
// Add a collision shape to the body and specify the mass of the shape // Add a collision shape to the body and specify the mass of the shape
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass);
mBody = body; mBody = body;
@ -145,7 +145,7 @@ Sphere::~Sphere() {
mVBOTextureCoords.destroy(); mVBOTextureCoords.destroy();
mVAO.destroy(); mVAO.destroy();
} }
delete mCollisionShape;
totalNbSpheres--; totalNbSpheres--;
} }

View File

@ -41,6 +41,9 @@ class Sphere : public openglframework::Mesh, public PhysicsObject {
/// Radius of the sphere /// Radius of the sphere
float mRadius; float mRadius;
/// Collision shape
rp3d::SphereShape* mCollisionShape;
/// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions)
openglframework::Matrix4 mScalingMatrix; openglframework::Matrix4 mScalingMatrix;