diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index 99b91af2..3cc5b32c 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -40,7 +40,7 @@ int Box::totalNbBoxes = 0; // Constructor Box::Box(bool createRigidBody, const openglframework::Vector3& size, reactphysics3d::PhysicsCommon& physicsCommon, reactphysics3d::PhysicsWorld* world, const std::string& meshFolderPath) - : PhysicsObject(physicsCommon, meshFolderPath + "cube.obj") { + : PhysicsObject(physicsCommon, meshFolderPath + "cube.obj"), mPhysicsWorld(world) { // Initialize the size of the box mSize[0] = size.x * 0.5f; @@ -97,6 +97,13 @@ Box::~Box() { mVBONormals.destroy(); mVAO.destroy(); } + rp3d::RigidBody* body = dynamic_cast<rp3d::RigidBody*>(mBody); + if (body != nullptr) { + mPhysicsWorld->destroyRigidBody(body); + } + else { + mPhysicsWorld->destroyCollisionBody(mBody); + } mPhysicsCommon.destroyBoxShape(mBoxShape); totalNbBoxes--; } diff --git a/testbed/common/Box.h b/testbed/common/Box.h index e1aefd00..bb4a95ee 100644 --- a/testbed/common/Box.h +++ b/testbed/common/Box.h @@ -47,6 +47,8 @@ class Box : public PhysicsObject { /// Scaling matrix (applied to a cube to obtain the correct box dimensions) openglframework::Matrix4 mScalingMatrix; + rp3d::PhysicsWorld* mPhysicsWorld; + /// Vertex Buffer Object for the vertices data static openglframework::VertexBufferObject mVBOVertices; diff --git a/testbed/common/Capsule.cpp b/testbed/common/Capsule.cpp index 2c3b4358..d99920d1 100644 --- a/testbed/common/Capsule.cpp +++ b/testbed/common/Capsule.cpp @@ -34,9 +34,9 @@ openglframework::VertexArrayObject Capsule::mVAO; int Capsule::totalNbCapsules = 0; // Constructor -Capsule::Capsule(bool createRigidBody, float radius, float height, reactphysics3d::PhysicsCommon &physicsCommon, rp3d::PhysicsWorld* physicsWorld, +Capsule::Capsule(bool createRigidBody, float radius, float height, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshFolderPath) - : PhysicsObject(physicsCommon, meshFolderPath + "capsule.obj"), mRadius(radius), mHeight(height) { + : PhysicsObject(physicsCommon, meshFolderPath + "capsule.obj"), mRadius(radius), mHeight(height), mPhysicsWorld(physicsWorld) { // Compute the scaling matrix mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, @@ -91,7 +91,16 @@ Capsule::~Capsule() { mVBOTextureCoords.destroy(); mVAO.destroy(); } + + rp3d::RigidBody* body = dynamic_cast<rp3d::RigidBody*>(mBody); + if (body != nullptr) { + mPhysicsWorld->destroyRigidBody(body); + } + else { + mPhysicsWorld->destroyCollisionBody(mBody); + } mPhysicsCommon.destroyCapsuleShape(mCapsuleShape); + totalNbCapsules--; } diff --git a/testbed/common/Capsule.h b/testbed/common/Capsule.h index 8df832d0..d7f7f454 100644 --- a/testbed/common/Capsule.h +++ b/testbed/common/Capsule.h @@ -51,7 +51,9 @@ class Capsule : public PhysicsObject { rp3d::CapsuleShape* mCapsuleShape; rp3d::Collider* mCollider; - /// Vertex Buffer Object for the vertices data + rp3d::PhysicsWorld* mPhysicsWorld; + + /// Vertex Buffer Object for the vertices data static openglframework::VertexBufferObject mVBOVertices; /// Vertex Buffer Object for the normals data diff --git a/testbed/common/ConcaveMesh.cpp b/testbed/common/ConcaveMesh.cpp index fce0bdfb..a764a1e6 100644 --- a/testbed/common/ConcaveMesh.cpp +++ b/testbed/common/ConcaveMesh.cpp @@ -28,7 +28,7 @@ // Constructor ConcaveMesh::ConcaveMesh(bool createRigidBody, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath) - : PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER), + : PhysicsObject(physicsCommon, meshPath), mPhysicsWorld(physicsWorld), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { @@ -93,6 +93,13 @@ ConcaveMesh::~ConcaveMesh() { mVBOTextureCoords.destroy(); mVAO.destroy(); + rp3d::RigidBody* body = dynamic_cast<rp3d::RigidBody*>(mBody); + if (body != nullptr) { + mPhysicsWorld->destroyRigidBody(body); + } + else { + mPhysicsWorld->destroyCollisionBody(mBody); + } mPhysicsCommon.destroyConcaveMeshShape(mConcaveShape); } diff --git a/testbed/common/ConcaveMesh.h b/testbed/common/ConcaveMesh.h index 9dc25aa0..cf3d1d57 100644 --- a/testbed/common/ConcaveMesh.h +++ b/testbed/common/ConcaveMesh.h @@ -42,6 +42,8 @@ class ConcaveMesh : public PhysicsObject { rp3d::ConcaveMeshShape* mConcaveShape; rp3d::Collider* mCollider; + rp3d::PhysicsWorld* mPhysicsWorld; + /// Scaling matrix openglframework::Matrix4 mScalingMatrix; diff --git a/testbed/common/ConvexMesh.cpp b/testbed/common/ConvexMesh.cpp index 51120602..f97ac9af 100755 --- a/testbed/common/ConvexMesh.cpp +++ b/testbed/common/ConvexMesh.cpp @@ -29,7 +29,7 @@ // Constructor ConvexMesh::ConvexMesh(bool createRigidBody, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath) - : PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER), + : PhysicsObject(physicsCommon, meshPath), mPhysicsWorld(physicsWorld), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { @@ -88,7 +88,6 @@ ConvexMesh::ConvexMesh(bool createRigidBody, rp3d::PhysicsCommon& physicsCommon, mCollider = mBody->addCollider(mConvexShape, rp3d::Transform::identity()); } - // Create the VBOs and VAO createVBOAndVAO(); @@ -108,6 +107,14 @@ ConvexMesh::~ConvexMesh() { mVBOTextureCoords.destroy(); mVAO.destroy(); + rp3d::RigidBody* body = dynamic_cast<rp3d::RigidBody*>(mBody); + if (body != nullptr) { + mPhysicsWorld->destroyRigidBody(body); + } + else { + mPhysicsWorld->destroyCollisionBody(mBody); + } + mPhysicsCommon.destroyConvexMeshShape(mConvexShape); mPhysicsCommon.destroyPolyhedronMesh(mPolyhedronMesh); delete mPolygonVertexArray; diff --git a/testbed/common/ConvexMesh.h b/testbed/common/ConvexMesh.h index 342b9a13..1c03986c 100644 --- a/testbed/common/ConvexMesh.h +++ b/testbed/common/ConvexMesh.h @@ -48,6 +48,8 @@ class ConvexMesh : public PhysicsObject { rp3d::ConvexMeshShape* mConvexShape; rp3d::Collider* mCollider; + rp3d::PhysicsWorld* mPhysicsWorld; + /// Scaling matrix openglframework::Matrix4 mScalingMatrix; diff --git a/testbed/common/Dumbbell.cpp b/testbed/common/Dumbbell.cpp index 56433cb1..0f753a76 100644 --- a/testbed/common/Dumbbell.cpp +++ b/testbed/common/Dumbbell.cpp @@ -35,7 +35,7 @@ int Dumbbell::totalNbDumbbells = 0; // Constructor Dumbbell::Dumbbell(bool createRigidBody, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshFolderPath) - : PhysicsObject(physicsCommon, meshFolderPath + "dumbbell.obj") { + : PhysicsObject(physicsCommon, meshFolderPath + "dumbbell.obj"), mPhysicsWorld(physicsWorld) { // Identity scaling matrix mScalingMatrix.setToIdentity(); @@ -112,6 +112,14 @@ Dumbbell::~Dumbbell() { mVBOTextureCoords.destroy(); mVAO.destroy(); } + + rp3d::RigidBody* body = dynamic_cast<rp3d::RigidBody*>(mBody); + if (body != nullptr) { + mPhysicsWorld->destroyRigidBody(body); + } + else { + mPhysicsWorld->destroyCollisionBody(mBody); + } mPhysicsCommon.destroySphereShape(mSphereShape); mPhysicsCommon.destroyCapsuleShape(mCapsuleShape); totalNbDumbbells--; diff --git a/testbed/common/Dumbbell.h b/testbed/common/Dumbbell.h index 1b919663..ce2364d4 100644 --- a/testbed/common/Dumbbell.h +++ b/testbed/common/Dumbbell.h @@ -48,6 +48,8 @@ class Dumbbell : public PhysicsObject { rp3d::Collider* mColliderSphere1; rp3d::Collider* mColliderSphere2; + rp3d::PhysicsWorld* mPhysicsWorld; + /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) openglframework::Matrix4 mScalingMatrix; diff --git a/testbed/common/HeightField.cpp b/testbed/common/HeightField.cpp index ad5b15b9..458d5de8 100644 --- a/testbed/common/HeightField.cpp +++ b/testbed/common/HeightField.cpp @@ -29,7 +29,7 @@ // Constructor HeightField::HeightField(bool createRigidBody, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld) - : PhysicsObject(physicsCommon), mVBOVertices(GL_ARRAY_BUFFER), + : PhysicsObject(physicsCommon), mPhysicsWorld(physicsWorld), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { @@ -83,6 +83,13 @@ HeightField::~HeightField() { mVBOTextureCoords.destroy(); mVAO.destroy(); + rp3d::RigidBody* body = dynamic_cast<rp3d::RigidBody*>(mBody); + if (body != nullptr) { + mPhysicsWorld->destroyRigidBody(body); + } + else { + mPhysicsWorld->destroyCollisionBody(mBody); + } mPhysicsCommon.destroyHeightFieldShape(mHeightFieldShape); } diff --git a/testbed/common/HeightField.h b/testbed/common/HeightField.h index 5c43cda1..d49b9a3c 100644 --- a/testbed/common/HeightField.h +++ b/testbed/common/HeightField.h @@ -49,6 +49,8 @@ class HeightField : public PhysicsObject { rp3d::HeightFieldShape* mHeightFieldShape; rp3d::Collider* mCollider; + rp3d::PhysicsWorld* mPhysicsWorld; + /// Scaling matrix openglframework::Matrix4 mScalingMatrix; diff --git a/testbed/common/Sphere.cpp b/testbed/common/Sphere.cpp index 09bfefb6..ee387bef 100644 --- a/testbed/common/Sphere.cpp +++ b/testbed/common/Sphere.cpp @@ -36,7 +36,7 @@ int Sphere::totalNbSpheres = 0; // Constructor Sphere::Sphere(bool createRigidBody, float radius, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* world, const std::string& meshFolderPath) - : PhysicsObject(physicsCommon, meshFolderPath + "sphere.obj"), mRadius(radius) { + : PhysicsObject(physicsCommon, meshFolderPath + "sphere.obj"), mRadius(radius), mPhysicsWorld(world) { // Compute the scaling matrix mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, @@ -80,6 +80,7 @@ Sphere::Sphere(bool createRigidBody, float radius, rp3d::PhysicsCommon& physicsC Sphere::~Sphere() { if (totalNbSpheres == 1) { + // Destroy the mesh destroy(); @@ -90,6 +91,13 @@ Sphere::~Sphere() { mVBOTextureCoords.destroy(); mVAO.destroy(); } + rp3d::RigidBody* body = dynamic_cast<rp3d::RigidBody*>(mBody); + if (body != nullptr) { + mPhysicsWorld->destroyRigidBody(body); + } + else { + mPhysicsWorld->destroyCollisionBody(mBody); + } mPhysicsCommon.destroySphereShape(mCollisionShape); totalNbSpheres--; } diff --git a/testbed/common/Sphere.h b/testbed/common/Sphere.h index ae49848e..4994e5a3 100644 --- a/testbed/common/Sphere.h +++ b/testbed/common/Sphere.h @@ -45,6 +45,8 @@ class Sphere : public PhysicsObject { rp3d::SphereShape* mCollisionShape; rp3d::Collider* mCollider; + rp3d::PhysicsWorld* mPhysicsWorld; + /// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions) openglframework::Matrix4 mScalingMatrix; diff --git a/testbed/scenes/ballandsocketjoint/BallAndSocketJointScene.cpp b/testbed/scenes/ballandsocketjoint/BallAndSocketJointScene.cpp index 806e2db0..939c8295 100644 --- a/testbed/scenes/ballandsocketjoint/BallAndSocketJointScene.cpp +++ b/testbed/scenes/ballandsocketjoint/BallAndSocketJointScene.cpp @@ -41,11 +41,7 @@ BallAndSocketJointScene::BallAndSocketJointScene(const std::string& name, Engine // Set the center of the scene setScenePosition(center, SCENE_RADIUS); - // Gravity vector in the physics world - rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); - - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -53,42 +49,48 @@ BallAndSocketJointScene::BallAndSocketJointScene(const std::string& name, Engine static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); - - // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); - physicsWorld->setEventListener(this); - mPhysicsWorld = physicsWorld; - - // Create the Ball-and-Socket joint - createBallAndSocketJoint(); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } // Destructor BallAndSocketJointScene::~BallAndSocketJointScene() { - // Destroy the joints - mPhysicsWorld->destroyJoint(mJoint); + destroyPhysicsWorld(); +} - // Destroy all the rigid bodies of the scene - mPhysicsWorld->destroyRigidBody(mBox1->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mBox2->getRigidBody()); +// Create the physics world +void BallAndSocketJointScene::createPhysicsWorld() { - delete mBox1; - delete mBox2; + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + // Create the physics world for the physics simulation + mPhysicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); + mPhysicsWorld->setEventListener(this); + + // Create the Ball-and-Socket joint + createBallAndSocketJoint(); +} + +// Initialize the bodies positions +void BallAndSocketJointScene::initBodiesPositions() { + + mBox1->setTransform(rp3d::Transform(rp3d::Vector3(0, 8, 0), rp3d::Quaternion::identity())); + mBox2->setTransform(rp3d::Transform(rp3d::Vector3(0, 0, 0), rp3d::Quaternion::identity())); +} + +// Destroy the physics world +void BallAndSocketJointScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + delete mBox1; + delete mBox2; + + mPhysicsObjects.clear(); + + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } } // Reset the scene @@ -96,8 +98,9 @@ void BallAndSocketJointScene::reset() { SceneDemo::reset(); - mBox1->setTransform(rp3d::Transform(rp3d::Vector3(0, 8, 0), rp3d::Quaternion::identity())); - mBox2->setTransform(rp3d::Transform(rp3d::Vector3(0, 0, 0), rp3d::Quaternion::identity())); + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); } // Create the boxes and joints for the Ball-and-Socket joint example @@ -145,9 +148,3 @@ void BallAndSocketJointScene::createBallAndSocketJoint() { mJoint->enableConeLimit(true); } - -// Update the scene -void BallAndSocketJointScene::update() { - - SceneDemo::update(); -} diff --git a/testbed/scenes/ballandsocketjoint/BallAndSocketJointScene.h b/testbed/scenes/ballandsocketjoint/BallAndSocketJointScene.h index 58bff4c5..4626e269 100644 --- a/testbed/scenes/ballandsocketjoint/BallAndSocketJointScene.h +++ b/testbed/scenes/ballandsocketjoint/BallAndSocketJointScene.h @@ -57,6 +57,9 @@ class BallAndSocketJointScene : public SceneDemo { /// Ball-And-Socket joint rp3d::BallAndSocketJoint* mJoint; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + // -------------------- Methods -------------------- // /// Create the Ball-and-Socket joint @@ -75,8 +78,14 @@ class BallAndSocketJointScene : public SceneDemo { /// Reset the scene virtual void reset() override; - /// Update the scene - virtual void update() override; + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.cpp b/testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.cpp index 8653d1c2..00e96e67 100644 --- a/testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.cpp +++ b/testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.cpp @@ -43,11 +43,7 @@ BallAndSocketJointsChainScene::BallAndSocketJointsChainScene(const std::string& // Set the center of the scene setScenePosition(center, SCENE_RADIUS); - // Gravity vector in the physics world - rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); - - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -55,17 +51,29 @@ BallAndSocketJointsChainScene::BallAndSocketJointsChainScene(const std::string& static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); +} + +// Destructor +BallAndSocketJointsChainScene::~BallAndSocketJointsChainScene() { + + destroyPhysicsWorld(); +} + +// Create the physics world +void BallAndSocketJointsChainScene::createPhysicsWorld() { + + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); - physicsWorld->setEventListener(this); - mPhysicsWorld = physicsWorld; + mPhysicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); + mPhysicsWorld->setEventListener(this); // Create all the spheres of the scene for (int i=0; i<NB_SPHERES; i++) { // Create a sphere and a corresponding rigid in the physics world - mSpheres[i] = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, meshFolderPath); + mSpheres[i] = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); // Set the sphere color mSpheres[i]->setColor(mObjectColorDemo); @@ -84,64 +92,14 @@ BallAndSocketJointsChainScene::BallAndSocketJointsChainScene(const std::string& } // Set the position of the spheres before the joints creation - reset(); + initBodiesPositions(); // Create the Ball-and-Socket joints createJoints(); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } -// Destructor -BallAndSocketJointsChainScene::~BallAndSocketJointsChainScene() { - - // Destroy the joints - for (uint i=0; i < mBallAndSocketJoints.size(); i++) { - - mPhysicsWorld->destroyJoint(mBallAndSocketJoints[i]); - } - - // Destroy all the rigid bodies of the scene - for (int i=0; i<NB_SPHERES; i++) { - - mPhysicsWorld->destroyRigidBody(mSpheres[i]->getRigidBody()); - } - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); -} - -// Create the joints -void BallAndSocketJointsChainScene::createJoints() { - - for (int i=0; i < NB_SPHERES-1; i++) { - - // Create the joint info object - rp3d::RigidBody* body1 = mSpheres[i]->getRigidBody(); - rp3d::RigidBody* body2 = mSpheres[i+1]->getRigidBody(); - rp3d::Vector3 body1Position = body1->getTransform().getPosition(); - rp3d::Vector3 body2Position = body2->getTransform().getPosition(); - const rp3d::Vector3 anchorPointWorldSpace = body1Position; - rp3d::BallAndSocketJointInfo jointInfo(body1, body2, anchorPointWorldSpace); - jointInfo.isCollisionEnabled = false; - rp3d::BallAndSocketJoint* joint = dynamic_cast<rp3d::BallAndSocketJoint*>( mPhysicsWorld->createJoint(jointInfo)); - mBallAndSocketJoints.push_back(joint); - } -} - -// Reset the scene -void BallAndSocketJointsChainScene::reset() { - - SceneDemo::reset(); +// Initialize the bodies positions +void BallAndSocketJointsChainScene::initBodiesPositions() { const float space = 0.5f; @@ -157,3 +115,50 @@ void BallAndSocketJointsChainScene::reset() { mSpheres[i]->setTransform(transform); } } + +// Destroy the physics world +void BallAndSocketJointsChainScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + // Destroy all the physics objects of the scene + for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + + // Destroy the object + delete (*it); + } + + mBallAndSocketJoints.clear(); + mPhysicsObjects.clear(); + + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } +} + +// Create the joints +void BallAndSocketJointsChainScene::createJoints() { + + for (int i=0; i < NB_SPHERES-1; i++) { + + // Create the joint info object + rp3d::RigidBody* body1 = mSpheres[i]->getRigidBody(); + rp3d::RigidBody* body2 = mSpheres[i+1]->getRigidBody(); + rp3d::Vector3 body1Position = body1->getTransform().getPosition(); + const rp3d::Vector3 anchorPointWorldSpace = body1Position; + rp3d::BallAndSocketJointInfo jointInfo(body1, body2, anchorPointWorldSpace); + jointInfo.isCollisionEnabled = false; + rp3d::BallAndSocketJoint* joint = dynamic_cast<rp3d::BallAndSocketJoint*>( mPhysicsWorld->createJoint(jointInfo)); + mBallAndSocketJoints.push_back(joint); + } +} + +// Reset the scene +void BallAndSocketJointsChainScene::reset() { + + SceneDemo::reset(); + + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); +} diff --git a/testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.h b/testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.h index c3bbdebd..658e249d 100644 --- a/testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.h +++ b/testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.h @@ -52,6 +52,9 @@ class BallAndSocketJointsChainScene : public SceneDemo { /// Ball-And-Socket joints of the chain std::vector<rp3d::BallAndSocketJoint*> mBallAndSocketJoints; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + // -------------------- Methods -------------------- // /// Create the joints @@ -69,6 +72,15 @@ class BallAndSocketJointsChainScene : public SceneDemo { /// Reset the scene virtual void reset() override; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/boxtower/BoxTowerScene.cpp b/testbed/scenes/boxtower/BoxTowerScene.cpp index 0aa30e08..4c35672f 100644 --- a/testbed/scenes/boxtower/BoxTowerScene.cpp +++ b/testbed/scenes/boxtower/BoxTowerScene.cpp @@ -45,8 +45,7 @@ BoxTowerScene::BoxTowerScene(const std::string& name, EngineSettings& settings) // Gravity vector in the physics world rp3d::Vector3 gravity(0, -9.81f, 0); - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -54,11 +53,23 @@ BoxTowerScene::BoxTowerScene(const std::string& name, EngineSettings& settings) static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); +} + +// Destructor +BoxTowerScene::~BoxTowerScene() { + + destroyPhysicsWorld(); +} + +// Create the physics world +void BoxTowerScene::createPhysicsWorld() { + + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); - physicsWorld->setEventListener(this); - mPhysicsWorld = physicsWorld; + mPhysicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); + mPhysicsWorld->setEventListener(this); // Create all the boxes of the scene for (int i=0; i<NB_BOXES; i++) { @@ -76,13 +87,13 @@ BoxTowerScene::BoxTowerScene(const std::string& name, EngineSettings& settings) // Add the sphere the list of boxes in the scene mBoxes.push_back(box); - mPhysicsObjects.push_back(box); + mPhysicsObjects.push_back(box); } // ---------- Create the floor --------- mFloor = new Box(true, FLOOR_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); - mPhysicsObjects.push_back(mFloor); + mPhysicsObjects.push_back(mFloor); // Set the box color mFloor->setColor(mFloorColorDemo); @@ -94,40 +105,10 @@ BoxTowerScene::BoxTowerScene(const std::string& name, EngineSettings& settings) // Change the material properties of the rigid body rp3d::Material& material = mFloor->getCollider()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } -// Destructor -BoxTowerScene::~BoxTowerScene() { - - // Destroy all the physics objects of the scene - for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { - - // Destroy the corresponding rigid body from the physics world - mPhysicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the object - delete (*it); - } - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(static_cast<rp3d::PhysicsWorld*>(mPhysicsWorld)); -} - -/// Reset the scene -void BoxTowerScene::reset() { - - SceneDemo::reset(); +// Initialize the bodies positions +void BoxTowerScene::initBodiesPositions() { float distFromCenter = 4.0f; @@ -158,3 +139,38 @@ void BoxTowerScene::reset() { mFloor->setTransform(rp3d::Transform::identity()); } + +// Destroy the physics world +void BoxTowerScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + // Destroy all the physics objects of the scene + for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + + // Destroy the object + delete (*it); + } + mBoxes.clear(); + mSpheres.clear(); + mCapsules.clear(); + mConvexMeshes.clear(); + mDumbbells.clear(); + + mPhysicsObjects.clear(); + + // Destroy the physics world + mPhysicsCommon.destroyPhysicsWorld(static_cast<rp3d::PhysicsWorld*>(mPhysicsWorld)); + mPhysicsWorld = nullptr; + } +} + +/// Reset the scene +void BoxTowerScene::reset() { + + SceneDemo::reset(); + + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); +} diff --git a/testbed/scenes/boxtower/BoxTowerScene.h b/testbed/scenes/boxtower/BoxTowerScene.h index 2af03415..297e76bf 100644 --- a/testbed/scenes/boxtower/BoxTowerScene.h +++ b/testbed/scenes/boxtower/BoxTowerScene.h @@ -69,6 +69,9 @@ class BoxTowerScene : public SceneDemo { /// Box for the floor Box* mFloor; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + public: // -------------------- Methods -------------------- // @@ -81,6 +84,15 @@ class BoxTowerScene : public SceneDemo { /// Reset the scene virtual void reset() override; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/bridge/BridgeScene.cpp b/testbed/scenes/bridge/BridgeScene.cpp index 969196fb..e3364fe1 100644 --- a/testbed/scenes/bridge/BridgeScene.cpp +++ b/testbed/scenes/bridge/BridgeScene.cpp @@ -43,11 +43,7 @@ BridgeScene::BridgeScene(const std::string& name, EngineSettings& settings) // Set the center of the scene setScenePosition(center, SCENE_RADIUS); - // Gravity vector in the physics world - rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); - - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -55,95 +51,12 @@ BridgeScene::BridgeScene(const std::string& name, EngineSettings& settings) static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); - - // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); - physicsWorld->setEventListener(this); - mPhysicsWorld = physicsWorld; - - for (int b=0; b < NB_BRIDGES; b++) { - - // Create all the boxes of the scene - for (int i=0; i<NB_BOXES; i++) { - - const uint boxIndex = b * NB_BOXES + i; - - // Create a box and a corresponding rigid in the physics world - mBoxes[boxIndex] = new Box(true, BOX_SIZE, mPhysicsCommon, mPhysicsWorld, meshFolderPath); - - // Set the box color - mBoxes[boxIndex]->setColor(mObjectColorDemo); - mBoxes[boxIndex]->setSleepingColor(mSleepingColorDemo); - - // Change the material properties of the rigid body - rp3d::Material& material = mBoxes[boxIndex]->getCollider()->getMaterial(); - material.setBounciness(rp3d::decimal(0.0)); - - if (i == 0 || i == NB_BOXES-1) { - mBoxes[boxIndex]->getRigidBody()->setType(rp3d::BodyType::STATIC); - } - - // Add the box the list of boxes in the scene - mPhysicsObjects.push_back(mBoxes[boxIndex]); - } - } - - // Create all the spheres of the scene - for (int i=0; i<NB_BRIDGES; i++) { - - // Create a sphere and a corresponding rigid in the physics world - mSpheres[i] = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, meshFolderPath); - - // Set the box color - mSpheres[i]->setColor(mObjectColorDemo); - mSpheres[i]->setSleepingColor(mSleepingColorDemo); - - // Change the material properties of the rigid body - rp3d::Material& material = mSpheres[i]->getCollider()->getMaterial(); - material.setBounciness(rp3d::decimal(0.2)); - mSpheres[i]->getRigidBody()->setMass(SPHERE_MASS); - - // Add the sphere the list of sphere in the scene - mPhysicsObjects.push_back(mSpheres[i]); - } - - // Set the position of the boxes before the joints creation - reset(); - - // Create the Ball-and-Socket joints - createJoints(); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } // Destructor BridgeScene::~BridgeScene() { - // Destroy the joints - for (uint i=0; i < mHingeJoints.size(); i++) { - - if (mHingeJoints[i] != nullptr) { - mPhysicsWorld->destroyJoint(mHingeJoints[i]); - } - } - - // Destroy all the rigid bodies of the scene - for (int i=0; i<NB_BOXES * NB_BRIDGES; i++) { - - mPhysicsWorld->destroyRigidBody(mBoxes[i]->getRigidBody()); - } - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + destroyPhysicsWorld(); } // Create the joints @@ -160,7 +73,6 @@ void BridgeScene::createJoints() { rp3d::RigidBody* body1 = mBoxes[box1Index]->getRigidBody(); rp3d::RigidBody* body2 = mBoxes[box2Index]->getRigidBody(); rp3d::Vector3 body1Position = body1->getTransform().getPosition(); - rp3d::Vector3 body2Position = body2->getTransform().getPosition(); const rp3d::Vector3 anchorPointWorldSpace = body1Position + rp3d::Vector3(BOX_SIZE.x / 2.0f, 0, 0); rp3d::HingeJointInfo jointInfo(body1, body2, anchorPointWorldSpace, rp3d::Vector3(0, 0, 1)); jointInfo.isCollisionEnabled = false; @@ -191,10 +103,71 @@ void BridgeScene::updatePhysics() { } } -// Reset the scene -void BridgeScene::reset() { +// Create the physics world +void BridgeScene::createPhysicsWorld() { - SceneDemo::reset(); + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); + + // Create the physics world for the physics simulation + mPhysicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); + mPhysicsWorld->setEventListener(this); + + for (int b=0; b < NB_BRIDGES; b++) { + + // Create all the boxes of the scene + for (int i=0; i<NB_BOXES; i++) { + + const uint boxIndex = b * NB_BOXES + i; + + // Create a box and a corresponding rigid in the physics world + mBoxes[boxIndex] = new Box(true, BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); + + // Set the box color + mBoxes[boxIndex]->setColor(mObjectColorDemo); + mBoxes[boxIndex]->setSleepingColor(mSleepingColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = mBoxes[boxIndex]->getCollider()->getMaterial(); + material.setBounciness(rp3d::decimal(0.0)); + + if (i == 0 || i == NB_BOXES-1) { + mBoxes[boxIndex]->getRigidBody()->setType(rp3d::BodyType::STATIC); + } + + // Add the box the list of boxes in the scene + mPhysicsObjects.push_back(mBoxes[boxIndex]); + } + } + + // Create all the spheres of the scene + for (int i=0; i<NB_BRIDGES; i++) { + + // Create a sphere and a corresponding rigid in the physics world + mSpheres[i] = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); + + // Set the box color + mSpheres[i]->setColor(mObjectColorDemo); + mSpheres[i]->setSleepingColor(mSleepingColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = mSpheres[i]->getCollider()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + mSpheres[i]->getRigidBody()->setMass(SPHERE_MASS); + + // Add the sphere the list of sphere in the scene + mPhysicsObjects.push_back(mSpheres[i]); + } + + // Set the position of the boxes before the joints creation + initBodiesPositions(); + + // Create the Ball-and-Socket joints + createJoints(); +} + +// Initialize the bodies positions +void BridgeScene::initBodiesPositions() { const rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); @@ -218,7 +191,7 @@ void BridgeScene::reset() { for (int i=0; i < NB_BRIDGES; i++) { // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(0, + rp3d::Vector3 initPosition(-12, 10, (-NB_BRIDGES/2 + i) * (BOX_SIZE.z + 4)); @@ -239,3 +212,33 @@ void BridgeScene::reset() { createJoints(); } + +// Destroy the physics world +void BridgeScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + // Destroy all the physics objects of the scene + for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + + // Destroy the object + delete (*it); + } + + mHingeJoints.clear(); + mPhysicsObjects.clear(); + + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } +} + +// Reset the scene +void BridgeScene::reset() { + + SceneDemo::reset(); + + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); +} diff --git a/testbed/scenes/bridge/BridgeScene.h b/testbed/scenes/bridge/BridgeScene.h index fd2c56ce..d00f4021 100644 --- a/testbed/scenes/bridge/BridgeScene.h +++ b/testbed/scenes/bridge/BridgeScene.h @@ -59,6 +59,9 @@ class BridgeScene : public SceneDemo { /// Hinge joints of the bridge std::vector<rp3d::HingeJoint*> mHingeJoints; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + // -------------------- Methods -------------------- // /// Create the joints @@ -79,6 +82,15 @@ class BridgeScene : public SceneDemo { /// Reset the scene virtual void reset() override; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp index 908e1336..cf27321d 100644 --- a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp +++ b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp @@ -184,36 +184,14 @@ void CollisionDetectionScene::reset() { // Destructor CollisionDetectionScene::~CollisionDetectionScene() { - // Destroy the box rigid body from the physics world - //mPhysicsWorld->destroyCollisionBody(mBox->getCollisionBody()); - //delete mBox; - - // Destroy the spheres - mPhysicsWorld->destroyCollisionBody(mSphere1->getCollisionBody()); delete mSphere1; - - mPhysicsWorld->destroyCollisionBody(mSphere2->getCollisionBody()); delete mSphere2; - - mPhysicsWorld->destroyCollisionBody(mCapsule1->getCollisionBody()); delete mCapsule1; - - mPhysicsWorld->destroyCollisionBody(mCapsule2->getCollisionBody()); delete mCapsule2; - - mPhysicsWorld->destroyCollisionBody(mBox1->getCollisionBody()); delete mBox1; - - mPhysicsWorld->destroyCollisionBody(mBox2->getCollisionBody()); delete mBox2; - - mPhysicsWorld->destroyCollisionBody(mConvexMesh->getCollisionBody()); delete mConvexMesh; - - mPhysicsWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody()); delete mConcaveMesh; - - mPhysicsWorld->destroyCollisionBody(mHeightField->getCollisionBody()); delete mHeightField; // Destroy the static data for the visual contact points diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp index 5a5b92e4..3f705d71 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -42,11 +42,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin // Set the center of the scene setScenePosition(center, SCENE_RADIUS); - // Gravity vector in the physics world - rp3d::Vector3 gravity(0, -9.81f, 0); - - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -54,16 +50,28 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); +} + +// Destructor +CollisionShapesScene::~CollisionShapesScene() { + + destroyPhysicsWorld(); +} + +// Create the physics world +void CollisionShapesScene::createPhysicsWorld() { + + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); - physicsWorld->setEventListener(this); - mPhysicsWorld = physicsWorld; + mPhysicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); + mPhysicsWorld->setEventListener(this); for (int i=0; i<NB_COMPOUND_SHAPES; i++) { // Create a convex mesh and a corresponding rigid in the physics world - Dumbbell* dumbbell = new Dumbbell(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath); + Dumbbell* dumbbell = new Dumbbell(true, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); // Set the box color dumbbell->setColor(mObjectColorDemo); @@ -79,7 +87,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin // Add the mesh the list of dumbbells in the scene mDumbbells.push_back(dumbbell); - mPhysicsObjects.push_back(dumbbell); + mPhysicsObjects.push_back(dumbbell); } // Create all the boxes of the scene @@ -98,14 +106,14 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin // Add the sphere the list of sphere in the scene mBoxes.push_back(box); - mPhysicsObjects.push_back(box); + mPhysicsObjects.push_back(box); } // Create all the spheres of the scene for (int i=0; i<NB_SPHERES; i++) { // Create a sphere and a corresponding rigid in the physics world - Sphere* sphere = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, meshFolderPath); + Sphere* sphere = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); // Set the box color sphere->setColor(mObjectColorDemo); @@ -117,7 +125,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin // Add the sphere the list of sphere in the scene mSpheres.push_back(sphere); - mPhysicsObjects.push_back(sphere); + mPhysicsObjects.push_back(sphere); } // Create all the capsules of the scene @@ -125,7 +133,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin // Create a cylinder and a corresponding rigid in the physics world Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT, - mPhysicsCommon, mPhysicsWorld, meshFolderPath); + mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); // Set the box color capsule->setColor(mObjectColorDemo); @@ -137,14 +145,14 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin // Add the cylinder the list of sphere in the scene mCapsules.push_back(capsule); - mPhysicsObjects.push_back(capsule); + mPhysicsObjects.push_back(capsule); } // Create all the convex meshes of the scene for (int i=0; i<NB_MESHES; i++) { // Create a convex mesh and a corresponding rigid in the physics world - ConvexMesh* mesh = new ConvexMesh(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj"); + ConvexMesh* mesh = new ConvexMesh(true, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj"); // Set the box color mesh->setColor(mObjectColorDemo); @@ -156,13 +164,13 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin // Add the mesh the list of sphere in the scene mConvexMeshes.push_back(mesh); - mPhysicsObjects.push_back(mesh); + mPhysicsObjects.push_back(mesh); } // ---------- Create the floor --------- mFloor = new Box(true, FLOOR_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); - mPhysicsObjects.push_back(mFloor); + mPhysicsObjects.push_back(mFloor); // Set the box color mFloor->setColor(mFloorColorDemo); @@ -174,40 +182,10 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin // Change the material properties of the rigid body rp3d::Material& material = mFloor->getCollider()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } -// Destructor -CollisionShapesScene::~CollisionShapesScene() { - - // Destroy all the physics objects of the scene - for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { - - // Destroy the corresponding rigid body from the physics world - mPhysicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the object - delete (*it); - } - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(static_cast<rp3d::PhysicsWorld*>(mPhysicsWorld)); -} - -/// Reset the scene -void CollisionShapesScene::reset() { - - SceneDemo::reset(); +// Initialize the bodies positions +void CollisionShapesScene::initBodiesPositions() { const float radius = 3.0f; @@ -274,3 +252,39 @@ void CollisionShapesScene::reset() { mFloor->setTransform(rp3d::Transform::identity()); } + +// Destroy the physics world +void CollisionShapesScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + // Destroy all the physics objects of the scene + for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + + // Destroy the object + delete (*it); + } + + mBoxes.clear(); + mSpheres.clear(); + mCapsules.clear(); + mConvexMeshes.clear(); + mDumbbells.clear(); + + // Destroy the physics world + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + + mPhysicsObjects.clear(); + } +} + +/// Reset the scene +void CollisionShapesScene::reset() { + + SceneDemo::reset(); + + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); +} diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.h b/testbed/scenes/collisionshapes/CollisionShapesScene.h index e836111e..98705ca8 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.h +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.h @@ -81,6 +81,9 @@ class CollisionShapesScene : public SceneDemo { /// Box for the floor Box* mFloor; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + public: // -------------------- Methods -------------------- // @@ -93,6 +96,15 @@ class CollisionShapesScene : public SceneDemo { /// Reset the scene virtual void reset() override; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/concavemesh/ConcaveMeshScene.cpp b/testbed/scenes/concavemesh/ConcaveMeshScene.cpp index c0c1b3e0..6a4f2d7b 100644 --- a/testbed/scenes/concavemesh/ConcaveMeshScene.cpp +++ b/testbed/scenes/concavemesh/ConcaveMeshScene.cpp @@ -42,11 +42,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett // Set the center of the scene setScenePosition(center, SCENE_RADIUS); - // Gravity vector in the physics world - rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); - - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -54,9 +50,22 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); +} + +// Destructor +ConcaveMeshScene::~ConcaveMeshScene() { + + destroyPhysicsWorld(); +} + +// Create the physics world +void ConcaveMeshScene::createPhysicsWorld() { + + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); + rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); physicsWorld->setEventListener(this); mPhysicsWorld = physicsWorld; @@ -64,7 +73,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett for (int i = 0; i<NB_COMPOUND_SHAPES; i++) { // Create a convex mesh and a corresponding rigid in the physics world - Dumbbell* dumbbell = new Dumbbell(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath); + Dumbbell* dumbbell = new Dumbbell(true, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); // Set the box color dumbbell->setColor(mObjectColorDemo); @@ -106,7 +115,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett for (int i = 0; i<NB_SPHERES; i++) { // Create a sphere and a corresponding rigid in the physics world - Sphere* sphere = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, meshFolderPath); + Sphere* sphere = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); // Set the box color sphere->setColor(mObjectColorDemo); @@ -126,7 +135,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett // Create a cylinder and a corresponding rigid in the physics world Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT, - mPhysicsCommon, mPhysicsWorld, meshFolderPath); + mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); // Set the box color capsule->setColor(mObjectColorDemo); @@ -145,7 +154,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett for (int i = 0; i<NB_MESHES; i++) { // Create a convex mesh and a corresponding rigid in the physics world - ConvexMesh* mesh = new ConvexMesh(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj"); + ConvexMesh* mesh = new ConvexMesh(true, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj"); // Set the box color mesh->setColor(mObjectColorDemo); @@ -163,7 +172,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett // ---------- Create the triangular mesh ---------- // // Create a convex mesh and a corresponding rigid in the physics world - mConcaveMesh = new ConcaveMesh(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "city.obj"); + mConcaveMesh = new ConcaveMesh(true, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "city.obj"); // Set the mesh as beeing static mConcaveMesh->getRigidBody()->setType(rp3d::BodyType::STATIC); @@ -178,40 +187,10 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett rp3d::Material& material = mConcaveMesh->getCollider()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); material.setFrictionCoefficient(rp3d::decimal(0.1)); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } -// Destructor -ConcaveMeshScene::~ConcaveMeshScene() { - - // Destroy all the physics objects of the scene - for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { - - // Destroy the corresponding rigid body from the physics world - mPhysicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the object - delete (*it); - } - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); -} - -// Reset the scene -void ConcaveMeshScene::reset() { - - SceneDemo::reset(); +// Initialize the bodies positions +void ConcaveMeshScene::initBodiesPositions() { const float radius = 15.0f; @@ -278,3 +257,36 @@ void ConcaveMeshScene::reset() { mConcaveMesh->setTransform(rp3d::Transform::identity()); } + +// Destroy the physics world +void ConcaveMeshScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + // Destroy all the physics objects of the scene + for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + + // Destroy the object + delete (*it); + } + mBoxes.clear(); + mSpheres.clear(); + mCapsules.clear(); + mConvexMeshes.clear(); + mDumbbells.clear(); + + mPhysicsObjects.clear(); + + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } +} +// Reset the scene +void ConcaveMeshScene::reset() { + + SceneDemo::reset(); + + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); +} diff --git a/testbed/scenes/concavemesh/ConcaveMeshScene.h b/testbed/scenes/concavemesh/ConcaveMeshScene.h index 8838b5d3..c4f5cdad 100644 --- a/testbed/scenes/concavemesh/ConcaveMeshScene.h +++ b/testbed/scenes/concavemesh/ConcaveMeshScene.h @@ -79,6 +79,9 @@ class ConcaveMeshScene : public SceneDemo { /// Concave triangles mesh ConcaveMesh* mConcaveMesh; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + public: // -------------------- Methods -------------------- // @@ -91,6 +94,15 @@ class ConcaveMeshScene : public SceneDemo { /// Reset the scene virtual void reset() override; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index 7c45e15b..6bb57f7f 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -42,11 +42,7 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings) // Set the center of the scene setScenePosition(center, SCENE_RADIUS); - // Gravity vector in the physics world - rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); - - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -54,11 +50,23 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings) static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); +} + +// Destructor +CubesScene::~CubesScene() { + + destroyPhysicsWorld(); +} + +// Create the physics world +void CubesScene::createPhysicsWorld() { + + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); - physicsWorld->setEventListener(this); - mPhysicsWorld = physicsWorld; + mPhysicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); + mPhysicsWorld->setEventListener(this); // Create all the cubes of the scene for (int i=0; i<NB_CUBES; i++) { @@ -79,7 +87,7 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings) mPhysicsObjects.push_back(cube); } - // ------------------------- FLOOR ----------------------- // + // ------------------------- FLOOR ----------------------- // // Create the floor mFloor = new Box(true, FLOOR_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); @@ -88,45 +96,11 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings) // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC); - mPhysicsObjects.push_back(mFloor); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); + mPhysicsObjects.push_back(mFloor); } -// Destructor -CubesScene::~CubesScene() { - - // Destroy all the cubes of the scene - for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - - // Destroy the corresponding rigid body from the physics world - mPhysicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the cube - delete (*it); - } - - // Destroy the rigid body of the floor - mPhysicsWorld->destroyRigidBody(mFloor->getRigidBody()); - - // Destroy the floor - delete mFloor; - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); -} - -// Reset the scene -void CubesScene::reset() { +// Initialize the bodies positions +void CubesScene::initBodiesPositions() { float radius = 2.0f; @@ -148,3 +122,36 @@ void CubesScene::reset() { mFloor->setTransform(rp3d::Transform(rp3d::Vector3::zero(), rp3d::Quaternion::identity())); } + +// Destroy the physics world +void CubesScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + // Destroy all the cubes of the scene + for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { + + // Destroy the cube + delete (*it); + } + mBoxes.clear(); + + // Destroy the floor + delete mFloor; + + mPhysicsObjects.clear(); + + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } +} + +// Reset the scene +void CubesScene::reset() { + + SceneDemo::reset(); + + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); +} diff --git a/testbed/scenes/cubes/CubesScene.h b/testbed/scenes/cubes/CubesScene.h index dd012a70..bc767630 100755 --- a/testbed/scenes/cubes/CubesScene.h +++ b/testbed/scenes/cubes/CubesScene.h @@ -35,9 +35,9 @@ namespace cubesscene { // Constants -const float SCENE_RADIUS = 30.0f; // Radius of the scene in meters -const int NB_CUBES = 40; // Number of boxes in the scene -const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters +const float SCENE_RADIUS = 30.0f; // Radius of the scene in meters +const int NB_CUBES = 30; // Number of boxes in the scene +const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters const openglframework::Vector3 FLOOR_SIZE(50, 1, 50); // Floor dimensions in meters // Class CubesScene @@ -55,6 +55,9 @@ class CubesScene : public SceneDemo { unsigned int iter; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + public: // -------------------- Methods -------------------- // @@ -67,6 +70,15 @@ class CubesScene : public SceneDemo { /// Reset the scene virtual void reset() override; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/cubestack/CubeStackScene.cpp b/testbed/scenes/cubestack/CubeStackScene.cpp index 40b2b66d..71ab9acc 100644 --- a/testbed/scenes/cubestack/CubeStackScene.cpp +++ b/testbed/scenes/cubestack/CubeStackScene.cpp @@ -40,11 +40,7 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings // Set the center of the scene setScenePosition(center, SCENE_RADIUS); - // Gravity vector in the physics world - rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); - - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -52,9 +48,16 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); +} + +// Create the physics world +void CubeStackScene::createPhysicsWorld() { + + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); + rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); physicsWorld->setEventListener(this); mPhysicsWorld = physicsWorld; @@ -90,46 +93,10 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC); mPhysicsObjects.push_back(mFloor); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } -// Destructor -CubeStackScene::~CubeStackScene() { - - // Destroy all the cubes of the scene - for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - - // Destroy the corresponding rigid body from the physics world - mPhysicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the cube - delete (*it); - } - - // Destroy the rigid body of the floor - mPhysicsWorld->destroyRigidBody(mFloor->getRigidBody()); - - // Destroy the floor - delete mFloor; - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); -} - -// Reset the scene -void CubeStackScene::reset() { - - SceneDemo::reset(); +// Initialize the bodies positions +void CubeStackScene::initBodiesPositions() { int index = 0; for (int i=NB_FLOORS; i > 0; i--) { @@ -145,8 +112,6 @@ void CubeStackScene::reset() { 0); box->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); - box->getRigidBody()->setLinearVelocity(rp3d::Vector3::zero()); - box->getRigidBody()->setAngularVelocity(rp3d::Vector3::zero()); index++; } @@ -154,3 +119,41 @@ void CubeStackScene::reset() { mFloor->setTransform(rp3d::Transform(rp3d::Vector3::zero(), rp3d::Quaternion::identity())); } + +// Destroy the physics world +void CubeStackScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + // Destroy all the cubes of the scene + for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { + + // Destroy the cube + delete (*it); + } + mBoxes.clear(); + + // Destroy the floor + delete mFloor; + + mPhysicsObjects.clear(); + + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } +} + +// Destructor +CubeStackScene::~CubeStackScene() { + destroyPhysicsWorld(); +} + +// Reset the scene +void CubeStackScene::reset() { + + SceneDemo::reset(); + + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); +} diff --git a/testbed/scenes/cubestack/CubeStackScene.h b/testbed/scenes/cubestack/CubeStackScene.h index 2a0aa5d5..275db5a6 100644 --- a/testbed/scenes/cubestack/CubeStackScene.h +++ b/testbed/scenes/cubestack/CubeStackScene.h @@ -53,6 +53,9 @@ class CubeStackScene : public SceneDemo { /// Box for the floor Box* mFloor; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + public: // -------------------- Methods -------------------- // @@ -65,6 +68,15 @@ class CubeStackScene : public SceneDemo { /// Reset the scene virtual void reset() override; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/fixedjoint/FixedJointScene.cpp b/testbed/scenes/fixedjoint/FixedJointScene.cpp index 75c6396b..36f4270b 100644 --- a/testbed/scenes/fixedjoint/FixedJointScene.cpp +++ b/testbed/scenes/fixedjoint/FixedJointScene.cpp @@ -41,11 +41,7 @@ FixedJointScene::FixedJointScene(const std::string& name, EngineSettings& settin // Set the center of the scene setScenePosition(center, SCENE_RADIUS); - // Gravity vector in the physics world - rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); - - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -53,51 +49,57 @@ FixedJointScene::FixedJointScene(const std::string& name, EngineSettings& settin static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); - - // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); - physicsWorld->setEventListener(this); - mPhysicsWorld = physicsWorld; - - // Create the fixed joint - createFixedJoint(); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } // Destructor FixedJointScene::~FixedJointScene() { - // Destroy the joints - mPhysicsWorld->destroyJoint(mFixedJoint); - - // Destroy all the rigid bodies of the scene - mPhysicsWorld->destroyRigidBody(mBox1->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mBox2->getRigidBody()); - - delete mBox1; - delete mBox2; - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + destroyPhysicsWorld(); } +// Create the physics world +void FixedJointScene::createPhysicsWorld() { + + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); + + // Create the physics world for the physics simulation + mPhysicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); + mPhysicsWorld->setEventListener(this); + + // Create the fixed joint + createFixedJoint(); +} + +// Initialize the bodies positions +void FixedJointScene::initBodiesPositions() { + + mBox1->setTransform(rp3d::Transform(rp3d::Vector3(0, 4, 0), rp3d::Quaternion::identity())); + mBox2->setTransform(rp3d::Transform(rp3d::Vector3(4, 8, 4), rp3d::Quaternion::identity())); +} + +// Destroy the physics world +void FixedJointScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + delete mBox1; + delete mBox2; + + mPhysicsObjects.clear(); + + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } +} // Reset the scene void FixedJointScene::reset() { SceneDemo::reset(); - mBox1->setTransform(rp3d::Transform(rp3d::Vector3(0, 4, 0), rp3d::Quaternion::identity())); - mBox2->setTransform(rp3d::Transform(rp3d::Vector3(4, 8, 4), rp3d::Quaternion::identity())); + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); } /// Create the fixed joint diff --git a/testbed/scenes/fixedjoint/FixedJointScene.h b/testbed/scenes/fixedjoint/FixedJointScene.h index 5beb29dc..1021955a 100644 --- a/testbed/scenes/fixedjoint/FixedJointScene.h +++ b/testbed/scenes/fixedjoint/FixedJointScene.h @@ -57,6 +57,9 @@ class FixedJointScene : public SceneDemo { /// Fixed joint rp3d::FixedJoint* mFixedJoint; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + // -------------------- Methods -------------------- // /// Create the fixed joint @@ -74,6 +77,15 @@ class FixedJointScene : public SceneDemo { /// Reset the scene virtual void reset() override; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/heightfield/HeightFieldScene.cpp b/testbed/scenes/heightfield/HeightFieldScene.cpp index 4620ca54..d8250b91 100644 --- a/testbed/scenes/heightfield/HeightFieldScene.cpp +++ b/testbed/scenes/heightfield/HeightFieldScene.cpp @@ -34,6 +34,8 @@ using namespace heightfieldscene; HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& settings) : SceneDemo(name, settings, true, SCENE_RADIUS) { + mWorldSettings.gravity = rp3d::Vector3(settings.gravity.x, settings.gravity.y, settings.gravity.z); + std::string meshFolderPath("meshes/"); // Compute the radius and the center of the scene @@ -42,34 +44,43 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett // Set the center of the scene setScenePosition(center, SCENE_RADIUS); - // Gravity vector in the physics world - rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); + mWorldSettings.worldName = name; - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); uint logLevel = static_cast<uint>(rp3d::Logger::Level::Information) | static_cast<uint>(rp3d::Logger::Level::Warning) | static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); +} +// Destructor +HeightFieldScene::~HeightFieldScene() { + + destroyPhysicsWorld(); +} + +// Create the physics world +void HeightFieldScene::createPhysicsWorld() { + + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); + rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); physicsWorld->setEventListener(this); mPhysicsWorld = physicsWorld; for (int i = 0; i<NB_COMPOUND_SHAPES; i++) { // Create a convex mesh and a corresponding rigid in the physics world - Dumbbell* dumbbell = new Dumbbell(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath); + Dumbbell* dumbbell = new Dumbbell(true, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); - // Set the box color - dumbbell->setColor(mObjectColorDemo); - dumbbell->setSleepingColor(mSleepingColorDemo); + // Set the box color + dumbbell->setColor(mObjectColorDemo); + dumbbell->setSleepingColor(mSleepingColorDemo); - // Change the material properties of the rigid body + // Change the material properties of the rigid body rp3d::Material& capsuleMaterial = dumbbell->getCapsuleCollider()->getMaterial(); capsuleMaterial.setBounciness(rp3d::decimal(0.2)); rp3d::Material& sphere1Material = dumbbell->getSphere1Collider()->getMaterial(); @@ -77,86 +88,86 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett rp3d::Material& sphere2Material = dumbbell->getSphere2Collider()->getMaterial(); sphere2Material.setBounciness(rp3d::decimal(0.2)); - // Add the mesh the list of dumbbells in the scene - mDumbbells.push_back(dumbbell); - mPhysicsObjects.push_back(dumbbell); - } + // Add the mesh the list of dumbbells in the scene + mDumbbells.push_back(dumbbell); + mPhysicsObjects.push_back(dumbbell); + } - // Create all the boxes of the scene - for (int i = 0; i<NB_BOXES; i++) { + // Create all the boxes of the scene + for (int i = 0; i<NB_BOXES; i++) { // Create a sphere and a corresponding rigid in the physics world Box* box = new Box(true, BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); - // Set the box color - box->setColor(mObjectColorDemo); - box->setSleepingColor(mSleepingColorDemo); + // Set the box color + box->setColor(mObjectColorDemo); + box->setSleepingColor(mSleepingColorDemo); - // Change the material properties of the rigid body + // Change the material properties of the rigid body rp3d::Material& material = box->getCollider()->getMaterial(); - material.setBounciness(rp3d::decimal(0.2)); + material.setBounciness(rp3d::decimal(0.2)); - // Add the sphere the list of sphere in the scene - mBoxes.push_back(box); - mPhysicsObjects.push_back(box); - } + // Add the sphere the list of sphere in the scene + mBoxes.push_back(box); + mPhysicsObjects.push_back(box); + } - // Create all the spheres of the scene - for (int i = 0; i<NB_SPHERES; i++) { + // Create all the spheres of the scene + for (int i = 0; i<NB_SPHERES; i++) { // Create a sphere and a corresponding rigid in the physics world - Sphere* sphere = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, meshFolderPath); + Sphere* sphere = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); - // Set the box color - sphere->setColor(mObjectColorDemo); - sphere->setSleepingColor(mSleepingColorDemo); + // Set the box color + sphere->setColor(mObjectColorDemo); + sphere->setSleepingColor(mSleepingColorDemo); - // Change the material properties of the rigid body + // Change the material properties of the rigid body rp3d::Material& material = sphere->getCollider()->getMaterial(); - material.setBounciness(rp3d::decimal(0.2)); + material.setBounciness(rp3d::decimal(0.2)); - // Add the sphere the list of sphere in the scene - mSpheres.push_back(sphere); - mPhysicsObjects.push_back(sphere); - } + // Add the sphere the list of sphere in the scene + mSpheres.push_back(sphere); + mPhysicsObjects.push_back(sphere); + } - // Create all the capsules of the scene - for (int i = 0; i<NB_CAPSULES; i++) { + // Create all the capsules of the scene + for (int i = 0; i<NB_CAPSULES; i++) { // Create a cylinder and a corresponding rigid in the physics world - Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, meshFolderPath); + Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); - // Set the box color - capsule->setColor(mObjectColorDemo); - capsule->setSleepingColor(mSleepingColorDemo); + // Set the box color + capsule->setColor(mObjectColorDemo); + capsule->setSleepingColor(mSleepingColorDemo); - // Change the material properties of the rigid body + // Change the material properties of the rigid body rp3d::Material& material = capsule->getCollider()->getMaterial(); - material.setBounciness(rp3d::decimal(0.2)); + material.setBounciness(rp3d::decimal(0.2)); - // Add the cylinder the list of sphere in the scene - mCapsules.push_back(capsule); - mPhysicsObjects.push_back(capsule); - } + // Add the cylinder the list of sphere in the scene + mCapsules.push_back(capsule); + mPhysicsObjects.push_back(capsule); + } - // Create all the convex meshes of the scene - for (int i = 0; i<NB_MESHES; i++) { + // Create all the convex meshes of the scene + for (int i = 0; i<NB_MESHES; i++) { // Create a convex mesh and a corresponding rigid in the physics world - ConvexMesh* mesh = new ConvexMesh(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj"); + ConvexMesh* mesh = new ConvexMesh(true, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj"); - // Set the box color - mesh->setColor(mObjectColorDemo); - mesh->setSleepingColor(mSleepingColorDemo); + // Set the box color + mesh->setColor(mObjectColorDemo); + mesh->setSleepingColor(mSleepingColorDemo); - // Change the material properties of the rigid body + // Change the material properties of the rigid body rp3d::Material& material = mesh->getCollider()->getMaterial(); - material.setBounciness(rp3d::decimal(0.2)); + material.setBounciness(rp3d::decimal(0.2)); - // Add the mesh the list of sphere in the scene - mConvexMeshes.push_back(mesh); - mPhysicsObjects.push_back(mesh); - } + // Add the mesh the list of sphere in the scene + mConvexMeshes.push_back(mesh); + mPhysicsObjects.push_back(mesh); + } // ---------- Create the height field ---------- // @@ -166,7 +177,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett // Set the mesh as beeing static mHeightField->getRigidBody()->setType(rp3d::BodyType::STATIC); - mPhysicsObjects.push_back(mHeightField); + mPhysicsObjects.push_back(mHeightField); // Set the color mHeightField->setColor(mFloorColorDemo); @@ -176,40 +187,10 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett rp3d::Material& material = mHeightField->getCollider()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); material.setFrictionCoefficient(0.1f); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } -// Destructor -HeightFieldScene::~HeightFieldScene() { - - // Destroy all the physics objects of the scene - for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { - - // Destroy the corresponding rigid body from the physics world - mPhysicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the object - delete (*it); - } - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); -} - -// Reset the scene -void HeightFieldScene::reset() { - - SceneDemo::reset(); +// Initialize the bodies positions +void HeightFieldScene::initBodiesPositions() { const float radius = 3.0f; @@ -272,7 +253,40 @@ void HeightFieldScene::reset() { mConvexMeshes[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); } - // ---------- Create the triangular mesh ---------- // - mHeightField->setTransform(rp3d::Transform::identity()); } + +// Destroy the physics world +void HeightFieldScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + // Destroy all the physics objects of the scene + for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + + // Destroy the object + delete (*it); + } + + mBoxes.clear(); + mSpheres.clear(); + mCapsules.clear(); + mConvexMeshes.clear(); + mDumbbells.clear(); + + mPhysicsObjects.clear(); + + // Destroy the physics world + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } +} +// Reset the scene +void HeightFieldScene::reset() { + + SceneDemo::reset(); + + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); +} diff --git a/testbed/scenes/heightfield/HeightFieldScene.h b/testbed/scenes/heightfield/HeightFieldScene.h index a5d95d86..f6f761fd 100644 --- a/testbed/scenes/heightfield/HeightFieldScene.h +++ b/testbed/scenes/heightfield/HeightFieldScene.h @@ -80,6 +80,9 @@ class HeightFieldScene : public SceneDemo { /// Height field HeightField* mHeightField; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + public: // -------------------- Methods -------------------- // @@ -92,6 +95,15 @@ class HeightFieldScene : public SceneDemo { /// Reset the scene virtual void reset() override ; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/hingejoint/HingeJointScene.cpp b/testbed/scenes/hingejoint/HingeJointScene.cpp index 4f0ee76c..36e7f7ea 100644 --- a/testbed/scenes/hingejoint/HingeJointScene.cpp +++ b/testbed/scenes/hingejoint/HingeJointScene.cpp @@ -41,11 +41,7 @@ HingeJointScene::HingeJointScene(const std::string& name, EngineSettings& settin // Set the center of the scene setScenePosition(center, SCENE_RADIUS); - // Gravity vector in the physics world - rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); - - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -53,51 +49,57 @@ HingeJointScene::HingeJointScene(const std::string& name, EngineSettings& settin static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); - - // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); - physicsWorld->setEventListener(this); - mPhysicsWorld = physicsWorld; - - // Create the Hinge joint - createHingeJoint(); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } // Destructor HingeJointScene::~HingeJointScene() { - // Destroy the joints - mPhysicsWorld->destroyJoint(mJoint); - - // Destroy all the rigid bodies of the scene - mPhysicsWorld->destroyRigidBody(mBox1->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mBox2->getRigidBody()); - - delete mBox1; - delete mBox2; - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + destroyPhysicsWorld(); } +// Create the physics world +void HingeJointScene::createPhysicsWorld() { + + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); + + // Create the physics world for the physics simulation + mPhysicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); + mPhysicsWorld->setEventListener(this); + + // Create the Hinge joint + createHingeJoint(); +} + +// Initialize the bodies positions +void HingeJointScene::initBodiesPositions() { + + mBox1->setTransform(rp3d::Transform(rp3d::Vector3(0, 4, 0), rp3d::Quaternion::identity())); + mBox2->setTransform(rp3d::Transform(rp3d::Vector3(4, 4, 0), rp3d::Quaternion::identity())); +} + +// Destroy the physics world +void HingeJointScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + delete mBox1; + delete mBox2; + + mPhysicsObjects.clear(); + + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } +} // Reset the scene void HingeJointScene::reset() { SceneDemo::reset(); - mBox1->setTransform(rp3d::Transform(rp3d::Vector3(0, 4, 0), rp3d::Quaternion::identity())); - mBox2->setTransform(rp3d::Transform(rp3d::Vector3(4, 4, 0), rp3d::Quaternion::identity())); + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); } /// Create the hinge joint diff --git a/testbed/scenes/hingejoint/HingeJointScene.h b/testbed/scenes/hingejoint/HingeJointScene.h index 4d64e32f..49f679ff 100644 --- a/testbed/scenes/hingejoint/HingeJointScene.h +++ b/testbed/scenes/hingejoint/HingeJointScene.h @@ -57,6 +57,9 @@ class HingeJointScene : public SceneDemo { /// Hinge joint rp3d::HingeJoint* mJoint; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + // -------------------- Methods -------------------- // /// Create the boxes and joint for the Hinge joint example @@ -74,6 +77,15 @@ class HingeJointScene : public SceneDemo { /// Reset the scene virtual void reset() override; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/hingejointschain/HingeJointsChainScene.cpp b/testbed/scenes/hingejointschain/HingeJointsChainScene.cpp index e6ebc47f..1ea40dad 100644 --- a/testbed/scenes/hingejointschain/HingeJointsChainScene.cpp +++ b/testbed/scenes/hingejointschain/HingeJointsChainScene.cpp @@ -46,8 +46,7 @@ HingeJointsChainScene::HingeJointsChainScene(const std::string& name, EngineSett // Gravity vector in the physics world rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -55,17 +54,29 @@ HingeJointsChainScene::HingeJointsChainScene(const std::string& name, EngineSett static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); +} + +// Destructor +HingeJointsChainScene::~HingeJointsChainScene() { + + destroyPhysicsWorld(); +} + +// Create the physics world +void HingeJointsChainScene::createPhysicsWorld() { + + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); - physicsWorld->setEventListener(this); - mPhysicsWorld = physicsWorld; + mPhysicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); + mPhysicsWorld->setEventListener(this); // Create all the boxes of the scene for (int i=0; i<NB_BOXES; i++) { // Create a box and a corresponding rigid in the physics world - mBoxes[i] = new Box(true, BOX_SIZE, mPhysicsCommon, mPhysicsWorld, meshFolderPath); + mBoxes[i] = new Box(true, BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); // Set the box color mBoxes[i]->setColor(mObjectColorDemo); @@ -84,64 +95,14 @@ HingeJointsChainScene::HingeJointsChainScene(const std::string& name, EngineSett } // Set the position of the boxes before the joints creation - reset(); + initBodiesPositions(); // Create the Ball-and-Socket joints createJoints(); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } -// Destructor -HingeJointsChainScene::~HingeJointsChainScene() { - - // Destroy the joints - for (uint i=0; i < mHingeJoints.size(); i++) { - - mPhysicsWorld->destroyJoint(mHingeJoints[i]); - } - - // Destroy all the rigid bodies of the scene - for (int i=0; i<NB_BOXES; i++) { - - mPhysicsWorld->destroyRigidBody(mBoxes[i]->getRigidBody()); - } - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); -} - -// Create the joints -void HingeJointsChainScene::createJoints() { - - for (int i=0; i < NB_BOXES-1; i++) { - - // Create the joint info object - rp3d::RigidBody* body1 = mBoxes[i]->getRigidBody(); - rp3d::RigidBody* body2 = mBoxes[i+1]->getRigidBody(); - rp3d::Vector3 body1Position = body1->getTransform().getPosition(); - rp3d::Vector3 body2Position = body2->getTransform().getPosition(); - const rp3d::Vector3 anchorPointWorldSpace = body1Position + rp3d::Vector3(BOX_SIZE.x / 2.0f, 0, 0); - rp3d::HingeJointInfo jointInfo(body1, body2, anchorPointWorldSpace, rp3d::Vector3(0, 0, 1)); - jointInfo.isCollisionEnabled = false; - rp3d::HingeJoint* joint = dynamic_cast<rp3d::HingeJoint*>(mPhysicsWorld->createJoint(jointInfo)); - mHingeJoints.push_back(joint); - } -} - -// Reset the scene -void HingeJointsChainScene::reset() { - - SceneDemo::reset(); +// Initialize the bodies positions +void HingeJointsChainScene::initBodiesPositions() { const float space = 0.3f; @@ -157,3 +118,49 @@ void HingeJointsChainScene::reset() { mBoxes[i]->setTransform(transform); } } + +// Destroy the physics world +void HingeJointsChainScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + // Destroy all the physics objects of the scene + for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + + // Destroy the object + delete (*it); + } + + mHingeJoints.clear(); + mPhysicsObjects.clear(); + + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } +} +// Create the joints +void HingeJointsChainScene::createJoints() { + + for (int i=0; i < NB_BOXES-1; i++) { + + // Create the joint info object + rp3d::RigidBody* body1 = mBoxes[i]->getRigidBody(); + rp3d::RigidBody* body2 = mBoxes[i+1]->getRigidBody(); + rp3d::Vector3 body1Position = body1->getTransform().getPosition(); + const rp3d::Vector3 anchorPointWorldSpace = body1Position + rp3d::Vector3(BOX_SIZE.x / 2.0f, 0, 0); + rp3d::HingeJointInfo jointInfo(body1, body2, anchorPointWorldSpace, rp3d::Vector3(0, 0, 1)); + jointInfo.isCollisionEnabled = false; + rp3d::HingeJoint* joint = dynamic_cast<rp3d::HingeJoint*>(mPhysicsWorld->createJoint(jointInfo)); + mHingeJoints.push_back(joint); + } +} + +// Reset the scene +void HingeJointsChainScene::reset() { + + SceneDemo::reset(); + + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); +} diff --git a/testbed/scenes/hingejointschain/HingeJointsChainScene.h b/testbed/scenes/hingejointschain/HingeJointsChainScene.h index ad37b612..5826309b 100644 --- a/testbed/scenes/hingejointschain/HingeJointsChainScene.h +++ b/testbed/scenes/hingejointschain/HingeJointsChainScene.h @@ -52,6 +52,9 @@ class HingeJointsChainScene : public SceneDemo { /// Hinge joints of the chain std::vector<rp3d::HingeJoint*> mHingeJoints; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + // -------------------- Methods -------------------- // /// Create the joints @@ -69,6 +72,15 @@ class HingeJointsChainScene : public SceneDemo { /// Reset the scene virtual void reset() override; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index fa4c54c6..b5e43c85 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -44,8 +44,7 @@ JointsScene::JointsScene(const std::string& name, EngineSettings& settings) // Gravity vector in the physics world rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -53,11 +52,33 @@ JointsScene::JointsScene(const std::string& name, EngineSettings& settings) static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); +} + +// Destructor +JointsScene::~JointsScene() { + + destroyPhysicsWorld(); +} + +// Update the physics world (take a simulation step) +void JointsScene::updatePhysics() { + + // Update the motor speed of the Slider Joint (to move up and down) + double motorSpeed = 2.0 * std::cos(mEngineSettings.elapsedTime.count() * 1.5); + mSliderJoint->setMotorSpeed(rp3d::decimal(motorSpeed)); + + SceneDemo::updatePhysics(); +} + +// Create the physics world +void JointsScene::createPhysicsWorld() { + + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); - physicsWorld->setEventListener(this); - mPhysicsWorld = physicsWorld; + mPhysicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); + mPhysicsWorld->setEventListener(this); // Create the Ball-and-Socket joint createBallAndSocketJoints(); @@ -73,72 +94,10 @@ JointsScene::JointsScene(const std::string& name, EngineSettings& settings) // Create the floor createFloor(); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } -// Destructor -JointsScene::~JointsScene() { - - // Destroy the joints - mPhysicsWorld->destroyJoint(mSliderJoint); - mPhysicsWorld->destroyJoint(mPropellerHingeJoint); - mPhysicsWorld->destroyJoint(mFixedJoint1); - mPhysicsWorld->destroyJoint(mFixedJoint2); - for (int i=0; i<NB_BALLSOCKETJOINT_BOXES-1; i++) { - mPhysicsWorld->destroyJoint(mBallAndSocketJoints[i]); - } - - // Destroy all the rigid bodies of the scene - mPhysicsWorld->destroyRigidBody(mSliderJointBottomBox->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mSliderJointTopBox->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mPropellerBox->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mFixedJointBox1->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mFixedJointBox2->getRigidBody()); - for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) { - mPhysicsWorld->destroyRigidBody(mBallAndSocketJointChainBoxes[i]->getRigidBody()); - } - - delete mSliderJointBottomBox; - delete mSliderJointTopBox; - delete mPropellerBox; - delete mFixedJointBox1; - delete mFixedJointBox2; - for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) { - delete mBallAndSocketJointChainBoxes[i]; - } - - // Destroy the floor - mPhysicsWorld->destroyRigidBody(mFloor->getRigidBody()); - delete mFloor; - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); -} - -// Update the physics world (take a simulation step) -void JointsScene::updatePhysics() { - - // Update the motor speed of the Slider Joint (to move up and down) - double motorSpeed = 2.0 * std::cos(mEngineSettings.elapsedTime.count() * 1.5); - mSliderJoint->setMotorSpeed(rp3d::decimal(motorSpeed)); - - SceneDemo::updatePhysics(); -} - -// Reset the scene -void JointsScene::reset() { - - SceneDemo::reset(); +// Initialize the bodies positions +void JointsScene::initBodiesPositions() { openglframework::Vector3 positionBox(0, 15, 5); openglframework::Vector3 boxDimension(1, 1, 1); @@ -208,6 +167,39 @@ void JointsScene::reset() { mFixedJointBox2->setTransform(transformFixedBox2); } +// Destroy the physics world +void JointsScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + delete mSliderJointBottomBox; + delete mSliderJointTopBox; + delete mPropellerBox; + delete mFixedJointBox1; + delete mFixedJointBox2; + for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) { + delete mBallAndSocketJointChainBoxes[i]; + } + + // Destroy the floor + delete mFloor; + + mPhysicsObjects.clear(); + + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } +} +// Reset the scene +void JointsScene::reset() { + + SceneDemo::reset(); + + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); +} + // Create the boxes and joints for the Ball-and-Socket joint example void JointsScene::createBallAndSocketJoints() { diff --git a/testbed/scenes/joints/JointsScene.h b/testbed/scenes/joints/JointsScene.h index 31a45a8c..8a946bb3 100644 --- a/testbed/scenes/joints/JointsScene.h +++ b/testbed/scenes/joints/JointsScene.h @@ -90,6 +90,9 @@ class JointsScene : public SceneDemo { /// Box for the floor Box* mFloor; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + // -------------------- Methods -------------------- // /// Create the boxes and joints for the Ball-and-Socket joint example @@ -123,6 +126,15 @@ class JointsScene : public SceneDemo { /// Reset the scene virtual void reset() override; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/pile/PileScene.cpp b/testbed/scenes/pile/PileScene.cpp index 636fe087..b3ef3bd3 100644 --- a/testbed/scenes/pile/PileScene.cpp +++ b/testbed/scenes/pile/PileScene.cpp @@ -42,11 +42,7 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings) // Set the center of the scene setScenePosition(center, SCENE_RADIUS); - // Gravity vector in the physics world - rp3d::Vector3 gravity(0, -9.81f, 0); - - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -54,14 +50,29 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings) static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); +} + +// Destructor +PileScene::~PileScene() { + + destroyPhysicsWorld(); +} + +// Create the physics world +void PileScene::createPhysicsWorld() { + + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); // Create the physics world for the physics simulation - mPhysicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); + rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); + physicsWorld->setEventListener(this); + mPhysicsWorld = physicsWorld; for (int i=0; i<NB_COMPOUND_SHAPES; i++) { // Create a convex mesh and a corresponding rigid in the physics world - Dumbbell* dumbbell = new Dumbbell(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath); + Dumbbell* dumbbell = new Dumbbell(true, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); // Set the box color dumbbell->setColor(mObjectColorDemo); @@ -103,7 +114,7 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings) for (int i=0; i<NB_SPHERES; i++) { // Create a sphere and a corresponding rigid in the physics world - Sphere* sphere = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, meshFolderPath); + Sphere* sphere = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); // Set the box color sphere->setColor(mObjectColorDemo); @@ -123,7 +134,7 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings) // Create a cylinder and a corresponding rigid in the physics world Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT, - mPhysicsCommon, mPhysicsWorld, meshFolderPath); + mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); // Set the box color capsule->setColor(mObjectColorDemo); @@ -142,7 +153,7 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings) for (int i=0; i<NB_MESHES; i++) { // Create a convex mesh and a corresponding rigid in the physics world - ConvexMesh* mesh = new ConvexMesh(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj"); + ConvexMesh* mesh = new ConvexMesh(true, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj"); // Set the box color mesh->setColor(mObjectColorDemo); @@ -160,7 +171,7 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings) // ---------- Create the triangular mesh ---------- // // Create a convex mesh and a corresponding rigid in the physics world - mSandbox = new ConcaveMesh(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "sandbox.obj"); + mSandbox = new ConcaveMesh(true, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "sandbox.obj"); // Set the mesh as beeing static mSandbox->getRigidBody()->setType(rp3d::BodyType::STATIC); @@ -175,38 +186,10 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings) rp3d::Material& material = mSandbox->getCollider()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); material.setFrictionCoefficient(rp3d::decimal(0.1)); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } -// Destructor -PileScene::~PileScene() { - - // Destroy all the physics objects of the scene - for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { - - // Destroy the corresponding rigid body from the physics world - mPhysicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the object - delete (*it); - } - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); -} - -/// Reset the scene -void PileScene::reset() { +// Initialize the bodies positions +void PileScene::initBodiesPositions() { const float radius = 3.0f; @@ -273,3 +256,36 @@ void PileScene::reset() { mSandbox->setTransform(rp3d::Transform::identity()); } + +// Destroy the physics world +void PileScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + // Destroy all the physics objects of the scene + for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + + // Destroy the object + delete (*it); + } + mBoxes.clear(); + mSpheres.clear(); + mCapsules.clear(); + mConvexMeshes.clear(); + mDumbbells.clear(); + + mPhysicsObjects.clear(); + + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } +} +/// Reset the scene +void PileScene::reset() { + + SceneDemo::reset(); + + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); +} diff --git a/testbed/scenes/pile/PileScene.h b/testbed/scenes/pile/PileScene.h index f32cf1d3..1cb12b9c 100644 --- a/testbed/scenes/pile/PileScene.h +++ b/testbed/scenes/pile/PileScene.h @@ -81,6 +81,9 @@ class PileScene : public SceneDemo { /// Sandbox for the floor ConcaveMesh* mSandbox; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + public: // -------------------- Methods -------------------- // @@ -93,6 +96,15 @@ class PileScene : public SceneDemo { /// Reset the scene virtual void reset() override; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/ragdoll/RagdollScene.cpp b/testbed/scenes/ragdoll/RagdollScene.cpp index 2b959378..72190da1 100644 --- a/testbed/scenes/ragdoll/RagdollScene.cpp +++ b/testbed/scenes/ragdoll/RagdollScene.cpp @@ -41,11 +41,7 @@ RagdollScene::RagdollScene(const std::string& name, EngineSettings& settings) // Set the center of the scene setScenePosition(center, SCENE_RADIUS); - // Gravity vector in the physics world - rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); - - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -53,11 +49,23 @@ RagdollScene::RagdollScene(const std::string& name, EngineSettings& settings) static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); +} + +// Destructor +RagdollScene::~RagdollScene() { + + destroyPhysicsWorld(); +} + +// Create the physics world +void RagdollScene::createPhysicsWorld() { + + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); - physicsWorld->setEventListener(this); - mPhysicsWorld = physicsWorld; + mPhysicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); + mPhysicsWorld->setEventListener(this); // Create the ragdoll createRagdolls(); @@ -100,74 +108,10 @@ RagdollScene::RagdollScene(const std::string& name, EngineSettings& settings) mInclinedPlaneBox->setSleepingColor(mFloorColorDemo); mInclinedPlaneBox->getRigidBody()->setType(rp3d::BodyType::STATIC); mPhysicsObjects.push_back(mInclinedPlaneBox); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } -// Destructor -RagdollScene::~RagdollScene() { - - // For each ragdoll - for (int i=0; i < NB_RAGDOLLS; i++) { - - // Destroy the joints - mPhysicsWorld->destroyJoint(mHeadTorsoJoint[i]); - mPhysicsWorld->destroyJoint(mTorsoLeftUpperArmJoint[i]); - mPhysicsWorld->destroyJoint(mLeftUpperLeftLowerArmJoint[i]); - mPhysicsWorld->destroyJoint(mTorsoLeftUpperLegJoint[i]); - mPhysicsWorld->destroyJoint(mLeftUpperLeftLowerLegJoint[i]); - mPhysicsWorld->destroyJoint(mTorsoRightUpperArmJoint[i]); - mPhysicsWorld->destroyJoint(mRightUpperRightLowerArmJoint[i]); - mPhysicsWorld->destroyJoint(mTorsoRightUpperLegJoint[i]); - mPhysicsWorld->destroyJoint(mRightUpperRightLowerLegJoint[i]); - - // Destroy all the rigid bodies of the scene - mPhysicsWorld->destroyRigidBody(mHeadBox[i]->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mTorsoBox[i]->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mLeftUpperArmBox[i]->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mLeftLowerArmBox[i]->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mLeftUpperLegBox[i]->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mLeftLowerLegBox[i]->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mRightUpperArmBox[i]->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mRightLowerArmBox[i]->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mRightUpperLegBox[i]->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mRightLowerLegBox[i]->getRigidBody()); - - delete mHeadBox[i]; - delete mTorsoBox[i]; - delete mLeftUpperArmBox[i]; - delete mLeftLowerArmBox[i]; - delete mLeftUpperLegBox[i]; - delete mLeftLowerLegBox[i]; - delete mRightUpperArmBox[i]; - delete mRightLowerArmBox[i]; - delete mRightUpperLegBox[i]; - delete mRightLowerLegBox[i]; - } - - mPhysicsWorld->destroyRigidBody(mFloor1->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mFloor2->getRigidBody()); - - delete mFloor1; - delete mFloor2; - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); -} - -// Reset the scene -void RagdollScene::reset() { - - SceneDemo::reset(); +// Initialize the bodies positions +void RagdollScene::initBodiesPositions() { // For each ragdoll for (int i=0; i < NB_RAGDOLLS; i++) { @@ -185,6 +129,45 @@ void RagdollScene::reset() { } } +// Destroy the physics world +void RagdollScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + // For each ragdoll + for (int i=0; i < NB_RAGDOLLS; i++) { + + delete mHeadBox[i]; + delete mTorsoBox[i]; + delete mLeftUpperArmBox[i]; + delete mLeftLowerArmBox[i]; + delete mLeftUpperLegBox[i]; + delete mLeftLowerLegBox[i]; + delete mRightUpperArmBox[i]; + delete mRightLowerArmBox[i]; + delete mRightUpperLegBox[i]; + delete mRightLowerLegBox[i]; + } + + delete mFloor1; + delete mFloor2; + + mPhysicsObjects.clear(); + + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } +} +// Reset the scene +void RagdollScene::reset() { + + SceneDemo::reset(); + + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); +} + // Create the boxes and joints for the ragdoll void RagdollScene::createRagdolls() { diff --git a/testbed/scenes/ragdoll/RagdollScene.h b/testbed/scenes/ragdoll/RagdollScene.h index ddb81e26..d3186329 100644 --- a/testbed/scenes/ragdoll/RagdollScene.h +++ b/testbed/scenes/ragdoll/RagdollScene.h @@ -132,6 +132,9 @@ class RagdollScene : public SceneDemo { rp3d::Vector3 mRightUpperLegPos[NB_RAGDOLLS]; rp3d::Vector3 mRightLowerLegPos[NB_RAGDOLLS]; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + // -------------------- Methods -------------------- // /// Create the bodies and joints for the ragdoll @@ -149,6 +152,15 @@ class RagdollScene : public SceneDemo { /// Reset the scene virtual void reset() override; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index 338d4ce3..f13cc6cc 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -212,42 +212,12 @@ void RaycastScene::reset() { // Destructor RaycastScene::~RaycastScene() { - // Destroy the box rigid body from the physics world - mPhysicsWorld->destroyCollisionBody(mBox->getCollisionBody()); delete mBox; - - // Destroy the sphere - mPhysicsWorld->destroyCollisionBody(mSphere->getCollisionBody()); delete mSphere; - - // Destroy the corresponding rigid body from the physics world - mPhysicsWorld->destroyCollisionBody(mCapsule->getCollisionBody()); - - // Destroy the sphere delete mCapsule; - - // Destroy the corresponding rigid body from the physics world - mPhysicsWorld->destroyCollisionBody(mConvexMesh->getCollisionBody()); - - // Destroy the convex mesh delete mConvexMesh; - - // Destroy the corresponding rigid body from the physics world - mPhysicsWorld->destroyCollisionBody(mDumbbell->getCollisionBody()); - - // Destroy the dumbbell delete mDumbbell; - - // Destroy the corresponding rigid body from the physics world - mPhysicsWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody()); - - // Destroy the convex mesh delete mConcaveMesh; - - // Destroy the corresponding rigid body from the physics world - mPhysicsWorld->destroyCollisionBody(mHeightField->getCollisionBody()); - - // Destroy the convex mesh delete mHeightField; mRaycastManager.resetPoints(); diff --git a/testbed/scenes/rope/RopeScene.cpp b/testbed/scenes/rope/RopeScene.cpp index 748e12f5..cea1c720 100644 --- a/testbed/scenes/rope/RopeScene.cpp +++ b/testbed/scenes/rope/RopeScene.cpp @@ -45,14 +45,7 @@ RopeScene::RopeScene(const std::string& name, EngineSettings& settings) // Set the center of the scene setScenePosition(center, SCENE_RADIUS); - // Gravity vector in the physics world - rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); - - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; - - const float linearDamping = 0.03f; - const float angularDamping = 0.03f; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -60,143 +53,12 @@ RopeScene::RopeScene(const std::string& name, EngineSettings& settings) static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); - - // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); - physicsWorld->setEventListener(this); - mPhysicsWorld = physicsWorld; - - // ---------- Create the ropes --------- // - - for (int r=0; r < NB_ROPES; r++) { - - // Create all the capsules of the scene - for (int i=0; i<NB_CAPSULES_PER_ROPE; i++) { - - const uint capsuleIndex = r * NB_CAPSULES_PER_ROPE + i; - - // Create a capsule and a corresponding rigid in the physics world - mCapsules[capsuleIndex] = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, meshFolderPath); - - // Set the capsule color - mCapsules[capsuleIndex]->setColor(mObjectColorDemo); - mCapsules[capsuleIndex]->setSleepingColor(mSleepingColorDemo); - - // Change the material properties of the rigid body - rp3d::Material& material = mCapsules[capsuleIndex]->getCollider()->getMaterial(); - material.setBounciness(rp3d::decimal(0.0)); - material.setMassDensity(rp3d::decimal(0.1)); - - mCapsules[capsuleIndex]->getRigidBody()->setAngularDamping(angularDamping); - mCapsules[capsuleIndex]->getRigidBody()->setLinearDamping(linearDamping); - - if (i == 0) { - mCapsules[capsuleIndex]->getRigidBody()->setType(rp3d::BodyType::STATIC); - } - - // Add the capsule the list of capsules in the scene - mPhysicsObjects.push_back(mCapsules[capsuleIndex]); - } - } - - // ---------- Create the first box --------- // - - // Create a box and a corresponding rigid in the physics world - mBox1 = new Box(true, Vector3(BOX_SIZE, BOX_SIZE, BOX_SIZE), mPhysicsCommon, mPhysicsWorld, meshFolderPath); - mBox1->getRigidBody()->setAngularDamping(angularDamping); - mBox1->getRigidBody()->setLinearDamping(linearDamping); - - // Set the box color - mBox1->setColor(mObjectColorDemo); - mBox1->setSleepingColor(mSleepingColorDemo); - - // Change the material properties of the rigid body - rp3d::Material& material1 = mBox1->getCollider()->getMaterial(); - material1.setBounciness(rp3d::decimal(0.0)); - material1.setMassDensity(rp3d::decimal(0.02)); - mBox1->getRigidBody()->updateMassPropertiesFromColliders(); - - std::cout << "Mass: " << mBox1->getRigidBody()->getMass() << std::endl; - - mPhysicsObjects.push_back(mBox1); - - // ---------- Create the second box --------- // - - // Create a box and a corresponding rigid in the physics world - mBox2 = new Box(true, Vector3(BOX_SIZE, BOX_SIZE, BOX_SIZE), mPhysicsCommon, mPhysicsWorld, meshFolderPath); - mBox2->getRigidBody()->setAngularDamping(angularDamping); - mBox2->getRigidBody()->setLinearDamping(linearDamping); - - // Set the box color - mBox2->setColor(mObjectColorDemo); - mBox2->setSleepingColor(mSleepingColorDemo); - - // Change the material properties of the rigid body - rp3d::Material& material2 = mBox2->getCollider()->getMaterial(); - material2.setBounciness(rp3d::decimal(0.0)); - material2.setMassDensity(rp3d::decimal(0.7)); - mBox2->getRigidBody()->updateMassPropertiesFromColliders(); - - mPhysicsObjects.push_back(mBox2); - - // ---------- Create plank box --------- // - - // Create a box and a corresponding rigid in the physics world - mPlank = new Box(true, Vector3(10, 2, 15), mPhysicsCommon, mPhysicsWorld, meshFolderPath); - mPlank->getRigidBody()->setType(rp3d::BodyType::STATIC); - - // Set the box color - mPlank->setColor(mObjectColorDemo); - mPlank->setSleepingColor(mSleepingColorDemo); - - // Change the material properties of the rigid body - rp3d::Material& material3 = mPlank->getCollider()->getMaterial(); - material3.setBounciness(rp3d::decimal(0.5)); - - mPhysicsObjects.push_back(mPlank); - - // Initialize the bodies positions - initializeBodiesPositions(); - - // Create the Ball-and-Socket joints - createJoints(); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } // Destructor RopeScene::~RopeScene() { - // Destroy the joints - for (uint i=0; i < mBallAndSocketJoints.size(); i++) { - - mPhysicsWorld->destroyJoint(mBallAndSocketJoints[i]); - } - - // Destroy all the rigid bodies of the scene - for (int r=0; r < NB_ROPES; r++) { - for (int i=0; i<NB_CAPSULES_PER_ROPE; i++) { - - const uint capsuleIndex = r * NB_CAPSULES_PER_ROPE + i; - mPhysicsWorld->destroyRigidBody(mCapsules[capsuleIndex]->getRigidBody()); - } - } - - // Destroy the boxes - mPhysicsWorld->destroyRigidBody(mBox1->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mBox2->getRigidBody()); - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + destroyPhysicsWorld(); } // Create the joints @@ -232,7 +94,7 @@ void RopeScene::createJoints() { } } -void RopeScene::initializeBodiesPositions() { +void RopeScene::initBodiesPositions() { rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); @@ -274,15 +136,117 @@ void RopeScene::initializeBodiesPositions() { mPlank->setTransform(plankTransform); } -// Reset the scene -void RopeScene::reset() { +// Create the physics world +void RopeScene::createPhysicsWorld() { - SceneDemo::reset(); + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); + + // Create the physics world for the physics simulation + mPhysicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); + mPhysicsWorld->setEventListener(this); + + const float linearDamping = 0.03f; + const float angularDamping = 0.03f; + + // ---------- Create the ropes --------- // + + for (int r=0; r < NB_ROPES; r++) { + + // Create all the capsules of the scene + for (int i=0; i<NB_CAPSULES_PER_ROPE; i++) { + + const uint capsuleIndex = r * NB_CAPSULES_PER_ROPE + i; + + // Create a capsule and a corresponding rigid in the physics world + mCapsules[capsuleIndex] = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); + + // Set the capsule color + mCapsules[capsuleIndex]->setColor(mObjectColorDemo); + mCapsules[capsuleIndex]->setSleepingColor(mSleepingColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = mCapsules[capsuleIndex]->getCollider()->getMaterial(); + material.setBounciness(rp3d::decimal(0.0)); + material.setMassDensity(rp3d::decimal(0.1)); + + mCapsules[capsuleIndex]->getRigidBody()->setAngularDamping(angularDamping); + mCapsules[capsuleIndex]->getRigidBody()->setLinearDamping(linearDamping); + + if (i == 0) { + mCapsules[capsuleIndex]->getRigidBody()->setType(rp3d::BodyType::STATIC); + } + + // Add the capsule the list of capsules in the scene + mPhysicsObjects.push_back(mCapsules[capsuleIndex]); + } + } + + // ---------- Create the first box --------- // + + // Create a box and a corresponding rigid in the physics world + mBox1 = new Box(true, Vector3(BOX_SIZE, BOX_SIZE, BOX_SIZE), mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); + mBox1->getRigidBody()->setAngularDamping(angularDamping); + mBox1->getRigidBody()->setLinearDamping(linearDamping); + + // Set the box color + mBox1->setColor(mObjectColorDemo); + mBox1->setSleepingColor(mSleepingColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material1 = mBox1->getCollider()->getMaterial(); + material1.setBounciness(rp3d::decimal(0.0)); + material1.setMassDensity(rp3d::decimal(0.02)); + mBox1->getRigidBody()->updateMassPropertiesFromColliders(); + + std::cout << "Mass: " << mBox1->getRigidBody()->getMass() << std::endl; + + mPhysicsObjects.push_back(mBox1); + + // ---------- Create the second box --------- // + + // Create a box and a corresponding rigid in the physics world + mBox2 = new Box(true, Vector3(BOX_SIZE, BOX_SIZE, BOX_SIZE), mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); + mBox2->getRigidBody()->setAngularDamping(angularDamping); + mBox2->getRigidBody()->setLinearDamping(linearDamping); + + // Set the box color + mBox2->setColor(mObjectColorDemo); + mBox2->setSleepingColor(mSleepingColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material2 = mBox2->getCollider()->getMaterial(); + material2.setBounciness(rp3d::decimal(0.0)); + material2.setMassDensity(rp3d::decimal(0.7)); + mBox2->getRigidBody()->updateMassPropertiesFromColliders(); + + mPhysicsObjects.push_back(mBox2); + + // ---------- Create plank box --------- // + + // Create a box and a corresponding rigid in the physics world + mPlank = new Box(true, Vector3(10, 2, 15), mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); + mPlank->getRigidBody()->setType(rp3d::BodyType::STATIC); + + // Set the box color + mPlank->setColor(mObjectColorDemo); + mPlank->setSleepingColor(mSleepingColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material3 = mPlank->getCollider()->getMaterial(); + material3.setBounciness(rp3d::decimal(0.5)); + + mPhysicsObjects.push_back(mPlank); // Initialize the bodies positions - initializeBodiesPositions(); + initBodiesPositions(); - nbIterations = 0; + // Create the Ball-and-Socket joints + createJoints(); +} + +// Move the first rope to an horizontal position +void RopeScene::moveFirstRopeToHorizontalPosition() { // ---------- Move the first rope in a horizontal position ---------- // @@ -306,6 +270,39 @@ void RopeScene::reset() { mBox1->setTransform(box1Transform); } +// Destroy the physics world +void RopeScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + // Destroy all the physics objects of the scene + for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + + // Destroy the object + delete (*it); + } + + mBallAndSocketJoints.clear(); + mPhysicsObjects.clear(); + + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } +} + +// Reset the scene +void RopeScene::reset() { + + SceneDemo::reset(); + + nbIterations = 0; + + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); + moveFirstRopeToHorizontalPosition(); +} + /// Update the physics world (take a simulation step) /// Can be called several times per frame void RopeScene::updatePhysics() { diff --git a/testbed/scenes/rope/RopeScene.h b/testbed/scenes/rope/RopeScene.h index 4a30380d..f8825c95 100644 --- a/testbed/scenes/rope/RopeScene.h +++ b/testbed/scenes/rope/RopeScene.h @@ -68,6 +68,9 @@ class RopeScene : public SceneDemo { int nbIterations; int nbTorqueIterations; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + // -------------------- Methods -------------------- // /// Create the joints @@ -90,8 +93,17 @@ class RopeScene : public SceneDemo { /// Can be called several times per frame virtual void updatePhysics() override; - /// Initialize the positions of bodies - void initializeBodiesPositions(); + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); + + /// Move the first rope to an horizontal position + void moveFirstRopeToHorizontalPosition(); }; } diff --git a/testbed/scenes/sliderjoint/SliderJointScene.cpp b/testbed/scenes/sliderjoint/SliderJointScene.cpp index e660c125..c726ddcb 100644 --- a/testbed/scenes/sliderjoint/SliderJointScene.cpp +++ b/testbed/scenes/sliderjoint/SliderJointScene.cpp @@ -41,11 +41,7 @@ SliderJointScene::SliderJointScene(const std::string& name, EngineSettings& sett // Set the center of the scene setScenePosition(center, SCENE_RADIUS); - // Gravity vector in the physics world - rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); - - rp3d::PhysicsWorld::WorldSettings worldSettings; - worldSettings.worldName = name; + mWorldSettings.worldName = name; // Logger rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); @@ -53,49 +49,30 @@ SliderJointScene::SliderJointScene(const std::string& name, EngineSettings& sett static_cast<uint>(rp3d::Logger::Level::Error); defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); mPhysicsCommon.setLogger(defaultLogger); - - // Create the physics world for the physics simulation - rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); - physicsWorld->setEventListener(this); - mPhysicsWorld = physicsWorld; - - // Create the Slider joint - createSliderJoint(); - - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); - mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); - mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); - mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); - mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); - mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); - mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); - mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); } // Destructor SliderJointScene::~SliderJointScene() { - // Destroy the joints - mPhysicsWorld->destroyJoint(mJoint); - - // Destroy all the rigid bodies of the scene - mPhysicsWorld->destroyRigidBody(mBox1->getRigidBody()); - mPhysicsWorld->destroyRigidBody(mBox2->getRigidBody()); - - delete mBox1; - delete mBox2; - - // Destroy the physics world - mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + destroyPhysicsWorld(); } +// Create the physics world +void SliderJointScene::createPhysicsWorld() { -// Reset the scene -void SliderJointScene::reset() { + // Gravity vector in the physics world + mWorldSettings.gravity = rp3d::Vector3(mEngineSettings.gravity.x, mEngineSettings.gravity.y, mEngineSettings.gravity.z); - SceneDemo::reset(); + // Create the physics world for the physics simulation + mPhysicsWorld = mPhysicsCommon.createPhysicsWorld(mWorldSettings); + mPhysicsWorld->setEventListener(this); + + // Create the Slider joint + createSliderJoint(); +} + +// Initialize the bodies positions +void SliderJointScene::initBodiesPositions() { rp3d::Transform transform1(rp3d::Vector3(0,4,0), rp3d::Quaternion::identity()); mBox1->setTransform(transform1); @@ -104,6 +81,31 @@ void SliderJointScene::reset() { mBox2->setTransform(transform2); } +// Destroy the physics world +void SliderJointScene::destroyPhysicsWorld() { + + if (mPhysicsWorld != nullptr) { + + delete mBox1; + delete mBox2; + + mPhysicsObjects.clear(); + + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); + mPhysicsWorld = nullptr; + } +} + +// Reset the scene +void SliderJointScene::reset() { + + SceneDemo::reset(); + + destroyPhysicsWorld(); + createPhysicsWorld(); + initBodiesPositions(); +} + /// Create the boxes and joint for the Slider joint example void SliderJointScene::createSliderJoint() { diff --git a/testbed/scenes/sliderjoint/SliderJointScene.h b/testbed/scenes/sliderjoint/SliderJointScene.h index 24d97e47..70d7f25b 100644 --- a/testbed/scenes/sliderjoint/SliderJointScene.h +++ b/testbed/scenes/sliderjoint/SliderJointScene.h @@ -54,6 +54,9 @@ class SliderJointScene : public SceneDemo { /// Slider joint rp3d::SliderJoint* mJoint; + /// World settings + rp3d::PhysicsWorld::WorldSettings mWorldSettings; + // -------------------- Methods -------------------- // /// Create a slider joint @@ -71,6 +74,15 @@ class SliderJointScene : public SceneDemo { /// Reset the scene virtual void reset() override; + + /// Create the physics world + void createPhysicsWorld(); + + /// Destroy the physics world + void destroyPhysicsWorld(); + + /// Initialize the bodies positions + void initBodiesPositions(); }; } diff --git a/testbed/src/Scene.h b/testbed/src/Scene.h index f2abf56e..04740479 100644 --- a/testbed/src/Scene.h +++ b/testbed/src/Scene.h @@ -83,6 +83,7 @@ struct EngineSettings { defaultSettings.sleepLinearVelocity = worldSettings.defaultSleepLinearVelocity; defaultSettings.sleepAngularVelocity = worldSettings.defaultSleepAngularVelocity; defaultSettings.isGravityEnabled = true; + defaultSettings.gravity = openglframework::Vector3(0, -9.81, 0); return defaultSettings; } @@ -274,6 +275,7 @@ inline void Scene::reshape(int width, int height) { // Reset the scene inline void Scene::reset() { + mEngineSettings.elapsedTime = std::chrono::milliseconds::zero(); mSnapshotsContactPoints.clear(); } diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index 44ed54d8..75cf1ac4 100755 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -173,6 +173,10 @@ void TestbedApplication::createScenes() { PileScene* pileScene = new PileScene("Pile", mDefaultEngineSettings); mScenes.push_back(pileScene); + // Ball and Socket joint scene + BallAndSocketJointScene* ballAndSocketJointScene = new BallAndSocketJointScene("Ball and Socket joint", mDefaultEngineSettings); + mScenes.push_back(ballAndSocketJointScene); + // Box Tower scene BoxTowerScene* boxTowerScene = new BoxTowerScene("Box Tower", mDefaultEngineSettings); mScenes.push_back(boxTowerScene); @@ -197,10 +201,6 @@ void TestbedApplication::createScenes() { FixedJointScene* fixedJointScene = new FixedJointScene("Fixed joint", mDefaultEngineSettings); mScenes.push_back(fixedJointScene); - // Ball and Socket joint scene - BallAndSocketJointScene* ballAndSocketJointScene = new BallAndSocketJointScene("Ball and Socket joint", mDefaultEngineSettings); - mScenes.push_back(ballAndSocketJointScene); - // Hinge joint scene HingeJointScene* hingeJointScene = new HingeJointScene("Hinge joint", mDefaultEngineSettings); mScenes.push_back(hingeJointScene); @@ -360,6 +360,8 @@ void TestbedApplication::switchScene(Scene* newScene) { mCurrentScene = newScene; + mTimer.reset(); + // Reset the scene mCurrentScene->reset(); diff --git a/testbed/src/TestbedApplication.h b/testbed/src/TestbedApplication.h index df2dd1cf..70824dbb 100644 --- a/testbed/src/TestbedApplication.h +++ b/testbed/src/TestbedApplication.h @@ -251,6 +251,7 @@ inline void TestbedApplication::pauseSimulation() { // Restart the simulation inline void TestbedApplication::restartSimulation() { + mTimer.reset(); mCurrentScene->reset(); mTimer.start(); } diff --git a/testbed/src/Timer.h b/testbed/src/Timer.h index 81013284..c11d0a73 100644 --- a/testbed/src/Timer.h +++ b/testbed/src/Timer.h @@ -85,6 +85,9 @@ class Timer { /// Stop the timer void stop(); + /// Reset the timer to zero + void reset(); + /// Return true if the timer is running bool isRunning() const; @@ -132,6 +135,13 @@ inline void Timer::stop() { mIsRunning = false; } +// Reset the timer to zero +inline void Timer::reset() { + mAccumulator = std::chrono::milliseconds::zero(); + mStartTime = clock::now(); + mLastUpdateTime = mStartTime; +} + // True if it's possible to take a new step inline bool Timer::isPossibleToTakeStep(std::chrono::duration<double> timeStep) const { return (mAccumulator >= timeStep);