Refactor the testbed application and display objects AABBs

This commit is contained in:
Daniel Chappuis 2017-11-02 22:58:41 +01:00
parent ad0f805f53
commit 7495ff6598
39 changed files with 1066 additions and 1014 deletions

View File

@ -94,6 +94,8 @@ SET(COMMON_SOURCES
common/VisualContactPoint.cpp common/VisualContactPoint.cpp
common/PerlinNoise.h common/PerlinNoise.h
common/PerlinNoise.cpp common/PerlinNoise.cpp
common/AABB.h
common/AABB.cpp
) )
# Examples scenes source files # Examples scenes source files

202
testbed/common/AABB.cpp Normal file
View File

@ -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<openglframework::Vector3> vertices;
std::vector<openglframework::Vector3> normals;
std::vector<unsigned int> 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<GLsizei>(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<GLsizei>(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<GLsizei>(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();
}

79
testbed/common/AABB.h Normal file
View File

@ -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

View File

@ -38,8 +38,8 @@ openglframework::VertexArrayObject Box::mVAO;
int Box::totalNbBoxes = 0; int Box::totalNbBoxes = 0;
// Constructor // Constructor
Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, Box::Box(const openglframework::Vector3& size, reactphysics3d::CollisionWorld* world,
reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath) const std::string& meshFolderPath)
: PhysicsObject(meshFolderPath + "cube.obj") { : PhysicsObject(meshFolderPath + "cube.obj") {
// Initialize the size of the box // 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, mSize[2], 0,
0, 0, 0, 1); 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) // Create the collision shape for the rigid body (box shape)
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // 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 = 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 mPreviousTransform = rp3d::Transform::identity();
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
mPreviousTransform = transform;
// Create a rigid body in the dynamics world // Create a rigid body in the dynamics world
mBody = world->createCollisionBody(transform); mBody = world->createCollisionBody(mPreviousTransform);
// Add the collision shape to the body // Add the collision shape to the body
mProxyShape = mBody->addCollisionShape(mBoxShape, rp3d::Transform::identity()); mProxyShape = mBody->addCollisionShape(mBoxShape, rp3d::Transform::identity());
@ -87,8 +80,8 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
} }
// Constructor // Constructor
Box::Box(const openglframework::Vector3& size, const openglframework::Vector3& position, Box::Box(const openglframework::Vector3& size, float mass, reactphysics3d::DynamicsWorld* world,
float mass, reactphysics3d::DynamicsWorld* world, const std::string& meshFolderPath) const std::string& meshFolderPath)
: PhysicsObject(meshFolderPath + "cube.obj") { : PhysicsObject(meshFolderPath + "cube.obj") {
// Load the mesh from a file // 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, mSize[2], 0,
0, 0, 0, 1); 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) // Create the collision shape for the rigid body (box shape)
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // 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 = new rp3d::BoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2]));
// Initial position and orientation of the rigid body mPreviousTransform = rp3d::Transform::identity();
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
mPreviousTransform = transform;
// Create a rigid body in the dynamics world // 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 // Add the collision shape to the body
mProxyShape = body->addCollisionShape(mBoxShape, rp3d::Transform::identity(), mass); 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 // Render the cube at the correct position and with the correct orientation
void Box::render(openglframework::Shader& shader, void Box::render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) {
const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) {
if (wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
// Bind the shader // Bind the shader
shader.bind(); shader.bind();
@ -217,10 +197,6 @@ void Box::render(openglframework::Shader& shader,
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
if (wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
} }
// Create the Vertex Buffer Objects used to render to box with OpenGL. // Create the Vertex Buffer Objects used to render to box with OpenGL.

View File

@ -75,24 +75,22 @@ class Box : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Box(const openglframework::Vector3& size, const openglframework::Vector3& position, Box(const openglframework::Vector3& size, reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath);
reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath);
/// Constructor /// Constructor
Box(const openglframework::Vector3& size, const openglframework::Vector3& position, Box(const openglframework::Vector3& size, float mass, reactphysics3d::DynamicsWorld *world, const std::string& meshFolderPath);
float mass, reactphysics3d::DynamicsWorld *world, const std::string& meshFolderPath);
/// Destructor /// Destructor
~Box(); ~Box();
/// Render the cube at the correct position and with the correct orientation /// 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 /// Update the transform matrix of the object
virtual void updateTransform(float interpolationFactor) override; virtual void updateTransform(float interpolationFactor) override;
/// Set the scaling of the object /// 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 // Update the transform matrix of the object

View File

@ -34,9 +34,7 @@ openglframework::VertexArrayObject Capsule::mVAO;
int Capsule::totalNbCapsules = 0; int Capsule::totalNbCapsules = 0;
// Constructor // Constructor
Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, Capsule::Capsule(float radius, float height, rp3d::CollisionWorld* world, const std::string& meshFolderPath)
reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath)
: PhysicsObject(meshFolderPath + "capsule.obj"), mRadius(radius), mHeight(height) { : PhysicsObject(meshFolderPath + "capsule.obj"), mRadius(radius), mHeight(height) {
// Compute the scaling matrix // Compute the scaling matrix
@ -45,23 +43,16 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
0, 0, mRadius, 0, 0, 0, mRadius, 0,
0, 0, 0, 1.0f); 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) // Create the collision shape for the rigid body (sphere shape)
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
mCapsuleShape = new rp3d::CapsuleShape(mRadius, mHeight); mCapsuleShape = new rp3d::CapsuleShape(mRadius, mHeight);
//mCapsuleShape->setLocalScaling(rp3d::Vector3(2, 2, 2));
// Initial position and orientation of the rigid body mPreviousTransform = rp3d::Transform::identity();
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
mPreviousTransform = transform;
// Create a rigid body corresponding in the dynamics world // 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 // Add a collision shape to the body and specify the mass of the shape
mProxyShape = mBody->addCollisionShape(mCapsuleShape, rp3d::Transform::identity()); mProxyShape = mBody->addCollisionShape(mCapsuleShape, rp3d::Transform::identity());
@ -77,8 +68,7 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
} }
// Constructor // Constructor
Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, Capsule::Capsule(float radius, float height, float mass, rp3d::DynamicsWorld* dynamicsWorld,
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshFolderPath) const std::string& meshFolderPath)
: PhysicsObject(meshFolderPath + "capsule.obj"), mRadius(radius), mHeight(height) { : 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, mRadius, 0,
0, 0, 0, 1.0f); 0, 0, 0, 1.0f);
// Initialize the position where the sphere will be rendered mPreviousTransform = rp3d::Transform::identity();
translateWorld(position);
// Create the collision shape for the rigid body (sphere shape) // Create the collision shape for the rigid body (sphere shape)
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
mCapsuleShape = new rp3d::CapsuleShape(mRadius, mHeight); mCapsuleShape = new rp3d::CapsuleShape(mRadius, mHeight);
// Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
// Create a rigid body corresponding in the dynamics world // 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 // Add a collision shape to the body and specify the mass of the shape
mProxyShape = body->addCollisionShape(mCapsuleShape, rp3d::Transform::identity(), mass); 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 // Render the sphere at the correct position and with the correct orientation
void Capsule::render(openglframework::Shader& shader, void Capsule::render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) { const openglframework::Matrix4& worldToCameraMatrix) {
if (wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
// Bind the shader // Bind the shader
shader.bind(); shader.bind();
@ -198,10 +178,6 @@ void Capsule::render(openglframework::Shader& shader,
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
if (wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
} }
// Create the Vertex Buffer Objects used to render with OpenGL. // Create the Vertex Buffer Objects used to render with OpenGL.

View File

@ -82,25 +82,23 @@ class Capsule : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Capsule(float radius, float height, const openglframework::Vector3& position, Capsule(float radius, float height, rp3d::CollisionWorld* world, const std::string& meshFolderPath);
reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath);
/// Constructor /// Constructor
Capsule(float radius, float height, const openglframework::Vector3& position, Capsule(float radius, float height, float mass, rp3d::DynamicsWorld* dynamicsWorld,
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshFolderPath); const std::string& meshFolderPath);
/// Destructor /// Destructor
~Capsule(); ~Capsule();
/// Render the sphere at the correct position and with the correct orientation /// 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 /// Update the transform matrix of the object
virtual void updateTransform(float interpolationFactor) override; virtual void updateTransform(float interpolationFactor) override;
/// Set the scaling of the object /// 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 // Update the transform matrix of the object

View File

@ -27,16 +27,11 @@
#include "ConcaveMesh.h" #include "ConcaveMesh.h"
// Constructor // Constructor
ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position, ConcaveMesh::ConcaveMesh(rp3d::CollisionWorld* world, const std::string& meshPath)
reactphysics3d::CollisionWorld* world,
const std::string& meshPath)
: PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER), : PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
// Initialize the position where the sphere will be rendered
translateWorld(position);
// Compute the scaling matrix // Compute the scaling matrix
mScalingMatrix = openglframework::Matrix4::identity(); mScalingMatrix = openglframework::Matrix4::identity();
@ -58,15 +53,10 @@ ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position,
// do not forget to delete it at the end // do not forget to delete it at the end
mConcaveShape = new rp3d::ConcaveMeshShape(&mPhysicsTriangleMesh); mConcaveShape = new rp3d::ConcaveMeshShape(&mPhysicsTriangleMesh);
// Initial position and orientation of the rigid body mPreviousTransform = rp3d::Transform::identity();
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
mPreviousTransform = transform;
// Create a rigid body corresponding to the sphere in the dynamics world // 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 // Add a collision shape to the body and specify the mass of the collision shape
mProxyShape = mBody->addCollisionShape(mConcaveShape, rp3d::Transform::identity()); mProxyShape = mBody->addCollisionShape(mConcaveShape, rp3d::Transform::identity());
@ -78,16 +68,11 @@ ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position,
} }
// Constructor // Constructor
ConcaveMesh::ConcaveMesh(const openglframework::Vector3 &position, float mass, ConcaveMesh::ConcaveMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath)
reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshPath)
: PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER), : PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
// Initialize the position where the sphere will be rendered
translateWorld(position);
// Compute the scaling matrix // Compute the scaling matrix
mScalingMatrix = openglframework::Matrix4::identity(); 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 // do not forget to delete it at the end
mConcaveShape = new rp3d::ConcaveMeshShape(&mPhysicsTriangleMesh); mConcaveShape = new rp3d::ConcaveMeshShape(&mPhysicsTriangleMesh);
// Initial position and orientation of the rigid body mPreviousTransform = rp3d::Transform::identity();
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
// Create a rigid body corresponding to the sphere in the dynamics world // 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 // Add a collision shape to the body and specify the mass of the collision shape
mProxyShape = body->addCollisionShape(mConcaveShape, rp3d::Transform::identity(), mass); 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 // Render the sphere at the correct position and with the correct orientation
void ConcaveMesh::render(openglframework::Shader& shader, void ConcaveMesh::render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) { const openglframework::Matrix4& worldToCameraMatrix) {
if (wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
// Bind the shader // Bind the shader
shader.bind(); shader.bind();
@ -209,10 +187,6 @@ void ConcaveMesh::render(openglframework::Shader& shader,
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
if (wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
} }
// Create the Vertex Buffer Objects used to render with OpenGL. // Create the Vertex Buffer Objects used to render with OpenGL.

View File

@ -76,25 +76,23 @@ class ConcaveMesh : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
ConcaveMesh(const openglframework::Vector3& position, ConcaveMesh(rp3d::CollisionWorld* world, const std::string& meshPath);
rp3d::CollisionWorld* world, const std::string& meshPath);
/// Constructor /// Constructor
ConcaveMesh(const openglframework::Vector3& position, float mass, ConcaveMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath);
rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath);
/// Destructor /// Destructor
~ConcaveMesh(); ~ConcaveMesh();
/// Render the mesh at the correct position and with the correct orientation /// Render the mesh at the correct position and with the correct orientation
void render(openglframework::Shader& shader, void render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix, bool wireframe); const openglframework::Matrix4& worldToCameraMatrix) override;
/// Update the transform matrix of the object /// Update the transform matrix of the object
virtual void updateTransform(float interpolationFactor) override; virtual void updateTransform(float interpolationFactor) override;
/// Set the scaling of the object /// 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 // Update the transform matrix of the object

View File

@ -27,16 +27,11 @@
#include "ConvexMesh.h" #include "ConvexMesh.h"
// Constructor // Constructor
ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, ConvexMesh::ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath)
reactphysics3d::CollisionWorld* world,
const std::string& meshPath)
: PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER), : PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
// Initialize the position where the sphere will be rendered
translateWorld(position);
// Compute the scaling matrix // Compute the scaling matrix
mScalingMatrix = openglframework::Matrix4::identity(); mScalingMatrix = openglframework::Matrix4::identity();
@ -64,15 +59,10 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position,
// do not forget to delete it at the end // do not forget to delete it at the end
mConvexShape = new rp3d::ConvexMeshShape(mPolyhedronMesh); mConvexShape = new rp3d::ConvexMeshShape(mPolyhedronMesh);
// Initial position and orientation of the rigid body mPreviousTransform = rp3d::Transform::identity();
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
mPreviousTransform = transform;
// Create a rigid body corresponding to the sphere in the dynamics world // 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 // Add a collision shape to the body and specify the mass of the collision shape
mProxyShape = mBody->addCollisionShape(mConvexShape, rp3d::Transform::identity()); mProxyShape = mBody->addCollisionShape(mConvexShape, rp3d::Transform::identity());
@ -84,16 +74,11 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position,
} }
// Constructor // Constructor
ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, ConvexMesh::ConvexMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath)
reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshPath)
: PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER), : PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
// Initialize the position where the sphere will be rendered
translateWorld(position);
// Compute the scaling matrix // Compute the scaling matrix
mScalingMatrix = openglframework::Matrix4::identity(); mScalingMatrix = openglframework::Matrix4::identity();
@ -121,13 +106,10 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass,
// not forget to delete it at the end // not forget to delete it at the end
mConvexShape = new rp3d::ConvexMeshShape(mPolyhedronMesh); mConvexShape = new rp3d::ConvexMeshShape(mPolyhedronMesh);
// Initial position and orientation of the rigid body mPreviousTransform = rp3d::Transform::identity();
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
// Create a rigid body corresponding to the sphere in the dynamics world // 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 // Add a collision shape to the body and specify the mass of the collision shape
mProxyShape = body->addCollisionShape(mConvexShape, rp3d::Transform::identity(), mass); 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 // Render the sphere at the correct position and with the correct orientation
void ConvexMesh::render(openglframework::Shader& shader, void ConvexMesh::render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) { const openglframework::Matrix4& worldToCameraMatrix) {
if (wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
// Bind the shader // Bind the shader
shader.bind(); shader.bind();
@ -219,10 +197,6 @@ void ConvexMesh::render(openglframework::Shader& shader,
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
if (wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
} }
// Create the Vertex Buffer Objects used to render with OpenGL. // Create the Vertex Buffer Objects used to render with OpenGL.

View File

@ -79,24 +79,22 @@ class ConvexMesh : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
ConvexMesh(const openglframework::Vector3& position, ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath);
rp3d::CollisionWorld* world, const std::string& meshPath);
/// Constructor /// Constructor
ConvexMesh(const openglframework::Vector3& position, float mass, ConvexMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath);
rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath);
/// Destructor /// Destructor
~ConvexMesh(); ~ConvexMesh();
/// Render the mesh at the correct position and with the correct orientation /// 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 /// Update the transform matrix of the object
virtual void updateTransform(float interpolationFactor) override; virtual void updateTransform(float interpolationFactor) override;
/// Set the scaling of the object /// 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 // Update the transform matrix of the object

View File

@ -34,8 +34,7 @@ openglframework::VertexArrayObject Dumbbell::mVAO;
int Dumbbell::totalNbDumbbells = 0; int Dumbbell::totalNbDumbbells = 0;
// Constructor // Constructor
Dumbbell::Dumbbell(const openglframework::Vector3 &position, Dumbbell::Dumbbell(rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath)
reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath)
: PhysicsObject(meshFolderPath + "dumbbell.obj") { : PhysicsObject(meshFolderPath + "dumbbell.obj") {
// Identity scaling matrix // Identity scaling matrix
@ -43,9 +42,6 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
mDistanceBetweenSphere = 8.0f; 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 // Create a sphere collision shape for the two ends of the dumbbell
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // 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); const rp3d::decimal massCylinder = rp3d::decimal(1.0);
mCapsuleShape = new rp3d::CapsuleShape(radiusCapsule, heightCapsule); mCapsuleShape = new rp3d::CapsuleShape(radiusCapsule, heightCapsule);
// Initial position and orientation of the rigid body mPreviousTransform = rp3d::Transform::identity();
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;
// Initial transform of the first sphere collision shape of the dumbbell (in local-space) // 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()); 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()); rp3d::Transform transformCylinderShape(rp3d::Vector3(0, 0, 0), rp3d::Quaternion::identity());
// Create a rigid body corresponding to the dumbbell in the dynamics world // 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 // Add the three collision shapes to the body and specify the mass and transform of the shapes
mProxyShapeSphere1 = body->addCollisionShape(mSphereShape, transformSphereShape1, massSphere); mProxyShapeSphere1 = body->addCollisionShape(mSphereShape, transformSphereShape1, massSphere);
@ -99,8 +89,7 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
} }
// Constructor // Constructor
Dumbbell::Dumbbell(const openglframework::Vector3 &position, Dumbbell::Dumbbell(rp3d::CollisionWorld* world, const std::string& meshFolderPath)
reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath)
: PhysicsObject(meshFolderPath + "dumbbell.obj"){ : PhysicsObject(meshFolderPath + "dumbbell.obj"){
// Identity scaling matrix // Identity scaling matrix
@ -108,9 +97,6 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
mDistanceBetweenSphere = 8.0f; 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 // Create a sphere collision shape for the two ends of the dumbbell
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // 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); const rp3d::decimal heightCapsule = rp3d::decimal(7.0);
mCapsuleShape = new rp3d::CapsuleShape(radiusCapsule, heightCapsule); 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) // 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()); 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) // Initial transform of the cylinder collision shape of the dumbell (in local-space)
rp3d::Transform transformCylinderShape(rp3d::Vector3(0, 0, 0), rp3d::Quaternion::identity()); 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 // 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 // Add the three collision shapes to the body and specify the mass and transform of the shapes
mProxyShapeSphere1 = mBody->addCollisionShape(mSphereShape, transformSphereShape1); mProxyShapeSphere1 = mBody->addCollisionShape(mSphereShape, transformSphereShape1);
@ -179,11 +161,7 @@ Dumbbell::~Dumbbell() {
// Render the sphere at the correct position and with the correct orientation // Render the sphere at the correct position and with the correct orientation
void Dumbbell::render(openglframework::Shader& shader, void Dumbbell::render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) { const openglframework::Matrix4& worldToCameraMatrix) {
if (wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
// Bind the shader // Bind the shader
shader.bind(); shader.bind();
@ -237,10 +215,6 @@ void Dumbbell::render(openglframework::Shader& shader,
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
if (wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
} }
// Create the Vertex Buffer Objects used to render with OpenGL. // Create the Vertex Buffer Objects used to render with OpenGL.

View File

@ -82,24 +82,22 @@ class Dumbbell : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Dumbbell(const openglframework::Vector3& position, rp3d::DynamicsWorld* dynamicsWorld, Dumbbell(rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath);
const std::string& meshFolderPath);
/// Constructor /// Constructor
Dumbbell(const openglframework::Vector3& position, rp3d::CollisionWorld* world, Dumbbell(rp3d::CollisionWorld* world, const std::string& meshFolderPath);
const std::string& meshFolderPath);
/// Destructor /// Destructor
~Dumbbell(); ~Dumbbell();
/// Render the sphere at the correct position and with the correct orientation /// 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 /// Update the transform matrix of the object
virtual void updateTransform(float interpolationFactor) override; virtual void updateTransform(float interpolationFactor) override;
/// Set the scaling of the object /// 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 // Update the transform matrix of the object

View File

@ -28,15 +28,11 @@
#include "PerlinNoise.h" #include "PerlinNoise.h"
// Constructor // Constructor
HeightField::HeightField(const openglframework::Vector3 &position, HeightField::HeightField(rp3d::CollisionWorld* world)
reactphysics3d::CollisionWorld* world)
: mVBOVertices(GL_ARRAY_BUFFER), : mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
// Initialize the position where the sphere will be rendered
translateWorld(position);
// Compute the scaling matrix // Compute the scaling matrix
mScalingMatrix = openglframework::Matrix4::identity(); 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, mHeightFieldShape = new rp3d::HeightFieldShape(NB_POINTS_WIDTH, NB_POINTS_LENGTH, mMinHeight, mMaxHeight,
mHeightData, rp3d::HeightFieldShape::HeightDataType::HEIGHT_FLOAT_TYPE); mHeightData, rp3d::HeightFieldShape::HeightDataType::HEIGHT_FLOAT_TYPE);
// Initial position and orientation of the rigid body mPreviousTransform = rp3d::Transform::identity();
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
mPreviousTransform = transform;
// Create a rigid body corresponding to the sphere in the dynamics world // 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 // Add a collision shape to the body and specify the mass of the collision shape
mProxyShape = mBody->addCollisionShape(mHeightFieldShape, rp3d::Transform::identity()); mProxyShape = mBody->addCollisionShape(mHeightFieldShape, rp3d::Transform::identity());
@ -71,15 +62,11 @@ HeightField::HeightField(const openglframework::Vector3 &position,
} }
// Constructor // Constructor
HeightField::HeightField(const openglframework::Vector3 &position, float mass, HeightField::HeightField(float mass, rp3d::DynamicsWorld* dynamicsWorld)
reactphysics3d::DynamicsWorld* dynamicsWorld)
: mVBOVertices(GL_ARRAY_BUFFER), : mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
// Initialize the position where the sphere will be rendered
translateWorld(position);
// Compute the scaling matrix // Compute the scaling matrix
mScalingMatrix = openglframework::Matrix4::identity(); 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, mHeightFieldShape = new rp3d::HeightFieldShape(NB_POINTS_WIDTH, NB_POINTS_LENGTH, mMinHeight, mMaxHeight,
mHeightData, rp3d::HeightFieldShape::HeightDataType::HEIGHT_FLOAT_TYPE); mHeightData, rp3d::HeightFieldShape::HeightDataType::HEIGHT_FLOAT_TYPE);
// Initial position and orientation of the rigid body mPreviousTransform = rp3d::Transform::identity();
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
// Create a rigid body corresponding to the sphere in the dynamics world // 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 // Add a collision shape to the body and specify the mass of the collision shape
mProxyShape = body->addCollisionShape(mHeightFieldShape, rp3d::Transform::identity(), mass); 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 // Render the sphere at the correct position and with the correct orientation
void HeightField::render(openglframework::Shader& shader, void HeightField::render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix, bool wireframe) { const openglframework::Matrix4& worldToCameraMatrix) {
if (wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
// Bind the shader // Bind the shader
shader.bind(); shader.bind();
@ -189,10 +169,6 @@ void HeightField::render(openglframework::Shader& shader,
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
if (wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
} }
// Compute the heights of the height field // Compute the heights of the height field

View File

@ -89,25 +89,23 @@ class HeightField : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
HeightField(const openglframework::Vector3& position, HeightField(rp3d::CollisionWorld* world);
rp3d::CollisionWorld* world);
/// Constructor /// Constructor
HeightField(const openglframework::Vector3& position, float mass, HeightField(float mass, rp3d::DynamicsWorld* dynamicsWorld);
rp3d::DynamicsWorld* dynamicsWorld);
/// Destructor /// Destructor
~HeightField(); ~HeightField();
/// Render the mesh at the correct position and with the correct orientation /// Render the mesh at the correct position and with the correct orientation
void render(openglframework::Shader& shader, void render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix, bool wireframe); const openglframework::Matrix4& worldToCameraMatrix) override;
/// Update the transform matrix of the object /// Update the transform matrix of the object
virtual void updateTransform(float interpolationFactor) override; virtual void updateTransform(float interpolationFactor) override;
/// Set the scaling of the object /// 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 // Update the transform matrix of the object

View File

@ -63,7 +63,7 @@ class PhysicsObject : public openglframework::Mesh {
virtual void updateTransform(float interpolationFactor)=0; virtual void updateTransform(float interpolationFactor)=0;
/// Render the sphere at the correct position and with the correct orientation /// 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 /// Set the color of the box
void setColor(const openglframework::Color& color); void setColor(const openglframework::Color& color);

View File

@ -34,8 +34,7 @@ openglframework::VertexArrayObject Sphere::mVAO;
int Sphere::totalNbSpheres = 0; int Sphere::totalNbSpheres = 0;
// Constructor // Constructor
Sphere::Sphere(float radius, const openglframework::Vector3 &position, Sphere::Sphere(float radius, rp3d::CollisionWorld* world,
reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath) const std::string& meshFolderPath)
: PhysicsObject(meshFolderPath + "sphere.obj"), mRadius(radius) { : PhysicsObject(meshFolderPath + "sphere.obj"), mRadius(radius) {
@ -45,23 +44,16 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
0, 0, mRadius, 0, 0, 0, mRadius, 0,
0, 0, 0, 1); 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) // Create the collision shape for the rigid body (sphere shape)
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
mCollisionShape = new rp3d::SphereShape(mRadius); mCollisionShape = new rp3d::SphereShape(mRadius);
//mCollisionShape->setLocalScaling(rp3d::Vector3(2, 2, 2));
// Initial position and orientation of the rigid body mPreviousTransform = rp3d::Transform::identity();
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
mPreviousTransform = transform;
// Create a rigid body corresponding to the sphere in the dynamics world // 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 // Add a collision shape to the body and specify the mass of the shape
mProxyShape = mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity()); mProxyShape = mBody->addCollisionShape(mCollisionShape, rp3d::Transform::identity());
@ -77,8 +69,7 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
} }
// Constructor // Constructor
Sphere::Sphere(float radius, const openglframework::Vector3 &position, Sphere::Sphere(float radius, float mass, reactphysics3d::DynamicsWorld* world,
float mass, reactphysics3d::DynamicsWorld* world,
const std::string& meshFolderPath) const std::string& meshFolderPath)
: PhysicsObject(meshFolderPath + "sphere.obj"), mRadius(radius) { : PhysicsObject(meshFolderPath + "sphere.obj"), mRadius(radius) {
@ -88,21 +79,15 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
0, 0, mRadius, 0, 0, 0, mRadius, 0,
0, 0, 0, 1); 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) // Create the collision shape for the rigid body (sphere shape)
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
mCollisionShape = new rp3d::SphereShape(mRadius); mCollisionShape = new rp3d::SphereShape(mRadius);
// Initial position and orientation of the rigid body mPreviousTransform = rp3d::Transform::identity();
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
// Create a rigid body corresponding to the sphere in the dynamics world // 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 // Add a collision shape to the body and specify the mass of the shape
mProxyShape = body->addCollisionShape(mCollisionShape, rp3d::Transform::identity(), mass); 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 // Render the sphere at the correct position and with the correct orientation
void Sphere::render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix, bool wireFrame) { void Sphere::render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) {
if (wireFrame) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
// Bind the shader // Bind the shader
shader.bind(); shader.bind();
@ -196,10 +177,6 @@ void Sphere::render(openglframework::Shader& shader, const openglframework::Matr
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
if (wireFrame) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
} }
// Create the Vertex Buffer Objects used to render with OpenGL. // Create the Vertex Buffer Objects used to render with OpenGL.

View File

@ -79,24 +79,22 @@ class Sphere : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Sphere(float radius, const openglframework::Vector3& position, Sphere(float radius, rp3d::CollisionWorld* world, const std::string& meshFolderPath);
rp3d::CollisionWorld* world, const std::string& meshFolderPath);
/// Constructor /// Constructor
Sphere(float radius, const openglframework::Vector3& position, Sphere(float radius, float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath);
float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath);
/// Destructor /// Destructor
~Sphere(); ~Sphere();
/// Render the sphere at the correct position and with the correct orientation /// 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 /// Update the transform matrix of the object
virtual void updateTransform(float interpolationFactor) override; virtual void updateTransform(float interpolationFactor) override;
/// Set the scaling of the object /// 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 // Update the transform matrix of the object

View File

@ -31,8 +31,8 @@ using namespace openglframework;
using namespace collisiondetectionscene; using namespace collisiondetectionscene;
// Constructor // Constructor
CollisionDetectionScene::CollisionDetectionScene(const std::string& name) CollisionDetectionScene::CollisionDetectionScene(const std::string& name, EngineSettings& settings)
: SceneDemo(name, SCENE_RADIUS, false), mMeshFolderPath("meshes/"), : SceneDemo(name, settings, SCENE_RADIUS, false), mMeshFolderPath("meshes/"),
mContactManager(mPhongShader, mMeshFolderPath), mContactManager(mPhongShader, mMeshFolderPath),
mAreNormalsDisplayed(false) { mAreNormalsDisplayed(false) {
@ -47,25 +47,24 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name)
setScenePosition(center, SCENE_RADIUS); setScenePosition(center, SCENE_RADIUS);
// Create the dynamics world for the physics simulation // Create the dynamics world for the physics simulation
mCollisionWorld = new rp3d::CollisionWorld(); mPhysicsWorld = new rp3d::CollisionWorld();
// ---------- Sphere 1 ---------- // // ---------- Sphere 1 ---------- //
openglframework::Vector3 position1(12, 0, 0);
// Create a sphere and a corresponding collision body in the dynamics world // 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); mAllShapes.push_back(mSphere1);
// Set the color // Set the color
mSphere1->setColor(mGreyColorDemo); mSphere1->setColor(mGreyColorDemo);
mSphere1->setSleepingColor(mRedColorDemo); mSphere1->setSleepingColor(mRedColorDemo);
//mSphere1->setScaling(0.5f);
mPhysicsObjects.push_back(mSphere1); mPhysicsObjects.push_back(mSphere1);
// ---------- Sphere 2 ---------- // // ---------- Sphere 2 ---------- //
openglframework::Vector3 position2(12, 8, 0);
// Create a sphere and a corresponding collision body in the dynamics world // 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); mAllShapes.push_back(mSphere2);
// Set the color // Set the color
@ -74,10 +73,9 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name)
mPhysicsObjects.push_back(mSphere2); mPhysicsObjects.push_back(mSphere2);
// ---------- Capsule 1 ---------- // // ---------- Capsule 1 ---------- //
openglframework::Vector3 position3(-6, 7, 0);
// Create a cylinder and a corresponding collision body in the dynamics world // Create a cylinder and a corresponding collision body in the dynamics world
mCapsule1 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position3, mCollisionWorld, mMeshFolderPath); mCapsule1 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mCapsule1); mAllShapes.push_back(mCapsule1);
// Set the color // Set the color
@ -86,10 +84,9 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name)
mPhysicsObjects.push_back(mCapsule1); mPhysicsObjects.push_back(mCapsule1);
// ---------- Capsule 2 ---------- // // ---------- Capsule 2 ---------- //
openglframework::Vector3 position4(11, -8, 0);
// Create a cylinder and a corresponding collision body in the dynamics world // Create a cylinder and a corresponding collision body in the dynamics world
mCapsule2 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position4, mCollisionWorld, mMeshFolderPath); mCapsule2 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mCapsule2); mAllShapes.push_back(mCapsule2);
// Set the color // Set the color
@ -98,10 +95,9 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name)
mPhysicsObjects.push_back(mCapsule2); mPhysicsObjects.push_back(mCapsule2);
// ---------- Box 1 ---------- // // ---------- Box 1 ---------- //
openglframework::Vector3 position5(-4, -7, 0);
// Create a cylinder and a corresponding collision body in the dynamics world // 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); mAllShapes.push_back(mBox1);
// Set the color // Set the color
@ -110,10 +106,9 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name)
mPhysicsObjects.push_back(mBox1); mPhysicsObjects.push_back(mBox1);
// ---------- Box 2 ---------- // // ---------- Box 2 ---------- //
openglframework::Vector3 position6(0, 8, 0);
// Create a cylinder and a corresponding collision body in the dynamics world // 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); mAllShapes.push_back(mBox2);
// Set the color // Set the color
@ -122,10 +117,9 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name)
mPhysicsObjects.push_back(mBox2); mPhysicsObjects.push_back(mBox2);
// ---------- Convex Mesh ---------- // // ---------- Convex Mesh ---------- //
openglframework::Vector3 position7(-5, 0, 0);
// Create a convex mesh and a corresponding collision body in the dynamics world // 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); mAllShapes.push_back(mConvexMesh);
// Set the color // Set the color
@ -134,10 +128,9 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name)
mPhysicsObjects.push_back(mConvexMesh); mPhysicsObjects.push_back(mConvexMesh);
// ---------- Concave Mesh ---------- // // ---------- Concave Mesh ---------- //
openglframework::Vector3 position8(0, 100, 0);
// Create a convex mesh and a corresponding collision body in the dynamics world // 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); mAllShapes.push_back(mConcaveMesh);
// Set the color // Set the color
@ -146,10 +139,9 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name)
mPhysicsObjects.push_back(mConcaveMesh); mPhysicsObjects.push_back(mConcaveMesh);
// ---------- Heightfield ---------- // // ---------- Heightfield ---------- //
openglframework::Vector3 position9(0, -12, 0);
// Create a convex mesh and a corresponding collision body in the dynamics world // 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 // Set the color
mHeightField->setColor(mGreyColorDemo); mHeightField->setColor(mGreyColorDemo);
@ -162,76 +154,59 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name)
// Reset the scene // Reset the scene
void CollisionDetectionScene::reset() { 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 // Destructor
CollisionDetectionScene::~CollisionDetectionScene() { CollisionDetectionScene::~CollisionDetectionScene() {
// Destroy the box rigid body from the dynamics world // Destroy the box rigid body from the dynamics world
//mCollisionWorld->destroyCollisionBody(mBox->getCollisionBody()); //mPhysicsWorld->destroyCollisionBody(mBox->getCollisionBody());
//delete mBox; //delete mBox;
// Destroy the spheres // Destroy the spheres
mCollisionWorld->destroyCollisionBody(mSphere1->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mSphere1->getCollisionBody());
delete mSphere1; delete mSphere1;
mCollisionWorld->destroyCollisionBody(mSphere2->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mSphere2->getCollisionBody());
delete mSphere2; delete mSphere2;
mCollisionWorld->destroyCollisionBody(mCapsule1->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mCapsule1->getCollisionBody());
delete mCapsule1; delete mCapsule1;
mCollisionWorld->destroyCollisionBody(mCapsule2->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mCapsule2->getCollisionBody());
delete mCapsule2; delete mCapsule2;
mCollisionWorld->destroyCollisionBody(mBox1->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mBox1->getCollisionBody());
delete mBox1; delete mBox1;
mCollisionWorld->destroyCollisionBody(mBox2->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mBox2->getCollisionBody());
delete mBox2; delete mBox2;
mCollisionWorld->destroyCollisionBody(mConvexMesh->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mConvexMesh->getCollisionBody());
delete mConvexMesh; delete mConvexMesh;
mCollisionWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody());
delete mConcaveMesh; delete mConcaveMesh;
mCollisionWorld->destroyCollisionBody(mHeightField->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mHeightField->getCollisionBody());
delete mHeightField; 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(); mContactManager.resetPoints();
// Destroy the static data for the visual contact points // Destroy the static data for the visual contact points
VisualContactPoint::destroyStaticData(); VisualContactPoint::destroyStaticData();
// Destroy the collision world // Destroy the collision world
delete mCollisionWorld; delete mPhysicsWorld;
} }
// Take a step for the simulation // Take a step for the simulation
@ -239,14 +214,14 @@ void CollisionDetectionScene::update() {
mContactManager.resetPoints(); mContactManager.resetPoints();
mCollisionWorld->testCollision(&mContactManager); mPhysicsWorld->testCollision(&mContactManager);
SceneDemo::update(); SceneDemo::update();
} }
void CollisionDetectionScene::selectNextShape() { void CollisionDetectionScene::selectNextShape() {
int previousIndex = mSelectedShapeIndex; uint previousIndex = mSelectedShapeIndex;
mSelectedShapeIndex++; mSelectedShapeIndex++;
if (mSelectedShapeIndex >= mAllShapes.size()) { if (mSelectedShapeIndex >= mAllShapes.size()) {
mSelectedShapeIndex = 0; mSelectedShapeIndex = 0;

View File

@ -152,10 +152,7 @@ class CollisionDetectionScene : public SceneDemo {
std::vector<PhysicsObject*> mAllShapes; std::vector<PhysicsObject*> mAllShapes;
int mSelectedShapeIndex; uint mSelectedShapeIndex;
/// Collision world used for the physics simulation
rp3d::CollisionWorld* mCollisionWorld;
/// Select the next shape /// Select the next shape
void selectNextShape(); void selectNextShape();
@ -165,7 +162,7 @@ class CollisionDetectionScene : public SceneDemo {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
CollisionDetectionScene(const std::string& name); CollisionDetectionScene(const std::string& name, EngineSettings& settings);
/// Destructor /// Destructor
virtual ~CollisionDetectionScene() override; virtual ~CollisionDetectionScene() override;

View File

@ -31,8 +31,8 @@ using namespace openglframework;
using namespace collisionshapesscene; using namespace collisionshapesscene;
// Constructor // Constructor
CollisionShapesScene::CollisionShapesScene(const std::string& name) CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettings& settings)
: SceneDemo(name, SCENE_RADIUS) { : SceneDemo(name, settings, SCENE_RADIUS) {
std::string meshFolderPath("meshes/"); std::string meshFolderPath("meshes/");
@ -43,23 +43,15 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
setScenePosition(center, SCENE_RADIUS); setScenePosition(center, SCENE_RADIUS);
// Gravity vector in the dynamics world // 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 // Create the dynamics world for the physics simulation
mDynamicsWorld = new rp3d::DynamicsWorld(gravity); mPhysicsWorld = new rp3d::DynamicsWorld(gravity);
float radius = 3.0f;
for (int i=0; i<NB_COMPOUND_SHAPES; i++) { for (int i=0; i<NB_COMPOUND_SHAPES; i++) {
// Position
float angle = i * 30.0f;
openglframework::Vector3 position(radius * cos(angle),
100 + i * (DUMBBELL_HEIGHT + 0.3f),
radius * sin(angle));
// Create a convex mesh and a corresponding rigid in the dynamics world // Create a convex mesh and a corresponding rigid in the dynamics world
Dumbbell* dumbbell = new Dumbbell(position, mDynamicsWorld, meshFolderPath); Dumbbell* dumbbell = new Dumbbell(getDynamicsWorld(), meshFolderPath);
// Set the box color // Set the box color
dumbbell->setColor(mDemoColors[i % mNbDemoColors]); dumbbell->setColor(mDemoColors[i % mNbDemoColors]);
@ -77,14 +69,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
// Create all the boxes of the scene // Create all the boxes of the scene
for (int i=0; i<NB_BOXES; i++) { for (int i=0; i<NB_BOXES; i++) {
// Position
float angle = i * 30.0f;
openglframework::Vector3 position(radius * cos(angle),
60 + i * (BOX_SIZE.y + 0.8f),
radius * sin(angle));
// Create a sphere and a corresponding rigid in the dynamics world // Create a sphere and a corresponding rigid in the dynamics world
Box* box = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld, mMeshFolderPath); Box* box = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
// Set the box color // Set the box color
box->setColor(mDemoColors[i % mNbDemoColors]); box->setColor(mDemoColors[i % mNbDemoColors]);
@ -102,18 +88,11 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
// Create all the spheres of the scene // Create all the spheres of the scene
for (int i=0; i<NB_SPHERES; i++) { for (int i=0; i<NB_SPHERES; i++) {
// Position
float angle = i * 35.0f;
openglframework::Vector3 position(radius * cos(angle),
50 + i * (SPHERE_RADIUS + 0.8f),
radius * sin(angle));
// Create a sphere and a corresponding rigid in the dynamics world // Create a sphere and a corresponding rigid in the dynamics world
Sphere* sphere = new Sphere(SPHERE_RADIUS, position , BOX_MASS, mDynamicsWorld, Sphere* sphere = new Sphere(SPHERE_RADIUS, BOX_MASS, getDynamicsWorld(), meshFolderPath);
meshFolderPath);
// Add some rolling resistance // Add some rolling resistance
sphere->getRigidBody()->getMaterial().setRollingResistance(0.08); sphere->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
// Set the box color // Set the box color
sphere->setColor(mDemoColors[i % mNbDemoColors]); sphere->setColor(mDemoColors[i % mNbDemoColors]);
@ -131,17 +110,11 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
// Create all the capsules of the scene // Create all the capsules of the scene
for (int i=0; i<NB_CAPSULES; i++) { for (int i=0; i<NB_CAPSULES; i++) {
// Position
float angle = i * 45.0f;
openglframework::Vector3 position(radius * cos(angle),
15 + i * (CAPSULE_HEIGHT + 0.3f),
radius * sin(angle));
// Create a cylinder and a corresponding rigid in the dynamics world // Create a cylinder and a corresponding rigid in the dynamics world
Capsule* capsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position , Capsule* capsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, CAPSULE_MASS,
CAPSULE_MASS, mDynamicsWorld, meshFolderPath); getDynamicsWorld(), meshFolderPath);
capsule->getRigidBody()->getMaterial().setRollingResistance(0.08); capsule->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08f));
// Set the box color // Set the box color
capsule->setColor(mDemoColors[i % mNbDemoColors]); capsule->setColor(mDemoColors[i % mNbDemoColors]);
@ -159,14 +132,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
// Create all the convex meshes of the scene // Create all the convex meshes of the scene
for (int i=0; i<NB_MESHES; i++) { for (int i=0; i<NB_MESHES; i++) {
// Position
float angle = i * 30.0f;
openglframework::Vector3 position(radius * cos(angle),
5 + i * (CAPSULE_HEIGHT + 0.3f),
radius * sin(angle));
// Create a convex mesh and a corresponding rigid in the dynamics world // Create a convex mesh and a corresponding rigid in the dynamics world
ConvexMesh* mesh = new ConvexMesh(position, MESH_MASS, mDynamicsWorld, meshFolderPath + "convexmesh.obj"); ConvexMesh* mesh = new ConvexMesh(MESH_MASS, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
// Set the box color // Set the box color
mesh->setColor(mDemoColors[i % mNbDemoColors]); mesh->setColor(mDemoColors[i % mNbDemoColors]);
@ -183,8 +150,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
// ---------- Create the floor --------- // ---------- Create the floor ---------
openglframework::Vector3 floorPosition(0, 0, 0); mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath);
mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mMeshFolderPath);
mPhysicsObjects.push_back(mFloor); mPhysicsObjects.push_back(mFloor);
// Set the box color // Set the box color
@ -198,39 +164,16 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
rp3d::Material& material = mFloor->getRigidBody()->getMaterial(); rp3d::Material& material = mFloor->getRigidBody()->getMaterial();
material.setBounciness(rp3d::decimal(0.2)); 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 // Get the physics engine parameters
mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled(); mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled();
rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity(); rp3d::Vector3 gravityVector = getDynamicsWorld()->getGravity();
mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z);
mEngineSettings.isSleepingEnabled = mDynamicsWorld->isSleepingEnabled(); mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled();
mEngineSettings.sleepLinearVelocity = mDynamicsWorld->getSleepLinearVelocity(); mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity();
mEngineSettings.sleepAngularVelocity = mDynamicsWorld->getSleepAngularVelocity(); mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity();
mEngineSettings.nbPositionSolverIterations = mDynamicsWorld->getNbIterationsPositionSolver(); mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver();
mEngineSettings.nbVelocitySolverIterations = mDynamicsWorld->getNbIterationsVelocitySolver(); mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver();
mEngineSettings.timeBeforeSleep = mDynamicsWorld->getTimeBeforeSleep(); mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep();
} }
// Destructor // Destructor
@ -240,126 +183,81 @@ CollisionShapesScene::~CollisionShapesScene() {
for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) {
// Destroy the corresponding rigid body from the dynamics world // Destroy the corresponding rigid body from the dynamics world
mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); getDynamicsWorld()->destroyRigidBody((*it)->getRigidBody());
// Destroy the object // Destroy the object
delete (*it); delete (*it);
} }
// Destroy the dynamics world // Destroy the dynamics world
delete mDynamicsWorld; delete mPhysicsWorld;
}
// 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);
} }
/// Reset the scene /// Reset the scene
void CollisionShapesScene::reset() { void CollisionShapesScene::reset() {
float radius = 3.0f; const float radius = 3.0f;
for (int i=0; i<NB_COMPOUND_SHAPES; i++) { for (uint i = 0; i<NB_COMPOUND_SHAPES; i++) {
// Position // Position
float angle = i * 30.0f; float angle = i * 30.0f;
openglframework::Vector3 position(radius * cos(angle), rp3d::Vector3 position(radius * std::cos(angle),
100 + i * (DUMBBELL_HEIGHT + 0.3f), 125 + i * (DUMBBELL_HEIGHT + 0.3f),
radius * sin(angle)); radius * std::sin(angle));
// Initial position and orientation of the rigid body mDumbbells[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
// Reset the transform
mDumbbells[i]->setTransform(transform);
} }
// Create all the boxes of the scene // Create all the boxes of the scene
for (int i=0; i<NB_BOXES; i++) { for (uint i = 0; i<NB_BOXES; i++) {
// Position // Position
float angle = i * 30.0f; float angle = i * 30.0f;
openglframework::Vector3 position(radius * cos(angle), rp3d::Vector3 position(radius * std::cos(angle),
60 + i * (BOX_SIZE.y + 0.8f), 85 + i * (BOX_SIZE.y + 0.8f),
radius * sin(angle)); radius * std::sin(angle));
// Initial position and orientation of the rigid body mBoxes[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
// Reset the transform
mBoxes[i]->setTransform(transform);
} }
// Create all the spheres of the scene // Create all the spheres of the scene
for (int i=0; i<NB_SPHERES; i++) { for (uint i = 0; i<NB_SPHERES; i++) {
// Position // Position
float angle = i * 35.0f; float angle = i * 35.0f;
openglframework::Vector3 position(radius * cos(angle), rp3d::Vector3 position(radius * std::cos(angle),
50 + i * (SPHERE_RADIUS + 0.8f), 75 + i * (SPHERE_RADIUS + 0.8f),
radius * sin(angle)); radius * std::sin(angle));
// Initial position and orientation of the rigid body mSpheres[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
// Reset the transform
mSpheres[i]->setTransform(transform);
} }
// Create all the capsules of the scene // Create all the capsules of the scene
for (int i=0; i<NB_CAPSULES; i++) { for (uint i = 0; i<NB_CAPSULES; i++) {
// Position // Position
float angle = i * 45.0f; float angle = i * 45.0f;
openglframework::Vector3 position(radius * cos(angle), rp3d::Vector3 position(radius * std::cos(angle),
15 + i * (CAPSULE_HEIGHT + 0.3f), 40 + i * (CAPSULE_HEIGHT + 0.3f),
radius * sin(angle)); radius * std::sin(angle));
// Initial position and orientation of the rigid body mCapsules[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
// Reset the transform
mCapsules[i]->setTransform(transform);
} }
// Create all the convex meshes of the scene // Create all the convex meshes of the scene
for (int i=0; i<NB_MESHES; i++) { for (uint i = 0; i<NB_MESHES; i++) {
// Position // Position
float angle = i * 30.0f; float angle = i * 30.0f;
openglframework::Vector3 position(radius * cos(angle), rp3d::Vector3 position(radius * std::cos(angle),
5 + i * (CAPSULE_HEIGHT + 0.3f), 30 + i * (CAPSULE_HEIGHT + 0.3f),
radius * sin(angle)); radius * std::sin(angle));
// Initial position and orientation of the rigid body mConvexMeshes[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
rp3d::Vector3 initPosition(position.x, position.y, position.z); }
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
// Reset the transform // ---------- Create the triangular mesh ---------- //
mConvexMeshes[i]->setTransform(transform);
} mFloor->setTransform(rp3d::Transform::identity());
} }

View File

@ -45,7 +45,7 @@ const float SCENE_RADIUS = 30.0f;
const int NB_BOXES = 5; const int NB_BOXES = 5;
const int NB_SPHERES = 5; const int NB_SPHERES = 5;
const int NB_CAPSULES = 5; const int NB_CAPSULES = 5;
const int NB_MESHES = 3; const int NB_MESHES = 4;
const int NB_COMPOUND_SHAPES = 3; const int NB_COMPOUND_SHAPES = 3;
const openglframework::Vector3 BOX_SIZE(2, 2, 2); const openglframework::Vector3 BOX_SIZE(2, 2, 2);
const float SPHERE_RADIUS = 1.5f; const float SPHERE_RADIUS = 1.5f;
@ -87,23 +87,16 @@ class CollisionShapesScene : public SceneDemo {
/// Box for the floor /// Box for the floor
Box* mFloor; Box* mFloor;
/// Dynamics world used for the physics simulation
rp3d::DynamicsWorld* mDynamicsWorld;
public: public:
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
CollisionShapesScene(const std::string& name); CollisionShapesScene(const std::string& name, EngineSettings& settings);
/// Destructor /// Destructor
virtual ~CollisionShapesScene() override; 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 /// Reset the scene
virtual void reset() override; virtual void reset() override;
@ -113,7 +106,7 @@ class CollisionShapesScene : public SceneDemo {
// Return all the contact points of the scene // Return all the contact points of the scene
inline std::vector<ContactPoint> CollisionShapesScene::getContactPoints() const { inline std::vector<ContactPoint> CollisionShapesScene::getContactPoints() const {
return computeContactPointsOfWorld(mDynamicsWorld); return computeContactPointsOfWorld(getDynamicsWorld());
} }
} }

View File

@ -31,8 +31,8 @@ using namespace openglframework;
using namespace trianglemeshscene; using namespace trianglemeshscene;
// Constructor // Constructor
ConcaveMeshScene::ConcaveMeshScene(const std::string& name) ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& settings)
: SceneDemo(name, SCENE_RADIUS) { : SceneDemo(name, settings, SCENE_RADIUS) {
std::string meshFolderPath("meshes/"); std::string meshFolderPath("meshes/");
@ -46,38 +46,115 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name)
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
// Create the dynamics world for the physics simulation // 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; i<NB_COMPOUND_SHAPES; i++) {
for (int i=0; i<NB_BOXES_X; i++) { // Create a convex mesh and a corresponding rigid in the dynamics world
Dumbbell* dumbbell = new Dumbbell(getDynamicsWorld(), meshFolderPath);
for (int j=0; j<NB_BOXES_Z; j++) { // Set the box color
dumbbell->setColor(mDemoColors[i % mNbDemoColors]);
// Position dumbbell->setSleepingColor(mRedColorDemo);
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);
// 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);
// Set the sphere color
mBoxes[i * NB_BOXES_Z + j]->setColor(mDemoColors[0]);
mBoxes[i * NB_BOXES_Z + j]->setSleepingColor(mRedColorDemo);
// Change the material properties of the rigid body // Change the material properties of the rigid body
rp3d::Material& boxMaterial = mBoxes[i * NB_BOXES_Z + j]->getRigidBody()->getMaterial(); rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
boxMaterial.setBounciness(rp3d::decimal(0.2)); material.setBounciness(rp3d::decimal(0.2));
// Add the mesh the list of dumbbells in the scene
mDumbbells.push_back(dumbbell);
mPhysicsObjects.push_back(dumbbell);
} }
// Create all the boxes of the scene
for (int i = 0; i<NB_BOXES; i++) {
// 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; i<NB_SPHERES; i++) {
// Create a sphere and a corresponding rigid in the dynamics world
Sphere* sphere = new Sphere(SPHERE_RADIUS, BOX_MASS, getDynamicsWorld(), meshFolderPath);
// Add some rolling resistance
sphere->getRigidBody()->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; i<NB_CAPSULES; i++) {
// Create a cylinder and a corresponding rigid in the dynamics world
Capsule* capsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, CAPSULE_MASS,
getDynamicsWorld(), meshFolderPath);
capsule->getRigidBody()->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; i<NB_MESHES; i++) {
// Create a convex mesh and a corresponding rigid in the dynamics world
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
// Set the box color
mesh->setColor(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 ---------- // // ---------- Create the triangular mesh ---------- //
// Position // Position
openglframework::Vector3 position(0, 0, 0);
rp3d::decimal mass = 1.0; rp3d::decimal mass = 1.0;
// Create a convex mesh and a corresponding rigid in the dynamics world // 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 // Set the mesh as beeing static
mConcaveMesh->getRigidBody()->setType(rp3d::BodyType::STATIC); mConcaveMesh->getRigidBody()->setType(rp3d::BodyType::STATIC);
@ -86,106 +163,107 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name)
mConcaveMesh->setColor(mGreyColorDemo); mConcaveMesh->setColor(mGreyColorDemo);
mConcaveMesh->setSleepingColor(mGreyColorDemo); mConcaveMesh->setSleepingColor(mGreyColorDemo);
mPhysicsObjects.push_back(mConcaveMesh);
// Change the material properties of the rigid body // Change the material properties of the rigid body
rp3d::Material& material = mConcaveMesh->getRigidBody()->getMaterial(); rp3d::Material& material = mConcaveMesh->getRigidBody()->getMaterial();
material.setBounciness(rp3d::decimal(0.2)); material.setBounciness(rp3d::decimal(0.2));
material.setFrictionCoefficient(0.1); material.setFrictionCoefficient(rp3d::decimal(0.1));
// Get the physics engine parameters // Get the physics engine parameters
mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled(); mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled();
rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity(); rp3d::Vector3 gravityVector = getDynamicsWorld()->getGravity();
mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z);
mEngineSettings.isSleepingEnabled = mDynamicsWorld->isSleepingEnabled(); mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled();
mEngineSettings.sleepLinearVelocity = mDynamicsWorld->getSleepLinearVelocity(); mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity();
mEngineSettings.sleepAngularVelocity = mDynamicsWorld->getSleepAngularVelocity(); mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity();
mEngineSettings.nbPositionSolverIterations = mDynamicsWorld->getNbIterationsPositionSolver(); mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver();
mEngineSettings.nbVelocitySolverIterations = mDynamicsWorld->getNbIterationsVelocitySolver(); mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver();
mEngineSettings.timeBeforeSleep = mDynamicsWorld->getTimeBeforeSleep(); mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep();
} }
// Destructor // Destructor
ConcaveMeshScene::~ConcaveMeshScene() { ConcaveMeshScene::~ConcaveMeshScene() {
// Destroy all the physics objects of the scene
for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) {
// Destroy the corresponding rigid body from the dynamics world // Destroy the corresponding rigid body from the dynamics world
mDynamicsWorld->destroyRigidBody(mConcaveMesh->getRigidBody()); getDynamicsWorld()->destroyRigidBody((*it)->getRigidBody());
// Destroy the boxes // Destroy the object
for (int i=0; i<NB_BOXES_X * NB_BOXES_Z; i++) { delete (*it);
mDynamicsWorld->destroyRigidBody(mBoxes[i]->getRigidBody());
delete mBoxes[i];
} }
// Destroy the convex mesh
delete mConcaveMesh;
// Destroy the dynamics world // Destroy the dynamics world
delete mDynamicsWorld; delete getDynamicsWorld();
}
// 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; i<NB_BOXES_X * NB_BOXES_Z; i++) {
mBoxes[i]->updateTransform(mInterpolationFactor);
}
}
// Render the scene in a single pass
void ConcaveMeshScene::renderSinglePass(Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) {
// Bind the shader
shader.bind();
mConcaveMesh->render(shader, worldToCameraMatrix, mIsWireframeEnabled);
for (int i=0; i<NB_BOXES_X * NB_BOXES_Z; i++) {
mBoxes[i]->render(shader, worldToCameraMatrix, mIsWireframeEnabled);
}
// Unbind the shader
shader.unbind();
} }
// Reset the scene // Reset the scene
void ConcaveMeshScene::reset() { void ConcaveMeshScene::reset() {
// Reset the transform const float radius = 15.0f;
rp3d::Transform transform(rp3d::Vector3::zero(), rp3d::Quaternion::identity());
mConcaveMesh->setTransform(transform);
for (int i=0; i<NB_BOXES_X; i++) { for (uint i = 0; i<NB_COMPOUND_SHAPES; i++) {
for (int j=0; j<NB_BOXES_Z; j++) {
// Position // Position
rp3d::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); float angle = i * 30.0f;
rp3d::Vector3 position(radius * std::cos(angle),
125 + i * (DUMBBELL_HEIGHT + 0.3f),
radius * std::sin(angle));
rp3d::Transform boxTransform(boxPosition, rp3d::Quaternion::identity()); mDumbbells[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
mBoxes[i * NB_BOXES_Z + j]->setTransform(boxTransform);
}
} }
// Create all the boxes of the scene
for (uint i = 0; i<NB_BOXES; i++) {
// Position
float angle = i * 30.0f;
rp3d::Vector3 position(radius * std::cos(angle),
85 + i * (BOX_SIZE.y + 0.8f),
radius * std::sin(angle));
mBoxes[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
}
// Create all the spheres of the scene
for (uint i = 0; i<NB_SPHERES; i++) {
// Position
float angle = i * 35.0f;
rp3d::Vector3 position(radius * std::cos(angle),
75 + i * (SPHERE_RADIUS + 0.8f),
radius * std::sin(angle));
mSpheres[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
}
// Create all the capsules of the scene
for (uint i = 0; i<NB_CAPSULES; i++) {
// Position
float angle = i * 45.0f;
rp3d::Vector3 position(radius * std::cos(angle),
40 + i * (CAPSULE_HEIGHT + 0.3f),
radius * std::sin(angle));
mCapsules[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
}
// Create all the convex meshes of the scene
for (uint i = 0; i<NB_MESHES; i++) {
// Position
float angle = i * 30.0f;
rp3d::Vector3 position(radius * std::cos(angle),
30 + i * (CAPSULE_HEIGHT + 0.3f),
radius * std::sin(angle));
mConvexMeshes[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
}
// ---------- Create the triangular mesh ---------- //
mConcaveMesh->setTransform(rp3d::Transform::identity());
} }

View File

@ -33,15 +33,34 @@
#include "SceneDemo.h" #include "SceneDemo.h"
#include "ConcaveMesh.h" #include "ConcaveMesh.h"
#include "Box.h" #include "Box.h"
#include "Capsule.h"
#include "Dumbbell.h"
#include "Sphere.h"
#include "ConvexMesh.h"
namespace trianglemeshscene { namespace trianglemeshscene {
// Constants // Constants
const float SCENE_RADIUS = 70.0f; // Radius of the scene in meters const float SCENE_RADIUS = 70.0f; // Radius of the scene in meters
const int NB_BOXES_X = 8; static const int NB_BOXES = 10;
const int NB_BOXES_Z = 8; static const int NB_SPHERES = 5;
const float BOX_SIZE = 3.0f; static const int NB_CAPSULES = 5;
const float BOXES_SPACE = 2.0f; 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 TriangleMeshScene
class ConcaveMeshScene : public SceneDemo { class ConcaveMeshScene : public SceneDemo {
@ -50,35 +69,31 @@ class ConcaveMeshScene : public SceneDemo {
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
Box* mBoxes[NB_BOXES_X * NB_BOXES_Z]; std::vector<Box*> mBoxes;
std::vector<Sphere*> mSpheres;
std::vector<Capsule*> mCapsules;
/// All the convex meshes of the scene
std::vector<ConvexMesh*> mConvexMeshes;
/// All the dumbbell of the scene
std::vector<Dumbbell*> mDumbbells;
/// Concave triangles mesh /// Concave triangles mesh
ConcaveMesh* mConcaveMesh; ConcaveMesh* mConcaveMesh;
/// Dynamics world used for the physics simulation
rp3d::DynamicsWorld* mDynamicsWorld;
public: public:
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
ConcaveMeshScene(const std::string& name); ConcaveMeshScene(const std::string& name, EngineSettings& settings);
/// Destructor /// Destructor
virtual ~ConcaveMeshScene() override; 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 /// Reset the scene
virtual void reset() override; virtual void reset() override;
@ -88,7 +103,7 @@ class ConcaveMeshScene : public SceneDemo {
// Return all the contact points of the scene // Return all the contact points of the scene
inline std::vector<ContactPoint> ConcaveMeshScene::getContactPoints() const { inline std::vector<ContactPoint> ConcaveMeshScene::getContactPoints() const {
return computeContactPointsOfWorld(mDynamicsWorld); return computeContactPointsOfWorld(getDynamicsWorld());
} }
} }

View File

@ -31,8 +31,8 @@ using namespace openglframework;
using namespace cubesscene; using namespace cubesscene;
// Constructor // Constructor
CubesScene::CubesScene(const std::string& name) CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
: SceneDemo(name, SCENE_RADIUS) { : SceneDemo(name, settings, SCENE_RADIUS) {
// Compute the radius and the center of the scene // Compute the radius and the center of the scene
openglframework::Vector3 center(0, 5, 0); 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); rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
// Create the dynamics world for the physics simulation // 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; i<NB_CUBES; i++) {
//// Create all the cubes of the scene // Create a cube and a corresponding rigid in the dynamics world
//for (int i=0; i<NB_CUBES; i++) { Box* cube = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
// // Position of the cubes // Set the box color
// float angle = i * 30.0f; cube->setColor(mDemoColors[i % mNbDemoColors]);
// openglframework::Vector3 position(radius * cos(angle), cube->setSleepingColor(mRedColorDemo);
// 30 + i * (BOX_SIZE.y + 0.3f),
// 0);
// // Create a cube and a corresponding rigid in the dynamics world // Change the material properties of the rigid body
// Box* cube = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld); rp3d::Material& material = cube->getRigidBody()->getMaterial();
material.setBounciness(rp3d::decimal(0.4));
// // Set the box color // Add the box the list of box in the scene
// cube->setColor(mDemoColors[i % mNbDemoColors]); mBoxes.push_back(cube);
// cube->setSleepingColor(mRedColorDemo); mPhysicsObjects.push_back(cube);
}
// // 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);
//}
// ------------------------- FLOOR ----------------------- // // ------------------------- FLOOR ----------------------- //
// Create the floor // Create the floor
openglframework::Vector3 floorPosition(0, 0, 0); mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath);
mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mMeshFolderPath);
mFloor->setColor(mGreyColorDemo); mFloor->setColor(mGreyColorDemo);
mFloor->setSleepingColor(mGreyColorDemo); mFloor->setSleepingColor(mGreyColorDemo);
@ -84,37 +76,16 @@ CubesScene::CubesScene(const std::string& name)
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC); mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);
mPhysicsObjects.push_back(mFloor); 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 // Get the physics engine parameters
mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled(); mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled();
rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity(); rp3d::Vector3 gravityVector = getDynamicsWorld()->getGravity();
mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z);
mEngineSettings.isSleepingEnabled = mDynamicsWorld->isSleepingEnabled(); mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled();
mEngineSettings.sleepLinearVelocity = mDynamicsWorld->getSleepLinearVelocity(); mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity();
mEngineSettings.sleepAngularVelocity = mDynamicsWorld->getSleepAngularVelocity(); mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity();
mEngineSettings.nbPositionSolverIterations = mDynamicsWorld->getNbIterationsPositionSolver(); mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver();
mEngineSettings.nbVelocitySolverIterations = mDynamicsWorld->getNbIterationsVelocitySolver(); mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver();
mEngineSettings.timeBeforeSleep = mDynamicsWorld->getTimeBeforeSleep(); mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep();
} }
// Destructor // Destructor
@ -124,39 +95,20 @@ CubesScene::~CubesScene() {
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
// Destroy the corresponding rigid body from the dynamics world // Destroy the corresponding rigid body from the dynamics world
mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); getDynamicsWorld()->destroyRigidBody((*it)->getRigidBody());
// Destroy the cube // Destroy the cube
delete (*it); delete (*it);
} }
// Destroy the rigid body of the floor // Destroy the rigid body of the floor
mDynamicsWorld->destroyRigidBody(mFloor->getRigidBody()); getDynamicsWorld()->destroyRigidBody(mFloor->getRigidBody());
// Destroy the floor // Destroy the floor
delete mFloor; delete mFloor;
// Destroy the dynamics world // Destroy the dynamics world
delete mDynamicsWorld; delete getDynamicsWorld();
}
// 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);
} }
// Reset the scene // Reset the scene
@ -164,19 +116,21 @@ void CubesScene::reset() {
float radius = 2.0f; float radius = 2.0f;
// for (int i=0; i<NB_CUBES; i++) { // Create all the cubes of the scene
std::vector<Box*>::iterator it;
int i = 0;
for (it = mBoxes.begin(); it != mBoxes.end(); ++it) {
// // Position of the cubes // Position of the cubes
// float angle = i * 30.0f; float angle = i * 30.0f;
// openglframework::Vector3 position(radius * cos(angle), rp3d::Vector3 position(radius * std::cos(angle),
// 10 + i * (BOX_SIZE.y + 0.3f), 10 + i * (BOX_SIZE.y + 0.3f),
// 0); 0);
// // Initial position and orientation of the rigid body (*it)->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
// rp3d::Vector3 initPosition(position.x, position.y, position.z);
// rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
// rp3d::Transform transform(initPosition, initOrientation);
// mBoxes[i]->resetTransform(transform); i++;
// } }
mFloor->setTransform(rp3d::Transform(rp3d::Vector3::zero(), rp3d::Quaternion::identity()));
} }

View File

@ -38,7 +38,7 @@ namespace cubesscene {
const float SCENE_RADIUS = 30.0f; // Radius of the scene in meters const float SCENE_RADIUS = 30.0f; // Radius of the scene in meters
const int NB_CUBES = 30; // Number of boxes in the scene const 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 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 BOX_MASS = 1.0f; // Box mass in kilograms
const float FLOOR_MASS = 100.0f; // Floor 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 for the floor
Box* mFloor; Box* mFloor;
/// Dynamics world used for the physics simulation
rp3d::DynamicsWorld* mDynamicsWorld;
public: public:
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
CubesScene(const std::string& name); CubesScene(const std::string& name, EngineSettings& settings);
/// Destructor /// Destructor
virtual ~CubesScene() override; 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 /// Reset the scene
virtual void reset() override; virtual void reset() override;
@ -81,7 +74,7 @@ class CubesScene : public SceneDemo {
// Return all the contact points of the scene // Return all the contact points of the scene
inline std::vector<ContactPoint> CubesScene::getContactPoints() const { inline std::vector<ContactPoint> CubesScene::getContactPoints() const {
return computeContactPointsOfWorld(mDynamicsWorld); return computeContactPointsOfWorld(getDynamicsWorld());
} }
} }

View File

@ -31,7 +31,8 @@ using namespace openglframework;
using namespace heightfieldscene; using namespace heightfieldscene;
// Constructor // 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/"); 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); rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
// Create the dynamics world for the physics simulation // Create the dynamics world for the physics simulation
mDynamicsWorld = new rp3d::DynamicsWorld(gravity); mPhysicsWorld = new rp3d::DynamicsWorld(gravity);
float radius = 3.0f;
for (int i = 0; i<NB_COMPOUND_SHAPES; i++) { for (int i = 0; i<NB_COMPOUND_SHAPES; i++) {
// Position
float angle = i * 30.0f;
openglframework::Vector3 position(radius * cos(angle),
100 + i * (DUMBBELL_HEIGHT + 0.3f),
radius * sin(angle));
// Create a convex mesh and a corresponding rigid in the dynamics world // Create a convex mesh and a corresponding rigid in the dynamics world
Dumbbell* dumbbell = new Dumbbell(position, mDynamicsWorld, meshFolderPath); Dumbbell* dumbbell = new Dumbbell(getDynamicsWorld(), meshFolderPath);
// Set the box color // Set the box color
dumbbell->setColor(mDemoColors[i % mNbDemoColors]); dumbbell->setColor(mDemoColors[i % mNbDemoColors]);
@ -76,14 +69,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SC
// Create all the boxes of the scene // Create all the boxes of the scene
for (int i = 0; i<NB_BOXES; i++) { for (int i = 0; i<NB_BOXES; i++) {
// Position
float angle = i * 30.0f;
openglframework::Vector3 position(radius * cos(angle),
60 + i * (BOX_SIZE.y + 0.8f),
radius * sin(angle));
// Create a sphere and a corresponding rigid in the dynamics world // Create a sphere and a corresponding rigid in the dynamics world
Box* box = new Box(BOX_SIZE, position, BOX_MASS, mDynamicsWorld, mMeshFolderPath); Box* box = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
// Set the box color // Set the box color
box->setColor(mDemoColors[i % mNbDemoColors]); box->setColor(mDemoColors[i % mNbDemoColors]);
@ -101,18 +88,11 @@ HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SC
// Create all the spheres of the scene // Create all the spheres of the scene
for (int i = 0; i<NB_SPHERES; i++) { for (int i = 0; i<NB_SPHERES; i++) {
// Position
float angle = i * 35.0f;
openglframework::Vector3 position(radius * cos(angle),
50 + i * (SPHERE_RADIUS + 0.8f),
radius * sin(angle));
// Create a sphere and a corresponding rigid in the dynamics world // Create a sphere and a corresponding rigid in the dynamics world
Sphere* sphere = new Sphere(SPHERE_RADIUS, position, BOX_MASS, mDynamicsWorld, Sphere* sphere = new Sphere(SPHERE_RADIUS, BOX_MASS, getDynamicsWorld(), meshFolderPath);
meshFolderPath);
// Add some rolling resistance // Add some rolling resistance
sphere->getRigidBody()->getMaterial().setRollingResistance(0.08); sphere->getRigidBody()->getMaterial().setRollingResistance(0.08f);
// Set the box color // Set the box color
sphere->setColor(mDemoColors[i % mNbDemoColors]); 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 // Create all the capsules of the scene
for (int i = 0; i<NB_CAPSULES; i++) { for (int i = 0; i<NB_CAPSULES; i++) {
// Position
float angle = i * 45.0f;
openglframework::Vector3 position(radius * cos(angle),
15 + i * (CAPSULE_HEIGHT + 0.3f),
radius * sin(angle));
// Create a cylinder and a corresponding rigid in the dynamics world // Create a cylinder and a corresponding rigid in the dynamics world
Capsule* capsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position, Capsule* capsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, CAPSULE_MASS,
CAPSULE_MASS, mDynamicsWorld, meshFolderPath); getDynamicsWorld(), meshFolderPath);
capsule->getRigidBody()->getMaterial().setRollingResistance(0.08); capsule->getRigidBody()->getMaterial().setRollingResistance(0.08f);
// Set the box color // Set the box color
capsule->setColor(mDemoColors[i % mNbDemoColors]); 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 // Create all the convex meshes of the scene
for (int i = 0; i<NB_MESHES; i++) { for (int i = 0; i<NB_MESHES; i++) {
// Position
float angle = i * 30.0f;
openglframework::Vector3 position(radius * cos(angle),
5 + i * (CAPSULE_HEIGHT + 0.3f),
radius * sin(angle));
// Create a convex mesh and a corresponding rigid in the dynamics world // Create a convex mesh and a corresponding rigid in the dynamics world
ConvexMesh* mesh = new ConvexMesh(position, MESH_MASS, mDynamicsWorld, meshFolderPath + "convexmesh.obj"); ConvexMesh* mesh = new ConvexMesh(MESH_MASS, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
// Set the box color // Set the box color
mesh->setColor(mDemoColors[i % mNbDemoColors]); mesh->setColor(mDemoColors[i % mNbDemoColors]);
@ -183,11 +151,10 @@ HeightFieldScene::HeightFieldScene(const std::string& name) : SceneDemo(name, SC
// ---------- Create the height field ---------- // // ---------- Create the height field ---------- //
// Position // Position
openglframework::Vector3 position(0, 0, 0);
rp3d::decimal mass = 1.0; rp3d::decimal mass = 1.0;
// Create a convex mesh and a corresponding rigid in the dynamics world // 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 // Set the mesh as beeing static
mHeightField->getRigidBody()->setType(rp3d::BodyType::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 // Change the material properties of the rigid body
rp3d::Material& material = mHeightField->getRigidBody()->getMaterial(); rp3d::Material& material = mHeightField->getRigidBody()->getMaterial();
material.setBounciness(rp3d::decimal(0.2)); material.setBounciness(rp3d::decimal(0.2));
material.setFrictionCoefficient(0.1); material.setFrictionCoefficient(0.1f);
// Get the physics engine parameters // Get the physics engine parameters
mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled(); mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled();
rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity(); rp3d::Vector3 gravityVector = getDynamicsWorld()->getGravity();
mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z);
mEngineSettings.isSleepingEnabled = mDynamicsWorld->isSleepingEnabled(); mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled();
mEngineSettings.sleepLinearVelocity = mDynamicsWorld->getSleepLinearVelocity(); mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity();
mEngineSettings.sleepAngularVelocity = mDynamicsWorld->getSleepAngularVelocity(); mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity();
mEngineSettings.nbPositionSolverIterations = mDynamicsWorld->getNbIterationsPositionSolver(); mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver();
mEngineSettings.nbVelocitySolverIterations = mDynamicsWorld->getNbIterationsVelocitySolver(); mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver();
mEngineSettings.timeBeforeSleep = mDynamicsWorld->getTimeBeforeSleep(); mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep();
} }
// Destructor // Destructor
@ -222,47 +189,81 @@ HeightFieldScene::~HeightFieldScene() {
for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) {
// Destroy the corresponding rigid body from the dynamics world // Destroy the corresponding rigid body from the dynamics world
mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); getDynamicsWorld()->destroyRigidBody((*it)->getRigidBody());
// Destroy the object // Destroy the object
delete (*it); delete (*it);
} }
// Destroy the dynamics world // Destroy the dynamics world
delete mDynamicsWorld; delete getDynamicsWorld();
}
// 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);
} }
// Reset the scene // Reset the scene
void HeightFieldScene::reset() { void HeightFieldScene::reset() {
// Reset the transform const float radius = 3.0f;
rp3d::Transform transform(rp3d::Vector3(0, 0, 0), rp3d::Quaternion::identity());
mHeightField->setTransform(transform);
float heightFieldWidth = 10.0f; for (uint i = 0; i<NB_COMPOUND_SHAPES; i++) {
float stepDist = heightFieldWidth / (NB_BOXES + 1);
for (int i=0; i<NB_BOXES; i++) { // Position
rp3d::Vector3 boxPosition(-heightFieldWidth * 0.5f + i * stepDist , 14 + 6.0f * i, -heightFieldWidth * 0.5f + i * stepDist); float angle = i * 30.0f;
rp3d::Transform boxTransform(boxPosition, rp3d::Quaternion::identity()); rp3d::Vector3 position(radius * std::cos(angle),
mBoxes[i]->setTransform(boxTransform); 125 + i * (DUMBBELL_HEIGHT + 0.3f),
radius * std::sin(angle));
mDumbbells[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
} }
// Create all the boxes of the scene
for (uint i = 0; i<NB_BOXES; i++) {
// Position
float angle = i * 30.0f;
rp3d::Vector3 position(radius * std::cos(angle),
85 + i * (BOX_SIZE.y + 0.8f),
radius * std::sin(angle));
mBoxes[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
}
// Create all the spheres of the scene
for (uint i = 0; i<NB_SPHERES; i++) {
// Position
float angle = i * 35.0f;
rp3d::Vector3 position(radius * std::cos(angle),
75 + i * (SPHERE_RADIUS + 0.8f),
radius * std::sin(angle));
mSpheres[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
}
// Create all the capsules of the scene
for (uint i = 0; i<NB_CAPSULES; i++) {
// Position
float angle = i * 45.0f;
rp3d::Vector3 position(radius * std::cos(angle),
40 + i * (CAPSULE_HEIGHT + 0.3f),
radius * std::sin(angle));
mCapsules[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
}
// Create all the convex meshes of the scene
for (uint i = 0; i<NB_MESHES; i++) {
// Position
float angle = i * 30.0f;
rp3d::Vector3 position(radius * std::cos(angle),
30 + i * (CAPSULE_HEIGHT + 0.3f),
radius * std::sin(angle));
mConvexMeshes[i]->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
}
// ---------- Create the triangular mesh ---------- //
mHeightField->setTransform(rp3d::Transform::identity());
} }

View File

@ -44,7 +44,7 @@ const float SCENE_RADIUS = 50.0f;
static const int NB_BOXES = 10; static const int NB_BOXES = 10;
static const int NB_SPHERES = 5; static const int NB_SPHERES = 5;
static const int NB_CAPSULES = 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; static const int NB_COMPOUND_SHAPES = 3;
const openglframework::Vector3 BOX_SIZE(2, 2, 2); const openglframework::Vector3 BOX_SIZE(2, 2, 2);
const float SPHERE_RADIUS = 1.5f; const float SPHERE_RADIUS = 1.5f;
@ -86,23 +86,16 @@ class HeightFieldScene : public SceneDemo {
/// Height field /// Height field
HeightField* mHeightField; HeightField* mHeightField;
/// Dynamics world used for the physics simulation
rp3d::DynamicsWorld* mDynamicsWorld;
public: public:
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
HeightFieldScene(const std::string& name); HeightFieldScene(const std::string& name, EngineSettings& settings);
/// Destructor /// Destructor
virtual ~HeightFieldScene() override; 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 /// Reset the scene
virtual void reset() override ; virtual void reset() override ;
@ -112,7 +105,7 @@ class HeightFieldScene : public SceneDemo {
// Return all the contact points of the scene // Return all the contact points of the scene
inline std::vector<ContactPoint> HeightFieldScene::getContactPoints() const { inline std::vector<ContactPoint> HeightFieldScene::getContactPoints() const {
return computeContactPointsOfWorld(mDynamicsWorld); return computeContactPointsOfWorld(getDynamicsWorld());
} }
} }

View File

@ -32,8 +32,8 @@ using namespace openglframework;
using namespace jointsscene; using namespace jointsscene;
// Constructor // Constructor
JointsScene::JointsScene(const std::string& name) JointsScene::JointsScene(const std::string& name, EngineSettings& settings)
: SceneDemo(name, SCENE_RADIUS) { : SceneDemo(name, settings, SCENE_RADIUS) {
// Compute the radius and the center of the scene // Compute the radius and the center of the scene
openglframework::Vector3 center(0, 5, 0); 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); rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
// Create the dynamics world for the physics simulation // Create the dynamics world for the physics simulation
mDynamicsWorld = new rp3d::DynamicsWorld(gravity); mPhysicsWorld = new rp3d::DynamicsWorld(gravity);
// Create the Ball-and-Socket joint // Create the Ball-and-Socket joint
createBallAndSocketJoints(); createBallAndSocketJoints();
@ -63,37 +63,37 @@ JointsScene::JointsScene(const std::string& name)
createFloor(); createFloor();
// Get the physics engine parameters // Get the physics engine parameters
mEngineSettings.isGravityEnabled = mDynamicsWorld->isGravityEnabled(); mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled();
rp3d::Vector3 gravityVector = mDynamicsWorld->getGravity(); rp3d::Vector3 gravityVector = getDynamicsWorld()->getGravity();
mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z);
mEngineSettings.isSleepingEnabled = mDynamicsWorld->isSleepingEnabled(); mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled();
mEngineSettings.sleepLinearVelocity = mDynamicsWorld->getSleepLinearVelocity(); mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity();
mEngineSettings.sleepAngularVelocity = mDynamicsWorld->getSleepAngularVelocity(); mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity();
mEngineSettings.nbPositionSolverIterations = mDynamicsWorld->getNbIterationsPositionSolver(); mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver();
mEngineSettings.nbVelocitySolverIterations = mDynamicsWorld->getNbIterationsVelocitySolver(); mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver();
mEngineSettings.timeBeforeSleep = mDynamicsWorld->getTimeBeforeSleep(); mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep();
} }
// Destructor // Destructor
JointsScene::~JointsScene() { JointsScene::~JointsScene() {
// Destroy the joints // Destroy the joints
mDynamicsWorld->destroyJoint(mSliderJoint); getDynamicsWorld()->destroyJoint(mSliderJoint);
mDynamicsWorld->destroyJoint(mPropellerHingeJoint); getDynamicsWorld()->destroyJoint(mPropellerHingeJoint);
mDynamicsWorld->destroyJoint(mFixedJoint1); getDynamicsWorld()->destroyJoint(mFixedJoint1);
mDynamicsWorld->destroyJoint(mFixedJoint2); getDynamicsWorld()->destroyJoint(mFixedJoint2);
for (int i=0; i<NB_BALLSOCKETJOINT_BOXES-1; i++) { for (int i=0; i<NB_BALLSOCKETJOINT_BOXES-1; i++) {
mDynamicsWorld->destroyJoint(mBallAndSocketJoints[i]); getDynamicsWorld()->destroyJoint(mBallAndSocketJoints[i]);
} }
// Destroy all the rigid bodies of the scene // Destroy all the rigid bodies of the scene
mDynamicsWorld->destroyRigidBody(mSliderJointBottomBox->getRigidBody()); getDynamicsWorld()->destroyRigidBody(mSliderJointBottomBox->getRigidBody());
mDynamicsWorld->destroyRigidBody(mSliderJointTopBox->getRigidBody()); getDynamicsWorld()->destroyRigidBody(mSliderJointTopBox->getRigidBody());
mDynamicsWorld->destroyRigidBody(mPropellerBox->getRigidBody()); getDynamicsWorld()->destroyRigidBody(mPropellerBox->getRigidBody());
mDynamicsWorld->destroyRigidBody(mFixedJointBox1->getRigidBody()); getDynamicsWorld()->destroyRigidBody(mFixedJointBox1->getRigidBody());
mDynamicsWorld->destroyRigidBody(mFixedJointBox2->getRigidBody()); getDynamicsWorld()->destroyRigidBody(mFixedJointBox2->getRigidBody());
for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) { for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) {
mDynamicsWorld->destroyRigidBody(mBallAndSocketJointChainBoxes[i]->getRigidBody()); getDynamicsWorld()->destroyRigidBody(mBallAndSocketJointChainBoxes[i]->getRigidBody());
} }
delete mSliderJointBottomBox; delete mSliderJointBottomBox;
@ -106,58 +106,21 @@ JointsScene::~JointsScene() {
} }
// Destroy the floor // Destroy the floor
mDynamicsWorld->destroyRigidBody(mFloor->getRigidBody()); getDynamicsWorld()->destroyRigidBody(mFloor->getRigidBody());
delete mFloor; delete mFloor;
// Destroy the dynamics world // Destroy the dynamics world
delete mDynamicsWorld; delete getDynamicsWorld();
} }
// Update the physics world (take a simulation step) // Update the physics world (take a simulation step)
void JointsScene::updatePhysics() { 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) // 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<double>(mEngineSettings.elapsedTime) * 1.5);
mSliderJoint->setMotorSpeed(rp3d::decimal(motorSpeed)); mSliderJoint->setMotorSpeed(rp3d::decimal(motorSpeed));
// Take a simulation step SceneDemo::updatePhysics();
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; i<NB_BALLSOCKETJOINT_BOXES; i++) {
mBallAndSocketJointChainBoxes[i]->render(shader, worldToCameraMatrix, mIsWireframeEnabled);
}
// Render the floor
mFloor->render(shader, worldToCameraMatrix, mIsWireframeEnabled);
// Unbind the shader
shader.unbind();
} }
// Reset the scene // Reset the scene
@ -236,15 +199,16 @@ void JointsScene::createBallAndSocketJoints() {
// --------------- Create the boxes --------------- // // --------------- Create the boxes --------------- //
openglframework::Vector3 positionBox(0, 15, 5); rp3d::Vector3 positionBox(0, 15, 5);
openglframework::Vector3 boxDimension(1, 1, 1); openglframework::Vector3 boxDimension(1, 1, 1);
const float boxMass = 0.5f; const float boxMass = 0.5f;
for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) { for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) {
// Create a box and a corresponding rigid in the dynamics world // Create a box and a corresponding rigid in the dynamics world
mBallAndSocketJointChainBoxes[i] = new Box(boxDimension, positionBox , boxMass, mBallAndSocketJointChainBoxes[i] = new Box(boxDimension, boxMass,
mDynamicsWorld, mMeshFolderPath); getDynamicsWorld(), mMeshFolderPath);
mBallAndSocketJointChainBoxes[i]->setTransform(rp3d::Transform(positionBox, rp3d::Quaternion::identity()));
// Set the box color // Set the box color
mBallAndSocketJointChainBoxes[i]->setColor(mDemoColors[i % mNbDemoColors]); mBallAndSocketJointChainBoxes[i]->setColor(mDemoColors[i % mNbDemoColors]);
@ -281,7 +245,7 @@ void JointsScene::createBallAndSocketJoints() {
// Create the joint in the dynamics world // Create the joint in the dynamics world
mBallAndSocketJoints[i] = dynamic_cast<rp3d::BallAndSocketJoint*>( mBallAndSocketJoints[i] = dynamic_cast<rp3d::BallAndSocketJoint*>(
mDynamicsWorld->createJoint(jointInfo)); getDynamicsWorld()->createJoint(jointInfo));
} }
} }
@ -291,11 +255,12 @@ void JointsScene::createSliderJoint() {
// --------------- Create the first box --------------- // // --------------- Create the first box --------------- //
// Position of the 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 // Create a box and a corresponding rigid in the dynamics world
openglframework::Vector3 box1Dimension(2, 4, 2); 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 // Set the box color
mSliderJointBottomBox->setColor(mBlueColorDemo); mSliderJointBottomBox->setColor(mBlueColorDemo);
@ -312,11 +277,12 @@ void JointsScene::createSliderJoint() {
// --------------- Create the second box --------------- // // --------------- Create the second box --------------- //
// Position of the 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 // Create a box and a corresponding rigid in the dynamics world
openglframework::Vector3 box2Dimension(1.5f, 4, 1.5f); 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 // Set the box color
mSliderJointTopBox->setColor(mOrangeColorDemo); mSliderJointTopBox->setColor(mOrangeColorDemo);
@ -344,7 +310,7 @@ void JointsScene::createSliderJoint() {
jointInfo.isCollisionEnabled = false; jointInfo.isCollisionEnabled = false;
// Create the joint in the dynamics world // Create the joint in the dynamics world
mSliderJoint = dynamic_cast<rp3d::SliderJoint*>(mDynamicsWorld->createJoint(jointInfo)); mSliderJoint = dynamic_cast<rp3d::SliderJoint*>(getDynamicsWorld()->createJoint(jointInfo));
} }
/// Create the boxes and joint for the Hinge joint example /// Create the boxes and joint for the Hinge joint example
@ -353,11 +319,12 @@ void JointsScene::createPropellerHingeJoint() {
// --------------- Create the propeller box --------------- // // --------------- Create the propeller box --------------- //
// Position of the 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 // Create a box and a corresponding rigid in the dynamics world
openglframework::Vector3 boxDimension(10, 1, 1); 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 // Set the box color
mPropellerBox->setColor(mYellowColorDemo); mPropellerBox->setColor(mYellowColorDemo);
@ -384,7 +351,7 @@ void JointsScene::createPropellerHingeJoint() {
jointInfo.isCollisionEnabled = false; jointInfo.isCollisionEnabled = false;
// Create the joint in the dynamics world // Create the joint in the dynamics world
mPropellerHingeJoint = dynamic_cast<rp3d::HingeJoint*>(mDynamicsWorld->createJoint(jointInfo)); mPropellerHingeJoint = dynamic_cast<rp3d::HingeJoint*>(getDynamicsWorld()->createJoint(jointInfo));
} }
/// Create the boxes and joints for the fixed joints /// Create the boxes and joints for the fixed joints
@ -393,11 +360,12 @@ void JointsScene::createFixedJoints() {
// --------------- Create the first box --------------- // // --------------- Create the first box --------------- //
// Position of the 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 // Create a box and a corresponding rigid in the dynamics world
openglframework::Vector3 boxDimension(1.5, 1.5, 1.5); 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 // Set the box color
mFixedJointBox1->setColor(mPinkColorDemo); mFixedJointBox1->setColor(mPinkColorDemo);
@ -411,10 +379,11 @@ void JointsScene::createFixedJoints() {
// --------------- Create the second box --------------- // // --------------- Create the second box --------------- //
// Position of the 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 // 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 // Set the box color
mFixedJointBox2->setColor(mBlueColorDemo); mFixedJointBox2->setColor(mBlueColorDemo);
@ -435,7 +404,7 @@ void JointsScene::createFixedJoints() {
jointInfo1.isCollisionEnabled = false; jointInfo1.isCollisionEnabled = false;
// Create the joint in the dynamics world // Create the joint in the dynamics world
mFixedJoint1 = dynamic_cast<rp3d::FixedJoint*>(mDynamicsWorld->createJoint(jointInfo1)); mFixedJoint1 = dynamic_cast<rp3d::FixedJoint*>(getDynamicsWorld()->createJoint(jointInfo1));
// --------------- Create the second fixed joint --------------- // // --------------- Create the second fixed joint --------------- //
@ -446,15 +415,15 @@ void JointsScene::createFixedJoints() {
jointInfo2.isCollisionEnabled = false; jointInfo2.isCollisionEnabled = false;
// Create the joint in the dynamics world // Create the joint in the dynamics world
mFixedJoint2 = dynamic_cast<rp3d::FixedJoint*>(mDynamicsWorld->createJoint(jointInfo2)); mFixedJoint2 = dynamic_cast<rp3d::FixedJoint*>(getDynamicsWorld()->createJoint(jointInfo2));
} }
// Create the floor // Create the floor
void JointsScene::createFloor() { void JointsScene::createFloor() {
// Create the floor // Create the floor
openglframework::Vector3 floorPosition(0, 0, 0); rp3d::Vector3 floorPosition(0, 0, 0);
mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mMeshFolderPath); mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath);
// Set the box color // Set the box color
mFloor->setColor(mGreyColorDemo); mFloor->setColor(mGreyColorDemo);

View File

@ -92,9 +92,6 @@ class JointsScene : public SceneDemo {
/// Box for the floor /// Box for the floor
Box* mFloor; Box* mFloor;
/// Dynamics world used for the physics simulation
rp3d::DynamicsWorld* mDynamicsWorld;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Create the boxes and joints for the Ball-and-Socket joint example /// Create the boxes and joints for the Ball-and-Socket joint example
@ -117,7 +114,7 @@ class JointsScene : public SceneDemo {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
JointsScene(const std::string& name); JointsScene(const std::string& name, EngineSettings& settings);
/// Destructor /// Destructor
virtual ~JointsScene() override ; virtual ~JointsScene() override ;
@ -126,10 +123,6 @@ class JointsScene : public SceneDemo {
/// Can be called several times per frame /// Can be called several times per frame
virtual void updatePhysics() override; 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 /// Reset the scene
virtual void reset() override; virtual void reset() override;
@ -139,7 +132,7 @@ class JointsScene : public SceneDemo {
// Return all the contact points of the scene // Return all the contact points of the scene
inline std::vector<ContactPoint> JointsScene::getContactPoints() const { inline std::vector<ContactPoint> JointsScene::getContactPoints() const {
return computeContactPointsOfWorld(mDynamicsWorld); return computeContactPointsOfWorld(getDynamicsWorld());
} }
} }

View File

@ -31,8 +31,8 @@ using namespace openglframework;
using namespace raycastscene; using namespace raycastscene;
// Constructor // Constructor
RaycastScene::RaycastScene(const std::string& name) RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
: SceneDemo(name, SCENE_RADIUS, false), mMeshFolderPath("meshes/"), : SceneDemo(name, settings, SCENE_RADIUS, false), mMeshFolderPath("meshes/"),
mRaycastManager(mPhongShader, mMeshFolderPath), mCurrentBodyIndex(-1), mRaycastManager(mPhongShader, mMeshFolderPath), mCurrentBodyIndex(-1),
mAreNormalsDisplayed(false), mVBOVertices(GL_ARRAY_BUFFER) { mAreNormalsDisplayed(false), mVBOVertices(GL_ARRAY_BUFFER) {
@ -45,13 +45,12 @@ RaycastScene::RaycastScene(const std::string& name)
setScenePosition(center, SCENE_RADIUS); setScenePosition(center, SCENE_RADIUS);
// Create the dynamics world for the physics simulation // Create the dynamics world for the physics simulation
mCollisionWorld = new rp3d::CollisionWorld(); mPhysicsWorld = new rp3d::CollisionWorld();
// ---------- Dumbbell ---------- // // ---------- Dumbbell ---------- //
openglframework::Vector3 position1(0, 0, 0);
// Create a convex mesh and a corresponding collision body in the dynamics world // 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 // Set the box color
mDumbbell->setColor(mGreyColorDemo); mDumbbell->setColor(mGreyColorDemo);
@ -59,10 +58,9 @@ RaycastScene::RaycastScene(const std::string& name)
mPhysicsObjects.push_back(mDumbbell); mPhysicsObjects.push_back(mDumbbell);
// ---------- Box ---------- // // ---------- Box ---------- //
openglframework::Vector3 position2(0, 0, 0);
// Create a box and a corresponding collision body in the dynamics world // 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); mBox->getCollisionBody()->setIsActive(false);
// Set the box color // Set the box color
@ -71,11 +69,9 @@ RaycastScene::RaycastScene(const std::string& name)
mPhysicsObjects.push_back(mBox); mPhysicsObjects.push_back(mBox);
// ---------- Sphere ---------- // // ---------- Sphere ---------- //
openglframework::Vector3 position3(0, 0, 0);
// Create a sphere and a corresponding collision body in the dynamics world // Create a sphere and a corresponding collision body in the dynamics world
mSphere = new Sphere(SPHERE_RADIUS, position3, mCollisionWorld, mSphere = new Sphere(SPHERE_RADIUS, mPhysicsWorld, mMeshFolderPath);
mMeshFolderPath);
// Set the color // Set the color
mSphere->setColor(mGreyColorDemo); mSphere->setColor(mGreyColorDemo);
@ -86,8 +82,7 @@ RaycastScene::RaycastScene(const std::string& name)
openglframework::Vector3 position6(0, 0, 0); openglframework::Vector3 position6(0, 0, 0);
// Create a cylinder and a corresponding collision body in the dynamics world // Create a cylinder and a corresponding collision body in the dynamics world
mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position6 , mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath);
mCollisionWorld, mMeshFolderPath);
// Set the color // Set the color
mCapsule->setColor(mGreyColorDemo); mCapsule->setColor(mGreyColorDemo);
@ -95,10 +90,9 @@ RaycastScene::RaycastScene(const std::string& name)
mPhysicsObjects.push_back(mCapsule); mPhysicsObjects.push_back(mCapsule);
// ---------- Convex Mesh ---------- // // ---------- Convex Mesh ---------- //
openglframework::Vector3 position7(0, 0, 0);
// Create a convex mesh and a corresponding collision body in the dynamics world // 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 // Set the color
mConvexMesh->setColor(mGreyColorDemo); mConvexMesh->setColor(mGreyColorDemo);
@ -106,10 +100,9 @@ RaycastScene::RaycastScene(const std::string& name)
mPhysicsObjects.push_back(mConvexMesh); mPhysicsObjects.push_back(mConvexMesh);
// ---------- Concave Mesh ---------- // // ---------- Concave Mesh ---------- //
openglframework::Vector3 position8(0, 0, 0);
// Create a convex mesh and a corresponding collision body in the dynamics world // 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 // Set the color
mConcaveMesh->setColor(mGreyColorDemo); mConcaveMesh->setColor(mGreyColorDemo);
@ -117,10 +110,9 @@ RaycastScene::RaycastScene(const std::string& name)
mPhysicsObjects.push_back(mConcaveMesh); mPhysicsObjects.push_back(mConcaveMesh);
// ---------- Heightfield ---------- // // ---------- Heightfield ---------- //
openglframework::Vector3 position9(0, 0, 0);
// Create a convex mesh and a corresponding collision body in the dynamics world // 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 // Set the color
mHeightField->setColor(mGreyColorDemo); mHeightField->setColor(mGreyColorDemo);
@ -139,7 +131,7 @@ RaycastScene::RaycastScene(const std::string& name)
// Create the raycast lines // Create the raycast lines
void RaycastScene::createLines() { void RaycastScene::createLines() {
int nbRaysOneDimension = std::sqrt(float(NB_RAYS)); int nbRaysOneDimension = static_cast<int>(std::sqrt(float(NB_RAYS)));
for (int i=0; i<nbRaysOneDimension; i++) { for (int i=0; i<nbRaysOneDimension; i++) {
for (int j=0; j<nbRaysOneDimension; j++) { for (int j=0; j<nbRaysOneDimension; j++) {
@ -201,45 +193,49 @@ void RaycastScene::changeBody() {
// Reset the scene // Reset the scene
void RaycastScene::reset() { void RaycastScene::reset() {
std::vector<PhysicsObject*>::iterator it;
for (it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) {
(*it)->setTransform(rp3d::Transform(rp3d::Vector3::zero(), rp3d::Quaternion::identity()));
}
} }
// Destructor // Destructor
RaycastScene::~RaycastScene() { RaycastScene::~RaycastScene() {
// Destroy the box rigid body from the dynamics world // Destroy the box rigid body from the dynamics world
mCollisionWorld->destroyCollisionBody(mBox->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mBox->getCollisionBody());
delete mBox; delete mBox;
// Destroy the sphere // Destroy the sphere
mCollisionWorld->destroyCollisionBody(mSphere->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mSphere->getCollisionBody());
delete mSphere; delete mSphere;
// Destroy the corresponding rigid body from the dynamics world // Destroy the corresponding rigid body from the dynamics world
mCollisionWorld->destroyCollisionBody(mCapsule->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mCapsule->getCollisionBody());
// Destroy the sphere // Destroy the sphere
delete mCapsule; delete mCapsule;
// Destroy the corresponding rigid body from the dynamics world // Destroy the corresponding rigid body from the dynamics world
mCollisionWorld->destroyCollisionBody(mConvexMesh->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mConvexMesh->getCollisionBody());
// Destroy the convex mesh // Destroy the convex mesh
delete mConvexMesh; delete mConvexMesh;
// Destroy the corresponding rigid body from the dynamics world // Destroy the corresponding rigid body from the dynamics world
mCollisionWorld->destroyCollisionBody(mDumbbell->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mDumbbell->getCollisionBody());
// Destroy the dumbbell // Destroy the dumbbell
delete mDumbbell; delete mDumbbell;
// Destroy the corresponding rigid body from the dynamics world // Destroy the corresponding rigid body from the dynamics world
mCollisionWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody());
// Destroy the convex mesh // Destroy the convex mesh
delete mConcaveMesh; delete mConcaveMesh;
// Destroy the corresponding rigid body from the dynamics world // Destroy the corresponding rigid body from the dynamics world
mCollisionWorld->destroyCollisionBody(mHeightField->getCollisionBody()); mPhysicsWorld->destroyCollisionBody(mHeightField->getCollisionBody());
// Destroy the convex mesh // Destroy the convex mesh
delete mHeightField; delete mHeightField;
@ -250,7 +246,7 @@ RaycastScene::~RaycastScene() {
VisualContactPoint::destroyStaticData(); VisualContactPoint::destroyStaticData();
// Destroy the collision world // Destroy the collision world
delete mCollisionWorld; delete mPhysicsWorld;
// Destroy the lines // Destroy the lines
for (std::vector<Line*>::iterator it = mLines.begin(); it != mLines.end(); for (std::vector<Line*>::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 // Perform a raycast query on the physics world by passing a raycast
// callback class in argument. // callback class in argument.
mCollisionWorld->raycast(ray, &mRaycastManager); mPhysicsWorld->raycast(ray, &mRaycastManager);
} }
SceneDemo::update(); SceneDemo::update();
@ -307,7 +303,7 @@ void RaycastScene::renderSinglePass(openglframework::Shader& shader, const openg
mColorShader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix); mColorShader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix);
// Set the vertex color // 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); mColorShader.setVector4Uniform("vertexColor", color, false);
// Get the location of shader attribute variables // 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 // Render all the physics objects of the scene
for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) {
if ((*it)->getCollisionBody()->isActive()) { if ((*it)->getCollisionBody()->isActive()) {
(*it)->render(shader, worldToCameraMatrix, mIsWireframeEnabled); (*it)->render(shader, worldToCameraMatrix);
} }
} }

View File

@ -146,9 +146,6 @@ class RaycastScene : public SceneDemo {
ConcaveMesh* mConcaveMesh; ConcaveMesh* mConcaveMesh;
HeightField* mHeightField; HeightField* mHeightField;
/// Collision world used for the physics simulation
rp3d::CollisionWorld* mCollisionWorld;
/// All the points to render the lines /// All the points to render the lines
std::vector<openglframework::Vector3> mLinePoints; std::vector<openglframework::Vector3> mLinePoints;
@ -170,7 +167,7 @@ class RaycastScene : public SceneDemo {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
RaycastScene(const std::string& name); RaycastScene(const std::string& name, EngineSettings& settings);
/// Destructor /// Destructor
virtual ~RaycastScene() override; virtual ~RaycastScene() override;

View File

@ -388,6 +388,14 @@ void Gui::createSettingsPanel() {
mApp->mIsContactPointsDisplayed = value; 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 // Enabled/Disable VSync
CheckBox* checkboxVSync = new CheckBox(mRenderingPanel, "V-Sync"); CheckBox* checkboxVSync = new CheckBox(mRenderingPanel, "V-Sync");
checkboxVSync->setChecked(mApp->mIsVSyncEnabled); checkboxVSync->setChecked(mApp->mIsVSyncEnabled);

View File

@ -30,10 +30,10 @@
using namespace openglframework; using namespace openglframework;
// Constructor // Constructor
Scene::Scene(const std::string& name, bool isShadowMappingEnabled) Scene::Scene(const std::string& name, EngineSettings& engineSettings, bool isShadowMappingEnabled)
: mName(name), mInterpolationFactor(0.0f), mViewportX(0), mViewportY(0), : mName(name), mEngineSettings(engineSettings), mInterpolationFactor(0.0f), mViewportX(0), mViewportY(0),
mViewportWidth(0), mViewportHeight(0), mIsShadowMappingEnabled(isShadowMappingEnabled), 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)) { if ((xMouse >= 0) && (xMouse <= mWindowWidth) && (yMouse >= 0) && (yMouse <= mWindowHeight)) {
float x = float(xMouse - 0.5f * mWindowWidth) / float(mWindowWidth); float x = float(xMouse - 0.5f * mWindowWidth) / float(mWindowWidth);
float y = float(0.5f * mWindowHeight - yMouse) / float(mWindowHeight); float y = float(0.5f * mWindowHeight - yMouse) / float(mWindowHeight);
float sinx = sin(PI * x * 0.5f); float sinx = std::sin(PI * x * 0.5f);
float siny = sin(PI * y * 0.5f); float siny = std::sin(PI * y * 0.5f);
float sinx2siny2 = sinx * sinx + siny * siny; float sinx2siny2 = sinx * sinx + siny * siny;
// Compute the point on the sphere // Compute the point on the sphere
spherePoint.x = sinx; spherePoint.x = sinx;
spherePoint.y = siny; 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; return true;
} }
@ -175,9 +175,9 @@ void Scene::rotate(int xMouse, int yMouse) {
float cosAngle = mLastPointOnSphere.dot(newPoint3D); float cosAngle = mLastPointOnSphere.dot(newPoint3D);
float epsilon = std::numeric_limits<float>::epsilon(); float epsilon = std::numeric_limits<float>::epsilon();
if (fabs(cosAngle) < 1.0f && axis.length() > epsilon) { if (std::abs(cosAngle) < 1.0f && axis.length() > epsilon) {
axis.normalize(); axis.normalize();
float angle = 2.0f * acos(cosAngle); float angle = 2.0f * std::acos(cosAngle);
// Rotate the camera around the center of the scene // Rotate the camera around the center of the scene
mCamera.rotateAroundLocalPoint(axis, -angle, mCenterScene); mCamera.rotateAroundLocalPoint(axis, -angle, mCenterScene);

View File

@ -28,6 +28,7 @@
// Libraries // Libraries
#include "openglframework.h" #include "openglframework.h"
#include "reactphysics3d.h"
// Structure ContactPoint // Structure ContactPoint
struct ContactPoint { struct ContactPoint {
@ -52,8 +53,8 @@ struct EngineSettings {
long double elapsedTime; // Elapsed time (in seconds) long double elapsedTime; // Elapsed time (in seconds)
float timeStep; // Current time step (in seconds) float timeStep; // Current time step (in seconds)
int nbVelocitySolverIterations; // Nb of velocity solver iterations uint nbVelocitySolverIterations; // Nb of velocity solver iterations
int nbPositionSolverIterations; // Nb of position solver iterations uint nbPositionSolverIterations; // Nb of position solver iterations
bool isSleepingEnabled; // True if sleeping technique is enabled bool isSleepingEnabled; // True if sleeping technique is enabled
float timeBeforeSleep; // Time of inactivity before a body sleep float timeBeforeSleep; // Time of inactivity before a body sleep
float sleepLinearVelocity; // Sleep linear velocity float sleepLinearVelocity; // Sleep linear velocity
@ -65,6 +66,23 @@ struct EngineSettings {
EngineSettings() : elapsedTime(0.0f), timeStep(0.0f) { 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 // Class Scene
@ -79,7 +97,7 @@ class Scene {
std::string mName; std::string mName;
/// Physics engine settings /// Physics engine settings
EngineSettings mEngineSettings; EngineSettings& mEngineSettings;
/// Camera /// Camera
openglframework::Camera mCamera; openglframework::Camera mCamera;
@ -111,6 +129,9 @@ class Scene {
/// True if contact points are displayed /// True if contact points are displayed
bool mIsContactPointsDisplayed; bool mIsContactPointsDisplayed;
/// True if the AABBs of the phycis objects are displayed
bool mIsAABBsDisplayed;
/// True if we render shapes in wireframe mode /// True if we render shapes in wireframe mode
bool mIsWireframeEnabled; bool mIsWireframeEnabled;
@ -140,7 +161,7 @@ class Scene {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Scene(const std::string& name, bool isShadowMappingEnabled = false); Scene(const std::string& name, EngineSettings& engineSettings, bool isShadowMappingEnabled = false);
/// Destructor /// Destructor
virtual ~Scene(); virtual ~Scene();
@ -184,12 +205,6 @@ class Scene {
/// Return a reference to the camera /// Return a reference to the camera
const openglframework::Camera& getCamera() const; 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 /// Set the interpolation factor
void setInterpolationFactor(float interpolationFactor); void setInterpolationFactor(float interpolationFactor);
@ -205,6 +220,9 @@ class Scene {
/// Display/Hide the contact points /// Display/Hide the contact points
void virtual setIsContactPointsDisplayed(bool display); void virtual setIsContactPointsDisplayed(bool display);
/// Display/Hide the AABBs
void setIsAABBsDisplayed(bool display);
/// Return true if wireframe rendering is enabled /// Return true if wireframe rendering is enabled
bool getIsWireframeEnabled() const; bool getIsWireframeEnabled() const;
@ -244,16 +262,6 @@ inline void Scene::setViewport(int x, int y, int width, int height) {
mViewportHeight = 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 // Set the interpolation factor
inline void Scene::setInterpolationFactor(float interpolationFactor) { inline void Scene::setInterpolationFactor(float interpolationFactor) {
mInterpolationFactor = interpolationFactor; mInterpolationFactor = interpolationFactor;
@ -279,6 +287,11 @@ inline void Scene::setIsContactPointsDisplayed(bool display) {
mIsContactPointsDisplayed = display; mIsContactPointsDisplayed = display;
} }
// Display/Hide the AABBs
inline void Scene::setIsAABBsDisplayed(bool display) {
mIsAABBsDisplayed = display;
}
// Return true if wireframe rendering is enabled // Return true if wireframe rendering is enabled
inline bool Scene::getIsWireframeEnabled() const { inline bool Scene::getIsWireframeEnabled() const {
return mIsWireframeEnabled; return mIsWireframeEnabled;

View File

@ -26,27 +26,28 @@
// Libraries // Libraries
#include "SceneDemo.h" #include "SceneDemo.h"
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include "AABB.h"
using namespace openglframework; using namespace openglframework;
int SceneDemo::shadowMapTextureLevel = 0; int SceneDemo::shadowMapTextureLevel = 0;
openglframework::Color SceneDemo::mGreyColorDemo = Color(0.70f, 0.70f, 0.7f, 1.0); openglframework::Color SceneDemo::mGreyColorDemo = Color(0.70f, 0.70f, 0.7f, 1.0f);
openglframework::Color SceneDemo::mYellowColorDemo = Color(0.9, 0.88, 0.145, 1.0); openglframework::Color SceneDemo::mYellowColorDemo = Color(0.9f, 0.88f, 0.145f, 1.0f);
openglframework::Color SceneDemo::mBlueColorDemo = Color(0, 0.66, 0.95, 1.0); openglframework::Color SceneDemo::mBlueColorDemo = Color(0, 0.66f, 0.95f, 1.0f);
openglframework::Color SceneDemo::mOrangeColorDemo = Color(0.9, 0.35, 0, 1.0); openglframework::Color SceneDemo::mOrangeColorDemo = Color(0.9f, 0.35f, 0, 1.0f);
openglframework::Color SceneDemo::mPinkColorDemo = Color(0.83, 0.48, 0.64, 1.0); openglframework::Color SceneDemo::mPinkColorDemo = Color(0.83f, 0.48f, 0.64f, 1.0f);
openglframework::Color SceneDemo::mRedColorDemo = Color(0.95, 0, 0, 1.0); openglframework::Color SceneDemo::mRedColorDemo = Color(0.95f, 0, 0, 1.0f);
int SceneDemo::mNbDemoColors = 4; int SceneDemo::mNbDemoColors = 4;
openglframework::Color SceneDemo::mDemoColors[] = {SceneDemo::mYellowColorDemo, SceneDemo::mBlueColorDemo, openglframework::Color SceneDemo::mDemoColors[] = {SceneDemo::mYellowColorDemo, SceneDemo::mBlueColorDemo,
SceneDemo::mOrangeColorDemo, SceneDemo::mPinkColorDemo}; SceneDemo::mOrangeColorDemo, SceneDemo::mPinkColorDemo};
// Constructor // Constructor
SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMappingEnabled) SceneDemo::SceneDemo(const std::string& name, EngineSettings& settings, float sceneRadius, bool isShadowMappingEnabled)
: Scene(name, isShadowMappingEnabled), mIsShadowMappingInitialized(false), : Scene(name, settings, isShadowMappingEnabled), mIsShadowMappingInitialized(false),
mDepthShader("shaders/depth.vert", "shaders/depth.frag"), mDepthShader("shaders/depth.vert", "shaders/depth.frag"),
mPhongShader("shaders/phong.vert", "shaders/phong.frag"), mPhongShader("shaders/phong.vert", "shaders/phong.frag"),
mQuadShader("shaders/quad.vert", "shaders/quad.frag"),
mColorShader("shaders/color.vert", "shaders/color.frag"), mColorShader("shaders/color.vert", "shaders/color.frag"),
mQuadShader("shaders/quad.vert", "shaders/quad.frag"),
mVBOQuad(GL_ARRAY_BUFFER), mMeshFolderPath("meshes/") { mVBOQuad(GL_ARRAY_BUFFER), mMeshFolderPath("meshes/") {
shadowMapTextureLevel++; shadowMapTextureLevel++;
@ -75,6 +76,9 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMa
createQuadVBO(); createQuadVBO();
// Init rendering for the AABBs
AABB::init();
VisualContactPoint::createStaticData(mMeshFolderPath); VisualContactPoint::createStaticData(mMeshFolderPath);
} }
@ -93,6 +97,9 @@ SceneDemo::~SceneDemo() {
// Destroy the contact points // Destroy the contact points
removeAllContactPoints(); removeAllContactPoints();
// Destroy rendering data for the AABB
AABB::destroy();
VisualContactPoint::destroyStaticData(); VisualContactPoint::destroyStaticData();
} }
@ -114,6 +121,23 @@ void SceneDemo::update() {
// Can be called several times per frame // Can be called several times per frame
void SceneDemo::updatePhysics() { 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) // Render the scene (in multiple passes for shadow mapping)
@ -209,6 +233,11 @@ void SceneDemo::render() {
renderContactPoints(mPhongShader, worldToCameraMatrix); renderContactPoints(mPhongShader, worldToCameraMatrix);
} }
// Render the AABBs
if (mIsAABBsDisplayed) {
renderAABBs(worldToCameraMatrix);
}
if (mIsShadowMappingEnabled) mShadowMapTexture.unbind(); if (mIsShadowMappingEnabled) mShadowMapTexture.unbind();
mPhongShader.unbind(); mPhongShader.unbind();
@ -218,16 +247,24 @@ void SceneDemo::render() {
// Render the scene in a single pass // Render the scene in a single pass
void SceneDemo::renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { void SceneDemo::renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) {
if (mIsWireframeEnabled) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
// Bind the shader // Bind the shader
shader.bind(); shader.bind();
// Render all the physics objects of the scene // Render all the physics objects of the scene
for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) {
(*it)->render(shader, worldToCameraMatrix, mIsWireframeEnabled); (*it)->render(mIsWireframeEnabled ? mColorShader : shader, worldToCameraMatrix);
} }
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
if (mIsWireframeEnabled) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
} }
// Create the Shadow map FBO and texture // Create the Shadow map FBO and texture
@ -338,13 +375,38 @@ void SceneDemo::updateContactPoints() {
// Render the contact points // Render the contact points
void SceneDemo::renderContactPoints(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { void SceneDemo::renderContactPoints(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) {
// Render all the raycast hit points // Render all the contact points
for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin(); for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin();
it != mContactPoints.end(); ++it) { it != mContactPoints.end(); ++it) {
(*it)->render(mColorShader, worldToCameraMatrix); (*it)->render(mColorShader, worldToCameraMatrix);
} }
} }
// Render the AABBs
void SceneDemo::renderAABBs(const openglframework::Matrix4& worldToCameraMatrix) {
// For each physics object of the scene
for (std::vector<PhysicsObject*>::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() { void SceneDemo::removeAllContactPoints() {
// Destroy all the visual contact points // Destroy all the visual contact points

View File

@ -98,6 +98,8 @@ class SceneDemo : public Scene {
std::vector<PhysicsObject*> mPhysicsObjects; std::vector<PhysicsObject*> mPhysicsObjects;
rp3d::CollisionWorld* mPhysicsWorld;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
// Create the Shadow map FBO and texture // Create the Shadow map FBO and texture
@ -116,14 +118,25 @@ class SceneDemo : public Scene {
void renderContactPoints(openglframework::Shader& shader, void renderContactPoints(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix); const openglframework::Matrix4& worldToCameraMatrix);
/// Render the AABBs
void renderAABBs(const openglframework::Matrix4& worldToCameraMatrix);
/// Remove all contact points
void removeAllContactPoints(); 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: public:
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
SceneDemo(const std::string& name, float sceneRadius, bool isShadowMappingEnabled = true); SceneDemo(const std::string& name, EngineSettings& settings, float sceneRadius, bool isShadowMappingEnabled = true);
/// Destructor /// Destructor
virtual ~SceneDemo() override; 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<rp3d::DynamicsWorld*>(mPhysicsWorld);
}
// Return a reference to the dynamics world
inline const rp3d::DynamicsWorld* SceneDemo::getDynamicsWorld() const {
return dynamic_cast<rp3d::DynamicsWorld*>(mPhysicsWorld);
}
#endif #endif

View File

@ -59,12 +59,14 @@ TestbedApplication::TestbedApplication(bool isFullscreen)
mIsMultisamplingActive = true; mIsMultisamplingActive = true;
mWidth = 1280; mWidth = 1280;
mHeight = 720; mHeight = 720;
mEngineSettings = EngineSettings::defaultSettings();
mSinglePhysicsStepEnabled = false; mSinglePhysicsStepEnabled = false;
mSinglePhysicsStepDone = false; mSinglePhysicsStepDone = false;
mWindowToFramebufferRatio = Vector2(1, 1); mWindowToFramebufferRatio = Vector2(1, 1);
mIsShadowMappingEnabled = true; mIsShadowMappingEnabled = true;
mIsVSyncEnabled = false; mIsVSyncEnabled = false;
mIsContactPointsDisplayed = false; mIsContactPointsDisplayed = false;
mIsAABBsDisplayed = false;
mIsWireframeEnabled = false; mIsWireframeEnabled = false;
init(); init();
@ -97,39 +99,38 @@ void TestbedApplication::init() {
void TestbedApplication::createScenes() { void TestbedApplication::createScenes() {
// Cubes scene // Cubes scene
CubesScene* cubeScene = new CubesScene("Cubes"); CubesScene* cubeScene = new CubesScene("Cubes", mEngineSettings);
mScenes.push_back(cubeScene); mScenes.push_back(cubeScene);
// Joints scene // Joints scene
JointsScene* jointsScene = new JointsScene("Joints"); JointsScene* jointsScene = new JointsScene("Joints", mEngineSettings);
mScenes.push_back(jointsScene); mScenes.push_back(jointsScene);
// Collision shapes scene // Collision shapes scene
CollisionShapesScene* collisionShapesScene = new CollisionShapesScene("Collision Shapes"); CollisionShapesScene* collisionShapesScene = new CollisionShapesScene("Collision Shapes", mEngineSettings);
mScenes.push_back(collisionShapesScene); mScenes.push_back(collisionShapesScene);
// Heightfield shape scene // Heightfield shape scene
HeightFieldScene* heightFieldScene = new HeightFieldScene("Heightfield"); HeightFieldScene* heightFieldScene = new HeightFieldScene("Heightfield", mEngineSettings);
mScenes.push_back(heightFieldScene); mScenes.push_back(heightFieldScene);
// Raycast scene // Raycast scene
RaycastScene* raycastScene = new RaycastScene("Raycast"); RaycastScene* raycastScene = new RaycastScene("Raycast", mEngineSettings);
mScenes.push_back(raycastScene); mScenes.push_back(raycastScene);
// Collision Detection scene // Collision Detection scene
CollisionDetectionScene* collisionDetectionScene = new CollisionDetectionScene("Collision Detection"); CollisionDetectionScene* collisionDetectionScene = new CollisionDetectionScene("Collision Detection", mEngineSettings);
mScenes.push_back(collisionDetectionScene); mScenes.push_back(collisionDetectionScene);
// Concave Mesh scene // Concave Mesh scene
ConcaveMeshScene* concaveMeshScene = new ConcaveMeshScene("Concave Mesh"); ConcaveMeshScene* concaveMeshScene = new ConcaveMeshScene("Concave Mesh", mEngineSettings);
mScenes.push_back(concaveMeshScene); mScenes.push_back(concaveMeshScene);
assert(mScenes.size() > 0); assert(mScenes.size() > 0);
mCurrentScene = mScenes[5];
// Get the engine settings from the scene const int firstSceneIndex = 0;
mEngineSettings = mCurrentScene->getEngineSettings();
mEngineSettings.timeStep = DEFAULT_TIMESTEP; switchScene(mScenes[firstSceneIndex]);
} }
// Remove all the scenes // Remove all the scenes
@ -152,9 +153,8 @@ void TestbedApplication::updateSinglePhysicsStep() {
// Update the physics of the current scene // Update the physics of the current scene
void TestbedApplication::updatePhysics() { void TestbedApplication::updatePhysics() {
// Set the engine settings // Update the elapsed time
mEngineSettings.elapsedTime = mTimer.getPhysicsTime(); mEngineSettings.elapsedTime = mTimer.getPhysicsTime();
mCurrentScene->setEngineSettings(mEngineSettings);
if (mTimer.isRunning()) { if (mTimer.isRunning()) {
@ -202,6 +202,9 @@ void TestbedApplication::update() {
// Display/Hide contact points // Display/Hide contact points
mCurrentScene->setIsContactPointsDisplayed(mIsContactPointsDisplayed); mCurrentScene->setIsContactPointsDisplayed(mIsContactPointsDisplayed);
// Display/Hide the AABBs
mCurrentScene->setIsAABBsDisplayed(mIsAABBsDisplayed);
// Enable/Disable wireframe mode // Enable/Disable wireframe mode
mCurrentScene->setIsWireframeEnabled(mIsWireframeEnabled); mCurrentScene->setIsWireframeEnabled(mIsWireframeEnabled);
@ -259,11 +262,6 @@ void TestbedApplication::switchScene(Scene* newScene) {
mCurrentScene = newScene; mCurrentScene = newScene;
// Get the engine settings of the scene
float currentTimeStep = mEngineSettings.timeStep;
mEngineSettings = mCurrentScene->getEngineSettings();
mEngineSettings.timeStep = currentTimeStep;
// Reset the scene // Reset the scene
mCurrentScene->reset(); mCurrentScene->reset();

View File

@ -38,9 +38,6 @@ using namespace nanogui;
// Macro for OpenGL errors // Macro for OpenGL errors
#define checkOpenGLErrors() checkOpenGLErrorsInternal(__FILE__,__LINE__) #define checkOpenGLErrors() checkOpenGLErrorsInternal(__FILE__,__LINE__)
// Constants
const float DEFAULT_TIMESTEP = 1.0f / 60.0f;
/// Class TestbedApplication /// Class TestbedApplication
class TestbedApplication : public Screen { class TestbedApplication : public Screen {
@ -109,6 +106,9 @@ class TestbedApplication : public Screen {
/// True if contact points are displayed /// True if contact points are displayed
bool mIsContactPointsDisplayed; bool mIsContactPointsDisplayed;
/// True if the AABBs of physics objects are displayed
bool mIsAABBsDisplayed;
/// True if the wireframe rendering is enabled /// True if the wireframe rendering is enabled
bool mIsWireframeEnabled; bool mIsWireframeEnabled;