Make possible to witch between scenes and reset them

This commit is contained in:
Daniel Chappuis 2015-06-25 22:28:11 +02:00
parent f376e2043f
commit 39ddabb6f5
24 changed files with 822 additions and 216 deletions

View File

@ -33,7 +33,7 @@
openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER); openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
openglframework::VertexArrayObject Box::mVAO; openglframework::VertexArrayObject Box::mVAO;
bool Box::areVBOsCreated = false; int Box::totalNbBoxes = 0;
VertexData Box::mCubeVertices[8] = { VertexData Box::mCubeVertices[8] = {
{openglframework::Vector3(1,1,1),openglframework::Vector3(1,1,1),openglframework::Color(1,0,0,1)}, {openglframework::Vector3(1,1,1),openglframework::Vector3(1,1,1),openglframework::Color(1,0,0,1)},
{openglframework::Vector3(-1,1,1),openglframework::Vector3(-1,1,1),openglframework::Color(1,0,0,1)}, {openglframework::Vector3(-1,1,1),openglframework::Vector3(-1,1,1),openglframework::Color(1,0,0,1)},
@ -95,12 +95,14 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
// If the Vertex Buffer object has not been created yet // If the Vertex Buffer object has not been created yet
if (!areVBOsCreated) { if (totalNbBoxes == 0) {
// Create the Vertex Buffer // Create the Vertex Buffer
createVBOAndVAO(shader); createVBOAndVAO(shader);
} }
totalNbBoxes++;
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
} }
@ -142,26 +144,29 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
mRigidBody = body; mRigidBody = body;
// If the Vertex Buffer object has not been created yet // If the Vertex Buffer object has not been created yet
if (!areVBOsCreated) { if (totalNbBoxes == 0) {
// Create the Vertex Buffer // Create the Vertex Buffer
createVBOAndVAO(shader); createVBOAndVAO(shader);
} }
totalNbBoxes++;
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
} }
// Destructor // Destructor
Box::~Box() { Box::~Box() {
if (areVBOsCreated) { if (totalNbBoxes == 1) {
// Destroy the VBOs and VAO // Destroy the VBOs and VAO
mVBOIndices.destroy(); mVBOIndices.destroy();
mVBOVertices.destroy(); mVBOVertices.destroy();
mVAO.destroy(); mVAO.destroy();
areVBOsCreated = false;
} }
totalNbBoxes--;
} }
// Render the cube at the correct position and with the correct orientation // Render the cube at the correct position and with the correct orientation
@ -239,7 +244,6 @@ void Box::createVBOAndVAO(openglframework::Shader& shader) {
mVBOVertices.bind(); mVBOVertices.bind();
mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW); mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW);
mVBOVertices.unbind(); mVBOVertices.unbind();
size_t test = sizeof(mCubeVertices);
// Create th VBO for the indices data // Create th VBO for the indices data
mVBOIndices.create(); mVBOIndices.create();
@ -268,6 +272,22 @@ void Box::createVBOAndVAO(openglframework::Shader& shader) {
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
}
areVBOsCreated = true;
// Reset the transform
void Box::resetTransform(const rp3d::Transform& transform) {
// Reset the transform
mRigidBody->setTransform(transform);
mRigidBody->setIsSleeping(false);
// Reset the velocity of the rigid body
rp3d::RigidBody* rigidBody = dynamic_cast<rp3d::RigidBody*>(mRigidBody);
if (rigidBody != NULL) {
rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0));
rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0));
}
updateTransform(1.0f);
} }

View File

@ -77,8 +77,8 @@ class Box : public openglframework::Object3D {
/// Indices of the cube (used to render the box) /// Indices of the cube (used to render the box)
static GLuint mCubeIndices[36]; static GLuint mCubeIndices[36];
/// True if the VBOs have already been created /// Total number of boxes created
static bool areVBOsCreated; static int totalNbBoxes;
/// Main color of the box /// Main color of the box
openglframework::Color mColor; openglframework::Color mColor;
@ -117,6 +117,9 @@ class Box : public openglframework::Object3D {
/// Set the color of the box /// Set the color of the box
void setColor(const openglframework::Color& color); void setColor(const openglframework::Color& color);
/// Set the position of the box
void resetTransform(const rp3d::Transform& transform);
}; };
// Return a pointer to the collision body of the box // Return a pointer to the collision body of the box

View File

@ -26,13 +26,18 @@
// Libraries // Libraries
#include "Capsule.h" #include "Capsule.h"
openglframework::VertexBufferObject Capsule::mVBOVertices(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Capsule::mVBONormals(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Capsule::mVBOTextureCoords(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Capsule::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
openglframework::VertexArrayObject Capsule::mVAO;
int Capsule::totalNbCapsules = 0;
// Constructor // Constructor
Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, Capsule::Capsule(float radius, float height, const openglframework::Vector3& position,
reactphysics3d::CollisionWorld* world, reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath, openglframework::Shader& shader) const std::string& meshFolderPath, openglframework::Shader& shader)
: openglframework::Mesh(), mRadius(radius), mHeight(height), mVBOVertices(GL_ARRAY_BUFFER), : openglframework::Mesh(), mRadius(radius), mHeight(height) {
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this);
@ -70,7 +75,11 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(shader); if (totalNbCapsules == 0) {
createVBOAndVAO(shader);
}
totalNbCapsules++;
} }
// Constructor // Constructor
@ -78,8 +87,6 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshFolderPath, openglframework::Shader &shader) const std::string& meshFolderPath, openglframework::Shader &shader)
: openglframework::Mesh(), mRadius(radius), mHeight(height), : openglframework::Mesh(), mRadius(radius), mHeight(height),
mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER),
mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER),
mColor(0.5f, 0.5f, 0.5f, 1.0f) { mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
@ -118,21 +125,30 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(shader); if (totalNbCapsules == 0) {
createVBOAndVAO(shader);
}
totalNbCapsules++;
} }
// Destructor // Destructor
Capsule::~Capsule() { Capsule::~Capsule() {
// Destroy the mesh if (totalNbCapsules == 1) {
destroy();
// Destroy the VBOs and VAO // Destroy the mesh
mVBOIndices.destroy(); destroy();
mVBOVertices.destroy();
mVBONormals.destroy(); // Destroy the VBOs and VAO
mVBOTextureCoords.destroy(); mVBOIndices.destroy();
mVAO.destroy(); mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
}
totalNbCapsules--;
} }
// Render the sphere at the correct position and with the correct orientation // Render the sphere at the correct position and with the correct orientation
@ -267,3 +283,21 @@ void Capsule::createVBOAndVAO(openglframework::Shader& shader) {
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
} }
// Reset the transform
void Capsule::resetTransform(const rp3d::Transform& transform) {
// Reset the transform
mRigidBody->setTransform(transform);
mRigidBody->setIsSleeping(false);
// Reset the velocity of the rigid body
rp3d::RigidBody* rigidBody = dynamic_cast<rp3d::RigidBody*>(mRigidBody);
if (rigidBody != NULL) {
rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0));
rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0));
}
updateTransform(1.0f);
}

View File

@ -53,19 +53,22 @@ class Capsule : public openglframework::Mesh {
rp3d::Transform mPreviousTransform; rp3d::Transform mPreviousTransform;
/// Vertex Buffer Object for the vertices data /// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices; static openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data /// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals; static openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords /// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords; static openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices /// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices; static openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data /// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO; static openglframework::VertexArrayObject mVAO;
// Total number of capsules created
static int totalNbCapsules;
/// Color /// Color
openglframework::Color mColor; openglframework::Color mColor;
@ -104,6 +107,9 @@ class Capsule : public openglframework::Mesh {
/// 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 render(openglframework::Shader& shader, void render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix); const openglframework::Matrix4& worldToCameraMatrix);
/// Set the position of the box
void resetTransform(const rp3d::Transform& transform);
}; };
// Return a pointer to the collision body of the box // Return a pointer to the collision body of the box

View File

@ -26,13 +26,18 @@
// Libraries // Libraries
#include "Cone.h" #include "Cone.h"
openglframework::VertexBufferObject Cone::mVBOVertices(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Cone::mVBONormals(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Cone::mVBOTextureCoords(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Cone::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
openglframework::VertexArrayObject Cone::mVAO;
int Cone::totalNbCones = 0;
// Constructor // Constructor
Cone::Cone(float radius, float height, const openglframework::Vector3 &position, Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
reactphysics3d::CollisionWorld* world, reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath, openglframework::Shader& shader) const std::string& meshFolderPath, openglframework::Shader& shader)
: openglframework::Mesh(), mRadius(radius), mHeight(height), : openglframework::Mesh(), mRadius(radius), mHeight(height),
mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER),
mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER),
mColor(0.5f, 0.5f, 0.5f, 1.0f) { mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
@ -71,7 +76,11 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(shader); if (totalNbCones == 0) {
createVBOAndVAO(shader);
}
totalNbCones++;
} }
// Constructor // Constructor
@ -79,8 +88,6 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshFolderPath, openglframework::Shader &shader) const std::string& meshFolderPath, openglframework::Shader &shader)
: openglframework::Mesh(), mRadius(radius), mHeight(height), : openglframework::Mesh(), mRadius(radius), mHeight(height),
mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER),
mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER),
mColor(0.5f, 0.5f, 0.5f, 1.0f) { mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
@ -119,21 +126,29 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(shader); if (totalNbCones == 0) {
createVBOAndVAO(shader);
}
totalNbCones++;
} }
// Destructor // Destructor
Cone::~Cone() { Cone::~Cone() {
// Destroy the mesh if (totalNbCones == 1) {
destroy(); // Destroy the mesh
destroy();
// Destroy the VBOs and VAO // Destroy the VBOs and VAO
mVBOIndices.destroy(); mVBOIndices.destroy();
mVBOVertices.destroy(); mVBOVertices.destroy();
mVBONormals.destroy(); mVBONormals.destroy();
mVBOTextureCoords.destroy(); mVBOTextureCoords.destroy();
mVAO.destroy(); mVAO.destroy();
}
totalNbCones--;
} }
// Render the cone at the correct position and with the correct orientation // Render the cone at the correct position and with the correct orientation
@ -270,3 +285,21 @@ void Cone::createVBOAndVAO(openglframework::Shader& shader) {
shader.unbind(); shader.unbind();
} }
// Reset the transform
void Cone::resetTransform(const rp3d::Transform& transform) {
// Reset the transform
mRigidBody->setTransform(transform);
mRigidBody->setIsSleeping(false);
// Reset the velocity of the rigid body
rp3d::RigidBody* rigidBody = dynamic_cast<rp3d::RigidBody*>(mRigidBody);
if (rigidBody != NULL) {
rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0));
rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0));
}
updateTransform(1.0f);
}

View File

@ -53,19 +53,22 @@ class Cone : public openglframework::Mesh {
rp3d::Transform mPreviousTransform; rp3d::Transform mPreviousTransform;
/// Vertex Buffer Object for the vertices data /// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices; static openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data /// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals; static openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords /// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords; static openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices /// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices; static openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data /// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO; static openglframework::VertexArrayObject mVAO;
// Total number of cones created
static int totalNbCones;
/// Color /// Color
openglframework::Color mColor; openglframework::Color mColor;
@ -103,6 +106,9 @@ class Cone : public openglframework::Mesh {
/// Render the cone at the correct position and with the correct orientation /// Render the cone at the correct position and with the correct orientation
void render(openglframework::Shader& shader, void render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix); const openglframework::Matrix4& worldToCameraMatrix);
/// Set the position of the box
void resetTransform(const rp3d::Transform& transform);
}; };
// Return a pointer to the collision body of the box // Return a pointer to the collision body of the box

View File

@ -306,3 +306,21 @@ void ConvexMesh::createVBOAndVAO(openglframework::Shader& shader) {
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
} }
// Reset the transform
void ConvexMesh::resetTransform(const rp3d::Transform& transform) {
// Reset the transform
mRigidBody->setTransform(transform);
mRigidBody->setIsSleeping(false);
// Reset the velocity of the rigid body
rp3d::RigidBody* rigidBody = dynamic_cast<rp3d::RigidBody*>(mRigidBody);
if (rigidBody != NULL) {
rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0));
rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0));
}
updateTransform(1.0f);
}

View File

@ -94,6 +94,9 @@ class ConvexMesh : public openglframework::Mesh {
/// 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); const openglframework::Matrix4& worldToCameraMatrix);
/// Set the position of the box
void resetTransform(const rp3d::Transform& transform);
}; };
// Return a pointer to the collision body of the box // Return a pointer to the collision body of the box

View File

@ -26,14 +26,19 @@
// Libraries // Libraries
#include "Cylinder.h" #include "Cylinder.h"
openglframework::VertexBufferObject Cylinder::mVBOVertices(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Cylinder::mVBONormals(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Cylinder::mVBOTextureCoords(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Cylinder::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
openglframework::VertexArrayObject Cylinder::mVAO;
int Cylinder::totalNbCylinders = 0;
// Constructor // Constructor
Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position, Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position,
reactphysics3d::CollisionWorld* world, reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath, const std::string& meshFolderPath,
openglframework::Shader& shader) openglframework::Shader& shader)
: openglframework::Mesh(), mRadius(radius), mHeight(height), : openglframework::Mesh(), mRadius(radius), mHeight(height),
mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER),
mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER),
mColor(0.5f, 0.5f, 0.5f, 1.0f) { mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
@ -72,7 +77,11 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(shader); if (totalNbCylinders == 0) {
createVBOAndVAO(shader);
}
totalNbCylinders++;
} }
// Constructor // Constructor
@ -80,8 +89,6 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshFolderPath, openglframework::Shader& shader) const std::string& meshFolderPath, openglframework::Shader& shader)
: openglframework::Mesh(), mRadius(radius), mHeight(height), : openglframework::Mesh(), mRadius(radius), mHeight(height),
mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER),
mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER),
mColor(0.5f, 0.5f, 0.5f, 1.0f) { mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
@ -120,21 +127,30 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
mRigidBody = body; mRigidBody = body;
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(shader); if (totalNbCylinders == 0) {
createVBOAndVAO(shader);
}
totalNbCylinders++;
} }
// Destructor // Destructor
Cylinder::~Cylinder() { Cylinder::~Cylinder() {
// Destroy the mesh if (totalNbCylinders == 1) {
destroy();
// Destroy the VBOs and VAO // Destroy the mesh
mVBOIndices.destroy(); destroy();
mVBOVertices.destroy();
mVBONormals.destroy(); // Destroy the VBOs and VAO
mVBOTextureCoords.destroy(); mVBOIndices.destroy();
mVAO.destroy(); mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
}
totalNbCylinders--;
} }
// Render the cylinder at the correct position and with the correct orientation // Render the cylinder at the correct position and with the correct orientation
@ -269,3 +285,21 @@ void Cylinder::createVBOAndVAO(openglframework::Shader& shader) {
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
} }
// Reset the transform
void Cylinder::resetTransform(const rp3d::Transform& transform) {
// Reset the transform
mRigidBody->setTransform(transform);
mRigidBody->setIsSleeping(false);
// Reset the velocity of the rigid body
rp3d::RigidBody* rigidBody = dynamic_cast<rp3d::RigidBody*>(mRigidBody);
if (rigidBody != NULL) {
rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0));
rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0));
}
updateTransform(1.0f);
}

View File

@ -53,19 +53,22 @@ class Cylinder : public openglframework::Mesh {
rp3d::Transform mPreviousTransform; rp3d::Transform mPreviousTransform;
/// Vertex Buffer Object for the vertices data /// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices; static openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data /// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals; static openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords /// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords; static openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices /// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices; static openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data /// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO; static openglframework::VertexArrayObject mVAO;
// Total number of capsules created
static int totalNbCylinders;
/// Color /// Color
openglframework::Color mColor; openglframework::Color mColor;
@ -104,6 +107,9 @@ class Cylinder : public openglframework::Mesh {
/// Render the cylinder at the correct position and with the correct orientation /// Render the cylinder at the correct position and with the correct orientation
void render(openglframework::Shader& shader, void render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix); const openglframework::Matrix4& worldToCameraMatrix);
/// Set the position of the box
void resetTransform(const rp3d::Transform& transform);
}; };
// Return a pointer to the collision body of the box // Return a pointer to the collision body of the box

View File

@ -26,13 +26,18 @@
// Libraries // Libraries
#include "Dumbbell.h" #include "Dumbbell.h"
openglframework::VertexBufferObject Dumbbell::mVBOVertices(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Dumbbell::mVBONormals(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Dumbbell::mVBOTextureCoords(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Dumbbell::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
openglframework::VertexArrayObject Dumbbell::mVAO;
int Dumbbell::totalNbDumbbells = 0;
// Constructor // Constructor
Dumbbell::Dumbbell(const openglframework::Vector3 &position, Dumbbell::Dumbbell(const openglframework::Vector3 &position,
reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath, reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath,
openglframework::Shader& shader) openglframework::Shader& shader)
: openglframework::Mesh(),mVBOVertices(GL_ARRAY_BUFFER), : openglframework::Mesh(), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this);
@ -91,16 +96,18 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(shader); if (totalNbDumbbells == 0) {
createVBOAndVAO(shader);
}
totalNbDumbbells++;
} }
// Constructor // Constructor
Dumbbell::Dumbbell(const openglframework::Vector3 &position, Dumbbell::Dumbbell(const openglframework::Vector3 &position,
reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath, reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath,
openglframework::Shader& shader) openglframework::Shader& shader)
: openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER), : openglframework::Mesh(), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this);
@ -155,21 +162,30 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(shader); if (totalNbDumbbells == 0) {
createVBOAndVAO(shader);
}
totalNbDumbbells++;
} }
// Destructor // Destructor
Dumbbell::~Dumbbell() { Dumbbell::~Dumbbell() {
// Destroy the mesh if (totalNbDumbbells == 1) {
destroy();
// Destroy the VBOs and VAO // Destroy the mesh
mVBOIndices.destroy(); destroy();
mVBOVertices.destroy();
mVBONormals.destroy(); // Destroy the VBOs and VAO
mVBOTextureCoords.destroy(); mVBOIndices.destroy();
mVAO.destroy(); mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
}
totalNbDumbbells--;
} }
// Render the sphere at the correct position and with the correct orientation // Render the sphere at the correct position and with the correct orientation
@ -304,3 +320,21 @@ void Dumbbell::createVBOAndVAO(openglframework::Shader& shader) {
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
} }
// Reset the transform
void Dumbbell::resetTransform(const rp3d::Transform& transform) {
// Reset the transform
mBody->setTransform(transform);
mBody->setIsSleeping(false);
// Reset the velocity of the rigid body
rp3d::RigidBody* rigidBody = dynamic_cast<rp3d::RigidBody*>(mBody);
if (rigidBody != NULL) {
rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0));
rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0));
}
updateTransform(1.0f);
}

View File

@ -50,19 +50,22 @@ class Dumbbell : public openglframework::Mesh {
rp3d::Transform mPreviousTransform; rp3d::Transform mPreviousTransform;
/// Vertex Buffer Object for the vertices data /// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices; static openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data /// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals; static openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords /// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords; static openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices /// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices; static openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data /// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO; static openglframework::VertexArrayObject mVAO;
// Total number of capsules created
static int totalNbDumbbells;
/// Color /// Color
openglframework::Color mColor; openglframework::Color mColor;
@ -100,6 +103,9 @@ class Dumbbell : public openglframework::Mesh {
/// 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 render(openglframework::Shader& shader, void render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix); const openglframework::Matrix4& worldToCameraMatrix);
/// Set the position of the box
void resetTransform(const rp3d::Transform& transform);
}; };
// Return a pointer to the rigid body of the sphere // Return a pointer to the rigid body of the sphere

View File

@ -49,6 +49,10 @@ void Line::render(openglframework::Shader& shader,
// Set the model to camera matrix // Set the model to camera matrix
shader.setMatrix4x4Uniform("localToCameraMatrix", worldToCameraMatrix); shader.setMatrix4x4Uniform("localToCameraMatrix", worldToCameraMatrix);
// Set the vertex color
openglframework::Vector4 color(1, 0, 0, 1);
shader.setVector4Uniform("vertexColor", color);
glBegin(GL_LINES); glBegin(GL_LINES);
glVertex3f(mWorldPoint1.x, mWorldPoint1.y, mWorldPoint1.z); glVertex3f(mWorldPoint1.x, mWorldPoint1.y, mWorldPoint1.z);
glVertex3f(mWorldPoint2.x, mWorldPoint2.y, mWorldPoint2.z); glVertex3f(mWorldPoint2.x, mWorldPoint2.y, mWorldPoint2.z);

View File

@ -26,13 +26,18 @@
// Libraries // Libraries
#include "Sphere.h" #include "Sphere.h"
openglframework::VertexBufferObject Sphere::mVBOVertices(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Sphere::mVBONormals(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Sphere::mVBOTextureCoords(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Sphere::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
openglframework::VertexArrayObject Sphere::mVAO;
int Sphere::totalNbSpheres = 0;
// Constructor // Constructor
Sphere::Sphere(float radius, const openglframework::Vector3 &position, Sphere::Sphere(float radius, const openglframework::Vector3 &position,
reactphysics3d::CollisionWorld* world, reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath, openglframework::Shader& shader) const std::string& meshFolderPath, openglframework::Shader& shader)
: openglframework::Mesh(), mRadius(radius), mVBOVertices(GL_ARRAY_BUFFER), : openglframework::Mesh(), mRadius(radius), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this);
@ -70,16 +75,18 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(shader); if (totalNbSpheres == 0) {
createVBOAndVAO(shader);
}
totalNbSpheres++;
} }
// Constructor // Constructor
Sphere::Sphere(float radius, const openglframework::Vector3 &position, Sphere::Sphere(float radius, const openglframework::Vector3 &position,
float mass, reactphysics3d::DynamicsWorld* world, float mass, reactphysics3d::DynamicsWorld* world,
const std::string& meshFolderPath, openglframework::Shader& shader) const std::string& meshFolderPath, openglframework::Shader& shader)
: openglframework::Mesh(), mRadius(radius), mVBOVertices(GL_ARRAY_BUFFER), : openglframework::Mesh(), mRadius(radius), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this);
@ -117,21 +124,29 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(shader); if (totalNbSpheres == 0) {
createVBOAndVAO(shader);
}
totalNbSpheres++;
} }
// Destructor // Destructor
Sphere::~Sphere() { Sphere::~Sphere() {
// Destroy the mesh if (totalNbSpheres == 1) {
destroy(); // Destroy the mesh
destroy();
// Destroy the VBOs and VAO // Destroy the VBOs and VAO
mVBOIndices.destroy(); mVBOIndices.destroy();
mVBOVertices.destroy(); mVBOVertices.destroy();
mVBONormals.destroy(); mVBONormals.destroy();
mVBOTextureCoords.destroy(); mVBOTextureCoords.destroy();
mVAO.destroy(); mVAO.destroy();
}
totalNbSpheres--;
} }
// Render the sphere at the correct position and with the correct orientation // Render the sphere at the correct position and with the correct orientation
@ -266,3 +281,21 @@ void Sphere::createVBOAndVAO(openglframework::Shader& shader) {
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
} }
// Reset the transform
void Sphere::resetTransform(const rp3d::Transform& transform) {
// Reset the transform
mRigidBody->setTransform(transform);
mRigidBody->setIsSleeping(false);
// Reset the velocity of the rigid body
rp3d::RigidBody* rigidBody = dynamic_cast<rp3d::RigidBody*>(mRigidBody);
if (rigidBody != NULL) {
rigidBody->setLinearVelocity(rp3d::Vector3(0, 0, 0));
rigidBody->setAngularVelocity(rp3d::Vector3(0, 0, 0));
}
updateTransform(1.0f);
}

View File

@ -50,19 +50,22 @@ class Sphere : public openglframework::Mesh {
rp3d::Transform mPreviousTransform; rp3d::Transform mPreviousTransform;
/// Vertex Buffer Object for the vertices data /// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices; static openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data /// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals; static openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords /// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords; static openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices /// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices; static openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data /// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO; static openglframework::VertexArrayObject mVAO;
// Total number of capsules created
static int totalNbSpheres;
/// Color /// Color
openglframework::Color mColor; openglframework::Color mColor;
@ -101,6 +104,9 @@ class Sphere : public openglframework::Mesh {
/// 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 render(openglframework::Shader& shader, void render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix); const openglframework::Matrix4& worldToCameraMatrix);
/// Set the position of the box
void resetTransform(const rp3d::Transform& transform);
}; };
// Return a pointer to the collision body of the box // Return a pointer to the collision body of the box

View File

@ -27,46 +27,65 @@
#include "VisualContactPoint.h" #include "VisualContactPoint.h"
// Initialization of static variables // Initialization of static variables
openglframework::VertexBufferObject VisualContactPoint::mVBOVertices(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject VisualContactPoint::mVBONormals(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject VisualContactPoint::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
openglframework::VertexArrayObject VisualContactPoint::mVAO;
int VisualContactPoint::mNbTotalPoints = 0; int VisualContactPoint::mNbTotalPoints = 0;
bool VisualContactPoint::mIsMeshInitialized = false;
openglframework::Mesh VisualContactPoint::mMesh; openglframework::Mesh VisualContactPoint::mMesh;
int VisualContactPoint::totalNbBoxes = 0;
// Constructor // Constructor
VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position) { VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position,
openglframework::Shader& shader,
const std::string& meshFolderPath)
: mColor(1.0f, 0.0f, 0.0f, 1.0f) {
assert(mIsMeshInitialized); // Initialize the position where the mesh will be rendered
// Initialize the position where the sphere will be rendered
translateWorld(position); translateWorld(position);
// Create the VBOs and VAO
if (totalNbBoxes == 0) {
createStaticData(meshFolderPath);
createVBOAndVAO(shader);
}
totalNbBoxes++;
} }
// Destructor // Destructor
VisualContactPoint::~VisualContactPoint() { VisualContactPoint::~VisualContactPoint() {
if (totalNbBoxes == 1) {
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVAO.destroy();
destroyStaticData();
}
totalNbBoxes--;
} }
// Load and initialize the mesh for all the contact points // Load and initialize the mesh for all the contact points
void VisualContactPoint::createStaticData(const std::string& meshFolderPath) { void VisualContactPoint::createStaticData(const std::string& meshFolderPath) {
if (!mIsMeshInitialized) { // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", mMesh);
// Load the mesh from a file // Calculate the normals of the mesh
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", mMesh); mMesh.calculateNormals();
// Calculate the normals of the mesh mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS);
mMesh.calculateNormals();
mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS);
mIsMeshInitialized = true;
}
} }
// Destroy the mesh for the contact points // Destroy the mesh for the contact points
void VisualContactPoint::destroyStaticData() { void VisualContactPoint::destroyStaticData() {
mMesh.destroy(); mMesh.destroy();
mIsMeshInitialized = false;
} }
// Render the sphere at the correct position and with the correct orientation // Render the sphere at the correct position and with the correct orientation
@ -86,29 +105,77 @@ void VisualContactPoint::render(openglframework::Shader& shader,
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
glEnableClientState(GL_VERTEX_ARRAY); // Set the vertex color
glEnableClientState(GL_NORMAL_ARRAY); openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
if (mMesh.hasTexture()) { shader.setVector4Uniform("vertexColor", color);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
glVertexPointer(3, GL_FLOAT, 0, mMesh.getVerticesPointer()); // Bind the VAO
glNormalPointer(GL_FLOAT, 0, mMesh.getNormalsPointer()); mVAO.bind();
if(mMesh.hasTexture()) {
glTexCoordPointer(2, GL_FLOAT, 0, mMesh.getUVTextureCoordinatesPointer());
}
// For each part of the mesh // For each part of the mesh
for (unsigned int i=0; i<mMesh.getNbParts(); i++) { for (unsigned int i=0; i<mMesh.getNbParts(); i++) {
glDrawElements(GL_TRIANGLES, mMesh.getNbFaces(i) * 3, glDrawElements(GL_TRIANGLES, mMesh.getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
GL_UNSIGNED_INT, mMesh.getIndicesPointer());
} }
glDisableClientState(GL_NORMAL_ARRAY); // Unbind the VAO
glDisableClientState(GL_VERTEX_ARRAY); mVAO.unbind();
if (mMesh.hasTexture()) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Unbind the shader
} shader.unbind();
}
// Create the Vertex Buffer Objects used to render with OpenGL.
/// We create two VBOs (one for vertices and one for indices)
void VisualContactPoint::createVBOAndVAO(openglframework::Shader& shader) {
// Bind the shader
shader.bind();
// Get the location of shader attribute variables
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal");
GLint vertexTexCoordLoc = shader.getAttribLocation("textureCoords");
// Create the VBO for the vertices data
mVBOVertices.create();
mVBOVertices.bind();
size_t sizeVertices = mMesh.getVertices().size() * sizeof(openglframework::Vector3);
mVBOVertices.copyDataIntoVBO(sizeVertices, mMesh.getVerticesPointer(), GL_STATIC_DRAW);
mVBOVertices.unbind();
// Create the VBO for the normals data
mVBONormals.create();
mVBONormals.bind();
size_t sizeNormals = mMesh.getNormals().size() * sizeof(openglframework::Vector3);
mVBONormals.copyDataIntoVBO(sizeNormals, mMesh.getNormalsPointer(), GL_STATIC_DRAW);
mVBONormals.unbind();
// Create th VBO for the indices data
mVBOIndices.create();
mVBOIndices.bind();
size_t sizeIndices = mMesh.getIndices(0).size() * sizeof(uint);
mVBOIndices.copyDataIntoVBO(sizeIndices, mMesh.getIndicesPointer(), GL_STATIC_DRAW);
mVBOIndices.unbind();
// Create the VAO for both VBOs
mVAO.create();
mVAO.bind();
// Bind the VBO of vertices
mVBOVertices.bind();
glEnableVertexAttribArray(vertexPositionLoc);
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
// Bind the VBO of normals
mVBONormals.bind();
glEnableVertexAttribArray(vertexNormalLoc);
glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
// Bind the VBO of indices
mVBOIndices.bind();
// Unbind the VAO
mVAO.unbind();
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();

View File

@ -44,8 +44,26 @@ class VisualContactPoint : public openglframework::Object3D {
/// Sphere mesh for the visual contact point /// Sphere mesh for the visual contact point
static openglframework::Mesh mMesh; static openglframework::Mesh mMesh;
/// True if the mesh has been initialized /// Vertex Buffer Object for the vertices data
static bool mIsMeshInitialized; 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;
/// Total number of points created
static int totalNbBoxes;
/// Color
openglframework::Color mColor;
// Create the Vertex Buffer Objects used to render with OpenGL.
static void createVBOAndVAO(openglframework::Shader& shader);
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
@ -54,7 +72,9 @@ class VisualContactPoint : public openglframework::Object3D {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
VisualContactPoint(const openglframework::Vector3& position); VisualContactPoint(const openglframework::Vector3& position,
openglframework::Shader &shader,
const std::string &meshFolderPath);
/// Destructor /// Destructor
~VisualContactPoint(); ~VisualContactPoint();

View File

@ -58,9 +58,6 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
// Set the number of iterations of the constraint solver // Set the number of iterations of the constraint solver
mDynamicsWorld->setNbIterationsVelocitySolver(15); mDynamicsWorld->setNbIterationsVelocitySolver(15);
// Create the static data for the visual contact points
VisualContactPoint::createStaticData(meshFolderPath);
float radius = 3.0f; float radius = 3.0f;
for (int i=0; i<NB_COMPOUND_SHAPES; i++) { for (int i=0; i<NB_COMPOUND_SHAPES; i++) {
@ -443,4 +440,130 @@ void CollisionShapesScene::render() {
/// Reset the scene /// Reset the scene
void CollisionShapesScene::reset() { void CollisionShapesScene::reset() {
float radius = 3.0f;
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));
// 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);
// Reset the transform
mDumbbells[i]->resetTransform(transform);
}
// Create all the boxes of the scene
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));
// 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);
// Reset the transform
mBoxes[i]->resetTransform(transform);
}
// Create all the spheres of the scene
for (int i=0; i<NB_CUBES; i++) {
// Position
float angle = i * 35.0f;
openglframework::Vector3 position(radius * cos(angle),
50 + i * (SPHERE_RADIUS + 0.8f),
radius * sin(angle));
// 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);
// Reset the transform
mSpheres[i]->resetTransform(transform);
}
// Create all the cones of the scene
for (int i=0; i<NB_CONES; i++) {
// Position
float angle = i * 50.0f;
openglframework::Vector3 position(radius * cos(angle),
35 + i * (CONE_HEIGHT + 0.3f),
radius * sin(angle));
// 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);
// Reset the transform
mCones[i]->resetTransform(transform);
}
// Create all the cylinders of the scene
for (int i=0; i<NB_CYLINDERS; i++) {
// Position
float angle = i * 35.0f;
openglframework::Vector3 position(radius * cos(angle),
25 + i * (CYLINDER_HEIGHT + 0.3f),
radius * sin(angle));
// 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);
// Reset the transform
mCylinders[i]->resetTransform(transform);
}
// Create all the capsules of the scene
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));
// 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);
// Reset the transform
mCapsules[i]->resetTransform(transform);
}
// Create all the convex meshes of the scene
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));
// 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);
// Reset the transform
mConvexMeshes[i]->resetTransform(transform);
}
} }

View File

@ -65,7 +65,7 @@ CubesScene::CubesScene(const std::string& name)
// Position of the cubes // Position of the cubes
float angle = i * 30.0f; float angle = i * 30.0f;
openglframework::Vector3 position(radius * cos(angle), openglframework::Vector3 position(radius * cos(angle),
10 + i * (BOX_SIZE.y + 0.3f), 30 + i * (BOX_SIZE.y + 0.3f),
0); 0);
// Create a cube and a corresponding rigid in the dynamics world // Create a cube and a corresponding rigid in the dynamics world
@ -150,8 +150,6 @@ void CubesScene::update() {
// Render the scene // Render the scene
void CubesScene::render() { void CubesScene::render() {
checkOpenGLErrors();
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
@ -172,49 +170,36 @@ void CubesScene::render() {
mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b));
mPhongShader.setFloatUniform("shininess", 60.0f); mPhongShader.setFloatUniform("shininess", 60.0f);
checkOpenGLErrors();
// Render all the cubes of the scene // Render all the cubes of the scene
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
(*it)->render(mPhongShader, worldToCameraMatrix); (*it)->render(mPhongShader, worldToCameraMatrix);
} }
checkOpenGLErrors();
// Render the floor // Render the floor
mFloor->render(mPhongShader, worldToCameraMatrix); mFloor->render(mPhongShader, worldToCameraMatrix);
// Unbind the shader // Unbind the shader
mPhongShader.unbind(); mPhongShader.unbind();
checkOpenGLErrors();
} }
// Reset the scene // Reset the scene
void CubesScene::reset() { void CubesScene::reset() {
} float radius = 2.0f;
// Check the OpenGL errors for (int i=0; i<NB_CUBES; i++) {
void CubesScene::checkOpenGLErrors() {
GLenum glError;
// Get the OpenGL errors // Position of the cubes
glError = glGetError(); float angle = i * 30.0f;
openglframework::Vector3 position(radius * cos(angle),
10 + i * (BOX_SIZE.y + 0.3f),
0);
// While there are errors // Initial position and orientation of the rigid body
while (glError != GL_NO_ERROR) { rp3d::Vector3 initPosition(position.x, position.y, position.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
// Get the error string mBoxes[i]->resetTransform(transform);
const GLubyte* stringError = gluErrorString(glError);
// Display the error
if (stringError)
std::cerr << "OpenGL Error #" << glError << "(" << gluErrorString(glError) << ")" << std::endl;
else
std::cerr << "OpenGL Error #" << glError << " (no message available)" << std::endl;
// Get the next error
glError = glGetError();
} }
} }

View File

@ -35,7 +35,7 @@
namespace cubesscene { namespace cubesscene {
// Constants // Constants
const int NB_CUBES = 200; // Number of boxes in the scene const int NB_CUBES = 20; // 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(50, 0.5f, 50); // Floor dimensions in meters const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 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
@ -85,9 +85,6 @@ class CubesScene : public Scene {
/// Reset the scene /// Reset the scene
virtual void reset(); virtual void reset();
// Check the OpenGL errors
static void checkOpenGLErrors();
}; };
} }

View File

@ -187,6 +187,72 @@ void JointsScene::render() {
// Reset the scene // Reset the scene
void JointsScene::reset() { void JointsScene::reset() {
openglframework::Vector3 positionBox(0, 15, 5);
openglframework::Vector3 boxDimension(1, 1, 1);
for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) {
// Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(positionBox.x, positionBox.y, positionBox.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
// Create a box and a corresponding rigid in the dynamics world
mBallAndSocketJointChainBoxes[i]->resetTransform(transform);
positionBox.y -= boxDimension.y + 0.5f;
}
// --------------- Slider Joint --------------- //
// Position of the box
openglframework::Vector3 positionBox1(0, 2.1f, 0);
rp3d::Vector3 initPosition(positionBox1.x, positionBox1.y, positionBox1.z);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transformBottomBox(initPosition, initOrientation);
// Create a box and a corresponding rigid in the dynamics world
mSliderJointBottomBox->resetTransform(transformBottomBox);
// Position of the box
openglframework::Vector3 positionBox2(0, 4.2f, 0);
initPosition = rp3d::Vector3(positionBox2.x, positionBox2.y, positionBox2.z);
initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transformTopBox(initPosition, initOrientation);
// Create a box and a corresponding rigid in the dynamics world
mSliderJointTopBox->resetTransform(transformTopBox);
// --------------- Propeller Hinge joint --------------- //
// Position of the box
positionBox1 = openglframework::Vector3(0, 7, 0);
initPosition = rp3d::Vector3(positionBox1.x, positionBox1.y, positionBox1.z);
initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transformHingeBox(initPosition, initOrientation);
// Create a box and a corresponding rigid in the dynamics world
mPropellerBox->resetTransform(transformHingeBox);
// --------------- Fixed joint --------------- //
// Position of the box
positionBox1 = openglframework::Vector3(5, 7, 0);
initPosition = rp3d::Vector3(positionBox1.x, positionBox1.y, positionBox1.z);
initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transformFixedBox1(initPosition, initOrientation);
// Create a box and a corresponding rigid in the dynamics world
mFixedJointBox1->resetTransform(transformFixedBox1);
// Position of the box
positionBox2 = openglframework::Vector3(-5, 7, 0);
initPosition = rp3d::Vector3(positionBox2.x, positionBox2.y, positionBox2.z);
initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transformFixedBox2(initPosition, initOrientation);
// Create a box and a corresponding rigid in the dynamics world
mFixedJointBox2->resetTransform(transformFixedBox2);
} }
// Create the boxes and joints for the Ball-and-Socket joint example // Create the boxes and joints for the Ball-and-Socket joint example

View File

@ -33,9 +33,9 @@ using namespace raycastscene;
// Constructor // Constructor
RaycastScene::RaycastScene(const std::string& name) RaycastScene::RaycastScene(const std::string& name)
: Scene(name), mLight0(0), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), : Scene(name), mLight0(0), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false),
mPhongShader("shaders/phong.vert", "shaders/phong.frag") { mPhongShader("shaders/phong.vert", "shaders/phong.frag"),
mMeshFolderPath("meshes/"), mRaycastManager(mPhongShader, mMeshFolderPath),
std::string meshFolderPath("meshes/"); mVBOVertices(GL_ARRAY_BUFFER) {
// Move the light 0 // Move the light 0
mLight0.translateWorld(Vector3(50, 50, 50)); mLight0.translateWorld(Vector3(50, 50, 50));
@ -50,14 +50,11 @@ RaycastScene::RaycastScene(const std::string& name)
// Create the dynamics world for the physics simulation // Create the dynamics world for the physics simulation
mCollisionWorld = new rp3d::CollisionWorld(); mCollisionWorld = new rp3d::CollisionWorld();
// Create the static data for the visual contact points
VisualContactPoint::createStaticData(meshFolderPath);
// ---------- Dumbbell ---------- // // ---------- Dumbbell ---------- //
openglframework::Vector3 position1(0, 0, 0); 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, meshFolderPath, mPhongShader); mDumbbell = new Dumbbell(position1, mCollisionWorld, mMeshFolderPath, mPhongShader);
// ---------- Box ---------- // // ---------- Box ---------- //
openglframework::Vector3 position2(0, 0, 0); openglframework::Vector3 position2(0, 0, 0);
@ -71,38 +68,41 @@ RaycastScene::RaycastScene(const std::string& name)
// 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, position3, mCollisionWorld,
meshFolderPath, mPhongShader); mMeshFolderPath, mPhongShader);
// ---------- Cone ---------- // // ---------- Cone ---------- //
openglframework::Vector3 position4(0, 0, 0); openglframework::Vector3 position4(0, 0, 0);
// Create a cone and a corresponding collision body in the dynamics world // Create a cone and a corresponding collision body in the dynamics world
mCone = new Cone(CONE_RADIUS, CONE_HEIGHT, position4, mCollisionWorld, mCone = new Cone(CONE_RADIUS, CONE_HEIGHT, position4, mCollisionWorld,
meshFolderPath, mPhongShader); mMeshFolderPath, mPhongShader);
// ---------- Cylinder ---------- // // ---------- Cylinder ---------- //
openglframework::Vector3 position5(0, 0, 0); openglframework::Vector3 position5(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
mCylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position5, mCylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position5,
mCollisionWorld, meshFolderPath, mPhongShader); mCollisionWorld, mMeshFolderPath, mPhongShader);
// ---------- Capsule ---------- // // ---------- Capsule ---------- //
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, position6 ,
mCollisionWorld, meshFolderPath, mPhongShader); mCollisionWorld, mMeshFolderPath, mPhongShader);
// ---------- Convex Mesh ---------- // // ---------- Convex Mesh ---------- //
openglframework::Vector3 position7(0, 0, 0); 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, meshFolderPath, mPhongShader); mConvexMesh = new ConvexMesh(position7, mCollisionWorld, mMeshFolderPath, mPhongShader);
// Create the lines that will be used for raycasting // Create the lines that will be used for raycasting
createLines(); createLines();
// Create the VBO and VAO to render the lines
createVBOAndVAO(mPhongShader);
changeBody(); changeBody();
} }
@ -128,6 +128,9 @@ void RaycastScene::createLines() {
openglframework::Vector3 point2(0.0f, 0.0f, 0.0f); openglframework::Vector3 point2(0.0f, 0.0f, 0.0f);
Line* line = new Line(point1, point2); Line* line = new Line(point1, point2);
mLines.push_back(line); mLines.push_back(line);
mLinePoints.push_back(point1);
mLinePoints.push_back(point2);
} }
} }
} }
@ -225,6 +228,10 @@ RaycastScene::~RaycastScene() {
++it) { ++it) {
delete (*it); delete (*it);
} }
// Destroy the VBOs and VAO
mVBOVertices.destroy();
mVAO.destroy();
} }
// Update the physics world (take a simulation step) // Update the physics world (take a simulation step)
@ -264,25 +271,48 @@ void RaycastScene::render() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
// Get the world-space to camera-space matrix
const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse();
// Bind the shader // Bind the shader
mPhongShader.bind(); mPhongShader.bind();
openglframework::Vector4 grey(0.7, 0.7, 0.7, 1); // Get the world-space to camera-space matrix
mPhongShader.setVector4Uniform("vertexColor", grey); const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse();
// Set the variables of the shader // Set the variables of the shader
mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix());
mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin());
mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f));
const Color& diffColLight0 = mLight0.getDiffuseColor(); const Color& diffCol = mLight0.getDiffuseColor();
const Color& specColLight0 = mLight0.getSpecularColor(); const Color& specCol = mLight0.getSpecularColor();
mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffColLight0.r, diffColLight0.g, diffColLight0.b)); mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b));
mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specColLight0.r, specColLight0.g, specColLight0.b)); mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b));
mPhongShader.setFloatUniform("shininess", 200.0f); mPhongShader.setFloatUniform("shininess", 60.0f);
// Set the model to camera matrix
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix;
mPhongShader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
// model-view matrix)
const openglframework::Matrix3 normalMatrix =
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
mPhongShader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
// Set the vertex color
openglframework::Vector4 color(1, 0, 0, 1);
mPhongShader.setVector4Uniform("vertexColor", color);
// Bind the VAO
mVAO.bind();
// Draw the lines
glDrawArrays(GL_LINES, 0, NB_RAYS);
// Unbind the VAO
mVAO.unbind();
mPhongShader.unbind();
// Render the shapes
if (mBox->getCollisionBody()->isActive()) mBox->render(mPhongShader, worldToCameraMatrix); if (mBox->getCollisionBody()->isActive()) mBox->render(mPhongShader, worldToCameraMatrix);
if (mSphere->getCollisionBody()->isActive()) mSphere->render(mPhongShader, worldToCameraMatrix); if (mSphere->getCollisionBody()->isActive()) mSphere->render(mPhongShader, worldToCameraMatrix);
if (mCone->getCollisionBody()->isActive()) mCone->render(mPhongShader, worldToCameraMatrix); if (mCone->getCollisionBody()->isActive()) mCone->render(mPhongShader, worldToCameraMatrix);
@ -291,7 +321,7 @@ void RaycastScene::render() {
if (mConvexMesh->getCollisionBody()->isActive()) mConvexMesh->render(mPhongShader, worldToCameraMatrix); if (mConvexMesh->getCollisionBody()->isActive()) mConvexMesh->render(mPhongShader, worldToCameraMatrix);
if (mDumbbell->getCollisionBody()->isActive()) mDumbbell->render(mPhongShader, worldToCameraMatrix); if (mDumbbell->getCollisionBody()->isActive()) mDumbbell->render(mPhongShader, worldToCameraMatrix);
mPhongShader.unbind(); //mPhongShader.unbind();
mPhongShader.bind(); mPhongShader.bind();
mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(0, 0, 0)); mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(0, 0, 0));
@ -299,7 +329,7 @@ void RaycastScene::render() {
mPhongShader.setVector4Uniform("vertexColor", redColor); mPhongShader.setVector4Uniform("vertexColor", redColor);
// Render all the raycast hit points // Render all the raycast hit points
mRaycastManager.render(mPhongShader, worldToCameraMatrix, mAreNormalsDisplayed); mRaycastManager.render(worldToCameraMatrix, mAreNormalsDisplayed);
mPhongShader.unbind(); mPhongShader.unbind();
mPhongShader.bind(); mPhongShader.bind();
@ -316,3 +346,45 @@ void RaycastScene::render() {
// Unbind the shader // Unbind the shader
mPhongShader.unbind(); mPhongShader.unbind();
} }
// Create the Vertex Buffer Objects used to render with OpenGL.
/// We create two VBOs (one for vertices and one for indices)
void RaycastScene::createVBOAndVAO(openglframework::Shader& shader) {
// Bind the shader
shader.bind();
// Get the location of shader attribute variables
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
// Create the VBO for the vertices data
mVBOVertices.create();
mVBOVertices.bind();
size_t sizeVertices = mLinePoints.size() * sizeof(openglframework::Vector3);
mVBOVertices.copyDataIntoVBO(sizeVertices, &mLinePoints[0], GL_STATIC_DRAW);
mVBOVertices.unbind();
// Create the VAO for both VBOs
mVAO.create();
mVAO.bind();
// Bind the VBO of vertices
mVBOVertices.bind();
glEnableVertexAttribArray(vertexPositionLoc);
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
// Unbind the VAO
mVAO.unbind();
// Unbind the shader
shader.unbind();
}
// Called when a keyboard event occurs
void RaycastScene::keyboardEvent(int key, int scancode, int action, int mods) {
// If the space key has been pressed
if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) {
changeBody();
}
}

View File

@ -70,12 +70,24 @@ class RaycastManager : public rp3d::RaycastCallback {
/// All the normals at hit points /// All the normals at hit points
std::vector<Line*> mNormals; std::vector<Line*> mNormals;
/// Shader
openglframework::Shader& mShader;
/// Contact point mesh folder path
std::string mMeshFolderPath;
public: public:
RaycastManager(openglframework::Shader& shader,
const std::string& meshFolderPath)
: mShader(shader), mMeshFolderPath(meshFolderPath) {
}
virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) { virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) {
rp3d::Vector3 hitPos = raycastInfo.worldPoint; rp3d::Vector3 hitPos = raycastInfo.worldPoint;
openglframework::Vector3 position(hitPos.x, hitPos.y, hitPos.z); openglframework::Vector3 position(hitPos.x, hitPos.y, hitPos.z);
VisualContactPoint* point = new VisualContactPoint(position); VisualContactPoint* point = new VisualContactPoint(position, mShader, mMeshFolderPath);
mHitPoints.push_back(point); mHitPoints.push_back(point);
// Create a line to display the normal at hit point // Create a line to display the normal at hit point
@ -87,14 +99,13 @@ class RaycastManager : public rp3d::RaycastCallback {
return raycastInfo.hitFraction; return raycastInfo.hitFraction;
} }
void render(openglframework::Shader& shader, void render(const openglframework::Matrix4& worldToCameraMatrix,
const openglframework::Matrix4& worldToCameraMatrix,
bool showNormals) { bool showNormals) {
// Render all the raycast hit points // Render all the raycast hit points
for (std::vector<VisualContactPoint*>::iterator it = mHitPoints.begin(); for (std::vector<VisualContactPoint*>::iterator it = mHitPoints.begin();
it != mHitPoints.end(); ++it) { it != mHitPoints.end(); ++it) {
(*it)->render(shader, worldToCameraMatrix); (*it)->render(mShader, worldToCameraMatrix);
} }
if (showNormals) { if (showNormals) {
@ -102,7 +113,7 @@ class RaycastManager : public rp3d::RaycastCallback {
// Render all the normals at hit points // Render all the normals at hit points
for (std::vector<Line*>::iterator it = mNormals.begin(); for (std::vector<Line*>::iterator it = mNormals.begin();
it != mNormals.end(); ++it) { it != mNormals.end(); ++it) {
(*it)->render(shader, worldToCameraMatrix); (*it)->render(mShader, worldToCameraMatrix);
} }
} }
} }
@ -132,15 +143,18 @@ class RaycastScene : public Scene {
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
/// Raycast manager
RaycastManager mRaycastManager;
/// Light 0 /// Light 0
openglframework::Light mLight0; openglframework::Light mLight0;
/// Phong shader /// Phong shader
openglframework::Shader mPhongShader; openglframework::Shader mPhongShader;
/// Contact point mesh folder path
std::string mMeshFolderPath;
/// Raycast manager
RaycastManager mRaycastManager;
/// All the raycast lines /// All the raycast lines
std::vector<Line*> mLines; std::vector<Line*> mLines;
@ -164,9 +178,22 @@ class RaycastScene : public Scene {
/// Collision world used for the physics simulation /// Collision world used for the physics simulation
rp3d::CollisionWorld* mCollisionWorld; rp3d::CollisionWorld* mCollisionWorld;
/// All the points to render the lines
std::vector<openglframework::Vector3> mLinePoints;
/// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices;
/// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO;
/// Create the raycast lines /// Create the raycast lines
void createLines(); void createLines();
// Create the Vertex Buffer Objects used to render with OpenGL.
void createVBOAndVAO(openglframework::Shader& shader);
public: public:
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
@ -195,6 +222,9 @@ class RaycastScene : public Scene {
/// Display or not the surface normals at hit points /// Display or not the surface normals at hit points
void showHideNormals(); void showHideNormals();
/// Called when a keyboard event occurs
virtual void keyboardEvent(int key, int scancode, int action, int mods);
}; };
// Display or not the surface normals at hit points // Display or not the surface normals at hit points

View File

@ -162,7 +162,7 @@ void TestbedApplication::createScenes() {
mScenes.push_back(raycastScene); mScenes.push_back(raycastScene);
assert(mScenes.size() > 0); assert(mScenes.size() > 0);
mCurrentScene = mScenes[1]; mCurrentScene = mScenes[0];
} }
// Remove all the scenes // Remove all the scenes