From e135d4b592d8b6544b482d197ee310e8cc834ea7 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Mon, 26 Oct 2015 18:15:56 +0100 Subject: [PATCH] Add Concave Mesh scene in testbed application --- testbed/CMakeLists.txt | 4 + testbed/common/ConcaveMesh.cpp | 345 ++++++++++++++++++ testbed/common/ConcaveMesh.h | 101 +++++ testbed/meshes/concavemesh.obj | 9 + .../scenes/concavemesh/ConcaveMeshScene.cpp | 171 +++++++++ testbed/scenes/concavemesh/ConcaveMeshScene.h | 92 +++++ testbed/src/TestbedApplication.cpp | 6 + 7 files changed, 728 insertions(+) create mode 100644 testbed/common/ConcaveMesh.cpp create mode 100644 testbed/common/ConcaveMesh.h create mode 100644 testbed/meshes/concavemesh.obj create mode 100644 testbed/scenes/concavemesh/ConcaveMeshScene.cpp create mode 100644 testbed/scenes/concavemesh/ConcaveMeshScene.h diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index 33f71720..544d9a7d 100644 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -66,6 +66,8 @@ SET(COMMON_SOURCES common/Capsule.cpp common/ConvexMesh.h common/ConvexMesh.cpp + common/ConcaveMesh.h + common/ConcaveMesh.cpp common/Cylinder.h common/Cylinder.cpp common/Dumbbell.h @@ -86,6 +88,8 @@ SET(SCENES_SOURCES scenes/raycast/RaycastScene.cpp scenes/collisionshapes/CollisionShapesScene.h scenes/collisionshapes/CollisionShapesScene.cpp + scenes/concavemesh/ConcaveMeshScene.h + scenes/concavemesh/ConcaveMeshScene.cpp ) # Create the executable diff --git a/testbed/common/ConcaveMesh.cpp b/testbed/common/ConcaveMesh.cpp new file mode 100644 index 00000000..f8cedfc9 --- /dev/null +++ b/testbed/common/ConcaveMesh.cpp @@ -0,0 +1,345 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "ConcaveMesh.h" + +// Constructor +ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position, + reactphysics3d::CollisionWorld* world, + const std::string& meshFolderPath) + : openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER), + mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), + mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "concavemesh.obj", *this); + + // Calculate the normals of the mesh + calculateNormals(); + + // Initialize the position where the sphere will be rendered + translateWorld(position); + + // Convert the vertices array to the rp3d::decimal type + /*rp3d::decimal* vertices = new rp3d::decimal[3 * mVertices.size()]; + for (int i=0; i < mVertices.size(); i++) { + vertices[3 * i] = static_cast(mVertices[i].x); + vertices[3 * i + 1] = static_cast(mVertices[i].y); + vertices[3 * i + 2] = static_cast(mVertices[i].z); + } + */ + + // For each subpart of the mesh + for (int i=0; iaddEdge(v1, v2); + mCollisionShape->addEdge(v1, v3); + mCollisionShape->addEdge(v2, v3); + } + mCollisionShape->setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges + */ + + // Initial position and orientation of the rigid body + rp3d::Vector3 initPosition(position.x, position.y, position.z); + rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transform(initPosition, initOrientation); + + mPreviousTransform = transform; + + // Create a rigid body corresponding to the sphere in the dynamics world + mBody = world->createCollisionBody(transform); + + // Add a collision shape to the body and specify the mass of the collision shape + mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity()); + + // Create the VBOs and VAO + createVBOAndVAO(); +} + +// Constructor +ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position, float mass, + reactphysics3d::DynamicsWorld* dynamicsWorld, + const std::string& meshFolderPath) + : openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER), + mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), + mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { + + // Load the mesh from a file + openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "concavemesh.obj", *this); + + // Calculate the normals of the mesh + calculateNormals(); + + // Initialize the position where the sphere will be rendered + translateWorld(position); + + /* + // Convert the vertices array to the rp3d::decimal type + rp3d::decimal* vertices = new rp3d::decimal[3 * mVertices.size()]; + for (int i=0; i < mVertices.size(); i++) { + vertices[3 * i] = static_cast(mVertices[i].x); + vertices[3 * i + 1] = static_cast(mVertices[i].y); + vertices[3 * i + 2] = static_cast(mVertices[i].z); + } + */ + + // For each subpart of the mesh + for (int i=0; iaddEdge(v1, v2); + mCollisionShape->addEdge(v1, v3); + mCollisionShape->addEdge(v2, v3); + } + mCollisionShape->setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges + */ + + // Initial position and orientation of the rigid body + rp3d::Vector3 initPosition(position.x, position.y, position.z); + rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transform(initPosition, initOrientation); + + // Create a rigid body corresponding to the sphere in the dynamics world + rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); + + // Add a collision shape to the body and specify the mass of the collision shape + body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass); + + mBody = body; + + // Create the VBOs and VAO + createVBOAndVAO(); +} + +// Destructor +ConcaveMesh::~ConcaveMesh() { + + // Destroy the triangle mesh data for the physics engine + for (int i=0; isetTransform(transform); + + mBody->setIsSleeping(false); + + // Reset the velocity of the rigid body + rp3d::RigidBody* rigidBody = dynamic_cast(mBody); + if (rigidBody != NULL) { + rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0)); + rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0)); + } + + updateTransform(1.0f); +} + diff --git a/testbed/common/ConcaveMesh.h b/testbed/common/ConcaveMesh.h new file mode 100644 index 00000000..167e78ff --- /dev/null +++ b/testbed/common/ConcaveMesh.h @@ -0,0 +1,101 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef CONCAVE_MESH_H +#define CONCAVE_MESH_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" +#include "PhysicsObject.h" + +// Class ConcaveMesh +class ConcaveMesh : public openglframework::Mesh, public PhysicsObject { + + private : + + // -------------------- Attributes -------------------- // + + /// Previous transform (for interpolation) + rp3d::Transform mPreviousTransform; + + /// Collision shape + rp3d::ConcaveMeshShape* mCollisionShape; + + /// Vertex Buffer Object for the vertices data + openglframework::VertexBufferObject mVBOVertices; + + /// Vertex Buffer Object for the normals data + openglframework::VertexBufferObject mVBONormals; + + /// Vertex Buffer Object for the texture coords + openglframework::VertexBufferObject mVBOTextureCoords; + + /// Vertex Buffer Object for the indices + openglframework::VertexBufferObject mVBOIndices; + + /// Vertex Array Object for the vertex data + openglframework::VertexArrayObject mVAO; + + /// Structure with pointer to the shared mesh data (vertices, indices, ...) + rp3d::TriangleMesh mPhysicsTriangleMesh; + + // -------------------- Methods -------------------- // + + // Create the Vertex Buffer Objects used to render with OpenGL. + void createVBOAndVAO(); + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + ConcaveMesh(const openglframework::Vector3& position, + rp3d::CollisionWorld* world, const std::string& meshFolderPath); + + /// Constructor + ConcaveMesh(const openglframework::Vector3& position, float mass, + rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); + + /// Destructor + ~ConcaveMesh(); + + /// Render the mesh at the correct position and with the correct orientation + void render(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); + + /// Set the position of the box + void resetTransform(const rp3d::Transform& transform); + + /// Update the transform matrix of the object + virtual void updateTransform(float interpolationFactor); +}; + +// Update the transform matrix of the object +inline void ConcaveMesh::updateTransform(float interpolationFactor) { + mTransformMatrix = computeTransform(interpolationFactor, openglframework::Matrix4::identity()); +} + +#endif diff --git a/testbed/meshes/concavemesh.obj b/testbed/meshes/concavemesh.obj new file mode 100644 index 00000000..62d9132c --- /dev/null +++ b/testbed/meshes/concavemesh.obj @@ -0,0 +1,9 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +v -10.000000 0.000000 10.000000 +v 10.000000 0.000000 10.000000 +v -10.000000 0.000000 -10.000000 +v 10.000000 0.000000 -10.000000 +s off +f 2 4 3 +f 1 2 3 diff --git a/testbed/scenes/concavemesh/ConcaveMeshScene.cpp b/testbed/scenes/concavemesh/ConcaveMeshScene.cpp new file mode 100644 index 00000000..01791334 --- /dev/null +++ b/testbed/scenes/concavemesh/ConcaveMeshScene.cpp @@ -0,0 +1,171 @@ + +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "ConcaveMeshScene.h" + +// Namespaces +using namespace openglframework; +using namespace trianglemeshscene; + +// Constructor +ConcaveMeshScene::ConcaveMeshScene(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); + + // Set the center of the scene + setScenePosition(center, SCENE_RADIUS); + + // Gravity vector in the dynamics world + rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); + + // Create the dynamics world for the physics simulation + mDynamicsWorld = new rp3d::DynamicsWorld(gravity); + + // Set the number of iterations of the constraint solver + mDynamicsWorld->setNbIterationsVelocitySolver(15); + + // ---------- Create the sphere ----------- // + + // Position + rp3d::decimal radius = 2.0; + openglframework::Vector3 spherePos(0, 10, 0); + + // Create a sphere and a corresponding rigid in the dynamics world + mSphere = new Sphere(radius, spherePos , 1.0, mDynamicsWorld, meshFolderPath); + + // Set the sphere color + mSphere->setColor(mDemoColors[1]); + mSphere->setSleepingColor(mRedColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& sphereMat = mSphere->getRigidBody()->getMaterial(); + sphereMat.setBounciness(rp3d::decimal(0.2)); + + // ---------- Create the triangular mesh ---------- // + + // Position + openglframework::Vector3 position(0, 0, 0); + rp3d::decimal mass = 1.0; + + // Create a convex mesh and a corresponding rigid in the dynamics world + mConcaveMesh = new ConcaveMesh(position, mass, mDynamicsWorld, meshFolderPath); + + // Set the mesh as beeing static + mConcaveMesh->getRigidBody()->setType(rp3d::STATIC); + + // Set the box color + mConcaveMesh->setColor(mDemoColors[0]); + mConcaveMesh->setSleepingColor(mRedColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = mConcaveMesh->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Get the physics engine parameters + mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled(); + rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity(); + mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); + mEngineSettings.isSleepingEnabled = mDynamicsWorld->isSleepingEnabled(); + mEngineSettings.sleepLinearVelocity = mDynamicsWorld->getSleepLinearVelocity(); + mEngineSettings.sleepAngularVelocity = mDynamicsWorld->getSleepAngularVelocity(); + mEngineSettings.nbPositionSolverIterations = mDynamicsWorld->getNbIterationsPositionSolver(); + mEngineSettings.nbVelocitySolverIterations = mDynamicsWorld->getNbIterationsVelocitySolver(); + mEngineSettings.timeBeforeSleep = mDynamicsWorld->getTimeBeforeSleep(); +} + +// Destructor +ConcaveMeshScene::~ConcaveMeshScene() { + + mDynamicsWorld->destroyRigidBody(mSphere->getRigidBody()); + // Destroy the corresponding rigid body from the dynamics world + mDynamicsWorld->destroyRigidBody(mConcaveMesh->getRigidBody()); + + delete mSphere; + + // Destroy the convex mesh + delete mConcaveMesh; + + // Destroy the dynamics world + delete mDynamicsWorld; +} + +// Update the physics world (take a simulation step) +void ConcaveMeshScene::updatePhysics() { + + // Update the physics engine parameters + mDynamicsWorld->setIsGratityEnabled(mEngineSettings.isGravityEnabled); + rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y, + mEngineSettings.gravity.z); + mDynamicsWorld->setGravity(gravity); + mDynamicsWorld->enableSleeping(mEngineSettings.isSleepingEnabled); + mDynamicsWorld->setSleepLinearVelocity(mEngineSettings.sleepLinearVelocity); + mDynamicsWorld->setSleepAngularVelocity(mEngineSettings.sleepAngularVelocity); + mDynamicsWorld->setNbIterationsPositionSolver(mEngineSettings.nbPositionSolverIterations); + mDynamicsWorld->setNbIterationsVelocitySolver(mEngineSettings.nbVelocitySolverIterations); + mDynamicsWorld->setTimeBeforeSleep(mEngineSettings.timeBeforeSleep); + + // Take a simulation step + mDynamicsWorld->update(mEngineSettings.timeStep); +} + +// Update the scene +void ConcaveMeshScene::update() { + + SceneDemo::update(); + + // Update the transform used for the rendering + mConcaveMesh->updateTransform(mInterpolationFactor); + mSphere->updateTransform(mInterpolationFactor); +} + +// Render the scene in a single pass +void ConcaveMeshScene::renderSinglePass(Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { + + // Bind the shader + shader.bind(); + + mConcaveMesh->render(shader, worldToCameraMatrix); + mSphere->render(shader, worldToCameraMatrix); + + // Unbind the shader + shader.unbind(); +} + +// Reset the scene +void ConcaveMeshScene::reset() { + + // Reset the transform + mConcaveMesh->resetTransform(rp3d::Transform::identity()); + + rp3d::Vector3 spherePos(10.1, 10, 0); + rp3d::Transform sphereTransform(spherePos, rp3d::Quaternion::identity()); + mSphere->resetTransform(sphereTransform); +} diff --git a/testbed/scenes/concavemesh/ConcaveMeshScene.h b/testbed/scenes/concavemesh/ConcaveMeshScene.h new file mode 100644 index 00000000..d7ca68d8 --- /dev/null +++ b/testbed/scenes/concavemesh/ConcaveMeshScene.h @@ -0,0 +1,92 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +#ifndef TRIANGLE_MESH_SCENE_H +#define TRIANGLE_MESH_SCENE_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" +#include "Box.h" +#include "SceneDemo.h" +#include "ConcaveMesh.h" +#include "Sphere.h" + +namespace trianglemeshscene { + +// Constants +const float SCENE_RADIUS = 30.0f; // Radius of the scene in meters + +// Class TriangleMeshScene +class ConcaveMeshScene : public SceneDemo { + + protected : + + // -------------------- Attributes -------------------- // + + Sphere* mSphere; + + /// Concave triangles mesh + ConcaveMesh* mConcaveMesh; + + /// Dynamics world used for the physics simulation + rp3d::DynamicsWorld* mDynamicsWorld; + + public: + + // -------------------- Methods -------------------- // + + /// Constructor + ConcaveMeshScene(const std::string& name); + + /// Destructor + virtual ~ConcaveMeshScene(); + + /// Update the physics world (take a simulation step) + /// Can be called several times per frame + virtual void updatePhysics(); + + /// Update the scene (take a simulation step) + virtual void update(); + + /// Render the scene in a single pass + virtual void renderSinglePass(openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); + + /// Reset the scene + virtual void reset(); + + /// Return all the contact points of the scene + virtual std::vector getContactPoints() const; +}; + +// Return all the contact points of the scene +inline std::vector ConcaveMeshScene::getContactPoints() const { + return computeContactPointsOfWorld(mDynamicsWorld); +} + +} + +#endif diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index fc958671..ec8ea200 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -33,12 +33,14 @@ #include "joints/JointsScene.h" #include "collisionshapes/CollisionShapesScene.h" #include "raycast/RaycastScene.h" +#include "concavemesh/ConcaveMeshScene.h" using namespace openglframework; using namespace jointsscene; using namespace cubesscene; using namespace raycastscene; using namespace collisionshapesscene; +using namespace trianglemeshscene; // Initialization of static variables const float TestbedApplication::SCROLL_SENSITIVITY = 0.02f; @@ -166,6 +168,10 @@ void TestbedApplication::createScenes() { RaycastScene* raycastScene = new RaycastScene("Raycast"); mScenes.push_back(raycastScene); + // Raycast scene + ConcaveMeshScene* concaveMeshScene = new ConcaveMeshScene("Concave Mesh"); + mScenes.push_back(concaveMeshScene); + assert(mScenes.size() > 0); mCurrentScene = mScenes[0];