From b1aad2b7c493e6b46cf28e138b65d522ae624333 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Thu, 19 Oct 2017 17:42:21 +0200 Subject: [PATCH] Refactor the testbed application --- testbed/common/Box.h | 2 +- testbed/common/Capsule.h | 3 +- testbed/common/ConvexMesh.h | 3 +- testbed/common/Dumbbell.h | 4 +- testbed/common/PhysicsObject.h | 3 + testbed/common/Sphere.h | 3 +- .../CollisionDetectionScene.cpp | 60 ++---- .../CollisionDetectionScene.h | 10 +- .../collisionshapes/CollisionShapesScene.cpp | 154 +------------- .../collisionshapes/CollisionShapesScene.h | 9 +- testbed/scenes/cubes/CubesScene.cpp | 35 +--- testbed/scenes/cubes/CubesScene.h | 7 - .../scenes/heightfield/HeightFieldScene.cpp | 191 +++++++++++++----- testbed/scenes/heightfield/HeightFieldScene.h | 47 ++++- testbed/scenes/joints/JointsScene.cpp | 27 +-- testbed/scenes/joints/JointsScene.h | 3 - testbed/scenes/raycast/RaycastScene.cpp | 33 +-- testbed/scenes/raycast/RaycastScene.h | 6 +- testbed/src/SceneDemo.cpp | 32 ++- testbed/src/SceneDemo.h | 10 +- testbed/src/TestbedApplication.cpp | 2 +- 21 files changed, 281 insertions(+), 363 deletions(-) mode change 100644 => 100755 testbed/scenes/cubes/CubesScene.cpp mode change 100644 => 100755 testbed/scenes/cubes/CubesScene.h diff --git a/testbed/common/Box.h b/testbed/common/Box.h index a1f05d5e..bd7a6024 100644 --- a/testbed/common/Box.h +++ b/testbed/common/Box.h @@ -86,7 +86,7 @@ class Box : public PhysicsObject { ~Box(); /// Render the cube at the correct position and with the correct orientation - void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix, bool wireframe); + virtual void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) override; /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; diff --git a/testbed/common/Capsule.h b/testbed/common/Capsule.h index f117984f..5c99120b 100644 --- a/testbed/common/Capsule.h +++ b/testbed/common/Capsule.h @@ -94,8 +94,7 @@ class Capsule : public PhysicsObject { ~Capsule(); /// Render the sphere at the correct position and with the correct orientation - void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix, bool wireframe); + virtual void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) override; /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; diff --git a/testbed/common/ConvexMesh.h b/testbed/common/ConvexMesh.h index e2ba5836..1b55611b 100644 --- a/testbed/common/ConvexMesh.h +++ b/testbed/common/ConvexMesh.h @@ -90,8 +90,7 @@ class ConvexMesh : public PhysicsObject { ~ConvexMesh(); /// Render the mesh at the correct position and with the correct orientation - void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix, bool wireframe); + virtual void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) override; /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; diff --git a/testbed/common/Dumbbell.h b/testbed/common/Dumbbell.h index ea2d3d88..aa6bded1 100644 --- a/testbed/common/Dumbbell.h +++ b/testbed/common/Dumbbell.h @@ -89,13 +89,11 @@ class Dumbbell : public PhysicsObject { Dumbbell(const openglframework::Vector3& position, rp3d::CollisionWorld* world, const std::string& meshFolderPath); - /// Destructor ~Dumbbell(); /// Render the sphere at the correct position and with the correct orientation - void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix, bool wireframe); + virtual void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) override; /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; diff --git a/testbed/common/PhysicsObject.h b/testbed/common/PhysicsObject.h index 0da224c3..7fcc612d 100644 --- a/testbed/common/PhysicsObject.h +++ b/testbed/common/PhysicsObject.h @@ -62,6 +62,9 @@ class PhysicsObject : public openglframework::Mesh { /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor)=0; + /// Render the sphere at the correct position and with the correct orientation + virtual void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix, bool wireframe)=0; + /// Set the color of the box void setColor(const openglframework::Color& color); diff --git a/testbed/common/Sphere.h b/testbed/common/Sphere.h index 62f1809e..000cc776 100644 --- a/testbed/common/Sphere.h +++ b/testbed/common/Sphere.h @@ -90,8 +90,7 @@ class Sphere : public PhysicsObject { ~Sphere(); /// Render the sphere at the correct position and with the correct orientation - void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix, bool wireframe); + void virtual render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) override; /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; diff --git a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp index 7606a61e..3b186943 100755 --- a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp +++ b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp @@ -59,6 +59,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) // Set the color mSphere1->setColor(mGreyColorDemo); mSphere1->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mSphere1); // ---------- Sphere 2 ---------- // openglframework::Vector3 position2(12, 8, 0); @@ -70,6 +71,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) // Set the color mSphere2->setColor(mGreyColorDemo); mSphere2->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mSphere2); // ---------- Capsule 1 ---------- // openglframework::Vector3 position3(-6, 7, 0); @@ -81,6 +83,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) // Set the color mCapsule1->setColor(mGreyColorDemo); mCapsule1->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mCapsule1); // ---------- Capsule 2 ---------- // openglframework::Vector3 position4(11, -8, 0); @@ -92,6 +95,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) // Set the color mCapsule2->setColor(mGreyColorDemo); mCapsule2->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mCapsule2); // ---------- Box 1 ---------- // openglframework::Vector3 position5(-4, -7, 0); @@ -103,6 +107,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) // Set the color mBox1->setColor(mGreyColorDemo); mBox1->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mBox1); // ---------- Box 2 ---------- // openglframework::Vector3 position6(0, 8, 0); @@ -114,6 +119,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) // Set the color mBox2->setColor(mGreyColorDemo); mBox2->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mBox2); // ---------- Convex Mesh ---------- // openglframework::Vector3 position7(-5, 0, 0); @@ -125,9 +131,10 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) // Set the color mConvexMesh->setColor(mGreyColorDemo); mConvexMesh->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mConvexMesh); // ---------- Concave Mesh ---------- // - openglframework::Vector3 position8(0, 0, 0); + openglframework::Vector3 position8(0, 100, 0); // Create a convex mesh and a corresponding collision body in the dynamics world mConcaveMesh = new ConcaveMesh(position8, mCollisionWorld, mMeshFolderPath + "city.obj"); @@ -136,16 +143,18 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) // Set the color mConcaveMesh->setColor(mGreyColorDemo); mConcaveMesh->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mConcaveMesh); // ---------- Heightfield ---------- // - //openglframework::Vector3 position9(0, 0, 0); + openglframework::Vector3 position9(0, -12, 0); // Create a convex mesh and a corresponding collision body in the dynamics world - //mHeightField = new HeightField(position9, mCollisionWorld); + mHeightField = new HeightField(position9, mCollisionWorld); // Set the color - //mHeightField->setColor(mGreyColorDemo); - //mHeightField->setSleepingColor(mRedColorDemo); + mHeightField->setColor(mGreyColorDemo); + mHeightField->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mHeightField); mAllShapes[mSelectedShapeIndex]->setColor(mBlueColorDemo); } @@ -187,6 +196,9 @@ CollisionDetectionScene::~CollisionDetectionScene() { mCollisionWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody()); delete mConcaveMesh; + mCollisionWorld->destroyCollisionBody(mHeightField->getCollisionBody()); + delete mHeightField; + /* // Destroy the corresponding rigid body from the dynamics world mCollisionWorld->destroyCollisionBody(mCone->getCollisionBody()); @@ -210,11 +222,7 @@ CollisionDetectionScene::~CollisionDetectionScene() { // Destroy the dumbbell delete mDumbbell; - // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mHeightField->getCollisionBody()); - - // Destroy the convex mesh - delete mHeightField; + */ mContactManager.resetPoints(); @@ -226,12 +234,6 @@ CollisionDetectionScene::~CollisionDetectionScene() { delete mCollisionWorld; } -// Update the physics world (take a simulation step) -void CollisionDetectionScene::updatePhysics() { - - -} - // Take a step for the simulation void CollisionDetectionScene::update() { @@ -242,32 +244,6 @@ void CollisionDetectionScene::update() { SceneDemo::update(); } -// Render the scene -void CollisionDetectionScene::renderSinglePass(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { - - // Render the shapes - if (mSphere1->getCollisionBody()->isActive()) mSphere1->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - if (mSphere2->getCollisionBody()->isActive()) mSphere2->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - if (mCapsule1->getCollisionBody()->isActive()) mCapsule1->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - if (mCapsule2->getCollisionBody()->isActive()) mCapsule2->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - if (mBox1->getCollisionBody()->isActive()) mBox1->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - if (mBox2->getCollisionBody()->isActive()) mBox2->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - if (mConvexMesh->getCollisionBody()->isActive()) mConvexMesh->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - if (mConcaveMesh->getCollisionBody()->isActive()) mConcaveMesh->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - - /* - if (mBox->getCollisionBody()->isActive()) mBox->render(shader, worldToCameraMatrix); - if (mCone->getCollisionBody()->isActive()) mCone->render(shader, worldToCameraMatrix); - if (mCylinder->getCollisionBody()->isActive()) mCylinder->render(shader, worldToCameraMatrix); - if (mCapsule->getCollisionBody()->isActive()) mCapsule->render(shader, worldToCameraMatrix); - if (mDumbbell->getCollisionBody()->isActive()) mDumbbell->render(shader, worldToCameraMatrix); - if (mHeightField->getCollisionBody()->isActive()) mHeightField->render(shader, worldToCameraMatrix); - */ - - shader.unbind(); -} - void CollisionDetectionScene::selectNextShape() { int previousIndex = mSelectedShapeIndex; diff --git a/testbed/scenes/collisiondetection/CollisionDetectionScene.h b/testbed/scenes/collisiondetection/CollisionDetectionScene.h index 8e94eaf5..8473ae73 100755 --- a/testbed/scenes/collisiondetection/CollisionDetectionScene.h +++ b/testbed/scenes/collisiondetection/CollisionDetectionScene.h @@ -148,7 +148,7 @@ class CollisionDetectionScene : public SceneDemo { ConvexMesh* mConvexMesh; //Dumbbell* mDumbbell; ConcaveMesh* mConcaveMesh; - //HeightField* mHeightField; + HeightField* mHeightField; std::vector mAllShapes; @@ -170,17 +170,9 @@ class CollisionDetectionScene : public SceneDemo { /// Destructor virtual ~CollisionDetectionScene() override; - /// Update the physics world (take a simulation step) - /// Can be called several times per frame - virtual void updatePhysics() override; - /// Take a step for the simulation virtual void update() override; - /// Render the scene in a single pass - virtual void renderSinglePass(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) override; - /// Reset the scene virtual void reset() override; diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp index 746942ff..e63f39d4 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -71,6 +71,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // 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 @@ -95,6 +96,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // 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 @@ -123,6 +125,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // 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 @@ -150,6 +153,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // 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 @@ -174,12 +178,14 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Add the mesh the list of sphere in the scene mConvexMeshes.push_back(mesh); + mPhysicsObjects.push_back(mesh); } // ---------- Create the floor --------- openglframework::Vector3 floorPosition(0, 0, 0); mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mMeshFolderPath); + mPhysicsObjects.push_back(mFloor); // Set the box color mFloor->setColor(mGreyColorDemo); @@ -230,68 +236,16 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Destructor CollisionShapesScene::~CollisionShapesScene() { - // Destroy all the boxes of the scene - for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { + // Destroy all the physics objects of the scene + for (std::vector::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { // Destroy the corresponding rigid body from the dynamics world mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); - // Destroy the box + // Destroy the object delete (*it); } - // Destroy all the sphere of the scene - for (std::vector::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) { - - // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the sphere - delete (*it); - } - - // Destroy all the capsules of the scene - for (std::vector::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) { - - // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the sphere - delete (*it); - } - - // Destroy all the convex meshes of the scene - for (std::vector::iterator it = mConvexMeshes.begin(); - it != mConvexMeshes.end(); ++it) { - - // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the convex mesh - delete (*it); - } - - // Destroy all the dumbbell of the scene - for (std::vector::iterator it = mDumbbells.begin(); - it != mDumbbells.end(); ++it) { - - // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); - - // Destroy the convex mesh - delete (*it); - } - - // Destroy the rigid body of the floor - mDynamicsWorld->destroyRigidBody(mFloor->getRigidBody()); - //mDynamicsWorld->destroyRigidBody(mConcaveMesh->getRigidBody()); - - // Destroy the floor - delete mFloor; - - // Destroy the convex mesh - //delete mConcaveMesh; - // Destroy the dynamics world delete mDynamicsWorld; } @@ -315,96 +269,6 @@ void CollisionShapesScene::updatePhysics() { mDynamicsWorld->update(mEngineSettings.timeStep); } -// Take a step for the simulation -void CollisionShapesScene::update() { - - SceneDemo::update(); - - // Update the position and orientation of the boxes - for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(mInterpolationFactor); - } - - // Update the position and orientation of the sphere - for (std::vector::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(mInterpolationFactor); - } - - // Update the position and orientation of the capsules - for (std::vector::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(mInterpolationFactor); - } - - // Update the position and orientation of the convex meshes - for (std::vector::iterator it = mConvexMeshes.begin(); - it != mConvexMeshes.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(mInterpolationFactor); - } - - // Update the position and orientation of the dumbbells - for (std::vector::iterator it = mDumbbells.begin(); - it != mDumbbells.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(mInterpolationFactor); - } - - //mConcaveMesh->updateTransform(mInterpolationFactor); - - mFloor->updateTransform(mInterpolationFactor); -} - -// Render the scene -void CollisionShapesScene::renderSinglePass(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { - - // Bind the shader - shader.bind(); - - // Render all the boxes of the scene - for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - (*it)->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - } - - // Render all the sphere of the scene - for (std::vector::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) { - (*it)->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - } - - // Render all the capsules of the scene - for (std::vector::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) { - (*it)->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - } - - // Render all the convex meshes of the scene - for (std::vector::iterator it = mConvexMeshes.begin(); - it != mConvexMeshes.end(); ++it) { - (*it)->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - } - - // Render all the dumbbells of the scene - for (std::vector::iterator it = mDumbbells.begin(); - it != mDumbbells.end(); ++it) { - (*it)->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - } - - // Render the floor - mFloor->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - - //mConcaveMesh->render(shader, worldToCameraMatrix); - - // Unbind the shader - shader.unbind(); -} - /// Reset the scene void CollisionShapesScene::reset() { diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.h b/testbed/scenes/collisionshapes/CollisionShapesScene.h index b253acef..70e28755 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.h +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.h @@ -71,7 +71,7 @@ class CollisionShapesScene : public SceneDemo { // -------------------- Attributes -------------------- // - /// All the spheres of the scene + /// All the boxes of the scene std::vector mBoxes; std::vector mSpheres; @@ -104,13 +104,6 @@ class CollisionShapesScene : public SceneDemo { /// Can be called several times per frame virtual void updatePhysics() override; - /// Take a step for the simulation - virtual void update() override; - - /// Render the scene in a single pass - virtual void renderSinglePass(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) override; - /// Reset the scene virtual void reset() override; diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp old mode 100644 new mode 100755 index 81929e58..3ddb1d61 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -82,6 +82,7 @@ CubesScene::CubesScene(const std::string& name) // The floor must be a static rigid body mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC); + mPhysicsObjects.push_back(mFloor); // Change the material properties of the floor rigid body //rp3d::Material& material = mFloor->getRigidBody()->getMaterial(); @@ -102,6 +103,7 @@ CubesScene::CubesScene(const std::string& name) // Add the box the list of box in the scene mBoxes.push_back(cube); + mPhysicsObjects.push_back(cube); // Get the physics engine parameters mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled(); @@ -157,39 +159,6 @@ void CubesScene::updatePhysics() { mDynamicsWorld->update(mEngineSettings.timeStep); } -// Update the scene -void CubesScene::update() { - - SceneDemo::update(); - - // Update the position and orientation of the boxes - for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - - // Update the transform used for the rendering - (*it)->updateTransform(mInterpolationFactor); - } - - mFloor->updateTransform(mInterpolationFactor); -} - -// Render the scene in a single pass -void CubesScene::renderSinglePass(Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { - - // Bind the shader - shader.bind(); - - // Render all the cubes of the scene - for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { - (*it)->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - } - - // Render the floor - mFloor->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - - // Unbind the shader - shader.unbind(); -} - // Reset the scene void CubesScene::reset() { diff --git a/testbed/scenes/cubes/CubesScene.h b/testbed/scenes/cubes/CubesScene.h old mode 100644 new mode 100755 index 4ad57f77..aa4b7073 --- a/testbed/scenes/cubes/CubesScene.h +++ b/testbed/scenes/cubes/CubesScene.h @@ -72,13 +72,6 @@ class CubesScene : public SceneDemo { /// Can be called several times per frame virtual void updatePhysics() override; - /// Update the scene (take a simulation step) - virtual void update() override; - - /// Render the scene in a single pass - virtual void renderSinglePass(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) override; - /// Reset the scene virtual void reset() override; diff --git a/testbed/scenes/heightfield/HeightFieldScene.cpp b/testbed/scenes/heightfield/HeightFieldScene.cpp index 3e4061c9..329712e9 100644 --- a/testbed/scenes/heightfield/HeightFieldScene.cpp +++ b/testbed/scenes/heightfield/HeightFieldScene.cpp @@ -33,6 +33,8 @@ using namespace heightfieldscene; // Constructor HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SCENE_RADIUS) { + std::string meshFolderPath("meshes/"); + // Compute the radius and the center of the scene openglframework::Vector3 center(0, 5, 0); @@ -45,25 +47,138 @@ HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SC // Create the dynamics world for the physics simulation mDynamicsWorld = new rp3d::DynamicsWorld(gravity); - // ---------- Create the boxes ----------- // + float radius = 3.0f; - // For each box - for (int i=0; isetColor(mDemoColors[2]); - mBoxes[i]->setSleepingColor(mRedColorDemo); + // Set the box color + dumbbell->setColor(mDemoColors[i % mNbDemoColors]); + dumbbell->setSleepingColor(mRedColorDemo); - // Change the material properties of the rigid body - rp3d::Material& boxMaterial = mBoxes[i]->getRigidBody()->getMaterial(); - boxMaterial.setBounciness(rp3d::decimal(0.2)); - } + // Change the material properties of the rigid body + rp3d::Material& material = dumbbell->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // 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; isetColor(mDemoColors[i % mNbDemoColors]); + box->setSleepingColor(mRedColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = box->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // 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; igetRigidBody()->getMaterial().setRollingResistance(0.08); + + // Set the box color + sphere->setColor(mDemoColors[i % mNbDemoColors]); + sphere->setSleepingColor(mRedColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = sphere->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // 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; igetRigidBody()->getMaterial().setRollingResistance(0.08); + + // Set the box color + capsule->setColor(mDemoColors[i % mNbDemoColors]); + capsule->setSleepingColor(mRedColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = capsule->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // 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; isetColor(mDemoColors[i % mNbDemoColors]); + mesh->setSleepingColor(mRedColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = mesh->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Add the mesh the list of sphere in the scene + mConvexMeshes.push_back(mesh); + mPhysicsObjects.push_back(mesh); + } // ---------- Create the height field ---------- // @@ -77,6 +192,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SC // Set the mesh as beeing static mHeightField->getRigidBody()->setType(rp3d::BodyType::STATIC); + mPhysicsObjects.push_back(mHeightField); + // Set the color mHeightField->setColor(mGreyColorDemo); mHeightField->setSleepingColor(mGreyColorDemo); @@ -101,18 +218,15 @@ HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SC // Destructor HeightFieldScene::~HeightFieldScene() { - // Destroy the corresponding rigid body from the dynamics world - for (int i=0; idestroyRigidBody(mBoxes[i]->getRigidBody()); - } - mDynamicsWorld->destroyRigidBody(mHeightField->getRigidBody()); + // Destroy all the physics objects of the scene + for (std::vector::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { - for (int i=0; idestroyRigidBody((*it)->getRigidBody()); - // Destroy the convex mesh - delete mHeightField; + // Destroy the object + delete (*it); + } // Destroy the dynamics world delete mDynamicsWorld; @@ -137,35 +251,6 @@ void HeightFieldScene::updatePhysics() { mDynamicsWorld->update(mEngineSettings.timeStep); } -// Update the scene -void HeightFieldScene::update() { - - SceneDemo::update(); - - // Update the transform used for the rendering - mHeightField->updateTransform(mInterpolationFactor); - - for (int i=0; iupdateTransform(mInterpolationFactor); - } -} - -// Render the scene in a single pass -void HeightFieldScene::renderSinglePass(Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { - - // Bind the shader - shader.bind(); - - mHeightField->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - - for (int i=0; irender(shader, worldToCameraMatrix, mIsWireframeEnabled); - } - - // Unbind the shader - shader.unbind(); -} - // Reset the scene void HeightFieldScene::reset() { diff --git a/testbed/scenes/heightfield/HeightFieldScene.h b/testbed/scenes/heightfield/HeightFieldScene.h index 7eb9527d..7306ae2c 100644 --- a/testbed/scenes/heightfield/HeightFieldScene.h +++ b/testbed/scenes/heightfield/HeightFieldScene.h @@ -30,6 +30,10 @@ #include "openglframework.h" #include "reactphysics3d.h" #include "Box.h" +#include "Sphere.h" +#include "ConvexMesh.h" +#include "Capsule.h" +#include "Dumbbell.h" #include "SceneDemo.h" #include "HeightField.h" @@ -37,17 +41,47 @@ namespace heightfieldscene { // Constants const float SCENE_RADIUS = 50.0f; +static const int NB_BOXES = 10; +static const int NB_SPHERES = 5; +static const int NB_CAPSULES = 5; +static const int NB_MESHES = 3; +static const int NB_COMPOUND_SHAPES = 3; +const openglframework::Vector3 BOX_SIZE(2, 2, 2); +const float SPHERE_RADIUS = 1.5f; +const float CONE_RADIUS = 2.0f; +const float CONE_HEIGHT = 3.0f; +const float CYLINDER_RADIUS = 1.0f; +const float CYLINDER_HEIGHT = 5.0f; +const float CAPSULE_RADIUS = 1.0f; +const float CAPSULE_HEIGHT = 1.0f; +const float DUMBBELL_HEIGHT = 1.0f; +const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters +const float BOX_MASS = 1.0f; +const float CONE_MASS = 1.0f; +const float CYLINDER_MASS = 1.0f; +const float CAPSULE_MASS = 1.0f; +const float MESH_MASS = 1.0f; +const float FLOOR_MASS = 100.0f; // Class HeightFieldScene class HeightFieldScene : public SceneDemo { - static const int NB_BOXES = 10; - protected : // -------------------- Attributes -------------------- // - Box* mBoxes[NB_BOXES]; + /// All the boxes of the scene + std::vector mBoxes; + + std::vector mSpheres; + + std::vector mCapsules; + + /// All the convex meshes of the scene + std::vector mConvexMeshes; + + /// All the dumbbell of the scene + std::vector mDumbbells; /// Height field HeightField* mHeightField; @@ -69,13 +103,6 @@ class HeightFieldScene : public SceneDemo { /// Can be called several times per frame virtual void updatePhysics() override; - /// Update the scene (take a simulation step) - virtual void update() override; - - /// Render the scene in a single pass - virtual void renderSinglePass(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) override ; - /// Reset the scene virtual void reset() override ; diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index 23bcdb93..282f7e51 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -136,25 +136,6 @@ void JointsScene::updatePhysics() { mDynamicsWorld->update(mEngineSettings.timeStep); } -// Take a step for the simulation -void JointsScene::update() { - - SceneDemo::update(); - - // Update the position and orientation of the boxes - mSliderJointBottomBox->updateTransform(mInterpolationFactor); - mSliderJointTopBox->updateTransform(mInterpolationFactor); - mPropellerBox->updateTransform(mInterpolationFactor); - mFixedJointBox1->updateTransform(mInterpolationFactor); - mFixedJointBox2->updateTransform(mInterpolationFactor); - for (int i=0; iupdateTransform(mInterpolationFactor); - } - - // Update the position and orientation of the floor - mFloor->updateTransform(mInterpolationFactor); -} - // Render the scene void JointsScene::renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { @@ -281,6 +262,8 @@ void JointsScene::createBallAndSocketJoints() { rp3d::Material& material = mBallAndSocketJointChainBoxes[i]->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.4)); + mPhysicsObjects.push_back(mBallAndSocketJointChainBoxes[i]); + positionBox.y -= boxDimension.y + 0.5f; } @@ -324,6 +307,7 @@ void JointsScene::createSliderJoint() { // Change the material properties of the rigid body rp3d::Material& material1 = mSliderJointBottomBox->getRigidBody()->getMaterial(); material1.setBounciness(0.4f); + mPhysicsObjects.push_back(mSliderJointBottomBox); // --------------- Create the second box --------------- // @@ -341,6 +325,7 @@ void JointsScene::createSliderJoint() { // Change the material properties of the rigid body rp3d::Material& material2 = mSliderJointTopBox->getRigidBody()->getMaterial(); material2.setBounciness(0.4f); + mPhysicsObjects.push_back(mSliderJointTopBox); // --------------- Create the joint --------------- // @@ -381,6 +366,7 @@ void JointsScene::createPropellerHingeJoint() { // Change the material properties of the rigid body rp3d::Material& material = mPropellerBox->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.4)); + mPhysicsObjects.push_back(mPropellerBox); // --------------- Create the Hinge joint --------------- // @@ -420,6 +406,7 @@ void JointsScene::createFixedJoints() { // Change the material properties of the rigid body rp3d::Material& material1 = mFixedJointBox1->getRigidBody()->getMaterial(); material1.setBounciness(rp3d::decimal(0.4)); + mPhysicsObjects.push_back(mFixedJointBox1); // --------------- Create the second box --------------- // @@ -436,6 +423,7 @@ void JointsScene::createFixedJoints() { // Change the material properties of the rigid body rp3d::Material& material2 = mFixedJointBox2->getRigidBody()->getMaterial(); material2.setBounciness(rp3d::decimal(0.4)); + mPhysicsObjects.push_back(mFixedJointBox2); // --------------- Create the first fixed joint --------------- // @@ -478,4 +466,5 @@ void JointsScene::createFloor() { // Change the material properties of the rigid body rp3d::Material& material = mFloor->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.3)); + mPhysicsObjects.push_back(mFloor); } diff --git a/testbed/scenes/joints/JointsScene.h b/testbed/scenes/joints/JointsScene.h index a9474393..16ccfe8c 100644 --- a/testbed/scenes/joints/JointsScene.h +++ b/testbed/scenes/joints/JointsScene.h @@ -126,9 +126,6 @@ class JointsScene : public SceneDemo { /// Can be called several times per frame virtual void updatePhysics() override; - /// Take a step for the simulation - virtual void update() override; - /// Render the scene in a single pass virtual void renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) override; diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index d420073f..2ded75d6 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -56,6 +56,7 @@ RaycastScene::RaycastScene(const std::string& name) // Set the box color mDumbbell->setColor(mGreyColorDemo); mDumbbell->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mDumbbell); // ---------- Box ---------- // openglframework::Vector3 position2(0, 0, 0); @@ -67,6 +68,7 @@ RaycastScene::RaycastScene(const std::string& name) // Set the box color mBox->setColor(mGreyColorDemo); mBox->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mBox); // ---------- Sphere ---------- // openglframework::Vector3 position3(0, 0, 0); @@ -78,6 +80,7 @@ RaycastScene::RaycastScene(const std::string& name) // Set the color mSphere->setColor(mGreyColorDemo); mSphere->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mSphere); // ---------- Capsule ---------- // openglframework::Vector3 position6(0, 0, 0); @@ -89,6 +92,7 @@ RaycastScene::RaycastScene(const std::string& name) // Set the color mCapsule->setColor(mGreyColorDemo); mCapsule->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mCapsule); // ---------- Convex Mesh ---------- // openglframework::Vector3 position7(0, 0, 0); @@ -99,6 +103,7 @@ RaycastScene::RaycastScene(const std::string& name) // Set the color mConvexMesh->setColor(mGreyColorDemo); mConvexMesh->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mConvexMesh); // ---------- Concave Mesh ---------- // openglframework::Vector3 position8(0, 0, 0); @@ -109,6 +114,7 @@ RaycastScene::RaycastScene(const std::string& name) // Set the color mConcaveMesh->setColor(mGreyColorDemo); mConcaveMesh->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mConcaveMesh); // ---------- Heightfield ---------- // openglframework::Vector3 position9(0, 0, 0); @@ -119,6 +125,7 @@ RaycastScene::RaycastScene(const std::string& name) // Set the color mHeightField->setColor(mGreyColorDemo); mHeightField->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mHeightField); // Create the lines that will be used for raycasting createLines(); @@ -256,12 +263,6 @@ RaycastScene::~RaycastScene() { mVAO.destroy(); } -// Update the physics world (take a simulation step) -void RaycastScene::updatePhysics() { - - -} - // Take a step for the simulation void RaycastScene::update() { @@ -327,14 +328,18 @@ void RaycastScene::renderSinglePass(openglframework::Shader& shader, const openg mColorShader.unbind(); - // Render the shapes - if (mBox->getCollisionBody()->isActive()) mBox->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - if (mSphere->getCollisionBody()->isActive()) mSphere->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - if (mCapsule->getCollisionBody()->isActive()) mCapsule->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - if (mConvexMesh->getCollisionBody()->isActive()) mConvexMesh->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - if (mDumbbell->getCollisionBody()->isActive()) mDumbbell->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - if (mConcaveMesh->getCollisionBody()->isActive()) mConcaveMesh->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - if (mHeightField->getCollisionBody()->isActive()) mHeightField->render(shader, worldToCameraMatrix, mIsWireframeEnabled); + // Bind the shader + shader.bind(); + + // Render all the physics objects of the scene + for (std::vector::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + if ((*it)->getCollisionBody()->isActive()) { + (*it)->render(shader, worldToCameraMatrix, mIsWireframeEnabled); + } + } + + // Unbind the shader + shader.unbind(); } // Create the Vertex Buffer Objects used to render with OpenGL. diff --git a/testbed/scenes/raycast/RaycastScene.h b/testbed/scenes/raycast/RaycastScene.h index 39b73799..1400fcf7 100644 --- a/testbed/scenes/raycast/RaycastScene.h +++ b/testbed/scenes/raycast/RaycastScene.h @@ -57,7 +57,7 @@ const float CAPSULE_HEIGHT = 5.0f; const float DUMBBELL_HEIGHT = 5.0f; const int NB_RAYS = 100; const float RAY_LENGTH = 30.0f; -const int NB_BODIES = 9; +const int NB_BODIES = 7; // Raycast manager class RaycastManager : public rp3d::RaycastCallback { @@ -175,10 +175,6 @@ class RaycastScene : public SceneDemo { /// Destructor virtual ~RaycastScene() override; - /// Update the physics world (take a simulation step) - /// Can be called several times per frame - virtual void updatePhysics() override; - /// Take a step for the simulation virtual void update() override; diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index 85e8a66f..d406bcea 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -80,7 +80,7 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMa // Destructor SceneDemo::~SceneDemo() { - + mShadowMapTexture.destroy(); mFBOShadowMap.destroy(); mVBOQuad.destroy(); @@ -101,6 +101,19 @@ void SceneDemo::update() { // Update the contact points updateContactPoints(); + + // Update the position and orientation of the physics objects + for (std::vector::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(mInterpolationFactor); + } +} + +// Update the physics world (take a simulation step) +// Can be called several times per frame +void SceneDemo::updatePhysics() { + } // Render the scene (in multiple passes for shadow mapping) @@ -202,6 +215,21 @@ void SceneDemo::render() { //drawTextureQuad(); } +// Render the scene in a single pass +void SceneDemo::renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { + + // Bind the shader + shader.bind(); + + // Render all the physics objects of the scene + for (std::vector::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + (*it)->render(shader, worldToCameraMatrix, mIsWireframeEnabled); + } + + // Unbind the shader + shader.unbind(); +} + // Create the Shadow map FBO and texture void SceneDemo::createShadowMapFBOAndTexture() { @@ -345,7 +373,7 @@ std::vector SceneDemo::computeContactPointsOfWorld(const rp3d::Dyn rp3d::ContactPoint* contactPoint = manifold->getContactPoints(); while (contactPoint != nullptr) { - rp3d::Vector3 point = contactPoint->getWorldPointOnBody1(); + rp3d::Vector3 point = manifold->getShape1()->getLocalToWorldTransform() * contactPoint->getLocalPointOnBody1(); rp3d::Vector3 normalWorld = contactPoint->getNormal(); openglframework::Vector3 normal = openglframework::Vector3(normalWorld.x, normalWorld.y, normalWorld.z); ContactPoint contact(openglframework::Vector3(point.x, point.y, point.z), normal, openglframework::Color::red()); diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index f7b5f7ce..a8b1941f 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -30,6 +30,7 @@ #include "Scene.h" #include "VisualContactPoint.h" #include "reactphysics3d.h" +#include "PhysicsObject.h" // Constants const int SHADOWMAP_WIDTH = 2048; @@ -95,6 +96,8 @@ class SceneDemo : public Scene { std::string mMeshFolderPath; + std::vector mPhysicsObjects; + // -------------------- Methods -------------------- // // Create the Shadow map FBO and texture @@ -128,12 +131,15 @@ class SceneDemo : public Scene { /// Update the scene virtual void update() override; + /// Update the physics world (take a simulation step) + /// Can be called several times per frame + virtual void updatePhysics() override; + /// Render the scene (possibly in multiple passes for shadow mapping) virtual void render() override; /// Render the scene in a single pass - virtual void renderSinglePass(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix)=0 ; + virtual void renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); /// Enabled/Disable the shadow mapping virtual void setIsShadowMappingEnabled(bool isShadowMappingEnabled) override; diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index 09f464f3..2b9195e5 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -125,7 +125,7 @@ void TestbedApplication::createScenes() { mScenes.push_back(concaveMeshScene); assert(mScenes.size() > 0); - mCurrentScene = mScenes[0]; + mCurrentScene = mScenes[5]; // Get the engine settings from the scene mEngineSettings = mCurrentScene->getEngineSettings();