From 22b214fb912dfad2fb88e964cec8c5e99b41937f Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Fri, 20 Nov 2015 07:20:56 +0100 Subject: [PATCH] Add setScaling() method to objects in testbed/common --- src/body/CollisionBody.cpp | 4 +- src/body/CollisionBody.h | 2 +- src/collision/CollisionDetection.h | 4 +- src/collision/ProxyShape.h | 24 +++-- .../broadphase/BroadPhaseAlgorithm.cpp | 4 +- .../broadphase/BroadPhaseAlgorithm.h | 2 +- src/collision/broadphase/DynamicAABBTree.cpp | 7 +- src/collision/broadphase/DynamicAABBTree.h | 2 +- testbed/common/Box.cpp | 25 ++++-- testbed/common/Box.h | 6 +- testbed/common/Capsule.cpp | 23 +++-- testbed/common/Capsule.h | 6 +- testbed/common/ConcaveMesh.cpp | 90 ++++++------------- testbed/common/ConcaveMesh.h | 11 ++- testbed/common/Cone.cpp | 23 +++-- testbed/common/Cone.h | 6 +- testbed/common/ConvexMesh.cpp | 49 +++++++--- testbed/common/ConvexMesh.h | 11 ++- testbed/common/Cylinder.cpp | 23 +++-- testbed/common/Cylinder.h | 6 +- testbed/common/Dumbbell.cpp | 28 ++++-- testbed/common/Dumbbell.h | 6 ++ testbed/common/PhysicsObject.h | 3 + testbed/common/Sphere.cpp | 17 +++- testbed/common/Sphere.h | 4 + 25 files changed, 250 insertions(+), 136 deletions(-) diff --git a/src/body/CollisionBody.cpp b/src/body/CollisionBody.cpp index 5d87eeb3..0536f823 100644 --- a/src/body/CollisionBody.cpp +++ b/src/body/CollisionBody.cpp @@ -203,14 +203,14 @@ void CollisionBody::updateBroadPhaseState() const { } // Update the broad-phase state of a proxy collision shape of the body -void CollisionBody::updateProxyShapeInBroadPhase(ProxyShape* proxyShape) const { +void CollisionBody::updateProxyShapeInBroadPhase(ProxyShape* proxyShape, bool forceReinsert) const { // Recompute the world-space AABB of the collision shape AABB aabb; proxyShape->getCollisionShape()->computeAABB(aabb, mTransform * proxyShape->getLocalToBodyTransform()); // Update the broad-phase state for the proxy collision shape - mWorld.mCollisionDetection.updateProxyCollisionShape(proxyShape, aabb); + mWorld.mCollisionDetection.updateProxyCollisionShape(proxyShape, aabb, Vector3(0, 0, 0), forceReinsert); } // Set whether or not the body is active diff --git a/src/body/CollisionBody.h b/src/body/CollisionBody.h index 89837b82..3adeecea 100644 --- a/src/body/CollisionBody.h +++ b/src/body/CollisionBody.h @@ -103,7 +103,7 @@ class CollisionBody : public Body { virtual void updateBroadPhaseState() const; /// Update the broad-phase state of a proxy collision shape of the body - void updateProxyShapeInBroadPhase(ProxyShape* proxyShape) const; + void updateProxyShapeInBroadPhase(ProxyShape* proxyShape, bool forceReinsert = false) const; /// Ask the broad-phase to test again the collision shapes of the body for collision /// (as if the body has moved). diff --git a/src/collision/CollisionDetection.h b/src/collision/CollisionDetection.h index 535e1015..fa94024e 100644 --- a/src/collision/CollisionDetection.h +++ b/src/collision/CollisionDetection.h @@ -170,7 +170,7 @@ class CollisionDetection : public NarrowPhaseCallback { /// Update a proxy collision shape (that has moved for instance) void updateProxyCollisionShape(ProxyShape* shape, const AABB& aabb, - const Vector3& displacement = Vector3(0, 0, 0)); + const Vector3& displacement = Vector3(0, 0, 0), bool forceReinsert = false); /// Add a pair of bodies that cannot collide with each other void addNoCollisionPair(CollisionBody* body1, CollisionBody* body2); @@ -282,7 +282,7 @@ inline void CollisionDetection::askForBroadPhaseCollisionCheck(ProxyShape* shape // Update a proxy collision shape (that has moved for instance) inline void CollisionDetection::updateProxyCollisionShape(ProxyShape* shape, const AABB& aabb, - const Vector3& displacement) { + const Vector3& displacement, bool forceReinsert) { mBroadPhaseAlgorithm.updateProxyCollisionShape(shape, aabb, displacement); } diff --git a/src/collision/ProxyShape.h b/src/collision/ProxyShape.h index 334fbcf1..22dfa2e6 100644 --- a/src/collision/ProxyShape.h +++ b/src/collision/ProxyShape.h @@ -152,11 +152,11 @@ class ProxyShape { /// Return the pointer to the cached collision data void** getCachedCollisionData(); - /// Return the scaling vector of the collision shape - Vector3 getScaling() const; + /// Return the local scaling vector of the collision shape + Vector3 getLocalScaling() const; - /// Set the scaling vector of the collision shape - virtual void setScaling(const Vector3& scaling); + /// Set the local scaling vector of the collision shape + virtual void setLocalScaling(const Vector3& scaling); // -------------------- Friendship -------------------- // @@ -299,19 +299,25 @@ inline void ProxyShape::setCollideWithMaskBits(unsigned short collideWithMaskBit mCollideWithMaskBits = collideWithMaskBits; } -// Return the scaling vector of the collision shape -inline Vector3 ProxyShape::getScaling() const { +// Return the local scaling vector of the collision shape +/** + * @return The local scaling vector + */ +inline Vector3 ProxyShape::getLocalScaling() const { return mCollisionShape->getScaling(); } -// Set the scaling vector of the collision shape -inline void ProxyShape::setScaling(const Vector3& scaling) { +// Set the local scaling vector of the collision shape +/** + * @param scaling The new local scaling vector + */ +inline void ProxyShape::setLocalScaling(const Vector3& scaling) { // Set the local scaling of the collision shape mCollisionShape->setLocalScaling(scaling); // Notify the body that the proxy shape has to be updated in the broad-phase - mBody->updateProxyShapeInBroadPhase(this); + mBody->updateProxyShapeInBroadPhase(this, true); } } diff --git a/src/collision/broadphase/BroadPhaseAlgorithm.cpp b/src/collision/broadphase/BroadPhaseAlgorithm.cpp index aa1d6ba8..ddce583b 100644 --- a/src/collision/broadphase/BroadPhaseAlgorithm.cpp +++ b/src/collision/broadphase/BroadPhaseAlgorithm.cpp @@ -143,14 +143,14 @@ void BroadPhaseAlgorithm::removeProxyCollisionShape(ProxyShape* proxyShape) { // Notify the broad-phase that a collision shape has moved and need to be updated void BroadPhaseAlgorithm::updateProxyCollisionShape(ProxyShape* proxyShape, const AABB& aabb, - const Vector3& displacement) { + const Vector3& displacement, bool forceReinsert) { int broadPhaseID = proxyShape->mBroadPhaseID; assert(broadPhaseID >= 0); // Update the dynamic AABB tree according to the movement of the collision shape - bool hasBeenReInserted = mDynamicAABBTree.updateObject(broadPhaseID, aabb, displacement); + bool hasBeenReInserted = mDynamicAABBTree.updateObject(broadPhaseID, aabb, displacement, forceReinsert); // If the collision shape has moved out of its fat AABB (and therefore has been reinserted // into the tree). diff --git a/src/collision/broadphase/BroadPhaseAlgorithm.h b/src/collision/broadphase/BroadPhaseAlgorithm.h index 9c3080ce..2382a96c 100644 --- a/src/collision/broadphase/BroadPhaseAlgorithm.h +++ b/src/collision/broadphase/BroadPhaseAlgorithm.h @@ -170,7 +170,7 @@ class BroadPhaseAlgorithm : BroadPhaseRaycastTestCallback { /// Notify the broad-phase that a collision shape has moved and need to be updated void updateProxyCollisionShape(ProxyShape* proxyShape, const AABB& aabb, - const Vector3& displacement); + const Vector3& displacement, bool forceReinsert = false); /// Add a collision shape in the array of shapes that have moved in the last simulation step /// and that need to be tested again for broad-phase overlapping. diff --git a/src/collision/broadphase/DynamicAABBTree.cpp b/src/collision/broadphase/DynamicAABBTree.cpp index 4f72c6a7..ba17f514 100644 --- a/src/collision/broadphase/DynamicAABBTree.cpp +++ b/src/collision/broadphase/DynamicAABBTree.cpp @@ -167,8 +167,9 @@ void DynamicAABBTree::removeObject(int nodeID) { /// nothing is done. Otherwise, the corresponding node is removed and reinserted into the tree. /// The method returns true if the object has been reinserted into the tree. The "displacement" /// argument is the linear velocity of the AABB multiplied by the elapsed time between two -/// frames. -bool DynamicAABBTree::updateObject(int nodeID, const AABB& newAABB, const Vector3& displacement) { +/// frames. If the "forceReinsert" parameter is true, we force a removal and reinsertion of the node +/// (this can be useful if the shape AABB has become much smaller than the previous one for instance). +bool DynamicAABBTree::updateObject(int nodeID, const AABB& newAABB, const Vector3& displacement, bool forceReinsert) { PROFILE("DynamicAABBTree::updateObject()"); @@ -177,7 +178,7 @@ bool DynamicAABBTree::updateObject(int nodeID, const AABB& newAABB, const Vector assert(mNodes[nodeID].height >= 0); // If the new AABB is still inside the fat AABB of the node - if (mNodes[nodeID].aabb.contains(newAABB)) { + if (!forceReinsert && mNodes[nodeID].aabb.contains(newAABB)) { return false; } diff --git a/src/collision/broadphase/DynamicAABBTree.h b/src/collision/broadphase/DynamicAABBTree.h index 8f2c6255..6b8707de 100644 --- a/src/collision/broadphase/DynamicAABBTree.h +++ b/src/collision/broadphase/DynamicAABBTree.h @@ -192,7 +192,7 @@ class DynamicAABBTree { void removeObject(int nodeID); /// Update the dynamic tree after an object has moved. - bool updateObject(int nodeID, const AABB& newAABB, const Vector3& displacement); + bool updateObject(int nodeID, const AABB& newAABB, const Vector3& displacement, bool forceReinsert = false); /// Return the fat AABB corresponding to a given node ID const AABB& getFatAABB(int nodeID) const; diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index 34dc26c0..860c5277 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -132,7 +132,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p // Create the collision shape for the rigid body (box shape) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - mboxCollisionShape = new rp3d::BoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); + mBoxShape = new rp3d::BoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); // Initial position and orientation of the rigid body 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); // Add the collision shape to the body - mBody->addCollisionShape(mboxCollisionShape, rp3d::Transform::identity()); + mProxyShape = mBody->addCollisionShape(mBoxShape, rp3d::Transform::identity()); // If the Vertex Buffer object has not been created yet 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) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - mboxCollisionShape = new rp3d::BoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); + mBoxShape = new rp3d::BoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); // Initial position and orientation of the rigid body 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); // Add the collision shape to the body - body->addCollisionShape(mboxCollisionShape, rp3d::Transform::identity(), mass); + mProxyShape = body->addCollisionShape(mBoxShape, rp3d::Transform::identity(), mass); mBody = body; @@ -220,7 +220,7 @@ Box::~Box() { mVBONormals.destroy(); mVAO.destroy(); } - delete mboxCollisionShape; + delete mBoxShape; totalNbBoxes--; } @@ -280,8 +280,6 @@ void Box::render(openglframework::Shader& shader, shader.unbind(); } - - // Create the Vertex Buffer Objects used to render to box with OpenGL. /// We create two VBOs (one for vertices and one for indices) to render all the boxes /// in the simulation. @@ -330,3 +328,16 @@ void Box::resetTransform(const rp3d::Transform& transform) { updateTransform(1.0f); } + +// Set the scaling of the object +void Box::setScaling(const openglframework::Vector3& scaling) { + + // Scale the collision shape + mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z)); + + // Scale the graphics object + mScalingMatrix = openglframework::Matrix4(mSize[0] * scaling.x, 0, 0, 0, + 0, mSize[1] * scaling.y, 0, 0, + 0, 0, mSize[2] * scaling.z, 0, + 0, 0, 0, 1); +} diff --git a/testbed/common/Box.h b/testbed/common/Box.h index 2969fdd0..f6ff37c1 100644 --- a/testbed/common/Box.h +++ b/testbed/common/Box.h @@ -41,7 +41,8 @@ class Box : public openglframework::Object3D, public PhysicsObject { /// Size of each side of the box float mSize[3]; - rp3d::BoxShape* mboxCollisionShape; + rp3d::BoxShape* mBoxShape; + rp3d::ProxyShape* mProxyShape; /// Scaling matrix (applied to a cube to obtain the correct box dimensions) openglframework::Matrix4 mScalingMatrix; @@ -92,6 +93,9 @@ class Box : public openglframework::Object3D, public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor); + + /// Set the scaling of the object + void setScaling(const openglframework::Vector3& scaling); }; // Update the transform matrix of the object diff --git a/testbed/common/Capsule.cpp b/testbed/common/Capsule.cpp index c2c2bc05..08e4d22c 100644 --- a/testbed/common/Capsule.cpp +++ b/testbed/common/Capsule.cpp @@ -57,7 +57,7 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos // Create the collision shape for the rigid body (sphere shape) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - mCollisionShape = new rp3d::CapsuleShape(mRadius, mHeight); + mCapsuleShape = new rp3d::CapsuleShape(mRadius, mHeight); // Initial position and orientation of the rigid body 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); // Add a collision shape to the body and specify the mass of the shape - mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity()); + mProxyShape = mBody->addCollisionShape(mCapsuleShape, rp3d::Transform::identity()); 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) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - mCollisionShape = new rp3d::CapsuleShape(mRadius, mHeight); + mCapsuleShape = new rp3d::CapsuleShape(mRadius, mHeight); // Initial position and orientation of the rigid body 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); // Add a collision shape to the body and specify the mass of the shape - body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass); + mProxyShape = body->addCollisionShape(mCapsuleShape, rp3d::Transform::identity(), mass); mBody = body; @@ -146,7 +146,7 @@ Capsule::~Capsule() { mVBOTextureCoords.destroy(); mVAO.destroy(); } - delete mCollisionShape; + delete mCapsuleShape; totalNbCapsules--; } @@ -281,3 +281,16 @@ void Capsule::resetTransform(const rp3d::Transform& transform) { updateTransform(1.0f); } + +// Set the scaling of the object +void Capsule::setScaling(const openglframework::Vector3& scaling) { + + // Scale the collision shape + mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z)); + + // Scale the graphics object + mScalingMatrix = openglframework::Matrix4(mRadius * scaling.x, 0, 0, 0, + 0, (mHeight + 2.0f * mRadius) / 3.0f * scaling.y, 0,0, + 0, 0, mRadius * scaling.z, 0, + 0, 0, 0, 1.0f); +} diff --git a/testbed/common/Capsule.h b/testbed/common/Capsule.h index e18c3ff5..02847252 100644 --- a/testbed/common/Capsule.h +++ b/testbed/common/Capsule.h @@ -45,7 +45,8 @@ class Capsule : public openglframework::Mesh, public PhysicsObject { float mHeight; /// Collision shape - rp3d::CapsuleShape* mCollisionShape; + rp3d::CapsuleShape* mCapsuleShape; + rp3d::ProxyShape* mProxyShape; /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) openglframework::Matrix4 mScalingMatrix; @@ -101,6 +102,9 @@ class Capsule : public openglframework::Mesh, public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor); + + /// Set the scaling of the object + void setScaling(const openglframework::Vector3& scaling); }; // Update the transform matrix of the object diff --git a/testbed/common/ConcaveMesh.cpp b/testbed/common/ConcaveMesh.cpp index f8cedfc9..cf355919 100644 --- a/testbed/common/ConcaveMesh.cpp +++ b/testbed/common/ConcaveMesh.cpp @@ -43,14 +43,8 @@ ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position, // Initialize the position where the sphere will be rendered translateWorld(position); - // Convert the vertices array to the rp3d::decimal type - /*rp3d::decimal* vertices = new rp3d::decimal[3 * mVertices.size()]; - for (int i=0; i < mVertices.size(); i++) { - vertices[3 * i] = static_cast(mVertices[i].x); - vertices[3 * i + 1] = static_cast(mVertices[i].y); - vertices[3 * i + 2] = static_cast(mVertices[i].z); - } - */ + // Compute the scaling matrix + mScalingMatrix = openglframework::Matrix4::identity(); // For each subpart of the mesh for (int i=0; iaddEdge(v1, v2); - mCollisionShape->addEdge(v1, v3); - mCollisionShape->addEdge(v2, v3); - } - mCollisionShape->setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges - */ + mConcaveShape = new rp3d::ConcaveMeshShape(&mPhysicsTriangleMesh); // Initial position and orientation of the rigid body rp3d::Vector3 initPosition(position.x, position.y, position.z); @@ -102,10 +75,12 @@ ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position, mBody = world->createCollisionBody(transform); // Add a collision shape to the body and specify the mass of the collision shape - mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity()); + mProxyShape = mBody->addCollisionShape(mConcaveShape, rp3d::Transform::identity()); // Create the VBOs and VAO createVBOAndVAO(); + + mTransformMatrix = mTransformMatrix * mScalingMatrix; } // Constructor @@ -125,15 +100,8 @@ ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position, float mass, // Initialize the position where the sphere will be rendered translateWorld(position); - /* - // Convert the vertices array to the rp3d::decimal type - rp3d::decimal* vertices = new rp3d::decimal[3 * mVertices.size()]; - for (int i=0; i < mVertices.size(); i++) { - vertices[3 * i] = static_cast(mVertices[i].x); - vertices[3 * i + 1] = static_cast(mVertices[i].y); - vertices[3 * i + 2] = static_cast(mVertices[i].z); - } - */ + // Compute the scaling matrix + mScalingMatrix = openglframework::Matrix4::identity(); // For each subpart of the mesh for (int i=0; iaddEdge(v1, v2); - mCollisionShape->addEdge(v1, v3); - mCollisionShape->addEdge(v2, v3); - } - mCollisionShape->setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges - */ + mConcaveShape = new rp3d::ConcaveMeshShape(&mPhysicsTriangleMesh); // Initial position and orientation of the rigid body rp3d::Vector3 initPosition(position.x, position.y, position.z); @@ -183,12 +130,14 @@ ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position, float mass, rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); // Add a collision shape to the body and specify the mass of the collision shape - body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass); + mProxyShape = body->addCollisionShape(mConcaveShape, rp3d::Transform::identity(), mass); mBody = body; // Create the VBOs and VAO createVBOAndVAO(); + + mTransformMatrix = mTransformMatrix * mScalingMatrix; } // Destructor @@ -209,7 +158,7 @@ ConcaveMesh::~ConcaveMesh() { mVBOTextureCoords.destroy(); mVAO.destroy(); - delete mCollisionShape; + delete mConcaveShape; } // Render the sphere at the correct position and with the correct orientation @@ -343,3 +292,16 @@ void ConcaveMesh::resetTransform(const rp3d::Transform& transform) { updateTransform(1.0f); } +// Set the scaling of the object +void ConcaveMesh::setScaling(const openglframework::Vector3& scaling) { + + // Scale the collision shape + mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z)); + + // Scale the graphics object + mScalingMatrix = openglframework::Matrix4(scaling.x, 0, 0, 0, + 0, scaling.y, 0,0, + 0, 0, scaling.z, 0, + 0, 0, 0, 1.0f); +} + diff --git a/testbed/common/ConcaveMesh.h b/testbed/common/ConcaveMesh.h index 167e78ff..cb01d629 100644 --- a/testbed/common/ConcaveMesh.h +++ b/testbed/common/ConcaveMesh.h @@ -42,7 +42,11 @@ class ConcaveMesh : public openglframework::Mesh, public PhysicsObject { rp3d::Transform mPreviousTransform; /// Collision shape - rp3d::ConcaveMeshShape* mCollisionShape; + rp3d::ConcaveMeshShape* mConcaveShape; + rp3d::ProxyShape* mProxyShape; + + /// Scaling matrix + openglframework::Matrix4 mScalingMatrix; /// Vertex Buffer Object for the vertices data openglframework::VertexBufferObject mVBOVertices; @@ -91,11 +95,14 @@ class ConcaveMesh : public openglframework::Mesh, public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor); + + /// Set the scaling of the object + void setScaling(const openglframework::Vector3& scaling); }; // Update the transform matrix of the object inline void ConcaveMesh::updateTransform(float interpolationFactor) { - mTransformMatrix = computeTransform(interpolationFactor, openglframework::Matrix4::identity()); + mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix); } #endif diff --git a/testbed/common/Cone.cpp b/testbed/common/Cone.cpp index 22953283..cbe25563 100644 --- a/testbed/common/Cone.cpp +++ b/testbed/common/Cone.cpp @@ -56,7 +56,7 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position, // Create the collision shape for the rigid body (cone shape) and do // not forget to delete it at the end - mCollisionShape = new rp3d::ConeShape(mRadius, mHeight); + mConeShape = new rp3d::ConeShape(mRadius, mHeight); // Initial position and orientation of the rigid body rp3d::Vector3 initPosition(position.x, position.y, position.z); @@ -69,7 +69,7 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position, mBody = world->createCollisionBody(transform); // Add a collision shape to the body and specify the mass of the shape - mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity()); + mProxyShape = mBody->addCollisionShape(mConeShape, rp3d::Transform::identity()); mTransformMatrix = mTransformMatrix * mScalingMatrix; @@ -104,7 +104,7 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position, // Create the collision shape for the rigid body (cone shape) and do not // forget to delete it at the end - mCollisionShape = new rp3d::ConeShape(mRadius, mHeight); + mConeShape = new rp3d::ConeShape(mRadius, mHeight); // Initial position and orientation of the rigid body rp3d::Vector3 initPosition(position.x, position.y, position.z); @@ -115,7 +115,7 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position, rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); // Add a collision shape to the body and specify the mass of the shape - body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass); + mProxyShape = body->addCollisionShape(mConeShape, rp3d::Transform::identity(), mass); mBody = body; @@ -143,7 +143,7 @@ Cone::~Cone() { mVBOTextureCoords.destroy(); mVAO.destroy(); } - delete mCollisionShape; + delete mConeShape; totalNbCones--; } @@ -278,3 +278,16 @@ void Cone::resetTransform(const rp3d::Transform& transform) { updateTransform(1.0f); } +// Set the scaling of the object +void Cone::setScaling(const openglframework::Vector3& scaling) { + + // Scale the collision shape + mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z)); + + // Scale the graphics object + mScalingMatrix = openglframework::Matrix4(mRadius * scaling.x, 0, 0, 0, + 0, mHeight * scaling.y, 0, 0, + 0, 0, mRadius * scaling.z, 0, + 0, 0, 0, 1); +} + diff --git a/testbed/common/Cone.h b/testbed/common/Cone.h index eeb4f0a4..cd27c012 100644 --- a/testbed/common/Cone.h +++ b/testbed/common/Cone.h @@ -45,7 +45,8 @@ class Cone : public openglframework::Mesh, public PhysicsObject { float mHeight; /// Collision shape - rp3d::ConeShape* mCollisionShape; + rp3d::ConeShape* mConeShape; + rp3d::ProxyShape* mProxyShape; /// Scaling matrix (applied to a sphere to obtain the correct cone dimensions) openglframework::Matrix4 mScalingMatrix; @@ -100,6 +101,9 @@ class Cone : public openglframework::Mesh, public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor); + + /// Set the scaling of the object + void setScaling(const openglframework::Vector3& scaling); }; // Update the transform matrix of the object diff --git a/testbed/common/ConvexMesh.cpp b/testbed/common/ConvexMesh.cpp index 4527e8fb..1e14483d 100644 --- a/testbed/common/ConvexMesh.cpp +++ b/testbed/common/ConvexMesh.cpp @@ -43,6 +43,9 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, // Initialize the position where the sphere will be rendered translateWorld(position); + // Compute the scaling matrix + mScalingMatrix = openglframework::Matrix4::identity(); + // Convert the vertices array to the rp3d::decimal type rp3d::decimal* vertices = new rp3d::decimal[3 * mVertices.size()]; for (int i=0; i < mVertices.size(); i++) { @@ -53,7 +56,7 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, // Create the collision shape for the rigid body (convex mesh shape) and // do not forget to delete it at the end - mCollisionShape = new rp3d::ConvexMeshShape(vertices, mVertices.size(), 3 * sizeof(rp3d::decimal)); + mConvexShape = new rp3d::ConvexMeshShape(vertices, mVertices.size(), 3 * sizeof(rp3d::decimal)); delete[] vertices; @@ -68,11 +71,11 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, unsigned int v3 = getVertexIndexInFace(i, 2); // Add the three edges into the collision shape - mCollisionShape->addEdge(v1, v2); - mCollisionShape->addEdge(v1, v3); - mCollisionShape->addEdge(v2, v3); + mConvexShape->addEdge(v1, v2); + mConvexShape->addEdge(v1, v3); + mConvexShape->addEdge(v2, v3); } - mCollisionShape->setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges + mConvexShape->setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges // Initial position and orientation of the rigid body rp3d::Vector3 initPosition(position.x, position.y, position.z); @@ -85,10 +88,12 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, mBody = world->createCollisionBody(transform); // Add a collision shape to the body and specify the mass of the collision shape - mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity()); + mProxyShape = mBody->addCollisionShape(mConvexShape, rp3d::Transform::identity()); // Create the VBOs and VAO createVBOAndVAO(); + + mTransformMatrix = mTransformMatrix * mScalingMatrix; } // Constructor @@ -108,6 +113,9 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, // Initialize the position where the sphere will be rendered translateWorld(position); + // Compute the scaling matrix + mScalingMatrix = openglframework::Matrix4::identity(); + // Convert the vertices array to the rp3d::decimal type rp3d::decimal* vertices = new rp3d::decimal[3 * mVertices.size()]; for (int i=0; i < mVertices.size(); i++) { @@ -118,7 +126,7 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, // Create the collision shape for the rigid body (convex mesh shape) and do // not forget to delete it at the end - mCollisionShape = new rp3d::ConvexMeshShape(vertices, mVertices.size(), 3 * sizeof(rp3d::decimal)); + mConvexShape = new rp3d::ConvexMeshShape(vertices, mVertices.size(), 3 * sizeof(rp3d::decimal)); delete[] vertices; @@ -133,11 +141,11 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, unsigned int v3 = getVertexIndexInFace(i, 2); // Add the three edges into the collision shape - mCollisionShape->addEdge(v1, v2); - mCollisionShape->addEdge(v1, v3); - mCollisionShape->addEdge(v2, v3); + mConvexShape->addEdge(v1, v2); + mConvexShape->addEdge(v1, v3); + mConvexShape->addEdge(v2, v3); } - mCollisionShape->setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges + mConvexShape->setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges // Initial position and orientation of the rigid body rp3d::Vector3 initPosition(position.x, position.y, position.z); @@ -148,12 +156,14 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); // Add a collision shape to the body and specify the mass of the collision shape - body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass); + mProxyShape = body->addCollisionShape(mConvexShape, rp3d::Transform::identity(), mass); mBody = body; // Create the VBOs and VAO createVBOAndVAO(); + + mTransformMatrix = mTransformMatrix * mScalingMatrix; } // Destructor @@ -169,7 +179,7 @@ ConvexMesh::~ConvexMesh() { mVBOTextureCoords.destroy(); mVAO.destroy(); - delete mCollisionShape; + delete mConvexShape; } // Render the sphere at the correct position and with the correct orientation @@ -302,3 +312,16 @@ void ConvexMesh::resetTransform(const rp3d::Transform& transform) { updateTransform(1.0f); } + +// Set the scaling of the object +void ConvexMesh::setScaling(const openglframework::Vector3& scaling) { + + // Scale the collision shape + mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z)); + + // Scale the graphics object + mScalingMatrix = openglframework::Matrix4(scaling.x, 0, 0, 0, + 0, scaling.y, 0, 0, + 0, 0, scaling.z, 0, + 0, 0, 0, 1); +} diff --git a/testbed/common/ConvexMesh.h b/testbed/common/ConvexMesh.h index b1089826..2017378b 100644 --- a/testbed/common/ConvexMesh.h +++ b/testbed/common/ConvexMesh.h @@ -42,7 +42,11 @@ class ConvexMesh : public openglframework::Mesh, public PhysicsObject { rp3d::Transform mPreviousTransform; /// Collision shape - rp3d::ConvexMeshShape* mCollisionShape; + rp3d::ConvexMeshShape* mConvexShape; + rp3d::ProxyShape* mProxyShape; + + /// Scaling matrix + openglframework::Matrix4 mScalingMatrix; /// Vertex Buffer Object for the vertices data openglframework::VertexBufferObject mVBOVertices; @@ -88,11 +92,14 @@ class ConvexMesh : public openglframework::Mesh, public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor); + + /// Set the scaling of the object + void setScaling(const openglframework::Vector3& scaling); }; // Update the transform matrix of the object inline void ConvexMesh::updateTransform(float interpolationFactor) { - mTransformMatrix = computeTransform(interpolationFactor, openglframework::Matrix4::identity()); + mTransformMatrix = computeTransform(interpolationFactor, mScalingMatrix); } #endif diff --git a/testbed/common/Cylinder.cpp b/testbed/common/Cylinder.cpp index f269637c..1342eeb5 100644 --- a/testbed/common/Cylinder.cpp +++ b/testbed/common/Cylinder.cpp @@ -56,7 +56,7 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p // Create the collision shape for the rigid body (cylinder shape) and do not // forget to delete it at the end - mCollisionShape = new rp3d::CylinderShape(mRadius, mHeight); + mCylinderShape = new rp3d::CylinderShape(mRadius, mHeight); // Initial position and orientation of the rigid body rp3d::Vector3 initPosition(position.x, position.y, position.z); @@ -69,7 +69,7 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p mBody = world->createCollisionBody(transform); // Add a collision shape to the body and specify the mass of the shape - mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity()); + mProxyShape = mBody->addCollisionShape(mCylinderShape, rp3d::Transform::identity()); mTransformMatrix = mTransformMatrix * mScalingMatrix; @@ -104,7 +104,7 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p // Create the collision shape for the rigid body (cylinder shape) and do // not forget to delete it at the end - mCollisionShape = new rp3d::CylinderShape(mRadius, mHeight); + mCylinderShape = new rp3d::CylinderShape(mRadius, mHeight); // Initial position and orientation of the rigid body rp3d::Vector3 initPosition(position.x, position.y, position.z); @@ -115,7 +115,7 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); // Add a collision shape to the body and specify the mass of the shape - body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass); + mProxyShape = body->addCollisionShape(mCylinderShape, rp3d::Transform::identity(), mass); mTransformMatrix = mTransformMatrix * mScalingMatrix; @@ -144,7 +144,7 @@ Cylinder::~Cylinder() { mVBOTextureCoords.destroy(); mVAO.destroy(); } - delete mCollisionShape; + delete mCylinderShape; totalNbCylinders--; } @@ -278,3 +278,16 @@ void Cylinder::resetTransform(const rp3d::Transform& transform) { updateTransform(1.0f); } + +// Set the scaling of the object +void Cylinder::setScaling(const openglframework::Vector3& scaling) { + + // Scale the collision shape + mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z)); + + // Scale the graphics object + mScalingMatrix = openglframework::Matrix4(mRadius * scaling.x, 0, 0, 0, + 0, mHeight * scaling.y, 0, 0, + 0, 0, mRadius * scaling.z, 0, + 0, 0, 0, 1); +} diff --git a/testbed/common/Cylinder.h b/testbed/common/Cylinder.h index 4bb5232e..65e6b2e3 100644 --- a/testbed/common/Cylinder.h +++ b/testbed/common/Cylinder.h @@ -51,7 +51,8 @@ class Cylinder : public openglframework::Mesh, public PhysicsObject { rp3d::Transform mPreviousTransform; /// Collision shape - rp3d::CylinderShape* mCollisionShape; + rp3d::CylinderShape* mCylinderShape; + rp3d::ProxyShape* mProxyShape; /// Vertex Buffer Object for the vertices data static openglframework::VertexBufferObject mVBOVertices; @@ -100,6 +101,9 @@ class Cylinder : public openglframework::Mesh, public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor); + + /// Set the scaling of the object + void setScaling(const openglframework::Vector3& scaling); }; // Update the transform matrix of the object diff --git a/testbed/common/Dumbbell.cpp b/testbed/common/Dumbbell.cpp index f4085c56..4b6e863d 100644 --- a/testbed/common/Dumbbell.cpp +++ b/testbed/common/Dumbbell.cpp @@ -86,9 +86,9 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position, rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transformBody); // Add the three collision shapes to the body and specify the mass and transform of the shapes - body->addCollisionShape(mSphereShape, transformSphereShape1, massSphere); - body->addCollisionShape(mSphereShape, transformSphereShape2, massSphere); - body->addCollisionShape(mCylinderShape, transformCylinderShape, massCylinder); + mProxyShapeSphere1 = body->addCollisionShape(mSphereShape, transformSphereShape1, massSphere); + mProxyShapeSphere2 = body->addCollisionShape(mSphereShape, transformSphereShape2, massSphere); + mProxyShapeCylinder = body->addCollisionShape(mCylinderShape, transformCylinderShape, massCylinder); mBody = body; @@ -151,9 +151,9 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position, mBody = world->createCollisionBody(transformBody); // Add the three collision shapes to the body and specify the mass and transform of the shapes - mBody->addCollisionShape(mSphereShape, transformSphereShape1); - mBody->addCollisionShape(mSphereShape, transformSphereShape2); - mBody->addCollisionShape(mCylinderShape, transformCylinderShape); + mProxyShapeSphere1 = mBody->addCollisionShape(mSphereShape, transformSphereShape1); + mProxyShapeSphere2 = mBody->addCollisionShape(mSphereShape, transformSphereShape2); + mProxyShapeCylinder = mBody->addCollisionShape(mCylinderShape, transformCylinderShape); mTransformMatrix = mTransformMatrix * mScalingMatrix; @@ -315,3 +315,19 @@ void Dumbbell::resetTransform(const rp3d::Transform& transform) { updateTransform(1.0f); } + +// Set the scaling of the object +void Dumbbell::setScaling(const openglframework::Vector3& scaling) { + + // Scale the collision shape + rp3d::Vector3 newScaling(scaling.x, scaling.y, scaling.z); + mProxyShapeCylinder->setLocalScaling(newScaling); + mProxyShapeSphere1->setLocalScaling(newScaling); + mProxyShapeSphere2->setLocalScaling(newScaling); + + // Scale the graphics object + mScalingMatrix = openglframework::Matrix4(scaling.x, 0, 0, 0, + 0, scaling.y, 0, 0, + 0, 0, scaling.z, 0, + 0, 0, 0, 1); +} diff --git a/testbed/common/Dumbbell.h b/testbed/common/Dumbbell.h index 9f933948..742cf1c2 100644 --- a/testbed/common/Dumbbell.h +++ b/testbed/common/Dumbbell.h @@ -44,6 +44,9 @@ class Dumbbell : public openglframework::Mesh, public PhysicsObject { /// Collision shapes rp3d::CylinderShape* mCylinderShape; rp3d::SphereShape* mSphereShape; + rp3d::ProxyShape* mProxyShapeCylinder; + rp3d::ProxyShape* mProxyShapeSphere1; + rp3d::ProxyShape* mProxyShapeSphere2; /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) openglframework::Matrix4 mScalingMatrix; @@ -99,6 +102,9 @@ class Dumbbell : public openglframework::Mesh, public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor); + + /// Set the scaling of the object + void setScaling(const openglframework::Vector3& scaling); }; // Update the transform matrix of the object diff --git a/testbed/common/PhysicsObject.h b/testbed/common/PhysicsObject.h index 1e1ef69d..bb922b88 100644 --- a/testbed/common/PhysicsObject.h +++ b/testbed/common/PhysicsObject.h @@ -70,6 +70,9 @@ class PhysicsObject { /// Return a pointer to the rigid body of the box reactphysics3d::RigidBody* getRigidBody(); + + /// Set the scaling of the object + virtual void setScaling(const openglframework::Vector3& scaling)=0; }; // Set the color of the box diff --git a/testbed/common/Sphere.cpp b/testbed/common/Sphere.cpp index 39eb10cd..a7a0c880 100644 --- a/testbed/common/Sphere.cpp +++ b/testbed/common/Sphere.cpp @@ -70,7 +70,7 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position, mBody = world->createCollisionBody(transform); // Add a collision shape to the body and specify the mass of the shape - mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity()); + mProxyShape = mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity()); mTransformMatrix = mTransformMatrix * mScalingMatrix; @@ -117,7 +117,7 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position, rp3d::RigidBody* body = world->createRigidBody(transform); // Add a collision shape to the body and specify the mass of the shape - body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass); + mProxyShape = body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass); mBody = body; @@ -279,3 +279,16 @@ void Sphere::resetTransform(const rp3d::Transform& transform) { updateTransform(1.0f); } + +// Set the scaling of the object +void Sphere::setScaling(const openglframework::Vector3& scaling) { + + // Scale the collision shape + mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z)); + + // Scale the graphics object + mScalingMatrix = openglframework::Matrix4(mRadius * scaling.x, 0, 0, 0, + 0, mRadius * scaling.y, 0, 0, + 0, 0, mRadius * scaling.z, 0, + 0, 0, 0, 1); +} diff --git a/testbed/common/Sphere.h b/testbed/common/Sphere.h index 0761b456..8b5cadd0 100644 --- a/testbed/common/Sphere.h +++ b/testbed/common/Sphere.h @@ -43,6 +43,7 @@ class Sphere : public openglframework::Mesh, public PhysicsObject { /// Collision shape rp3d::SphereShape* mCollisionShape; + rp3d::ProxyShape* mProxyShape; /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) openglframework::Matrix4 mScalingMatrix; @@ -97,6 +98,9 @@ class Sphere : public openglframework::Mesh, public PhysicsObject { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor); + + /// Set the scaling of the object + void setScaling(const openglframework::Vector3& scaling); }; // Update the transform matrix of the object