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::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
openglframework::VertexArrayObject Box::mVAO;
bool Box::areVBOsCreated = false;
int Box::totalNbBoxes = 0;
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)},
@ -95,12 +95,14 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
// If the Vertex Buffer object has not been created yet
if (!areVBOsCreated) {
if (totalNbBoxes == 0) {
// Create the Vertex Buffer
createVBOAndVAO(shader);
}
totalNbBoxes++;
mTransformMatrix = mTransformMatrix * mScalingMatrix;
}
@ -142,26 +144,29 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
mRigidBody = body;
// If the Vertex Buffer object has not been created yet
if (!areVBOsCreated) {
if (totalNbBoxes == 0) {
// Create the Vertex Buffer
createVBOAndVAO(shader);
}
totalNbBoxes++;
mTransformMatrix = mTransformMatrix * mScalingMatrix;
}
// Destructor
Box::~Box() {
if (areVBOsCreated) {
if (totalNbBoxes == 1) {
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVAO.destroy();
areVBOsCreated = false;
}
totalNbBoxes--;
}
// 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.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW);
mVBOVertices.unbind();
size_t test = sizeof(mCubeVertices);
// Create th VBO for the indices data
mVBOIndices.create();
@ -268,6 +272,22 @@ void Box::createVBOAndVAO(openglframework::Shader& shader) {
// Unbind the shader
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)
static GLuint mCubeIndices[36];
/// True if the VBOs have already been created
static bool areVBOsCreated;
/// Total number of boxes created
static int totalNbBoxes;
/// Main color of the box
openglframework::Color mColor;
@ -117,6 +117,9 @@ class Box : public openglframework::Object3D {
/// Set the color of the box
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

View File

@ -26,13 +26,18 @@
// Libraries
#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
Capsule::Capsule(float radius, float height, const openglframework::Vector3& position,
reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath, openglframework::Shader& shader)
: 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) {
: openglframework::Mesh(), mRadius(radius), mHeight(height) {
// Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this);
@ -70,7 +75,11 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
if (totalNbCapsules == 0) {
createVBOAndVAO(shader);
}
totalNbCapsules++;
}
// Constructor
@ -78,8 +87,6 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshFolderPath, openglframework::Shader &shader)
: 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) {
// Load the mesh from a file
@ -118,21 +125,30 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
if (totalNbCapsules == 0) {
createVBOAndVAO(shader);
}
totalNbCapsules++;
}
// Destructor
Capsule::~Capsule() {
// Destroy the mesh
destroy();
if (totalNbCapsules == 1) {
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
// Destroy the mesh
destroy();
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
}
totalNbCapsules--;
}
// 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
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;
/// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices;
static openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals;
static openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords;
static openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices;
static openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO;
static openglframework::VertexArrayObject mVAO;
// Total number of capsules created
static int totalNbCapsules;
/// Color
openglframework::Color mColor;
@ -104,6 +107,9 @@ class Capsule : public openglframework::Mesh {
/// Render the sphere at the correct position and with the correct orientation
void render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix);
/// Set the position of the box
void resetTransform(const rp3d::Transform& transform);
};
// Return a pointer to the collision body of the box

View File

@ -26,13 +26,18 @@
// Libraries
#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
Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath, openglframework::Shader& shader)
: 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) {
// Load the mesh from a file
@ -71,7 +76,11 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
if (totalNbCones == 0) {
createVBOAndVAO(shader);
}
totalNbCones++;
}
// Constructor
@ -79,8 +88,6 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshFolderPath, openglframework::Shader &shader)
: 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) {
// Load the mesh from a file
@ -119,21 +126,29 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
if (totalNbCones == 0) {
createVBOAndVAO(shader);
}
totalNbCones++;
}
// Destructor
Cone::~Cone() {
// Destroy the mesh
destroy();
if (totalNbCones == 1) {
// Destroy the mesh
destroy();
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
}
totalNbCones--;
}
// Render the cone at the correct position and with the correct orientation
@ -270,3 +285,21 @@ void Cone::createVBOAndVAO(openglframework::Shader& shader) {
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;
/// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices;
static openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals;
static openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords;
static openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices;
static openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO;
static openglframework::VertexArrayObject mVAO;
// Total number of cones created
static int totalNbCones;
/// Color
openglframework::Color mColor;
@ -103,6 +106,9 @@ class Cone : public openglframework::Mesh {
/// Render the cone at the correct position and with the correct orientation
void render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix);
/// Set the position of the box
void resetTransform(const rp3d::Transform& transform);
};
// 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
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
void render(openglframework::Shader& shader,
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

View File

@ -26,14 +26,19 @@
// Libraries
#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
Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position,
reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath,
openglframework::Shader& shader)
: 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) {
// Load the mesh from a file
@ -72,7 +77,11 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
if (totalNbCylinders == 0) {
createVBOAndVAO(shader);
}
totalNbCylinders++;
}
// Constructor
@ -80,8 +89,6 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshFolderPath, openglframework::Shader& shader)
: 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) {
// Load the mesh from a file
@ -120,21 +127,30 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
mRigidBody = body;
// Create the VBOs and VAO
createVBOAndVAO(shader);
if (totalNbCylinders == 0) {
createVBOAndVAO(shader);
}
totalNbCylinders++;
}
// Destructor
Cylinder::~Cylinder() {
// Destroy the mesh
destroy();
if (totalNbCylinders == 1) {
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
// Destroy the mesh
destroy();
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
}
totalNbCylinders--;
}
// 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
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;
/// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices;
static openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals;
static openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords;
static openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices;
static openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO;
static openglframework::VertexArrayObject mVAO;
// Total number of capsules created
static int totalNbCylinders;
/// Color
openglframework::Color mColor;
@ -104,6 +107,9 @@ class Cylinder : public openglframework::Mesh {
/// Render the cylinder at the correct position and with the correct orientation
void render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix);
/// Set the position of the box
void resetTransform(const rp3d::Transform& transform);
};
// Return a pointer to the collision body of the box

View File

@ -26,13 +26,18 @@
// Libraries
#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
Dumbbell::Dumbbell(const openglframework::Vector3 &position,
reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath,
openglframework::Shader& shader)
: openglframework::Mesh(),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) {
: openglframework::Mesh(), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this);
@ -91,16 +96,18 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
if (totalNbDumbbells == 0) {
createVBOAndVAO(shader);
}
totalNbDumbbells++;
}
// Constructor
Dumbbell::Dumbbell(const openglframework::Vector3 &position,
reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath,
openglframework::Shader& shader)
: openglframework::Mesh(), 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) {
: openglframework::Mesh(), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this);
@ -155,21 +162,30 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
if (totalNbDumbbells == 0) {
createVBOAndVAO(shader);
}
totalNbDumbbells++;
}
// Destructor
Dumbbell::~Dumbbell() {
// Destroy the mesh
destroy();
if (totalNbDumbbells == 1) {
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
// Destroy the mesh
destroy();
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
}
totalNbDumbbells--;
}
// 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
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;
/// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices;
static openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals;
static openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords;
static openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices;
static openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO;
static openglframework::VertexArrayObject mVAO;
// Total number of capsules created
static int totalNbDumbbells;
/// Color
openglframework::Color mColor;
@ -100,6 +103,9 @@ class Dumbbell : public openglframework::Mesh {
/// Render the sphere at the correct position and with the correct orientation
void render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix);
/// Set the position of the box
void resetTransform(const rp3d::Transform& transform);
};
// 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
shader.setMatrix4x4Uniform("localToCameraMatrix", worldToCameraMatrix);
// Set the vertex color
openglframework::Vector4 color(1, 0, 0, 1);
shader.setVector4Uniform("vertexColor", color);
glBegin(GL_LINES);
glVertex3f(mWorldPoint1.x, mWorldPoint1.y, mWorldPoint1.z);
glVertex3f(mWorldPoint2.x, mWorldPoint2.y, mWorldPoint2.z);

View File

@ -26,13 +26,18 @@
// Libraries
#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
Sphere::Sphere(float radius, const openglframework::Vector3 &position,
reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath, openglframework::Shader& shader)
: openglframework::Mesh(), mRadius(radius), 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) {
: openglframework::Mesh(), mRadius(radius), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this);
@ -70,16 +75,18 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
if (totalNbSpheres == 0) {
createVBOAndVAO(shader);
}
totalNbSpheres++;
}
// Constructor
Sphere::Sphere(float radius, const openglframework::Vector3 &position,
float mass, reactphysics3d::DynamicsWorld* world,
const std::string& meshFolderPath, openglframework::Shader& shader)
: openglframework::Mesh(), mRadius(radius), 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) {
: openglframework::Mesh(), mRadius(radius), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this);
@ -117,21 +124,29 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
if (totalNbSpheres == 0) {
createVBOAndVAO(shader);
}
totalNbSpheres++;
}
// Destructor
Sphere::~Sphere() {
// Destroy the mesh
destroy();
if (totalNbSpheres == 1) {
// Destroy the mesh
destroy();
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
}
totalNbSpheres--;
}
// 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
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;
/// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices;
static openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals;
static openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords;
static openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices;
static openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO;
static openglframework::VertexArrayObject mVAO;
// Total number of capsules created
static int totalNbSpheres;
/// Color
openglframework::Color mColor;
@ -101,6 +104,9 @@ class Sphere : public openglframework::Mesh {
/// Render the sphere at the correct position and with the correct orientation
void render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix);
/// Set the position of the box
void resetTransform(const rp3d::Transform& transform);
};
// Return a pointer to the collision body of the box

View File

@ -27,46 +27,65 @@
#include "VisualContactPoint.h"
// 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;
bool VisualContactPoint::mIsMeshInitialized = false;
openglframework::Mesh VisualContactPoint::mMesh;
int VisualContactPoint::totalNbBoxes = 0;
// 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 sphere will be rendered
// Initialize the position where the mesh will be rendered
translateWorld(position);
// Create the VBOs and VAO
if (totalNbBoxes == 0) {
createStaticData(meshFolderPath);
createVBOAndVAO(shader);
}
totalNbBoxes++;
}
// Destructor
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
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
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", mMesh);
// Calculate the normals of the mesh
mMesh.calculateNormals();
// Calculate the normals of the mesh
mMesh.calculateNormals();
mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS);
mIsMeshInitialized = true;
}
mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS);
}
// Destroy the mesh for the contact points
void VisualContactPoint::destroyStaticData() {
mMesh.destroy();
mIsMeshInitialized = false;
}
// 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();
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
if (mMesh.hasTexture()) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
// Set the vertex color
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
shader.setVector4Uniform("vertexColor", color);
glVertexPointer(3, GL_FLOAT, 0, mMesh.getVerticesPointer());
glNormalPointer(GL_FLOAT, 0, mMesh.getNormalsPointer());
if(mMesh.hasTexture()) {
glTexCoordPointer(2, GL_FLOAT, 0, mMesh.getUVTextureCoordinatesPointer());
}
// Bind the VAO
mVAO.bind();
// For each part of the mesh
for (unsigned int i=0; i<mMesh.getNbParts(); i++) {
glDrawElements(GL_TRIANGLES, mMesh.getNbFaces(i) * 3,
GL_UNSIGNED_INT, mMesh.getIndicesPointer());
glDrawElements(GL_TRIANGLES, mMesh.getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
}
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
if (mMesh.hasTexture()) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
// Unbind the VAO
mVAO.unbind();
// 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
shader.unbind();

View File

@ -44,8 +44,26 @@ class VisualContactPoint : public openglframework::Object3D {
/// Sphere mesh for the visual contact point
static openglframework::Mesh mMesh;
/// True if the mesh has been initialized
static bool mIsMeshInitialized;
/// 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;
/// 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 -------------------- //
@ -54,7 +72,9 @@ class VisualContactPoint : public openglframework::Object3D {
// -------------------- Methods -------------------- //
/// Constructor
VisualContactPoint(const openglframework::Vector3& position);
VisualContactPoint(const openglframework::Vector3& position,
openglframework::Shader &shader,
const std::string &meshFolderPath);
/// Destructor
~VisualContactPoint();

View File

@ -58,9 +58,6 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
// Set the number of iterations of the constraint solver
mDynamicsWorld->setNbIterationsVelocitySolver(15);
// Create the static data for the visual contact points
VisualContactPoint::createStaticData(meshFolderPath);
float radius = 3.0f;
for (int i=0; i<NB_COMPOUND_SHAPES; i++) {
@ -443,4 +440,130 @@ void CollisionShapesScene::render() {
/// Reset the scene
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
float angle = i * 30.0f;
openglframework::Vector3 position(radius * cos(angle),
10 + i * (BOX_SIZE.y + 0.3f),
30 + i * (BOX_SIZE.y + 0.3f),
0);
// Create a cube and a corresponding rigid in the dynamics world
@ -150,8 +150,6 @@ void CubesScene::update() {
// Render the scene
void CubesScene::render() {
checkOpenGLErrors();
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE);
@ -172,49 +170,36 @@ void CubesScene::render() {
mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b));
mPhongShader.setFloatUniform("shininess", 60.0f);
checkOpenGLErrors();
// Render all the cubes of the scene
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
(*it)->render(mPhongShader, worldToCameraMatrix);
}
checkOpenGLErrors();
// Render the floor
mFloor->render(mPhongShader, worldToCameraMatrix);
// Unbind the shader
mPhongShader.unbind();
checkOpenGLErrors();
}
// Reset the scene
void CubesScene::reset() {
}
float radius = 2.0f;
// Check the OpenGL errors
void CubesScene::checkOpenGLErrors() {
GLenum glError;
for (int i=0; i<NB_CUBES; i++) {
// Get the OpenGL errors
glError = glGetError();
// Position of the cubes
float angle = i * 30.0f;
openglframework::Vector3 position(radius * cos(angle),
10 + i * (BOX_SIZE.y + 0.3f),
0);
// While there are errors
while (glError != GL_NO_ERROR) {
// 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);
// Get the error string
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();
mBoxes[i]->resetTransform(transform);
}
}

View File

@ -35,7 +35,7 @@
namespace cubesscene {
// 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 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters
const float BOX_MASS = 1.0f; // Box mass in kilograms
@ -85,9 +85,6 @@ class CubesScene : public Scene {
/// Reset the scene
virtual void reset();
// Check the OpenGL errors
static void checkOpenGLErrors();
};
}

View File

@ -187,6 +187,72 @@ void JointsScene::render() {
// Reset the scene
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

View File

@ -33,9 +33,9 @@ using namespace raycastscene;
// Constructor
RaycastScene::RaycastScene(const std::string& name)
: Scene(name), mLight0(0), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false),
mPhongShader("shaders/phong.vert", "shaders/phong.frag") {
std::string meshFolderPath("meshes/");
mPhongShader("shaders/phong.vert", "shaders/phong.frag"),
mMeshFolderPath("meshes/"), mRaycastManager(mPhongShader, mMeshFolderPath),
mVBOVertices(GL_ARRAY_BUFFER) {
// Move the light 0
mLight0.translateWorld(Vector3(50, 50, 50));
@ -50,14 +50,11 @@ RaycastScene::RaycastScene(const std::string& name)
// Create the dynamics world for the physics simulation
mCollisionWorld = new rp3d::CollisionWorld();
// Create the static data for the visual contact points
VisualContactPoint::createStaticData(meshFolderPath);
// ---------- Dumbbell ---------- //
openglframework::Vector3 position1(0, 0, 0);
// Create a convex mesh and a corresponding collision body in the dynamics world
mDumbbell = new Dumbbell(position1, mCollisionWorld, meshFolderPath, mPhongShader);
mDumbbell = new Dumbbell(position1, mCollisionWorld, mMeshFolderPath, mPhongShader);
// ---------- Box ---------- //
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
mSphere = new Sphere(SPHERE_RADIUS, position3, mCollisionWorld,
meshFolderPath, mPhongShader);
mMeshFolderPath, mPhongShader);
// ---------- Cone ---------- //
openglframework::Vector3 position4(0, 0, 0);
// Create a cone and a corresponding collision body in the dynamics world
mCone = new Cone(CONE_RADIUS, CONE_HEIGHT, position4, mCollisionWorld,
meshFolderPath, mPhongShader);
mMeshFolderPath, mPhongShader);
// ---------- Cylinder ---------- //
openglframework::Vector3 position5(0, 0, 0);
// Create a cylinder and a corresponding collision body in the dynamics world
mCylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position5,
mCollisionWorld, meshFolderPath, mPhongShader);
mCollisionWorld, mMeshFolderPath, mPhongShader);
// ---------- Capsule ---------- //
openglframework::Vector3 position6(0, 0, 0);
// Create a cylinder and a corresponding collision body in the dynamics world
mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position6 ,
mCollisionWorld, meshFolderPath, mPhongShader);
mCollisionWorld, mMeshFolderPath, mPhongShader);
// ---------- Convex Mesh ---------- //
openglframework::Vector3 position7(0, 0, 0);
// Create a convex mesh and a corresponding collision body in the dynamics world
mConvexMesh = new ConvexMesh(position7, mCollisionWorld, meshFolderPath, mPhongShader);
mConvexMesh = new ConvexMesh(position7, mCollisionWorld, mMeshFolderPath, mPhongShader);
// Create the lines that will be used for raycasting
createLines();
// Create the VBO and VAO to render the lines
createVBOAndVAO(mPhongShader);
changeBody();
}
@ -128,6 +128,9 @@ void RaycastScene::createLines() {
openglframework::Vector3 point2(0.0f, 0.0f, 0.0f);
Line* line = new Line(point1, point2);
mLines.push_back(line);
mLinePoints.push_back(point1);
mLinePoints.push_back(point2);
}
}
}
@ -225,6 +228,10 @@ RaycastScene::~RaycastScene() {
++it) {
delete (*it);
}
// Destroy the VBOs and VAO
mVBOVertices.destroy();
mVAO.destroy();
}
// Update the physics world (take a simulation step)
@ -264,25 +271,48 @@ void RaycastScene::render() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE);
// Get the world-space to camera-space matrix
const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse();
// Bind the shader
mPhongShader.bind();
openglframework::Vector4 grey(0.7, 0.7, 0.7, 1);
mPhongShader.setVector4Uniform("vertexColor", grey);
// Get the world-space to camera-space matrix
const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse();
// Set the variables of the shader
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));
const Color& diffColLight0 = mLight0.getDiffuseColor();
const Color& specColLight0 = mLight0.getSpecularColor();
mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffColLight0.r, diffColLight0.g, diffColLight0.b));
mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specColLight0.r, specColLight0.g, specColLight0.b));
mPhongShader.setFloatUniform("shininess", 200.0f);
const Color& diffCol = mLight0.getDiffuseColor();
const Color& specCol = mLight0.getSpecularColor();
mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b));
mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b));
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 (mSphere->getCollisionBody()->isActive()) mSphere->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 (mDumbbell->getCollisionBody()->isActive()) mDumbbell->render(mPhongShader, worldToCameraMatrix);
mPhongShader.unbind();
//mPhongShader.unbind();
mPhongShader.bind();
mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(0, 0, 0));
@ -299,7 +329,7 @@ void RaycastScene::render() {
mPhongShader.setVector4Uniform("vertexColor", redColor);
// Render all the raycast hit points
mRaycastManager.render(mPhongShader, worldToCameraMatrix, mAreNormalsDisplayed);
mRaycastManager.render(worldToCameraMatrix, mAreNormalsDisplayed);
mPhongShader.unbind();
mPhongShader.bind();
@ -316,3 +346,45 @@ void RaycastScene::render() {
// Unbind the shader
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
std::vector<Line*> mNormals;
/// Shader
openglframework::Shader& mShader;
/// Contact point mesh folder path
std::string mMeshFolderPath;
public:
RaycastManager(openglframework::Shader& shader,
const std::string& meshFolderPath)
: mShader(shader), mMeshFolderPath(meshFolderPath) {
}
virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) {
rp3d::Vector3 hitPos = raycastInfo.worldPoint;
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);
// Create a line to display the normal at hit point
@ -87,14 +99,13 @@ class RaycastManager : public rp3d::RaycastCallback {
return raycastInfo.hitFraction;
}
void render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix,
void render(const openglframework::Matrix4& worldToCameraMatrix,
bool showNormals) {
// Render all the raycast hit points
for (std::vector<VisualContactPoint*>::iterator it = mHitPoints.begin();
it != mHitPoints.end(); ++it) {
(*it)->render(shader, worldToCameraMatrix);
(*it)->render(mShader, worldToCameraMatrix);
}
if (showNormals) {
@ -102,7 +113,7 @@ class RaycastManager : public rp3d::RaycastCallback {
// Render all the normals at hit points
for (std::vector<Line*>::iterator it = mNormals.begin();
it != mNormals.end(); ++it) {
(*it)->render(shader, worldToCameraMatrix);
(*it)->render(mShader, worldToCameraMatrix);
}
}
}
@ -132,15 +143,18 @@ class RaycastScene : public Scene {
// -------------------- Attributes -------------------- //
/// Raycast manager
RaycastManager mRaycastManager;
/// Light 0
openglframework::Light mLight0;
/// Phong shader
openglframework::Shader mPhongShader;
/// Contact point mesh folder path
std::string mMeshFolderPath;
/// Raycast manager
RaycastManager mRaycastManager;
/// All the raycast lines
std::vector<Line*> mLines;
@ -164,9 +178,22 @@ class RaycastScene : public Scene {
/// Collision world used for the physics simulation
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
void createLines();
// Create the Vertex Buffer Objects used to render with OpenGL.
void createVBOAndVAO(openglframework::Shader& shader);
public:
// -------------------- Methods -------------------- //
@ -195,6 +222,9 @@ class RaycastScene : public Scene {
/// Display or not the surface normals at hit points
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

View File

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