diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index a5620028..e5e3b312 100644 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -94,6 +94,8 @@ SET(COMMON_SOURCES common/VisualContactPoint.cpp common/PerlinNoise.h common/PerlinNoise.cpp + common/AABB.h + common/AABB.cpp ) # Examples scenes source files diff --git a/testbed/common/AABB.cpp b/testbed/common/AABB.cpp new file mode 100644 index 00000000..8c43700c --- /dev/null +++ b/testbed/common/AABB.cpp @@ -0,0 +1,202 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2016 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 "AABB.h" + +// Macros +#define MEMBER_OFFSET(s,m) ((char *)nullptr + (offsetof(s,m))) + +// Initialize static variables +openglframework::VertexBufferObject AABB::mVBOVertices(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject AABB::mVBONormals(GL_ARRAY_BUFFER); +openglframework::VertexBufferObject AABB::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); +openglframework::VertexArrayObject AABB::mVAO; + + +// Initialize the data to render AABBs +void AABB::init() { + createVBOAndVAO(); +} + +// Destroy the data used to render AABBs +void AABB::destroy() { + + // Destroy the VBOs and VAO + mVBOVertices.destroy(); + mVBONormals.destroy(); + mVAO.destroy(); +} + +// Render the AABB +void AABB::render(const openglframework::Vector3& position, const openglframework::Vector3& dimension, + openglframework::Color color, openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix) { + + // Render in wireframe mode + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + // Bind the shader + shader.bind(); + + // Transform matrix + openglframework::Matrix4 transformMatrix = openglframework::Matrix4::identity(); + transformMatrix = openglframework::Matrix4::translationMatrix(position) * transformMatrix; + + // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the + // model-view matrix) + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * transformMatrix; + const openglframework::Matrix3 normalMatrix = + localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); + shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false); + + + // Compute the scaling matrix + openglframework::Matrix4 scalingMatrix = openglframework::Matrix4(dimension.x, 0, 0, 0, + 0, dimension.y, 0, 0, + 0, 0, dimension.z, 0, + 0, 0, 0, 1); + + transformMatrix = transformMatrix * scalingMatrix; + + // Set the model to camera matrix + shader.setMatrix4x4Uniform("localToWorldMatrix", transformMatrix); + shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix); + + // Set the vertex color + openglframework::Vector4 colorVec(color.r, color.g, color.b, color.a); + shader.setVector4Uniform("vertexColor", colorVec, false); + + // Bind the VAO + mVAO.bind(); + + mVBOVertices.bind(); + + // Get the location of shader attribute variables + GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); + GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); + + glEnableVertexAttribArray(vertexPositionLoc); + glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)nullptr); + + mVBONormals.bind(); + + if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)nullptr); + if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); + + // Draw the geometry + glDrawElements(GL_LINES, 12 * 2, GL_UNSIGNED_INT, (char*)nullptr); + + glDisableVertexAttribArray(vertexPositionLoc); + if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc); + + mVBONormals.unbind(); + mVBOVertices.unbind(); + + // Unbind the VAO + mVAO.unbind(); + + // Unbind the shader + shader.unbind(); + + // Disable wireframe mode + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +} + +// Create the Vertex Buffer Objects used to render to box with OpenGL. +/// We create two VBOs (one for vertices and one for indices) +void AABB::createVBOAndVAO() { + + std::vector vertices; + std::vector normals; + std::vector indices; + + // Vertices + vertices.push_back(openglframework::Vector3(-0.5, -0.5, 0.5)); + vertices.push_back(openglframework::Vector3(0.5, -0.5, 0.5)); + vertices.push_back(openglframework::Vector3(0.5, 0.5, 0.5)); + vertices.push_back(openglframework::Vector3(-0.5, 0.5, 0.5)); + vertices.push_back(openglframework::Vector3(0.5, -0.5, -0.5)); + vertices.push_back(openglframework::Vector3(0.5, 0.5, -0.5)); + vertices.push_back(openglframework::Vector3(-0.5, 0.5, -0.5)); + vertices.push_back(openglframework::Vector3(-0.5, -0.5, -0.5)); + + // Normals + normals.push_back(openglframework::Vector3(1, -1, 1)); + normals.push_back(openglframework::Vector3(1, 1, 1)); + normals.push_back(openglframework::Vector3(-1, 1, 1)); + normals.push_back(openglframework::Vector3(-1, -1, 1)); + normals.push_back(openglframework::Vector3(1, -1, -1)); + normals.push_back(openglframework::Vector3(1, 1, -1)); + normals.push_back(openglframework::Vector3(-1, 1, -1)); + normals.push_back(openglframework::Vector3(-1, -1, -1)); + + // Indices + indices.push_back(0); indices.push_back(1); indices.push_back(1); indices.push_back(2); + indices.push_back(2); indices.push_back(3); indices.push_back(3); indices.push_back(0); + + indices.push_back(4); indices.push_back(5); indices.push_back(5); indices.push_back(6); + indices.push_back(6); indices.push_back(7); indices.push_back(7); indices.push_back(4); + + indices.push_back(1); indices.push_back(4); indices.push_back(2); indices.push_back(5); + indices.push_back(0); indices.push_back(7); indices.push_back(3); indices.push_back(6); + + // Create the VBO for the vertices data + mVBOVertices.create(); + mVBOVertices.bind(); + GLsizei sizeVertices = static_cast(vertices.size() * sizeof(openglframework::Vector3)); + mVBOVertices.copyDataIntoVBO(sizeVertices, &(vertices[0]), GL_STATIC_DRAW); + mVBOVertices.unbind(); + + // Create the VBO for the normals data + mVBONormals.create(); + mVBONormals.bind(); + GLsizei sizeNormals = static_cast(normals.size() * sizeof(openglframework::Vector3)); + mVBONormals.copyDataIntoVBO(sizeNormals, &(normals[0]), GL_STATIC_DRAW); + mVBONormals.unbind(); + + // Create th VBO for the indices data + mVBOIndices.create(); + mVBOIndices.bind(); + GLsizei sizeIndices = static_cast(indices.size() * sizeof(unsigned int)); + mVBOIndices.copyDataIntoVBO(sizeIndices, &(indices[0]), GL_STATIC_DRAW); + mVBOIndices.unbind(); + + // Create the VAO for both VBOs + mVAO.create(); + mVAO.bind(); + + // Bind the VBO of vertices + mVBOVertices.bind(); + + // Bind the VBO of normals + mVBONormals.bind(); + + // Bind the VBO of indices + mVBOIndices.bind(); + + // Unbind the VAO + mVAO.unbind(); +} diff --git a/testbed/common/AABB.h b/testbed/common/AABB.h new file mode 100644 index 00000000..e73326b5 --- /dev/null +++ b/testbed/common/AABB.h @@ -0,0 +1,79 @@ +/******************************************************************************** + * ReactPhysics3D physics library, http://www.reactphysics3d.com * + * Copyright (c) 2010-2016 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 AABB_H +#define AABB_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" + +// Class AABB +class AABB { + + private : + + // -------------------- Attributes -------------------- // + + /// Size of each side of the box + float mSize[3]; + + /// Scaling matrix (applied to a cube to obtain the correct box dimensions) + openglframework::Matrix4 mScalingMatrix; + + /// Vertex Buffer Object for the vertices data + static openglframework::VertexBufferObject mVBOVertices; + + /// Vertex Buffer Object for the normals data + static openglframework::VertexBufferObject mVBONormals; + + /// Vertex Buffer Object for the indices + static openglframework::VertexBufferObject mVBOIndices; + + /// Vertex Array Object for the vertex data + static openglframework::VertexArrayObject mVAO; + + // -------------------- Methods -------------------- // + + /// Create a the VAO and VBOs to render to box with OpenGL + static void createVBOAndVAO(); + + public : + + // -------------------- Methods -------------------- // + + /// Initialize the data to render AABBs + static void init(); + + /// Destroy the data used to render AABBs + static void destroy(); + + /// Render the cube at the correct position and with the correct orientation + static void render(const openglframework::Vector3& position, const openglframework::Vector3& dimension, + openglframework::Color color, openglframework::Shader& shader, + const openglframework::Matrix4& worldToCameraMatrix); +}; + +#endif diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index 09dc388e..508fa516 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -38,8 +38,8 @@ openglframework::VertexArrayObject Box::mVAO; int Box::totalNbBoxes = 0; // Constructor -Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, - reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath) +Box::Box(const openglframework::Vector3& size, reactphysics3d::CollisionWorld* world, + const std::string& meshFolderPath) : PhysicsObject(meshFolderPath + "cube.obj") { // Initialize the size of the box @@ -53,23 +53,16 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p 0, 0, mSize[2], 0, 0, 0, 0, 1); - // Initialize the position where the cube will be rendered - translateWorld(position); - // Create the collision shape for the rigid body (box shape) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() mBoxShape = new rp3d::BoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); + //mBoxShape->setLocalScaling(rp3d::Vector3(2, 2, 2)); - // 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; + mPreviousTransform = rp3d::Transform::identity(); // Create a rigid body in the dynamics world - mBody = world->createCollisionBody(transform); + mBody = world->createCollisionBody(mPreviousTransform); // Add the collision shape to the body mProxyShape = mBody->addCollisionShape(mBoxShape, rp3d::Transform::identity()); @@ -87,8 +80,8 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p } // Constructor -Box::Box(const openglframework::Vector3& size, const openglframework::Vector3& position, - float mass, reactphysics3d::DynamicsWorld* world, const std::string& meshFolderPath) +Box::Box(const openglframework::Vector3& size, float mass, reactphysics3d::DynamicsWorld* world, + const std::string& meshFolderPath) : PhysicsObject(meshFolderPath + "cube.obj") { // Load the mesh from a file @@ -108,23 +101,15 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3& p 0, 0, mSize[2], 0, 0, 0, 0, 1); - // Initialize the position where the cube will be rendered - translateWorld(position); - // Create the collision shape for the rigid body (box shape) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() mBoxShape = new rp3d::BoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); - rp3d::Transform transform(initPosition, initOrientation); - - mPreviousTransform = transform; + mPreviousTransform = rp3d::Transform::identity(); // Create a rigid body in the dynamics world - rp3d::RigidBody* body = world->createRigidBody(transform); + rp3d::RigidBody* body = world->createRigidBody(mPreviousTransform); // Add the collision shape to the body mProxyShape = body->addCollisionShape(mBoxShape, rp3d::Transform::identity(), mass); @@ -158,12 +143,7 @@ Box::~Box() { } // Render the cube at the correct position and with the correct orientation -void Box::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) { - - if (wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } +void Box::render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { // Bind the shader shader.bind(); @@ -217,10 +197,6 @@ void Box::render(openglframework::Shader& shader, // Unbind the shader shader.unbind(); - - if (wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } } // Create the Vertex Buffer Objects used to render to box with OpenGL. diff --git a/testbed/common/Box.h b/testbed/common/Box.h index bd7a6024..42d234f9 100644 --- a/testbed/common/Box.h +++ b/testbed/common/Box.h @@ -75,24 +75,22 @@ class Box : public PhysicsObject { // -------------------- Methods -------------------- // /// Constructor - Box(const openglframework::Vector3& size, const openglframework::Vector3& position, - reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath); + Box(const openglframework::Vector3& size, reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath); /// Constructor - Box(const openglframework::Vector3& size, const openglframework::Vector3& position, - float mass, reactphysics3d::DynamicsWorld *world, const std::string& meshFolderPath); + Box(const openglframework::Vector3& size, float mass, reactphysics3d::DynamicsWorld *world, const std::string& meshFolderPath); /// Destructor ~Box(); /// Render the cube at the correct position and with the correct orientation - virtual void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) override; + virtual void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) override; /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; /// Set the scaling of the object - void setScaling(const openglframework::Vector3& scaling); + void setScaling(const openglframework::Vector3& scaling) override; }; // Update the transform matrix of the object diff --git a/testbed/common/Capsule.cpp b/testbed/common/Capsule.cpp index 413d6eb2..b48baf69 100644 --- a/testbed/common/Capsule.cpp +++ b/testbed/common/Capsule.cpp @@ -34,9 +34,7 @@ openglframework::VertexArrayObject Capsule::mVAO; int Capsule::totalNbCapsules = 0; // Constructor -Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, - reactphysics3d::CollisionWorld* world, - const std::string& meshFolderPath) +Capsule::Capsule(float radius, float height, rp3d::CollisionWorld* world, const std::string& meshFolderPath) : PhysicsObject(meshFolderPath + "capsule.obj"), mRadius(radius), mHeight(height) { // Compute the scaling matrix @@ -45,23 +43,16 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos 0, 0, mRadius, 0, 0, 0, 0, 1.0f); - // Initialize the position where the sphere will be rendered - translateWorld(position); - // Create the collision shape for the rigid body (sphere shape) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() mCapsuleShape = new rp3d::CapsuleShape(mRadius, mHeight); + //mCapsuleShape->setLocalScaling(rp3d::Vector3(2, 2, 2)); - // 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; + mPreviousTransform = rp3d::Transform::identity(); // Create a rigid body corresponding in the dynamics world - mBody = world->createCollisionBody(transform); + mBody = world->createCollisionBody(mPreviousTransform); // Add a collision shape to the body and specify the mass of the shape mProxyShape = mBody->addCollisionShape(mCapsuleShape, rp3d::Transform::identity()); @@ -77,8 +68,7 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos } // Constructor -Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, - float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, +Capsule::Capsule(float radius, float height, float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath) : PhysicsObject(meshFolderPath + "capsule.obj"), mRadius(radius), mHeight(height) { @@ -88,21 +78,15 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos 0, 0, mRadius, 0, 0, 0, 0, 1.0f); - // Initialize the position where the sphere will be rendered - translateWorld(position); + mPreviousTransform = rp3d::Transform::identity(); // Create the collision shape for the rigid body (sphere shape) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() mCapsuleShape = new rp3d::CapsuleShape(mRadius, mHeight); - // 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 in the dynamics world - rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); + rp3d::RigidBody* body = dynamicsWorld->createRigidBody(mPreviousTransform); // Add a collision shape to the body and specify the mass of the shape mProxyShape = body->addCollisionShape(mCapsuleShape, rp3d::Transform::identity(), mass); @@ -140,11 +124,7 @@ Capsule::~Capsule() { // Render the sphere at the correct position and with the correct orientation void Capsule::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) { - - if (wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } + const openglframework::Matrix4& worldToCameraMatrix) { // Bind the shader shader.bind(); @@ -198,10 +178,6 @@ void Capsule::render(openglframework::Shader& shader, // Unbind the shader shader.unbind(); - - if (wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } } // Create the Vertex Buffer Objects used to render with OpenGL. diff --git a/testbed/common/Capsule.h b/testbed/common/Capsule.h index 5c99120b..d0e74436 100644 --- a/testbed/common/Capsule.h +++ b/testbed/common/Capsule.h @@ -82,25 +82,23 @@ class Capsule : public PhysicsObject { // -------------------- Methods -------------------- // /// Constructor - Capsule(float radius, float height, const openglframework::Vector3& position, - reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath); + Capsule(float radius, float height, rp3d::CollisionWorld* world, const std::string& meshFolderPath); /// Constructor - Capsule(float radius, float height, const openglframework::Vector3& position, - float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, + Capsule(float radius, float height, float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); /// Destructor ~Capsule(); /// Render the sphere at the correct position and with the correct orientation - virtual void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) override; + virtual void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) override; /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; /// Set the scaling of the object - void setScaling(const openglframework::Vector3& scaling); + void setScaling(const openglframework::Vector3& scaling) override; }; // Update the transform matrix of the object diff --git a/testbed/common/ConcaveMesh.cpp b/testbed/common/ConcaveMesh.cpp index c7e162a3..f6b04b9c 100644 --- a/testbed/common/ConcaveMesh.cpp +++ b/testbed/common/ConcaveMesh.cpp @@ -27,16 +27,11 @@ #include "ConcaveMesh.h" // Constructor -ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position, - reactphysics3d::CollisionWorld* world, - const std::string& meshPath) +ConcaveMesh::ConcaveMesh(rp3d::CollisionWorld* world, const std::string& meshPath) : PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { - // Initialize the position where the sphere will be rendered - translateWorld(position); - // Compute the scaling matrix mScalingMatrix = openglframework::Matrix4::identity(); @@ -58,15 +53,10 @@ ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position, // do not forget to delete it at the end mConcaveShape = new rp3d::ConcaveMeshShape(&mPhysicsTriangleMesh); - // 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; + mPreviousTransform = rp3d::Transform::identity(); // Create a rigid body corresponding to the sphere in the dynamics world - mBody = world->createCollisionBody(transform); + mBody = world->createCollisionBody(mPreviousTransform); // Add a collision shape to the body and specify the mass of the collision shape mProxyShape = mBody->addCollisionShape(mConcaveShape, rp3d::Transform::identity()); @@ -78,16 +68,11 @@ ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position, } // Constructor -ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position, float mass, - reactphysics3d::DynamicsWorld* dynamicsWorld, - const std::string& meshPath) +ConcaveMesh::ConcaveMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath) : PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { - // Initialize the position where the sphere will be rendered - translateWorld(position); - // Compute the scaling matrix mScalingMatrix = openglframework::Matrix4::identity(); @@ -109,13 +94,10 @@ ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position, float mass, // do not forget to delete it at the end mConcaveShape = new rp3d::ConcaveMeshShape(&mPhysicsTriangleMesh); - // 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 = rp3d::Transform::identity(); // Create a rigid body corresponding to the sphere in the dynamics world - rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); + rp3d::RigidBody* body = dynamicsWorld->createRigidBody(mPreviousTransform); // Add a collision shape to the body and specify the mass of the collision shape mProxyShape = body->addCollisionShape(mConcaveShape, rp3d::Transform::identity(), mass); @@ -151,11 +133,7 @@ ConcaveMesh::~ConcaveMesh() { // Render the sphere at the correct position and with the correct orientation void ConcaveMesh::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) { - - if (wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } + const openglframework::Matrix4& worldToCameraMatrix) { // Bind the shader shader.bind(); @@ -209,10 +187,6 @@ void ConcaveMesh::render(openglframework::Shader& shader, // Unbind the shader shader.unbind(); - - if (wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } } // Create the Vertex Buffer Objects used to render with OpenGL. diff --git a/testbed/common/ConcaveMesh.h b/testbed/common/ConcaveMesh.h index afda3d45..17755352 100644 --- a/testbed/common/ConcaveMesh.h +++ b/testbed/common/ConcaveMesh.h @@ -76,25 +76,23 @@ class ConcaveMesh : public PhysicsObject { // -------------------- Methods -------------------- // /// Constructor - ConcaveMesh(const openglframework::Vector3& position, - rp3d::CollisionWorld* world, const std::string& meshPath); + ConcaveMesh(rp3d::CollisionWorld* world, const std::string& meshPath); /// Constructor - ConcaveMesh(const openglframework::Vector3& position, float mass, - rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath); + ConcaveMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath); /// Destructor ~ConcaveMesh(); /// Render the mesh at the correct position and with the correct orientation void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix, bool wireframe); + const openglframework::Matrix4& worldToCameraMatrix) override; /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; /// Set the scaling of the object - void setScaling(const openglframework::Vector3& scaling); + void setScaling(const openglframework::Vector3& scaling) override; }; // Update the transform matrix of the object diff --git a/testbed/common/ConvexMesh.cpp b/testbed/common/ConvexMesh.cpp index b3cb3b95..a59c2f3d 100644 --- a/testbed/common/ConvexMesh.cpp +++ b/testbed/common/ConvexMesh.cpp @@ -27,16 +27,11 @@ #include "ConvexMesh.h" // Constructor -ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, - reactphysics3d::CollisionWorld* world, - const std::string& meshPath) +ConvexMesh::ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath) : PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { - // Initialize the position where the sphere will be rendered - translateWorld(position); - // Compute the scaling matrix mScalingMatrix = openglframework::Matrix4::identity(); @@ -64,15 +59,10 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, // do not forget to delete it at the end mConvexShape = new rp3d::ConvexMeshShape(mPolyhedronMesh); - // 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; + mPreviousTransform = rp3d::Transform::identity(); // Create a rigid body corresponding to the sphere in the dynamics world - mBody = world->createCollisionBody(transform); + mBody = world->createCollisionBody(mPreviousTransform); // Add a collision shape to the body and specify the mass of the collision shape mProxyShape = mBody->addCollisionShape(mConvexShape, rp3d::Transform::identity()); @@ -84,16 +74,11 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, } // Constructor -ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, - reactphysics3d::DynamicsWorld* dynamicsWorld, - const std::string& meshPath) +ConvexMesh::ConvexMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath) : PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { - // Initialize the position where the sphere will be rendered - translateWorld(position); - // Compute the scaling matrix mScalingMatrix = openglframework::Matrix4::identity(); @@ -121,13 +106,10 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, // not forget to delete it at the end mConvexShape = new rp3d::ConvexMeshShape(mPolyhedronMesh); - // 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 = rp3d::Transform::identity(); // Create a rigid body corresponding to the sphere in the dynamics world - rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); + rp3d::RigidBody* body = dynamicsWorld->createRigidBody(mPreviousTransform); // Add a collision shape to the body and specify the mass of the collision shape mProxyShape = body->addCollisionShape(mConvexShape, rp3d::Transform::identity(), mass); @@ -161,11 +143,7 @@ ConvexMesh::~ConvexMesh() { // Render the sphere at the correct position and with the correct orientation void ConvexMesh::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) { - - if (wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } + const openglframework::Matrix4& worldToCameraMatrix) { // Bind the shader shader.bind(); @@ -219,10 +197,6 @@ void ConvexMesh::render(openglframework::Shader& shader, // Unbind the shader shader.unbind(); - - if (wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } } // Create the Vertex Buffer Objects used to render with OpenGL. diff --git a/testbed/common/ConvexMesh.h b/testbed/common/ConvexMesh.h index 1b55611b..865921ca 100644 --- a/testbed/common/ConvexMesh.h +++ b/testbed/common/ConvexMesh.h @@ -79,24 +79,22 @@ class ConvexMesh : public PhysicsObject { // -------------------- Methods -------------------- // /// Constructor - ConvexMesh(const openglframework::Vector3& position, - rp3d::CollisionWorld* world, const std::string& meshPath); + ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath); /// Constructor - ConvexMesh(const openglframework::Vector3& position, float mass, - rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath); + ConvexMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath); /// Destructor ~ConvexMesh(); /// Render the mesh at the correct position and with the correct orientation - virtual void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) override; + virtual void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) override; /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; /// Set the scaling of the object - void setScaling(const openglframework::Vector3& scaling); + void setScaling(const openglframework::Vector3& scaling) override; }; // Update the transform matrix of the object diff --git a/testbed/common/Dumbbell.cpp b/testbed/common/Dumbbell.cpp index 02afe091..f90f0cc9 100644 --- a/testbed/common/Dumbbell.cpp +++ b/testbed/common/Dumbbell.cpp @@ -34,8 +34,7 @@ openglframework::VertexArrayObject Dumbbell::mVAO; int Dumbbell::totalNbDumbbells = 0; // Constructor -Dumbbell::Dumbbell(const openglframework::Vector3 &position, - reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath) +Dumbbell::Dumbbell(rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath) : PhysicsObject(meshFolderPath + "dumbbell.obj") { // Identity scaling matrix @@ -43,9 +42,6 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position, mDistanceBetweenSphere = 8.0f; - // Initialize the position where the sphere will be rendered - translateWorld(position); - // Create a sphere collision shape for the two ends of the dumbbell // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() @@ -61,13 +57,7 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position, const rp3d::decimal massCylinder = rp3d::decimal(1.0); mCapsuleShape = new rp3d::CapsuleShape(radiusCapsule, heightCapsule); - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::decimal angleAroundX = 0;//rp3d::PI / 2; - rp3d::Quaternion initOrientation(angleAroundX, 0, 0); - rp3d::Transform transformBody(initPosition, initOrientation); - - mPreviousTransform = transformBody; + mPreviousTransform = rp3d::Transform::identity(); // Initial transform of the first sphere collision shape of the dumbbell (in local-space) rp3d::Transform transformSphereShape1(rp3d::Vector3(0, mDistanceBetweenSphere / 2.0f, 0), rp3d::Quaternion::identity()); @@ -79,7 +69,7 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position, rp3d::Transform transformCylinderShape(rp3d::Vector3(0, 0, 0), rp3d::Quaternion::identity()); // Create a rigid body corresponding to the dumbbell in the dynamics world - rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transformBody); + rp3d::RigidBody* body = dynamicsWorld->createRigidBody(mPreviousTransform); // Add the three collision shapes to the body and specify the mass and transform of the shapes mProxyShapeSphere1 = body->addCollisionShape(mSphereShape, transformSphereShape1, massSphere); @@ -99,8 +89,7 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position, } // Constructor -Dumbbell::Dumbbell(const openglframework::Vector3 &position, - reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath) +Dumbbell::Dumbbell(rp3d::CollisionWorld* world, const std::string& meshFolderPath) : PhysicsObject(meshFolderPath + "dumbbell.obj"){ // Identity scaling matrix @@ -108,9 +97,6 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position, mDistanceBetweenSphere = 8.0f; - // Initialize the position where the sphere will be rendered - translateWorld(position); - // Create a sphere collision shape for the two ends of the dumbbell // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() @@ -124,12 +110,6 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position, const rp3d::decimal heightCapsule = rp3d::decimal(7.0); mCapsuleShape = new rp3d::CapsuleShape(radiusCapsule, heightCapsule); - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::decimal angleAroundX = 0;//rp3d::PI / 2; - rp3d::Quaternion initOrientation(angleAroundX, 0, 0); - rp3d::Transform transformBody(initPosition, initOrientation); - // Initial transform of the first sphere collision shape of the dumbbell (in local-space) rp3d::Transform transformSphereShape1(rp3d::Vector3(0, mDistanceBetweenSphere / 2.0f, 0), rp3d::Quaternion::identity()); @@ -139,8 +119,10 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position, // Initial transform of the cylinder collision shape of the dumbell (in local-space) rp3d::Transform transformCylinderShape(rp3d::Vector3(0, 0, 0), rp3d::Quaternion::identity()); + mPreviousTransform = rp3d::Transform::identity(); + // Create a rigid body corresponding to the dumbbell in the dynamics world - mBody = world->createCollisionBody(transformBody); + mBody = world->createCollisionBody(mPreviousTransform); // Add the three collision shapes to the body and specify the mass and transform of the shapes mProxyShapeSphere1 = mBody->addCollisionShape(mSphereShape, transformSphereShape1); @@ -179,11 +161,7 @@ Dumbbell::~Dumbbell() { // Render the sphere at the correct position and with the correct orientation void Dumbbell::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) { - - if (wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } + const openglframework::Matrix4& worldToCameraMatrix) { // Bind the shader shader.bind(); @@ -237,10 +215,6 @@ void Dumbbell::render(openglframework::Shader& shader, // Unbind the shader shader.unbind(); - - if (wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } } // Create the Vertex Buffer Objects used to render with OpenGL. diff --git a/testbed/common/Dumbbell.h b/testbed/common/Dumbbell.h index aa6bded1..135beabc 100644 --- a/testbed/common/Dumbbell.h +++ b/testbed/common/Dumbbell.h @@ -82,24 +82,22 @@ class Dumbbell : public PhysicsObject { // -------------------- Methods -------------------- // /// Constructor - Dumbbell(const openglframework::Vector3& position, rp3d::DynamicsWorld* dynamicsWorld, - const std::string& meshFolderPath); + Dumbbell(rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); /// Constructor - Dumbbell(const openglframework::Vector3& position, rp3d::CollisionWorld* world, - const std::string& meshFolderPath); + Dumbbell(rp3d::CollisionWorld* world, const std::string& meshFolderPath); /// Destructor ~Dumbbell(); /// Render the sphere at the correct position and with the correct orientation - virtual void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) override; + virtual void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) override; /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; /// Set the scaling of the object - void setScaling(const openglframework::Vector3& scaling); + void setScaling(const openglframework::Vector3& scaling) override; }; // Update the transform matrix of the object diff --git a/testbed/common/HeightField.cpp b/testbed/common/HeightField.cpp index 377cab07..e979936d 100644 --- a/testbed/common/HeightField.cpp +++ b/testbed/common/HeightField.cpp @@ -28,15 +28,11 @@ #include "PerlinNoise.h" // Constructor -HeightField::HeightField(const openglframework::Vector3 &position, - reactphysics3d::CollisionWorld* world) +HeightField::HeightField(rp3d::CollisionWorld* world) : mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { - // Initialize the position where the sphere will be rendered - translateWorld(position); - // Compute the scaling matrix mScalingMatrix = openglframework::Matrix4::identity(); @@ -51,15 +47,10 @@ HeightField::HeightField(const openglframework::Vector3 &position, mHeightFieldShape = new rp3d::HeightFieldShape(NB_POINTS_WIDTH, NB_POINTS_LENGTH, mMinHeight, mMaxHeight, mHeightData, rp3d::HeightFieldShape::HeightDataType::HEIGHT_FLOAT_TYPE); - // 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; + mPreviousTransform = rp3d::Transform::identity(); // Create a rigid body corresponding to the sphere in the dynamics world - mBody = world->createCollisionBody(transform); + mBody = world->createCollisionBody(mPreviousTransform); // Add a collision shape to the body and specify the mass of the collision shape mProxyShape = mBody->addCollisionShape(mHeightFieldShape, rp3d::Transform::identity()); @@ -71,15 +62,11 @@ HeightField::HeightField(const openglframework::Vector3 &position, } // Constructor -HeightField::HeightField(const openglframework::Vector3 &position, float mass, - reactphysics3d::DynamicsWorld* dynamicsWorld) +HeightField::HeightField(float mass, rp3d::DynamicsWorld* dynamicsWorld) : mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { - // Initialize the position where the sphere will be rendered - translateWorld(position); - // Compute the scaling matrix mScalingMatrix = openglframework::Matrix4::identity(); @@ -94,13 +81,10 @@ HeightField::HeightField(const openglframework::Vector3 &position, float mass, mHeightFieldShape = new rp3d::HeightFieldShape(NB_POINTS_WIDTH, NB_POINTS_LENGTH, mMinHeight, mMaxHeight, mHeightData, rp3d::HeightFieldShape::HeightDataType::HEIGHT_FLOAT_TYPE); - // 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 = rp3d::Transform::identity(); // Create a rigid body corresponding to the sphere in the dynamics world - rp3d::RigidBody* body = dynamicsWorld->createRigidBody(transform); + rp3d::RigidBody* body = dynamicsWorld->createRigidBody(mPreviousTransform); // Add a collision shape to the body and specify the mass of the collision shape mProxyShape = body->addCollisionShape(mHeightFieldShape, rp3d::Transform::identity(), mass); @@ -131,11 +115,7 @@ HeightField::~HeightField() { // Render the sphere at the correct position and with the correct orientation void HeightField::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) { - - if (wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } + const openglframework::Matrix4& worldToCameraMatrix) { // Bind the shader shader.bind(); @@ -189,10 +169,6 @@ void HeightField::render(openglframework::Shader& shader, // Unbind the shader shader.unbind(); - - if (wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } } // Compute the heights of the height field diff --git a/testbed/common/HeightField.h b/testbed/common/HeightField.h index acb39163..1ff390ee 100644 --- a/testbed/common/HeightField.h +++ b/testbed/common/HeightField.h @@ -89,25 +89,23 @@ class HeightField : public PhysicsObject { // -------------------- Methods -------------------- // /// Constructor - HeightField(const openglframework::Vector3& position, - rp3d::CollisionWorld* world); + HeightField(rp3d::CollisionWorld* world); /// Constructor - HeightField(const openglframework::Vector3& position, float mass, - rp3d::DynamicsWorld* dynamicsWorld); + HeightField(float mass, rp3d::DynamicsWorld* dynamicsWorld); /// Destructor ~HeightField(); /// Render the mesh at the correct position and with the correct orientation void render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix, bool wireframe); + const openglframework::Matrix4& worldToCameraMatrix) override; /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; /// Set the scaling of the object - void setScaling(const openglframework::Vector3& scaling); + void setScaling(const openglframework::Vector3& scaling) override; }; // Update the transform matrix of the object diff --git a/testbed/common/PhysicsObject.h b/testbed/common/PhysicsObject.h index 7fcc612d..e1714048 100644 --- a/testbed/common/PhysicsObject.h +++ b/testbed/common/PhysicsObject.h @@ -63,7 +63,7 @@ class PhysicsObject : public openglframework::Mesh { 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; + virtual void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix)=0; /// Set the color of the box void setColor(const openglframework::Color& color); diff --git a/testbed/common/Sphere.cpp b/testbed/common/Sphere.cpp index 9eaf62c2..f7c53579 100644 --- a/testbed/common/Sphere.cpp +++ b/testbed/common/Sphere.cpp @@ -34,8 +34,7 @@ openglframework::VertexArrayObject Sphere::mVAO; int Sphere::totalNbSpheres = 0; // Constructor -Sphere::Sphere(float radius, const openglframework::Vector3 &position, - reactphysics3d::CollisionWorld* world, +Sphere::Sphere(float radius, rp3d::CollisionWorld* world, const std::string& meshFolderPath) : PhysicsObject(meshFolderPath + "sphere.obj"), mRadius(radius) { @@ -45,23 +44,16 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position, 0, 0, mRadius, 0, 0, 0, 0, 1); - // Initialize the position where the sphere will be rendered - translateWorld(position); - // Create the collision shape for the rigid body (sphere shape) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() mCollisionShape = new rp3d::SphereShape(mRadius); + //mCollisionShape->setLocalScaling(rp3d::Vector3(2, 2, 2)); - // 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; + mPreviousTransform = rp3d::Transform::identity(); // Create a rigid body corresponding to the sphere in the dynamics world - mBody = world->createCollisionBody(transform); + mBody = world->createCollisionBody(mPreviousTransform); // Add a collision shape to the body and specify the mass of the shape mProxyShape = mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity()); @@ -77,8 +69,7 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position, } // Constructor -Sphere::Sphere(float radius, const openglframework::Vector3 &position, - float mass, reactphysics3d::DynamicsWorld* world, +Sphere::Sphere(float radius, float mass, reactphysics3d::DynamicsWorld* world, const std::string& meshFolderPath) : PhysicsObject(meshFolderPath + "sphere.obj"), mRadius(radius) { @@ -88,21 +79,15 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position, 0, 0, mRadius, 0, 0, 0, 0, 1); - // Initialize the position where the sphere will be rendered - translateWorld(position); - // Create the collision shape for the rigid body (sphere shape) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() mCollisionShape = new rp3d::SphereShape(mRadius); - // 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 = rp3d::Transform::identity(); // Create a rigid body corresponding to the sphere in the dynamics world - rp3d::RigidBody* body = world->createRigidBody(transform); + rp3d::RigidBody* body = world->createRigidBody(mPreviousTransform); // Add a collision shape to the body and specify the mass of the shape mProxyShape = body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass); @@ -138,11 +123,7 @@ Sphere::~Sphere() { } // Render the sphere at the correct position and with the correct orientation -void Sphere::render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix, bool wireFrame) { - - if (wireFrame) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } +void Sphere::render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { // Bind the shader shader.bind(); @@ -196,10 +177,6 @@ void Sphere::render(openglframework::Shader& shader, const openglframework::Matr // Unbind the shader shader.unbind(); - - if (wireFrame) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } } // Create the Vertex Buffer Objects used to render with OpenGL. diff --git a/testbed/common/Sphere.h b/testbed/common/Sphere.h index 000cc776..fe2b3f83 100644 --- a/testbed/common/Sphere.h +++ b/testbed/common/Sphere.h @@ -79,24 +79,22 @@ class Sphere : public PhysicsObject { // -------------------- Methods -------------------- // /// Constructor - Sphere(float radius, const openglframework::Vector3& position, - rp3d::CollisionWorld* world, const std::string& meshFolderPath); + Sphere(float radius, rp3d::CollisionWorld* world, const std::string& meshFolderPath); /// Constructor - Sphere(float radius, const openglframework::Vector3& position, - float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); + Sphere(float radius, float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); /// Destructor ~Sphere(); /// Render the sphere at the correct position and with the correct orientation - void virtual render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) override; + void virtual render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) override; /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor) override; /// Set the scaling of the object - void setScaling(const openglframework::Vector3& scaling); + void setScaling(const openglframework::Vector3& scaling) override; }; // Update the transform matrix of the object diff --git a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp index 3b186943..f00dbdba 100755 --- a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp +++ b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp @@ -31,8 +31,8 @@ using namespace openglframework; using namespace collisiondetectionscene; // Constructor -CollisionDetectionScene::CollisionDetectionScene(const std::string& name) - : SceneDemo(name, SCENE_RADIUS, false), mMeshFolderPath("meshes/"), +CollisionDetectionScene::CollisionDetectionScene(const std::string& name, EngineSettings& settings) + : SceneDemo(name, settings, SCENE_RADIUS, false), mMeshFolderPath("meshes/"), mContactManager(mPhongShader, mMeshFolderPath), mAreNormalsDisplayed(false) { @@ -47,61 +47,57 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) setScenePosition(center, SCENE_RADIUS); // Create the dynamics world for the physics simulation - mCollisionWorld = new rp3d::CollisionWorld(); + mPhysicsWorld = new rp3d::CollisionWorld(); // ---------- Sphere 1 ---------- // - openglframework::Vector3 position1(12, 0, 0); // Create a sphere and a corresponding collision body in the dynamics world - mSphere1 = new Sphere(4, position1, mCollisionWorld, mMeshFolderPath); + mSphere1 = new Sphere(4, mPhysicsWorld, mMeshFolderPath); mAllShapes.push_back(mSphere1); // Set the color mSphere1->setColor(mGreyColorDemo); mSphere1->setSleepingColor(mRedColorDemo); - mPhysicsObjects.push_back(mSphere1); + //mSphere1->setScaling(0.5f); + mPhysicsObjects.push_back(mSphere1); // ---------- Sphere 2 ---------- // - openglframework::Vector3 position2(12, 8, 0); // Create a sphere and a corresponding collision body in the dynamics world - mSphere2 = new Sphere(2, position2, mCollisionWorld, mMeshFolderPath); + mSphere2 = new Sphere(2, mPhysicsWorld, mMeshFolderPath); mAllShapes.push_back(mSphere2); // Set the color mSphere2->setColor(mGreyColorDemo); mSphere2->setSleepingColor(mRedColorDemo); - mPhysicsObjects.push_back(mSphere2); + mPhysicsObjects.push_back(mSphere2); - // ---------- Capsule 1 ---------- // - openglframework::Vector3 position3(-6, 7, 0); - - // Create a cylinder and a corresponding collision body in the dynamics world - mCapsule1 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position3, mCollisionWorld, mMeshFolderPath); - mAllShapes.push_back(mCapsule1); - - // Set the color - mCapsule1->setColor(mGreyColorDemo); - mCapsule1->setSleepingColor(mRedColorDemo); - mPhysicsObjects.push_back(mCapsule1); - - // ---------- Capsule 2 ---------- // - openglframework::Vector3 position4(11, -8, 0); + // ---------- Capsule 1 ---------- // // Create a cylinder and a corresponding collision body in the dynamics world - mCapsule2 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position4, mCollisionWorld, mMeshFolderPath); + mCapsule1 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath); + mAllShapes.push_back(mCapsule1); + + // Set the color + mCapsule1->setColor(mGreyColorDemo); + mCapsule1->setSleepingColor(mRedColorDemo); + mPhysicsObjects.push_back(mCapsule1); + + // ---------- Capsule 2 ---------- // + + // Create a cylinder and a corresponding collision body in the dynamics world + mCapsule2 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath); mAllShapes.push_back(mCapsule2); // Set the color mCapsule2->setColor(mGreyColorDemo); mCapsule2->setSleepingColor(mRedColorDemo); - mPhysicsObjects.push_back(mCapsule2); + mPhysicsObjects.push_back(mCapsule2); - // ---------- Box 1 ---------- // - openglframework::Vector3 position5(-4, -7, 0); + // ---------- Box 1 ---------- // // Create a cylinder and a corresponding collision body in the dynamics world - mBox1 = new Box(BOX_SIZE, position5, mCollisionWorld, mMeshFolderPath); + mBox1 = new Box(BOX_SIZE, mPhysicsWorld, mMeshFolderPath); mAllShapes.push_back(mBox1); // Set the color @@ -110,10 +106,9 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) mPhysicsObjects.push_back(mBox1); // ---------- Box 2 ---------- // - openglframework::Vector3 position6(0, 8, 0); // Create a cylinder and a corresponding collision body in the dynamics world - mBox2 = new Box(openglframework::Vector3(3, 2, 5), position6, mCollisionWorld, mMeshFolderPath); + mBox2 = new Box(openglframework::Vector3(3, 2, 5), mPhysicsWorld, mMeshFolderPath); mAllShapes.push_back(mBox2); // Set the color @@ -122,10 +117,9 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) mPhysicsObjects.push_back(mBox2); // ---------- Convex Mesh ---------- // - openglframework::Vector3 position7(-5, 0, 0); // Create a convex mesh and a corresponding collision body in the dynamics world - mConvexMesh = new ConvexMesh(position7, mCollisionWorld, mMeshFolderPath + "convexmesh.obj"); + mConvexMesh = new ConvexMesh(mPhysicsWorld, mMeshFolderPath + "convexmesh.obj"); mAllShapes.push_back(mConvexMesh); // Set the color @@ -134,10 +128,9 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) mPhysicsObjects.push_back(mConvexMesh); // ---------- Concave Mesh ---------- // - 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"); + mConcaveMesh = new ConcaveMesh(mPhysicsWorld, mMeshFolderPath + "city.obj"); mAllShapes.push_back(mConcaveMesh); // Set the color @@ -146,10 +139,9 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) mPhysicsObjects.push_back(mConcaveMesh); // ---------- Heightfield ---------- // - 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(mPhysicsWorld); // Set the color mHeightField->setColor(mGreyColorDemo); @@ -162,76 +154,59 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) // Reset the scene void CollisionDetectionScene::reset() { + mSphere1->setTransform(rp3d::Transform(rp3d::Vector3(12, 0, 0), rp3d::Quaternion::identity())); + mSphere2->setTransform(rp3d::Transform(rp3d::Vector3(12, 8, 0), rp3d::Quaternion::identity())); + mCapsule1->setTransform(rp3d::Transform(rp3d::Vector3(-6, 7, 0), rp3d::Quaternion::identity())); + mCapsule2->setTransform(rp3d::Transform(rp3d::Vector3(11, -8, 0), rp3d::Quaternion::identity())); + mBox1->setTransform(rp3d::Transform(rp3d::Vector3(-4, -7, 0), rp3d::Quaternion::identity())); + mBox2->setTransform(rp3d::Transform(rp3d::Vector3(0, 8, 0), rp3d::Quaternion::identity())); + mConvexMesh->setTransform(rp3d::Transform(rp3d::Vector3(-5, 0, 0), rp3d::Quaternion::identity())); + mConcaveMesh->setTransform(rp3d::Transform(rp3d::Vector3(0, 100, 0), rp3d::Quaternion::identity())); + mHeightField->setTransform(rp3d::Transform(rp3d::Vector3(0, -12, 0), rp3d::Quaternion::identity())); } // Destructor CollisionDetectionScene::~CollisionDetectionScene() { // Destroy the box rigid body from the dynamics world - //mCollisionWorld->destroyCollisionBody(mBox->getCollisionBody()); + //mPhysicsWorld->destroyCollisionBody(mBox->getCollisionBody()); //delete mBox; // Destroy the spheres - mCollisionWorld->destroyCollisionBody(mSphere1->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mSphere1->getCollisionBody()); delete mSphere1; - mCollisionWorld->destroyCollisionBody(mSphere2->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mSphere2->getCollisionBody()); delete mSphere2; - mCollisionWorld->destroyCollisionBody(mCapsule1->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mCapsule1->getCollisionBody()); delete mCapsule1; - mCollisionWorld->destroyCollisionBody(mCapsule2->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mCapsule2->getCollisionBody()); delete mCapsule2; - mCollisionWorld->destroyCollisionBody(mBox1->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mBox1->getCollisionBody()); delete mBox1; - mCollisionWorld->destroyCollisionBody(mBox2->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mBox2->getCollisionBody()); delete mBox2; - mCollisionWorld->destroyCollisionBody(mConvexMesh->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mConvexMesh->getCollisionBody()); delete mConvexMesh; - mCollisionWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody()); delete mConcaveMesh; - mCollisionWorld->destroyCollisionBody(mHeightField->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mHeightField->getCollisionBody()); delete mHeightField; - /* - // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mCone->getCollisionBody()); - delete mCone; - - // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mCylinder->getCollisionBody()); - - // Destroy the sphere - delete mCylinder; - - // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mCapsule->getCollisionBody()); - - // Destroy the sphere - delete mCapsule; - - // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mDumbbell->getCollisionBody()); - - // Destroy the dumbbell - delete mDumbbell; - - - */ - mContactManager.resetPoints(); // Destroy the static data for the visual contact points VisualContactPoint::destroyStaticData(); // Destroy the collision world - delete mCollisionWorld; + delete mPhysicsWorld; } // Take a step for the simulation @@ -239,14 +214,14 @@ void CollisionDetectionScene::update() { mContactManager.resetPoints(); - mCollisionWorld->testCollision(&mContactManager); + mPhysicsWorld->testCollision(&mContactManager); SceneDemo::update(); } void CollisionDetectionScene::selectNextShape() { - int previousIndex = mSelectedShapeIndex; + uint previousIndex = mSelectedShapeIndex; mSelectedShapeIndex++; if (mSelectedShapeIndex >= mAllShapes.size()) { mSelectedShapeIndex = 0; diff --git a/testbed/scenes/collisiondetection/CollisionDetectionScene.h b/testbed/scenes/collisiondetection/CollisionDetectionScene.h index 8473ae73..4bea0c0b 100755 --- a/testbed/scenes/collisiondetection/CollisionDetectionScene.h +++ b/testbed/scenes/collisiondetection/CollisionDetectionScene.h @@ -152,10 +152,7 @@ class CollisionDetectionScene : public SceneDemo { std::vector mAllShapes; - int mSelectedShapeIndex; - - /// Collision world used for the physics simulation - rp3d::CollisionWorld* mCollisionWorld; + uint mSelectedShapeIndex; /// Select the next shape void selectNextShape(); @@ -165,7 +162,7 @@ class CollisionDetectionScene : public SceneDemo { // -------------------- Methods -------------------- // /// Constructor - CollisionDetectionScene(const std::string& name); + CollisionDetectionScene(const std::string& name, EngineSettings& settings); /// Destructor virtual ~CollisionDetectionScene() override; diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp index e63f39d4..a6fd6662 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -31,8 +31,8 @@ using namespace openglframework; using namespace collisionshapesscene; // Constructor -CollisionShapesScene::CollisionShapesScene(const std::string& name) - : SceneDemo(name, SCENE_RADIUS) { +CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettings& settings) + : SceneDemo(name, settings, SCENE_RADIUS) { std::string meshFolderPath("meshes/"); @@ -43,23 +43,15 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) setScenePosition(center, SCENE_RADIUS); // Gravity vector in the dynamics world - rp3d::Vector3 gravity(0, -9.81, 0); + rp3d::Vector3 gravity(0, -9.81f, 0); // Create the dynamics world for the physics simulation - mDynamicsWorld = new rp3d::DynamicsWorld(gravity); - - float radius = 3.0f; + mPhysicsWorld = new rp3d::DynamicsWorld(gravity); for (int i=0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -77,14 +69,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create all the boxes of the scene for (int i=0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -102,18 +88,11 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create all the spheres of the scene for (int i=0; igetRigidBody()->getMaterial().setRollingResistance(0.08); + sphere->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08)); // Set the box color sphere->setColor(mDemoColors[i % mNbDemoColors]); @@ -131,17 +110,11 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create all the capsules of the scene for (int i=0; igetRigidBody()->getMaterial().setRollingResistance(0.08); + capsule->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08f)); // Set the box color capsule->setColor(mDemoColors[i % mNbDemoColors]); @@ -159,14 +132,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Create all the convex meshes of the scene for (int i=0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -183,8 +150,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // ---------- Create the floor --------- - openglframework::Vector3 floorPosition(0, 0, 0); - mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mMeshFolderPath); + mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath); mPhysicsObjects.push_back(mFloor); // Set the box color @@ -198,39 +164,16 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) rp3d::Material& material = mFloor->getRigidBody()->getMaterial(); material.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)); - material.setFrictionCoefficient(0.1); - */ - // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity(); + mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled(); + rp3d::Vector3 gravityVector = getDynamicsWorld()->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(); + mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled(); + mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity(); + mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity(); + mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver(); + mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver(); + mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep(); } // Destructor @@ -240,126 +183,81 @@ CollisionShapesScene::~CollisionShapesScene() { for (std::vector::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); + getDynamicsWorld()->destroyRigidBody((*it)->getRigidBody()); // Destroy the object delete (*it); } // Destroy the dynamics world - delete mDynamicsWorld; -} - -// Update the physics world (take a simulation step) -void CollisionShapesScene::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); + delete mPhysicsWorld; } /// Reset the scene void CollisionShapesScene::reset() { - float radius = 3.0f; + const float radius = 3.0f; - for (int i=0; isetTransform(transform); + mDumbbells[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); } // Create all the boxes of the scene - for (int i=0; isetTransform(transform); + mBoxes[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); } // Create all the spheres of the scene - for (int i=0; isetTransform(transform); + mSpheres[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); } // Create all the capsules of the scene - for (int i=0; isetTransform(transform); + mCapsules[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); } // Create all the convex meshes of the scene - for (int i=0; isetTransform(transform); + mConvexMeshes[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); } + + // ---------- Create the triangular mesh ---------- // + + mFloor->setTransform(rp3d::Transform::identity()); } diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.h b/testbed/scenes/collisionshapes/CollisionShapesScene.h index 70e28755..b22d8429 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.h +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.h @@ -45,7 +45,7 @@ const float SCENE_RADIUS = 30.0f; const int NB_BOXES = 5; const int NB_SPHERES = 5; const int NB_CAPSULES = 5; -const int NB_MESHES = 3; +const int NB_MESHES = 4; const int NB_COMPOUND_SHAPES = 3; const openglframework::Vector3 BOX_SIZE(2, 2, 2); const float SPHERE_RADIUS = 1.5f; @@ -87,23 +87,16 @@ class CollisionShapesScene : public SceneDemo { /// Box for the floor Box* mFloor; - /// Dynamics world used for the physics simulation - rp3d::DynamicsWorld* mDynamicsWorld; - public: // -------------------- Methods -------------------- // /// Constructor - CollisionShapesScene(const std::string& name); + CollisionShapesScene(const std::string& name, EngineSettings& settings); /// Destructor virtual ~CollisionShapesScene() override; - /// Update the physics world (take a simulation step) - /// Can be called several times per frame - virtual void updatePhysics() override; - /// Reset the scene virtual void reset() override; @@ -113,7 +106,7 @@ class CollisionShapesScene : public SceneDemo { // Return all the contact points of the scene inline std::vector CollisionShapesScene::getContactPoints() const { - return computeContactPointsOfWorld(mDynamicsWorld); + return computeContactPointsOfWorld(getDynamicsWorld()); } } diff --git a/testbed/scenes/concavemesh/ConcaveMeshScene.cpp b/testbed/scenes/concavemesh/ConcaveMeshScene.cpp index 11474819..d70a02af 100644 --- a/testbed/scenes/concavemesh/ConcaveMeshScene.cpp +++ b/testbed/scenes/concavemesh/ConcaveMeshScene.cpp @@ -31,8 +31,8 @@ using namespace openglframework; using namespace trianglemeshscene; // Constructor -ConcaveMeshScene::ConcaveMeshScene(const std::string& name) - : SceneDemo(name, SCENE_RADIUS) { +ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& settings) + : SceneDemo(name, settings, SCENE_RADIUS) { std::string meshFolderPath("meshes/"); @@ -46,38 +46,115 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name) rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); // Create the dynamics world for the physics simulation - mDynamicsWorld = new rp3d::DynamicsWorld(gravity); + mPhysicsWorld = new rp3d::DynamicsWorld(gravity); - // ---------- Create the boxes ----------- // + for (int i = 0; isetColor(mDemoColors[i % mNbDemoColors]); + dumbbell->setSleepingColor(mRedColorDemo); - // Position - openglframework::Vector3 boxPosition(-NB_BOXES_X * BOX_SIZE * BOXES_SPACE / 2 + i * BOX_SIZE * BOXES_SPACE, 30, -NB_BOXES_Z * BOX_SIZE * BOXES_SPACE / 2 + j * BOX_SIZE * BOXES_SPACE); + // Change the material properties of the rigid body + rp3d::Material& material = dumbbell->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); - // Create a sphere and a corresponding rigid in the dynamics world - mBoxes[i * NB_BOXES_Z + j] = new Box(Vector3(BOX_SIZE, BOX_SIZE, BOX_SIZE) * 0.5f, boxPosition, 80.1, mDynamicsWorld, mMeshFolderPath); + // Add the mesh the list of dumbbells in the scene + mDumbbells.push_back(dumbbell); + mPhysicsObjects.push_back(dumbbell); + } - // Set the sphere color - mBoxes[i * NB_BOXES_Z + j]->setColor(mDemoColors[0]); - mBoxes[i * NB_BOXES_Z + j]->setSleepingColor(mRedColorDemo); + // Create all the boxes of the scene + for (int i = 0; igetRigidBody()->getMaterial(); - boxMaterial.setBounciness(rp3d::decimal(0.2)); - } + // Create a sphere and a corresponding rigid in the dynamics world + Box* box = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath); + + // Set the box color + box->setColor(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(rp3d::decimal(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(rp3d::decimal(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 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 + "city.obj"); + mConcaveMesh = new ConcaveMesh(mass, getDynamicsWorld(), meshFolderPath + "city.obj"); // Set the mesh as beeing static mConcaveMesh->getRigidBody()->setType(rp3d::BodyType::STATIC); @@ -86,106 +163,107 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name) mConcaveMesh->setColor(mGreyColorDemo); mConcaveMesh->setSleepingColor(mGreyColorDemo); + mPhysicsObjects.push_back(mConcaveMesh); + // Change the material properties of the rigid body rp3d::Material& material = mConcaveMesh->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); - material.setFrictionCoefficient(0.1); + material.setFrictionCoefficient(rp3d::decimal(0.1)); // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity(); + mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled(); + rp3d::Vector3 gravityVector = getDynamicsWorld()->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(); + mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled(); + mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity(); + mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity(); + mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver(); + mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver(); + mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep(); } // Destructor ConcaveMeshScene::~ConcaveMeshScene() { - // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody(mConcaveMesh->getRigidBody()); + // Destroy all the physics objects of the scene + for (std::vector::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { - // Destroy the boxes - for (int i=0; idestroyRigidBody(mBoxes[i]->getRigidBody()); - delete mBoxes[i]; + // Destroy the corresponding rigid body from the dynamics world + getDynamicsWorld()->destroyRigidBody((*it)->getRigidBody()); + + // Destroy the object + delete (*it); } - // 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); - - for (int i=0; iupdateTransform(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, mIsWireframeEnabled); - - for (int i=0; irender(shader, worldToCameraMatrix, mIsWireframeEnabled); - } - - // Unbind the shader - shader.unbind(); + delete getDynamicsWorld(); } // Reset the scene void ConcaveMeshScene::reset() { - // Reset the transform - rp3d::Transform transform(rp3d::Vector3::zero(), rp3d::Quaternion::identity()); - mConcaveMesh->setTransform(transform); + const float radius = 15.0f; - for (int i=0; isetTransform(boxTransform); - } + mDumbbells[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); } + // Create all the boxes of the scene + for (uint i = 0; isetTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); + } + + // Create all the spheres of the scene + for (uint i = 0; isetTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); + } + + // Create all the capsules of the scene + for (uint i = 0; isetTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); + } + + // Create all the convex meshes of the scene + for (uint i = 0; isetTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); + } + + // ---------- Create the triangular mesh ---------- // + + mConcaveMesh->setTransform(rp3d::Transform::identity()); } diff --git a/testbed/scenes/concavemesh/ConcaveMeshScene.h b/testbed/scenes/concavemesh/ConcaveMeshScene.h index 5943fe6c..a8d566a1 100644 --- a/testbed/scenes/concavemesh/ConcaveMeshScene.h +++ b/testbed/scenes/concavemesh/ConcaveMeshScene.h @@ -33,15 +33,34 @@ #include "SceneDemo.h" #include "ConcaveMesh.h" #include "Box.h" +#include "Capsule.h" +#include "Dumbbell.h" +#include "Sphere.h" +#include "ConvexMesh.h" namespace trianglemeshscene { // Constants const float SCENE_RADIUS = 70.0f; // Radius of the scene in meters -const int NB_BOXES_X = 8; -const int NB_BOXES_Z = 8; -const float BOX_SIZE = 3.0f; -const float BOXES_SPACE = 2.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 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; // Class TriangleMeshScene class ConcaveMeshScene : public SceneDemo { @@ -50,35 +69,31 @@ class ConcaveMeshScene : public SceneDemo { // -------------------- Attributes -------------------- // - Box* mBoxes[NB_BOXES_X * NB_BOXES_Z]; + 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; /// Concave triangles mesh ConcaveMesh* mConcaveMesh; - /// Dynamics world used for the physics simulation - rp3d::DynamicsWorld* mDynamicsWorld; - public: // -------------------- Methods -------------------- // /// Constructor - ConcaveMeshScene(const std::string& name); + ConcaveMeshScene(const std::string& name, EngineSettings& settings); /// Destructor virtual ~ConcaveMeshScene() override; - /// Update the physics world (take a simulation step) - /// 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; @@ -88,7 +103,7 @@ class ConcaveMeshScene : public SceneDemo { // Return all the contact points of the scene inline std::vector ConcaveMeshScene::getContactPoints() const { - return computeContactPointsOfWorld(mDynamicsWorld); + return computeContactPointsOfWorld(getDynamicsWorld()); } } diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index 3ddb1d61..fa7f4ba5 100755 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -31,8 +31,8 @@ using namespace openglframework; using namespace cubesscene; // Constructor -CubesScene::CubesScene(const std::string& name) - : SceneDemo(name, SCENE_RADIUS) { +CubesScene::CubesScene(const std::string& name, EngineSettings& settings) + : SceneDemo(name, settings, SCENE_RADIUS) { // Compute the radius and the center of the scene openglframework::Vector3 center(0, 5, 0); @@ -44,39 +44,31 @@ CubesScene::CubesScene(const std::string& name) rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); // Create the dynamics world for the physics simulation - mDynamicsWorld = new rp3d::DynamicsWorld(gravity); + mPhysicsWorld = new rp3d::DynamicsWorld(gravity); - float radius = 2.0f; + // Create all the cubes of the scene + for (int i=0; isetColor(mDemoColors[i % mNbDemoColors]); + cube->setSleepingColor(mRedColorDemo); - // // Create a cube and a corresponding rigid in the dynamics world - // Box* cube = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld); + // Change the material properties of the rigid body + rp3d::Material& material = cube->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.4)); - // // Set the box color - // cube->setColor(mDemoColors[i % mNbDemoColors]); - // cube->setSleepingColor(mRedColorDemo); - - // // Change the material properties of the rigid body - // rp3d::Material& material = cube->getRigidBody()->getMaterial(); - // material.setBounciness(rp3d::decimal(0.4)); - - // // Add the box the list of box in the scene - // mBoxes.push_back(cube); - //} + // Add the box the list of box in the scene + mBoxes.push_back(cube); + mPhysicsObjects.push_back(cube); + } // ------------------------- FLOOR ----------------------- // // Create the floor - openglframework::Vector3 floorPosition(0, 0, 0); - mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mMeshFolderPath); + mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath); mFloor->setColor(mGreyColorDemo); mFloor->setSleepingColor(mGreyColorDemo); @@ -84,37 +76,16 @@ CubesScene::CubesScene(const std::string& name) 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(); - //material.setBounciness(rp3d::decimal(0.3)); - - // ------------------------- BOX ----------------------- // - - // Create a cube and a corresponding rigid in the dynamics world - Box* cube = new Box(BOX_SIZE, Vector3(0, 10, 0), BOX_MASS, mDynamicsWorld, mMeshFolderPath); - - // Set the box color - cube->setColor(mDemoColors[0]); - cube->setSleepingColor(mRedColorDemo); - - // Change the material properties of the rigid body - //rp3d::Material& material = cube->getRigidBody()->getMaterial(); - //material.setBounciness(rp3d::decimal(0.4)); - - // 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(); - rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity(); + mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled(); + rp3d::Vector3 gravityVector = getDynamicsWorld()->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(); + mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled(); + mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity(); + mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity(); + mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver(); + mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver(); + mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep(); } // Destructor @@ -124,39 +95,20 @@ CubesScene::~CubesScene() { for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); + getDynamicsWorld()->destroyRigidBody((*it)->getRigidBody()); // Destroy the cube delete (*it); } // Destroy the rigid body of the floor - mDynamicsWorld->destroyRigidBody(mFloor->getRigidBody()); + getDynamicsWorld()->destroyRigidBody(mFloor->getRigidBody()); // Destroy the floor delete mFloor; // Destroy the dynamics world - delete mDynamicsWorld; -} - -// Update the physics world (take a simulation step) -void CubesScene::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); + delete getDynamicsWorld(); } // Reset the scene @@ -164,19 +116,21 @@ void CubesScene::reset() { float radius = 2.0f; -// for (int i=0; i::iterator it; + int i = 0; + for (it = mBoxes.begin(); it != mBoxes.end(); ++it) { -// // Position of the cubes -// float angle = i * 30.0f; -// openglframework::Vector3 position(radius * cos(angle), -// 10 + i * (BOX_SIZE.y + 0.3f), -// 0); + // Position of the cubes + float angle = i * 30.0f; + rp3d::Vector3 position(radius * std::cos(angle), + 10 + i * (BOX_SIZE.y + 0.3f), + 0); -// // 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); + (*it)->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); -// mBoxes[i]->resetTransform(transform); -// } + i++; + } + + mFloor->setTransform(rp3d::Transform(rp3d::Vector3::zero(), rp3d::Quaternion::identity())); } diff --git a/testbed/scenes/cubes/CubesScene.h b/testbed/scenes/cubes/CubesScene.h index aa4b7073..6d553835 100755 --- a/testbed/scenes/cubes/CubesScene.h +++ b/testbed/scenes/cubes/CubesScene.h @@ -38,7 +38,7 @@ namespace cubesscene { 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(5, 5.0, 5); // Floor dimensions in meters +const openglframework::Vector3 FLOOR_SIZE(50, 1, 50); // Floor dimensions in meters const float BOX_MASS = 1.0f; // Box mass in kilograms const float FLOOR_MASS = 100.0f; // Floor mass in kilograms @@ -55,23 +55,16 @@ class CubesScene : public SceneDemo { /// Box for the floor Box* mFloor; - /// Dynamics world used for the physics simulation - rp3d::DynamicsWorld* mDynamicsWorld; - public: // -------------------- Methods -------------------- // /// Constructor - CubesScene(const std::string& name); + CubesScene(const std::string& name, EngineSettings& settings); /// Destructor virtual ~CubesScene() override; - /// Update the physics world (take a simulation step) - /// Can be called several times per frame - virtual void updatePhysics() override; - /// Reset the scene virtual void reset() override; @@ -81,7 +74,7 @@ class CubesScene : public SceneDemo { // Return all the contact points of the scene inline std::vector CubesScene::getContactPoints() const { - return computeContactPointsOfWorld(mDynamicsWorld); + return computeContactPointsOfWorld(getDynamicsWorld()); } } diff --git a/testbed/scenes/heightfield/HeightFieldScene.cpp b/testbed/scenes/heightfield/HeightFieldScene.cpp index 329712e9..238018dd 100644 --- a/testbed/scenes/heightfield/HeightFieldScene.cpp +++ b/testbed/scenes/heightfield/HeightFieldScene.cpp @@ -31,7 +31,8 @@ using namespace openglframework; using namespace heightfieldscene; // Constructor -HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SCENE_RADIUS) { +HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& settings) + : SceneDemo(name, settings, SCENE_RADIUS) { std::string meshFolderPath("meshes/"); @@ -45,20 +46,12 @@ HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SC rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); // Create the dynamics world for the physics simulation - mDynamicsWorld = new rp3d::DynamicsWorld(gravity); - - float radius = 3.0f; + mPhysicsWorld = new rp3d::DynamicsWorld(gravity); for (int i = 0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -76,14 +69,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SC // Create all the boxes of the scene for (int i = 0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -101,18 +88,11 @@ HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SC // Create all the spheres of the scene for (int i = 0; igetRigidBody()->getMaterial().setRollingResistance(0.08); + sphere->getRigidBody()->getMaterial().setRollingResistance(0.08f); // Set the box color sphere->setColor(mDemoColors[i % mNbDemoColors]); @@ -130,17 +110,11 @@ HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SC // Create all the capsules of the scene for (int i = 0; igetRigidBody()->getMaterial().setRollingResistance(0.08); + capsule->getRigidBody()->getMaterial().setRollingResistance(0.08f); // Set the box color capsule->setColor(mDemoColors[i % mNbDemoColors]); @@ -158,14 +132,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SC // Create all the convex meshes of the scene for (int i = 0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -183,11 +151,10 @@ HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SC // ---------- Create the height field ---------- // // Position - openglframework::Vector3 position(0, 0, 0); rp3d::decimal mass = 1.0; // Create a convex mesh and a corresponding rigid in the dynamics world - mHeightField = new HeightField(position, mass, mDynamicsWorld); + mHeightField = new HeightField(mass, getDynamicsWorld()); // Set the mesh as beeing static mHeightField->getRigidBody()->setType(rp3d::BodyType::STATIC); @@ -201,18 +168,18 @@ HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SC // Change the material properties of the rigid body rp3d::Material& material = mHeightField->getRigidBody()->getMaterial(); material.setBounciness(rp3d::decimal(0.2)); - material.setFrictionCoefficient(0.1); + material.setFrictionCoefficient(0.1f); // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity(); + mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled(); + rp3d::Vector3 gravityVector = getDynamicsWorld()->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(); + mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled(); + mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity(); + mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity(); + mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver(); + mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver(); + mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep(); } // Destructor @@ -222,47 +189,81 @@ HeightFieldScene::~HeightFieldScene() { for (std::vector::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { // Destroy the corresponding rigid body from the dynamics world - mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); + getDynamicsWorld()->destroyRigidBody((*it)->getRigidBody()); // Destroy the object delete (*it); } // Destroy the dynamics world - delete mDynamicsWorld; -} - -// Update the physics world (take a simulation step) -void HeightFieldScene::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); + delete getDynamicsWorld(); } // Reset the scene void HeightFieldScene::reset() { - // Reset the transform - rp3d::Transform transform(rp3d::Vector3(0, 0, 0), rp3d::Quaternion::identity()); - mHeightField->setTransform(transform); + const float radius = 3.0f; - float heightFieldWidth = 10.0f; - float stepDist = heightFieldWidth / (NB_BOXES + 1); - for (int i=0; isetTransform(boxTransform); + for (uint i = 0; isetTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); } + + // Create all the boxes of the scene + for (uint i = 0; isetTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); + } + + // Create all the spheres of the scene + for (uint i = 0; isetTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); + } + + // Create all the capsules of the scene + for (uint i = 0; isetTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); + } + + // Create all the convex meshes of the scene + for (uint i = 0; isetTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); + } + + // ---------- Create the triangular mesh ---------- // + + mHeightField->setTransform(rp3d::Transform::identity()); } diff --git a/testbed/scenes/heightfield/HeightFieldScene.h b/testbed/scenes/heightfield/HeightFieldScene.h index 7306ae2c..2a3e68f5 100644 --- a/testbed/scenes/heightfield/HeightFieldScene.h +++ b/testbed/scenes/heightfield/HeightFieldScene.h @@ -44,7 +44,7 @@ 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_MESHES = 4; static const int NB_COMPOUND_SHAPES = 3; const openglframework::Vector3 BOX_SIZE(2, 2, 2); const float SPHERE_RADIUS = 1.5f; @@ -86,23 +86,16 @@ class HeightFieldScene : public SceneDemo { /// Height field HeightField* mHeightField; - /// Dynamics world used for the physics simulation - rp3d::DynamicsWorld* mDynamicsWorld; - public: // -------------------- Methods -------------------- // /// Constructor - HeightFieldScene(const std::string& name); + HeightFieldScene(const std::string& name, EngineSettings& settings); /// Destructor virtual ~HeightFieldScene() override; - /// Update the physics world (take a simulation step) - /// Can be called several times per frame - virtual void updatePhysics() override; - /// Reset the scene virtual void reset() override ; @@ -112,7 +105,7 @@ class HeightFieldScene : public SceneDemo { // Return all the contact points of the scene inline std::vector HeightFieldScene::getContactPoints() const { - return computeContactPointsOfWorld(mDynamicsWorld); + return computeContactPointsOfWorld(getDynamicsWorld()); } } diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index 282f7e51..3252e90e 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -32,8 +32,8 @@ using namespace openglframework; using namespace jointsscene; // Constructor -JointsScene::JointsScene(const std::string& name) - : SceneDemo(name, SCENE_RADIUS) { +JointsScene::JointsScene(const std::string& name, EngineSettings& settings) + : SceneDemo(name, settings, SCENE_RADIUS) { // Compute the radius and the center of the scene openglframework::Vector3 center(0, 5, 0); @@ -45,7 +45,7 @@ JointsScene::JointsScene(const std::string& name) rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); // Create the dynamics world for the physics simulation - mDynamicsWorld = new rp3d::DynamicsWorld(gravity); + mPhysicsWorld = new rp3d::DynamicsWorld(gravity); // Create the Ball-and-Socket joint createBallAndSocketJoints(); @@ -63,37 +63,37 @@ JointsScene::JointsScene(const std::string& name) createFloor(); // Get the physics engine parameters - mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled(); - rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity(); + mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled(); + rp3d::Vector3 gravityVector = getDynamicsWorld()->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(); + mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled(); + mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity(); + mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity(); + mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver(); + mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver(); + mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep(); } // Destructor JointsScene::~JointsScene() { // Destroy the joints - mDynamicsWorld->destroyJoint(mSliderJoint); - mDynamicsWorld->destroyJoint(mPropellerHingeJoint); - mDynamicsWorld->destroyJoint(mFixedJoint1); - mDynamicsWorld->destroyJoint(mFixedJoint2); + getDynamicsWorld()->destroyJoint(mSliderJoint); + getDynamicsWorld()->destroyJoint(mPropellerHingeJoint); + getDynamicsWorld()->destroyJoint(mFixedJoint1); + getDynamicsWorld()->destroyJoint(mFixedJoint2); for (int i=0; idestroyJoint(mBallAndSocketJoints[i]); + getDynamicsWorld()->destroyJoint(mBallAndSocketJoints[i]); } // Destroy all the rigid bodies of the scene - mDynamicsWorld->destroyRigidBody(mSliderJointBottomBox->getRigidBody()); - mDynamicsWorld->destroyRigidBody(mSliderJointTopBox->getRigidBody()); - mDynamicsWorld->destroyRigidBody(mPropellerBox->getRigidBody()); - mDynamicsWorld->destroyRigidBody(mFixedJointBox1->getRigidBody()); - mDynamicsWorld->destroyRigidBody(mFixedJointBox2->getRigidBody()); + getDynamicsWorld()->destroyRigidBody(mSliderJointBottomBox->getRigidBody()); + getDynamicsWorld()->destroyRigidBody(mSliderJointTopBox->getRigidBody()); + getDynamicsWorld()->destroyRigidBody(mPropellerBox->getRigidBody()); + getDynamicsWorld()->destroyRigidBody(mFixedJointBox1->getRigidBody()); + getDynamicsWorld()->destroyRigidBody(mFixedJointBox2->getRigidBody()); for (int i=0; idestroyRigidBody(mBallAndSocketJointChainBoxes[i]->getRigidBody()); + getDynamicsWorld()->destroyRigidBody(mBallAndSocketJointChainBoxes[i]->getRigidBody()); } delete mSliderJointBottomBox; @@ -106,58 +106,21 @@ JointsScene::~JointsScene() { } // Destroy the floor - mDynamicsWorld->destroyRigidBody(mFloor->getRigidBody()); + getDynamicsWorld()->destroyRigidBody(mFloor->getRigidBody()); delete mFloor; // Destroy the dynamics world - delete mDynamicsWorld; + delete getDynamicsWorld(); } // Update the physics world (take a simulation step) void JointsScene::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); - // Update the motor speed of the Slider Joint (to move up and down) - long double motorSpeed = 2 * cos(mEngineSettings.elapsedTime * 1.5); + double motorSpeed = 2.0 * std::cos(static_cast(mEngineSettings.elapsedTime) * 1.5); mSliderJoint->setMotorSpeed(rp3d::decimal(motorSpeed)); - // Take a simulation step - mDynamicsWorld->update(mEngineSettings.timeStep); -} - -// Render the scene -void JointsScene::renderSinglePass(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { - - // Bind the shader - shader.bind(); - - // Render all the boxes - mSliderJointBottomBox->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - mSliderJointTopBox->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - mPropellerBox->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - mFixedJointBox1->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - mFixedJointBox2->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - for (int i=0; irender(shader, worldToCameraMatrix, mIsWireframeEnabled); - } - - // Render the floor - mFloor->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - - // Unbind the shader - shader.unbind(); + SceneDemo::updatePhysics(); } // Reset the scene @@ -236,15 +199,16 @@ void JointsScene::createBallAndSocketJoints() { // --------------- Create the boxes --------------- // - openglframework::Vector3 positionBox(0, 15, 5); + rp3d::Vector3 positionBox(0, 15, 5); openglframework::Vector3 boxDimension(1, 1, 1); const float boxMass = 0.5f; for (int i=0; isetTransform(rp3d::Transform(positionBox, rp3d::Quaternion::identity())); // Set the box color mBallAndSocketJointChainBoxes[i]->setColor(mDemoColors[i % mNbDemoColors]); @@ -281,7 +245,7 @@ void JointsScene::createBallAndSocketJoints() { // Create the joint in the dynamics world mBallAndSocketJoints[i] = dynamic_cast( - mDynamicsWorld->createJoint(jointInfo)); + getDynamicsWorld()->createJoint(jointInfo)); } } @@ -291,11 +255,12 @@ void JointsScene::createSliderJoint() { // --------------- Create the first box --------------- // // Position of the box - openglframework::Vector3 positionBox1(0, 2.1f, 0); + rp3d::Vector3 positionBox1(0, 2.1f, 0); // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 box1Dimension(2, 4, 2); - mSliderJointBottomBox = new Box(box1Dimension, positionBox1 , BOX_MASS, mDynamicsWorld, mMeshFolderPath); + mSliderJointBottomBox = new Box(box1Dimension , BOX_MASS, getDynamicsWorld(), mMeshFolderPath); + mSliderJointBottomBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity())); // Set the box color mSliderJointBottomBox->setColor(mBlueColorDemo); @@ -312,11 +277,12 @@ void JointsScene::createSliderJoint() { // --------------- Create the second box --------------- // // Position of the box - openglframework::Vector3 positionBox2(0, 4.2f, 0); + rp3d::Vector3 positionBox2(0, 4.2f, 0); // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 box2Dimension(1.5f, 4, 1.5f); - mSliderJointTopBox = new Box(box2Dimension, positionBox2, BOX_MASS, mDynamicsWorld, mMeshFolderPath); + mSliderJointTopBox = new Box(box2Dimension, BOX_MASS, getDynamicsWorld(), mMeshFolderPath); + mSliderJointTopBox->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity())); // Set the box color mSliderJointTopBox->setColor(mOrangeColorDemo); @@ -344,7 +310,7 @@ void JointsScene::createSliderJoint() { jointInfo.isCollisionEnabled = false; // Create the joint in the dynamics world - mSliderJoint = dynamic_cast(mDynamicsWorld->createJoint(jointInfo)); + mSliderJoint = dynamic_cast(getDynamicsWorld()->createJoint(jointInfo)); } /// Create the boxes and joint for the Hinge joint example @@ -353,11 +319,12 @@ void JointsScene::createPropellerHingeJoint() { // --------------- Create the propeller box --------------- // // Position of the box - openglframework::Vector3 positionBox1(0, 7, 0); + rp3d::Vector3 positionBox1(0, 7, 0); // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 boxDimension(10, 1, 1); - mPropellerBox = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld, mMeshFolderPath); + mPropellerBox = new Box(boxDimension, BOX_MASS, getDynamicsWorld(), mMeshFolderPath); + mPropellerBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity())); // Set the box color mPropellerBox->setColor(mYellowColorDemo); @@ -384,7 +351,7 @@ void JointsScene::createPropellerHingeJoint() { jointInfo.isCollisionEnabled = false; // Create the joint in the dynamics world - mPropellerHingeJoint = dynamic_cast(mDynamicsWorld->createJoint(jointInfo)); + mPropellerHingeJoint = dynamic_cast(getDynamicsWorld()->createJoint(jointInfo)); } /// Create the boxes and joints for the fixed joints @@ -393,11 +360,12 @@ void JointsScene::createFixedJoints() { // --------------- Create the first box --------------- // // Position of the box - openglframework::Vector3 positionBox1(5, 7, 0); + rp3d::Vector3 positionBox1(5, 7, 0); // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 boxDimension(1.5, 1.5, 1.5); - mFixedJointBox1 = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld, mMeshFolderPath); + mFixedJointBox1 = new Box(boxDimension, BOX_MASS, getDynamicsWorld(), mMeshFolderPath); + mFixedJointBox1->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity())); // Set the box color mFixedJointBox1->setColor(mPinkColorDemo); @@ -411,10 +379,11 @@ void JointsScene::createFixedJoints() { // --------------- Create the second box --------------- // // Position of the box - openglframework::Vector3 positionBox2(-5, 7, 0); + rp3d::Vector3 positionBox2(-5, 7, 0); // Create a box and a corresponding rigid in the dynamics world - mFixedJointBox2 = new Box(boxDimension, positionBox2 , BOX_MASS, mDynamicsWorld, mMeshFolderPath); + mFixedJointBox2 = new Box(boxDimension, BOX_MASS, getDynamicsWorld(), mMeshFolderPath); + mFixedJointBox2->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity())); // Set the box color mFixedJointBox2->setColor(mBlueColorDemo); @@ -435,7 +404,7 @@ void JointsScene::createFixedJoints() { jointInfo1.isCollisionEnabled = false; // Create the joint in the dynamics world - mFixedJoint1 = dynamic_cast(mDynamicsWorld->createJoint(jointInfo1)); + mFixedJoint1 = dynamic_cast(getDynamicsWorld()->createJoint(jointInfo1)); // --------------- Create the second fixed joint --------------- // @@ -446,15 +415,15 @@ void JointsScene::createFixedJoints() { jointInfo2.isCollisionEnabled = false; // Create the joint in the dynamics world - mFixedJoint2 = dynamic_cast(mDynamicsWorld->createJoint(jointInfo2)); + mFixedJoint2 = dynamic_cast(getDynamicsWorld()->createJoint(jointInfo2)); } // Create the floor void JointsScene::createFloor() { // Create the floor - openglframework::Vector3 floorPosition(0, 0, 0); - mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mMeshFolderPath); + rp3d::Vector3 floorPosition(0, 0, 0); + mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath); // Set the box color mFloor->setColor(mGreyColorDemo); diff --git a/testbed/scenes/joints/JointsScene.h b/testbed/scenes/joints/JointsScene.h index 16ccfe8c..dad9af38 100644 --- a/testbed/scenes/joints/JointsScene.h +++ b/testbed/scenes/joints/JointsScene.h @@ -92,9 +92,6 @@ class JointsScene : public SceneDemo { /// Box for the floor Box* mFloor; - /// Dynamics world used for the physics simulation - rp3d::DynamicsWorld* mDynamicsWorld; - // -------------------- Methods -------------------- // /// Create the boxes and joints for the Ball-and-Socket joint example @@ -117,7 +114,7 @@ class JointsScene : public SceneDemo { // -------------------- Methods -------------------- // /// Constructor - JointsScene(const std::string& name); + JointsScene(const std::string& name, EngineSettings& settings); /// Destructor virtual ~JointsScene() override ; @@ -126,10 +123,6 @@ class JointsScene : public SceneDemo { /// Can be called several times per frame virtual void updatePhysics() 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; @@ -139,7 +132,7 @@ class JointsScene : public SceneDemo { // Return all the contact points of the scene inline std::vector JointsScene::getContactPoints() const { - return computeContactPointsOfWorld(mDynamicsWorld); + return computeContactPointsOfWorld(getDynamicsWorld()); } } diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index 2ded75d6..bf806183 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -31,8 +31,8 @@ using namespace openglframework; using namespace raycastscene; // Constructor -RaycastScene::RaycastScene(const std::string& name) - : SceneDemo(name, SCENE_RADIUS, false), mMeshFolderPath("meshes/"), +RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings) + : SceneDemo(name, settings, SCENE_RADIUS, false), mMeshFolderPath("meshes/"), mRaycastManager(mPhongShader, mMeshFolderPath), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), mVBOVertices(GL_ARRAY_BUFFER) { @@ -45,13 +45,12 @@ RaycastScene::RaycastScene(const std::string& name) setScenePosition(center, SCENE_RADIUS); // Create the dynamics world for the physics simulation - mCollisionWorld = new rp3d::CollisionWorld(); + mPhysicsWorld = new rp3d::CollisionWorld(); // ---------- Dumbbell ---------- // - openglframework::Vector3 position1(0, 0, 0); // Create a convex mesh and a corresponding collision body in the dynamics world - mDumbbell = new Dumbbell(position1, mCollisionWorld, mMeshFolderPath); + mDumbbell = new Dumbbell(mPhysicsWorld, mMeshFolderPath); // Set the box color mDumbbell->setColor(mGreyColorDemo); @@ -59,10 +58,9 @@ RaycastScene::RaycastScene(const std::string& name) mPhysicsObjects.push_back(mDumbbell); // ---------- Box ---------- // - openglframework::Vector3 position2(0, 0, 0); // Create a box and a corresponding collision body in the dynamics world - mBox = new Box(BOX_SIZE, position2, mCollisionWorld, mMeshFolderPath); + mBox = new Box(BOX_SIZE, mPhysicsWorld, mMeshFolderPath); mBox->getCollisionBody()->setIsActive(false); // Set the box color @@ -71,11 +69,9 @@ RaycastScene::RaycastScene(const std::string& name) mPhysicsObjects.push_back(mBox); // ---------- Sphere ---------- // - openglframework::Vector3 position3(0, 0, 0); // Create a sphere and a corresponding collision body in the dynamics world - mSphere = new Sphere(SPHERE_RADIUS, position3, mCollisionWorld, - mMeshFolderPath); + mSphere = new Sphere(SPHERE_RADIUS, mPhysicsWorld, mMeshFolderPath); // Set the color mSphere->setColor(mGreyColorDemo); @@ -86,8 +82,7 @@ RaycastScene::RaycastScene(const std::string& name) openglframework::Vector3 position6(0, 0, 0); // Create a cylinder and a corresponding collision body in the dynamics world - mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position6 , - mCollisionWorld, mMeshFolderPath); + mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath); // Set the color mCapsule->setColor(mGreyColorDemo); @@ -95,10 +90,9 @@ RaycastScene::RaycastScene(const std::string& name) mPhysicsObjects.push_back(mCapsule); // ---------- Convex Mesh ---------- // - openglframework::Vector3 position7(0, 0, 0); // Create a convex mesh and a corresponding collision body in the dynamics world - mConvexMesh = new ConvexMesh(position7, mCollisionWorld, mMeshFolderPath + "convexmesh.obj"); + mConvexMesh = new ConvexMesh(mPhysicsWorld, mMeshFolderPath + "convexmesh.obj"); // Set the color mConvexMesh->setColor(mGreyColorDemo); @@ -106,10 +100,9 @@ RaycastScene::RaycastScene(const std::string& name) mPhysicsObjects.push_back(mConvexMesh); // ---------- Concave Mesh ---------- // - openglframework::Vector3 position8(0, 0, 0); // Create a convex mesh and a corresponding collision body in the dynamics world - mConcaveMesh = new ConcaveMesh(position8, mCollisionWorld, mMeshFolderPath + "city.obj"); + mConcaveMesh = new ConcaveMesh(mPhysicsWorld, mMeshFolderPath + "city.obj"); // Set the color mConcaveMesh->setColor(mGreyColorDemo); @@ -117,10 +110,9 @@ RaycastScene::RaycastScene(const std::string& name) mPhysicsObjects.push_back(mConcaveMesh); // ---------- Heightfield ---------- // - openglframework::Vector3 position9(0, 0, 0); // Create a convex mesh and a corresponding collision body in the dynamics world - mHeightField = new HeightField(position9, mCollisionWorld); + mHeightField = new HeightField(mPhysicsWorld); // Set the color mHeightField->setColor(mGreyColorDemo); @@ -139,7 +131,7 @@ RaycastScene::RaycastScene(const std::string& name) // Create the raycast lines void RaycastScene::createLines() { - int nbRaysOneDimension = std::sqrt(float(NB_RAYS)); + int nbRaysOneDimension = static_cast(std::sqrt(float(NB_RAYS))); for (int i=0; i::iterator it; + for (it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + (*it)->setTransform(rp3d::Transform(rp3d::Vector3::zero(), rp3d::Quaternion::identity())); + } } // Destructor RaycastScene::~RaycastScene() { // Destroy the box rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mBox->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mBox->getCollisionBody()); delete mBox; // Destroy the sphere - mCollisionWorld->destroyCollisionBody(mSphere->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mSphere->getCollisionBody()); delete mSphere; // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mCapsule->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mCapsule->getCollisionBody()); // Destroy the sphere delete mCapsule; // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mConvexMesh->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mConvexMesh->getCollisionBody()); // Destroy the convex mesh delete mConvexMesh; // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mDumbbell->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mDumbbell->getCollisionBody()); // Destroy the dumbbell delete mDumbbell; // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody()); // Destroy the convex mesh delete mConcaveMesh; // Destroy the corresponding rigid body from the dynamics world - mCollisionWorld->destroyCollisionBody(mHeightField->getCollisionBody()); + mPhysicsWorld->destroyCollisionBody(mHeightField->getCollisionBody()); // Destroy the convex mesh delete mHeightField; @@ -250,7 +246,7 @@ RaycastScene::~RaycastScene() { VisualContactPoint::destroyStaticData(); // Destroy the collision world - delete mCollisionWorld; + delete mPhysicsWorld; // Destroy the lines for (std::vector::iterator it = mLines.begin(); it != mLines.end(); @@ -284,7 +280,7 @@ void RaycastScene::update() { // Perform a raycast query on the physics world by passing a raycast // callback class in argument. - mCollisionWorld->raycast(ray, &mRaycastManager); + mPhysicsWorld->raycast(ray, &mRaycastManager); } SceneDemo::update(); @@ -307,7 +303,7 @@ void RaycastScene::renderSinglePass(openglframework::Shader& shader, const openg mColorShader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix); // Set the vertex color - openglframework::Vector4 color(1, 0.55, 0, 1); + openglframework::Vector4 color(1, 0.55f, 0, 1); mColorShader.setVector4Uniform("vertexColor", color, false); // Get the location of shader attribute variables @@ -334,7 +330,7 @@ void RaycastScene::renderSinglePass(openglframework::Shader& shader, const openg // 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); + (*it)->render(shader, worldToCameraMatrix); } } diff --git a/testbed/scenes/raycast/RaycastScene.h b/testbed/scenes/raycast/RaycastScene.h index 1400fcf7..8024ff1a 100644 --- a/testbed/scenes/raycast/RaycastScene.h +++ b/testbed/scenes/raycast/RaycastScene.h @@ -146,9 +146,6 @@ class RaycastScene : public SceneDemo { ConcaveMesh* mConcaveMesh; HeightField* mHeightField; - /// Collision world used for the physics simulation - rp3d::CollisionWorld* mCollisionWorld; - /// All the points to render the lines std::vector mLinePoints; @@ -170,7 +167,7 @@ class RaycastScene : public SceneDemo { // -------------------- Methods -------------------- // /// Constructor - RaycastScene(const std::string& name); + RaycastScene(const std::string& name, EngineSettings& settings); /// Destructor virtual ~RaycastScene() override; diff --git a/testbed/src/Gui.cpp b/testbed/src/Gui.cpp index cd9f8f4e..6ad24335 100644 --- a/testbed/src/Gui.cpp +++ b/testbed/src/Gui.cpp @@ -388,6 +388,14 @@ void Gui::createSettingsPanel() { mApp->mIsContactPointsDisplayed = value; }); + + // Display/Hide the AABBs + CheckBox* checkboxAABBs = new CheckBox(mRenderingPanel, "AABBs"); + checkboxAABBs->setChecked(mApp->mIsAABBsDisplayed); + checkboxAABBs->setCallback([&](bool value) { + mApp->mIsAABBsDisplayed = value; + }); + // Enabled/Disable VSync CheckBox* checkboxVSync = new CheckBox(mRenderingPanel, "V-Sync"); checkboxVSync->setChecked(mApp->mIsVSyncEnabled); diff --git a/testbed/src/Scene.cpp b/testbed/src/Scene.cpp index e872b3bc..b6668649 100644 --- a/testbed/src/Scene.cpp +++ b/testbed/src/Scene.cpp @@ -30,10 +30,10 @@ using namespace openglframework; // Constructor -Scene::Scene(const std::string& name, bool isShadowMappingEnabled) - : mName(name), mInterpolationFactor(0.0f), mViewportX(0), mViewportY(0), +Scene::Scene(const std::string& name, EngineSettings& engineSettings, bool isShadowMappingEnabled) + : mName(name), mEngineSettings(engineSettings), mInterpolationFactor(0.0f), mViewportX(0), mViewportY(0), mViewportWidth(0), mViewportHeight(0), mIsShadowMappingEnabled(isShadowMappingEnabled), - mIsContactPointsDisplayed(true), mIsWireframeEnabled(false) { + mIsContactPointsDisplayed(true), mIsAABBsDisplayed(false), mIsWireframeEnabled(false) { } @@ -74,14 +74,14 @@ bool Scene::mapMouseCoordinatesToSphere(double xMouse, double yMouse, if ((xMouse >= 0) && (xMouse <= mWindowWidth) && (yMouse >= 0) && (yMouse <= mWindowHeight)) { float x = float(xMouse - 0.5f * mWindowWidth) / float(mWindowWidth); float y = float(0.5f * mWindowHeight - yMouse) / float(mWindowHeight); - float sinx = sin(PI * x * 0.5f); - float siny = sin(PI * y * 0.5f); + float sinx = std::sin(PI * x * 0.5f); + float siny = std::sin(PI * y * 0.5f); float sinx2siny2 = sinx * sinx + siny * siny; // Compute the point on the sphere spherePoint.x = sinx; spherePoint.y = siny; - spherePoint.z = (sinx2siny2 < 1.0) ? sqrt(1.0f - sinx2siny2) : 0.0f; + spherePoint.z = (sinx2siny2 < 1.0f) ? std::sqrt(1.0f - sinx2siny2) : 0.0f; return true; } @@ -175,9 +175,9 @@ void Scene::rotate(int xMouse, int yMouse) { float cosAngle = mLastPointOnSphere.dot(newPoint3D); float epsilon = std::numeric_limits::epsilon(); - if (fabs(cosAngle) < 1.0f && axis.length() > epsilon) { + if (std::abs(cosAngle) < 1.0f && axis.length() > epsilon) { axis.normalize(); - float angle = 2.0f * acos(cosAngle); + float angle = 2.0f * std::acos(cosAngle); // Rotate the camera around the center of the scene mCamera.rotateAroundLocalPoint(axis, -angle, mCenterScene); diff --git a/testbed/src/Scene.h b/testbed/src/Scene.h index aa29b9e5..e33e9da9 100644 --- a/testbed/src/Scene.h +++ b/testbed/src/Scene.h @@ -28,6 +28,7 @@ // Libraries #include "openglframework.h" +#include "reactphysics3d.h" // Structure ContactPoint struct ContactPoint { @@ -52,8 +53,8 @@ struct EngineSettings { long double elapsedTime; // Elapsed time (in seconds) float timeStep; // Current time step (in seconds) - int nbVelocitySolverIterations; // Nb of velocity solver iterations - int nbPositionSolverIterations; // Nb of position solver iterations + uint nbVelocitySolverIterations; // Nb of velocity solver iterations + uint nbPositionSolverIterations; // Nb of position solver iterations bool isSleepingEnabled; // True if sleeping technique is enabled float timeBeforeSleep; // Time of inactivity before a body sleep float sleepLinearVelocity; // Sleep linear velocity @@ -65,6 +66,23 @@ struct EngineSettings { EngineSettings() : elapsedTime(0.0f), timeStep(0.0f) { } + + /// Return default engine settings + static EngineSettings defaultSettings() { + + EngineSettings defaultSettings; + + defaultSettings.timeStep = 1.0f / 60.0f; + defaultSettings.nbVelocitySolverIterations = rp3d::DEFAULT_VELOCITY_SOLVER_NB_ITERATIONS; + defaultSettings.nbPositionSolverIterations = rp3d::DEFAULT_POSITION_SOLVER_NB_ITERATIONS; + defaultSettings.isSleepingEnabled = rp3d::SLEEPING_ENABLED; + defaultSettings.timeBeforeSleep = rp3d::DEFAULT_TIME_BEFORE_SLEEP; + defaultSettings.sleepLinearVelocity = rp3d::DEFAULT_SLEEP_LINEAR_VELOCITY; + defaultSettings.sleepAngularVelocity = rp3d::DEFAULT_SLEEP_ANGULAR_VELOCITY; + defaultSettings.isGravityEnabled = true; + + return defaultSettings; + } }; // Class Scene @@ -79,7 +97,7 @@ class Scene { std::string mName; /// Physics engine settings - EngineSettings mEngineSettings; + EngineSettings& mEngineSettings; /// Camera openglframework::Camera mCamera; @@ -111,6 +129,9 @@ class Scene { /// True if contact points are displayed bool mIsContactPointsDisplayed; + /// True if the AABBs of the phycis objects are displayed + bool mIsAABBsDisplayed; + /// True if we render shapes in wireframe mode bool mIsWireframeEnabled; @@ -140,7 +161,7 @@ class Scene { // -------------------- Methods -------------------- // /// Constructor - Scene(const std::string& name, bool isShadowMappingEnabled = false); + Scene(const std::string& name, EngineSettings& engineSettings, bool isShadowMappingEnabled = false); /// Destructor virtual ~Scene(); @@ -184,12 +205,6 @@ class Scene { /// Return a reference to the camera const openglframework::Camera& getCamera() const; - /// Get the engine settings - EngineSettings getEngineSettings() const; - - /// Set the engine settings - void setEngineSettings(const EngineSettings& settings); - /// Set the interpolation factor void setInterpolationFactor(float interpolationFactor); @@ -205,6 +220,9 @@ class Scene { /// Display/Hide the contact points void virtual setIsContactPointsDisplayed(bool display); + /// Display/Hide the AABBs + void setIsAABBsDisplayed(bool display); + /// Return true if wireframe rendering is enabled bool getIsWireframeEnabled() const; @@ -244,16 +262,6 @@ inline void Scene::setViewport(int x, int y, int width, int height) { mViewportHeight = height; } -// Get the engine settings -inline EngineSettings Scene::getEngineSettings() const { - return mEngineSettings; -} - -// Set the engine settings -inline void Scene::setEngineSettings(const EngineSettings& settings) { - mEngineSettings = settings; -} - // Set the interpolation factor inline void Scene::setInterpolationFactor(float interpolationFactor) { mInterpolationFactor = interpolationFactor; @@ -279,6 +287,11 @@ inline void Scene::setIsContactPointsDisplayed(bool display) { mIsContactPointsDisplayed = display; } +// Display/Hide the AABBs +inline void Scene::setIsAABBsDisplayed(bool display) { + mIsAABBsDisplayed = display; +} + // Return true if wireframe rendering is enabled inline bool Scene::getIsWireframeEnabled() const { return mIsWireframeEnabled; diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index d406bcea..db5d030e 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -26,27 +26,28 @@ // Libraries #include "SceneDemo.h" #include +#include "AABB.h" using namespace openglframework; int SceneDemo::shadowMapTextureLevel = 0; -openglframework::Color SceneDemo::mGreyColorDemo = Color(0.70f, 0.70f, 0.7f, 1.0); -openglframework::Color SceneDemo::mYellowColorDemo = Color(0.9, 0.88, 0.145, 1.0); -openglframework::Color SceneDemo::mBlueColorDemo = Color(0, 0.66, 0.95, 1.0); -openglframework::Color SceneDemo::mOrangeColorDemo = Color(0.9, 0.35, 0, 1.0); -openglframework::Color SceneDemo::mPinkColorDemo = Color(0.83, 0.48, 0.64, 1.0); -openglframework::Color SceneDemo::mRedColorDemo = Color(0.95, 0, 0, 1.0); +openglframework::Color SceneDemo::mGreyColorDemo = Color(0.70f, 0.70f, 0.7f, 1.0f); +openglframework::Color SceneDemo::mYellowColorDemo = Color(0.9f, 0.88f, 0.145f, 1.0f); +openglframework::Color SceneDemo::mBlueColorDemo = Color(0, 0.66f, 0.95f, 1.0f); +openglframework::Color SceneDemo::mOrangeColorDemo = Color(0.9f, 0.35f, 0, 1.0f); +openglframework::Color SceneDemo::mPinkColorDemo = Color(0.83f, 0.48f, 0.64f, 1.0f); +openglframework::Color SceneDemo::mRedColorDemo = Color(0.95f, 0, 0, 1.0f); int SceneDemo::mNbDemoColors = 4; openglframework::Color SceneDemo::mDemoColors[] = {SceneDemo::mYellowColorDemo, SceneDemo::mBlueColorDemo, SceneDemo::mOrangeColorDemo, SceneDemo::mPinkColorDemo}; // Constructor -SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMappingEnabled) - : Scene(name, isShadowMappingEnabled), mIsShadowMappingInitialized(false), +SceneDemo::SceneDemo(const std::string& name, EngineSettings& settings, float sceneRadius, bool isShadowMappingEnabled) + : Scene(name, settings, isShadowMappingEnabled), mIsShadowMappingInitialized(false), mDepthShader("shaders/depth.vert", "shaders/depth.frag"), mPhongShader("shaders/phong.vert", "shaders/phong.frag"), - mQuadShader("shaders/quad.vert", "shaders/quad.frag"), mColorShader("shaders/color.vert", "shaders/color.frag"), + mQuadShader("shaders/quad.vert", "shaders/quad.frag"), mVBOQuad(GL_ARRAY_BUFFER), mMeshFolderPath("meshes/") { shadowMapTextureLevel++; @@ -75,6 +76,9 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMa createQuadVBO(); + // Init rendering for the AABBs + AABB::init(); + VisualContactPoint::createStaticData(mMeshFolderPath); } @@ -93,6 +97,9 @@ SceneDemo::~SceneDemo() { // Destroy the contact points removeAllContactPoints(); + // Destroy rendering data for the AABB + AABB::destroy(); + VisualContactPoint::destroyStaticData(); } @@ -114,6 +121,23 @@ void SceneDemo::update() { // Can be called several times per frame void SceneDemo::updatePhysics() { + if (getDynamicsWorld() != nullptr) { + + // Update the physics engine parameters + getDynamicsWorld()->setIsGratityEnabled(mEngineSettings.isGravityEnabled); + rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y, + mEngineSettings.gravity.z); + getDynamicsWorld()->setGravity(gravity); + getDynamicsWorld()->enableSleeping(mEngineSettings.isSleepingEnabled); + getDynamicsWorld()->setSleepLinearVelocity(mEngineSettings.sleepLinearVelocity); + getDynamicsWorld()->setSleepAngularVelocity(mEngineSettings.sleepAngularVelocity); + getDynamicsWorld()->setNbIterationsPositionSolver(mEngineSettings.nbPositionSolverIterations); + getDynamicsWorld()->setNbIterationsVelocitySolver(mEngineSettings.nbVelocitySolverIterations); + getDynamicsWorld()->setTimeBeforeSleep(mEngineSettings.timeBeforeSleep); + + // Take a simulation step + getDynamicsWorld()->update(mEngineSettings.timeStep); + } } // Render the scene (in multiple passes for shadow mapping) @@ -209,6 +233,11 @@ void SceneDemo::render() { renderContactPoints(mPhongShader, worldToCameraMatrix); } + // Render the AABBs + if (mIsAABBsDisplayed) { + renderAABBs(worldToCameraMatrix); + } + if (mIsShadowMappingEnabled) mShadowMapTexture.unbind(); mPhongShader.unbind(); @@ -218,16 +247,24 @@ void SceneDemo::render() { // Render the scene in a single pass void SceneDemo::renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { - // Bind the shader + if (mIsWireframeEnabled) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } + + // 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); + (*it)->render(mIsWireframeEnabled ? mColorShader : shader, worldToCameraMatrix); } // Unbind the shader shader.unbind(); + + if (mIsWireframeEnabled) { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } } // Create the Shadow map FBO and texture @@ -338,13 +375,38 @@ void SceneDemo::updateContactPoints() { // Render the contact points void SceneDemo::renderContactPoints(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { - // Render all the raycast hit points + // Render all the contact points for (std::vector::iterator it = mContactPoints.begin(); it != mContactPoints.end(); ++it) { (*it)->render(mColorShader, worldToCameraMatrix); } } +// Render the AABBs +void SceneDemo::renderAABBs(const openglframework::Matrix4& worldToCameraMatrix) { + + // For each physics object of the scene + for (std::vector::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + + // For each proxy shape of the object + rp3d::ProxyShape* proxyShape = (*it)->getCollisionBody()->getProxyShapesList(); + while (proxyShape != nullptr) { + + // Get the broad-phase AABB corresponding to the proxy shape + rp3d::AABB aabb = mPhysicsWorld->getWorldAABB(proxyShape); + + openglframework::Vector3 aabbCenter(aabb.getCenter().x, aabb.getCenter().y, aabb.getCenter().z); + openglframework::Vector3 aabbMin(aabb.getMin().x, aabb.getMin().y, aabb.getMin().z); + openglframework::Vector3 aabbMax(aabb.getMax().x, aabb.getMax().y, aabb.getMax().z); + + // Render the AABB + AABB::render(aabbCenter, aabbMax - aabbMin, Color::green(), mColorShader, worldToCameraMatrix); + + proxyShape = proxyShape->getNext(); + } + } +} + void SceneDemo::removeAllContactPoints() { // Destroy all the visual contact points diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index a8b1941f..359c2374 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -98,6 +98,8 @@ class SceneDemo : public Scene { std::vector mPhysicsObjects; + rp3d::CollisionWorld* mPhysicsWorld; + // -------------------- Methods -------------------- // // Create the Shadow map FBO and texture @@ -116,14 +118,25 @@ class SceneDemo : public Scene { void renderContactPoints(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); + + /// Render the AABBs + void renderAABBs(const openglframework::Matrix4& worldToCameraMatrix); + + /// Remove all contact points void removeAllContactPoints(); + /// Return a reference to the dynamics world + rp3d::DynamicsWorld* getDynamicsWorld(); + + /// Return a reference to the dynamics world + const rp3d::DynamicsWorld* getDynamicsWorld() const; + public: // -------------------- Methods -------------------- // /// Constructor - SceneDemo(const std::string& name, float sceneRadius, bool isShadowMappingEnabled = true); + SceneDemo(const std::string& name, EngineSettings& settings, float sceneRadius, bool isShadowMappingEnabled = true); /// Destructor virtual ~SceneDemo() override; @@ -158,6 +171,16 @@ inline void SceneDemo::setIsShadowMappingEnabled(bool isShadowMappingEnabled) { } } +// Return a reference to the dynamics world +inline rp3d::DynamicsWorld* SceneDemo::getDynamicsWorld() { + return dynamic_cast(mPhysicsWorld); +} + +// Return a reference to the dynamics world +inline const rp3d::DynamicsWorld* SceneDemo::getDynamicsWorld() const { + return dynamic_cast(mPhysicsWorld); +} + #endif diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index 2b9195e5..d94103ef 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -59,12 +59,14 @@ TestbedApplication::TestbedApplication(bool isFullscreen) mIsMultisamplingActive = true; mWidth = 1280; mHeight = 720; + mEngineSettings = EngineSettings::defaultSettings(); mSinglePhysicsStepEnabled = false; mSinglePhysicsStepDone = false; mWindowToFramebufferRatio = Vector2(1, 1); mIsShadowMappingEnabled = true; mIsVSyncEnabled = false; mIsContactPointsDisplayed = false; + mIsAABBsDisplayed = false; mIsWireframeEnabled = false; init(); @@ -97,39 +99,38 @@ void TestbedApplication::init() { void TestbedApplication::createScenes() { // Cubes scene - CubesScene* cubeScene = new CubesScene("Cubes"); + CubesScene* cubeScene = new CubesScene("Cubes", mEngineSettings); mScenes.push_back(cubeScene); // Joints scene - JointsScene* jointsScene = new JointsScene("Joints"); + JointsScene* jointsScene = new JointsScene("Joints", mEngineSettings); mScenes.push_back(jointsScene); // Collision shapes scene - CollisionShapesScene* collisionShapesScene = new CollisionShapesScene("Collision Shapes"); + CollisionShapesScene* collisionShapesScene = new CollisionShapesScene("Collision Shapes", mEngineSettings); mScenes.push_back(collisionShapesScene); // Heightfield shape scene - HeightFieldScene* heightFieldScene = new HeightFieldScene("Heightfield"); + HeightFieldScene* heightFieldScene = new HeightFieldScene("Heightfield", mEngineSettings); mScenes.push_back(heightFieldScene); // Raycast scene - RaycastScene* raycastScene = new RaycastScene("Raycast"); + RaycastScene* raycastScene = new RaycastScene("Raycast", mEngineSettings); mScenes.push_back(raycastScene); // Collision Detection scene - CollisionDetectionScene* collisionDetectionScene = new CollisionDetectionScene("Collision Detection"); + CollisionDetectionScene* collisionDetectionScene = new CollisionDetectionScene("Collision Detection", mEngineSettings); mScenes.push_back(collisionDetectionScene); // Concave Mesh scene - ConcaveMeshScene* concaveMeshScene = new ConcaveMeshScene("Concave Mesh"); + ConcaveMeshScene* concaveMeshScene = new ConcaveMeshScene("Concave Mesh", mEngineSettings); mScenes.push_back(concaveMeshScene); assert(mScenes.size() > 0); - mCurrentScene = mScenes[5]; - // Get the engine settings from the scene - mEngineSettings = mCurrentScene->getEngineSettings(); - mEngineSettings.timeStep = DEFAULT_TIMESTEP; + const int firstSceneIndex = 0; + + switchScene(mScenes[firstSceneIndex]); } // Remove all the scenes @@ -152,9 +153,8 @@ void TestbedApplication::updateSinglePhysicsStep() { // Update the physics of the current scene void TestbedApplication::updatePhysics() { - // Set the engine settings + // Update the elapsed time mEngineSettings.elapsedTime = mTimer.getPhysicsTime(); - mCurrentScene->setEngineSettings(mEngineSettings); if (mTimer.isRunning()) { @@ -202,6 +202,9 @@ void TestbedApplication::update() { // Display/Hide contact points mCurrentScene->setIsContactPointsDisplayed(mIsContactPointsDisplayed); + // Display/Hide the AABBs + mCurrentScene->setIsAABBsDisplayed(mIsAABBsDisplayed); + // Enable/Disable wireframe mode mCurrentScene->setIsWireframeEnabled(mIsWireframeEnabled); @@ -259,11 +262,6 @@ void TestbedApplication::switchScene(Scene* newScene) { mCurrentScene = newScene; - // Get the engine settings of the scene - float currentTimeStep = mEngineSettings.timeStep; - mEngineSettings = mCurrentScene->getEngineSettings(); - mEngineSettings.timeStep = currentTimeStep; - // Reset the scene mCurrentScene->reset(); diff --git a/testbed/src/TestbedApplication.h b/testbed/src/TestbedApplication.h index 8790a1f7..3a9fe071 100644 --- a/testbed/src/TestbedApplication.h +++ b/testbed/src/TestbedApplication.h @@ -38,9 +38,6 @@ using namespace nanogui; // Macro for OpenGL errors #define checkOpenGLErrors() checkOpenGLErrorsInternal(__FILE__,__LINE__) -// Constants -const float DEFAULT_TIMESTEP = 1.0f / 60.0f; - /// Class TestbedApplication class TestbedApplication : public Screen { @@ -109,6 +106,9 @@ class TestbedApplication : public Screen { /// True if contact points are displayed bool mIsContactPointsDisplayed; + /// True if the AABBs of physics objects are displayed + bool mIsAABBsDisplayed; + /// True if the wireframe rendering is enabled bool mIsWireframeEnabled;