From 434a1687857a397cc71a6d0288e5fbbf86ff99b1 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Fri, 26 Apr 2013 00:46:09 +0200 Subject: [PATCH] Add files for the joints example --- examples/CMakeLists.txt | 1 + examples/fallingcubes/Box.cpp | 180 ----------------- examples/joints/CMakeLists.txt | 17 ++ examples/joints/Joints.cpp | 151 +++++++++++++++ examples/joints/Scene.cpp | 182 ++++++++++++++++++ .../{fallingcubes/Box.h => joints/Scene.h} | 114 +++++------ 6 files changed, 411 insertions(+), 234 deletions(-) delete mode 100644 examples/fallingcubes/Box.cpp create mode 100644 examples/joints/CMakeLists.txt create mode 100644 examples/joints/Joints.cpp create mode 100644 examples/joints/Scene.cpp rename examples/{fallingcubes/Box.h => joints/Scene.h} (51%) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 568479fb..0740c9fc 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -3,3 +3,4 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) add_subdirectory(common/) add_subdirectory(fallingcubes/) +add_subdirectory(joints/) diff --git a/examples/fallingcubes/Box.cpp b/examples/fallingcubes/Box.cpp deleted file mode 100644 index d4169c9a..00000000 --- a/examples/fallingcubes/Box.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ * -* Copyright (c) 2010-2013 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "Box.h" - -// Macros -#define MEMBER_OFFSET(s,m) ((char *)NULL + (offsetof(s,m))) - -// Initialize static variables -openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER); -openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); -bool Box::areVBOsCreated = false; -VertexData Box::mCubeVertices[8] = { - {openglframework::Vector3(1,1,1),openglframework::Vector3(1,1,1),openglframework::Color(0,0,1,1)}, - {openglframework::Vector3(-1,1,1),openglframework::Vector3(-1,1,1),openglframework::Color(0,0,1,1)}, - {openglframework::Vector3(-1,-1,1),openglframework::Vector3(-1,-1,1),openglframework::Color(0,0,1,1)}, - {openglframework::Vector3(1,-1,1),openglframework::Vector3(1,-1,1),openglframework::Color(0,0,1,1)}, - {openglframework::Vector3(1,-1,-1),openglframework::Vector3(1,-1,-1),openglframework::Color(0,0,1,1)}, - {openglframework::Vector3(-1,-1,-1),openglframework::Vector3(-1,-1,-1),openglframework::Color(0,0,1,1)}, - {openglframework::Vector3(-1,1,-1),openglframework::Vector3(-1,1,-1),openglframework::Color(0,0,1,1)}, - {openglframework::Vector3(1,1,-1),openglframework::Vector3(1,1,-1),openglframework::Color(0,0,1,1)} -}; -GLuint Box::mCubeIndices[36] = { 0, 1, 2, - 2, 3, 0, - 7, 4, 5, - 5, 6, 7, - 6, 5, 2, - 2, 1, 6, - 7, 0, 3, - 3, 4, 7, - 7, 6, 1, - 1, 0, 7, - 3, 2, 5, - 5, 4, 3}; - -// Constructor -Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, - float mass, reactphysics3d::DynamicsWorld* dynamicsWorld) - : openglframework::Object3D() { - - // Initialize the size of the box - mSize[0] = size.x * 0.5f; - mSize[1] = size.y * 0.5f; - mSize[2] = size.z * 0.5f; - - // Compute the scaling matrix - mScalingMatrix = openglframework::Matrix4(mSize[0], 0, 0, 0, - 0, mSize[1], 0, 0, - 0, 0, mSize[2], 0, - 0, 0, 0, 1); - - // Initialize the position where the cube will be rendered - translateWorld(position); - - // Create the collision shape for the rigid body (box shape) - mCollisionShape = new rp3d::BoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); - - // Compute the inertia tensor of the body using its collision shape - rp3d::Matrix3x3 inertiaTensor; - mCollisionShape->computeLocalInertiaTensor(inertiaTensor, mass); - - // Initial position and orientation of the rigid body - rp3d::Vector3 initPosition(position.x, position.y, position.z); - rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); - rp3d::Transform transform(initPosition, initOrientation); - - // Create a rigid body corresponding to the cube in the dynamics world - mRigidBody = dynamicsWorld->createRigidBody(transform, mass, inertiaTensor, mCollisionShape); - - // If the Vertex Buffer object has not been created yet - if (!areVBOsCreated) { - // Create the Vertex Buffer - createVBO(); - } -} - -// Destructor -Box::~Box() { - - // Destroy the collision shape - delete mCollisionShape; -} - -// Render the cube at the correct position and with the correct orientation -void Box::render(openglframework::Shader& shader) { - - // Bind the shader - shader.bind(); - - // Set the model to World matrix - shader.setMatrix4x4Uniform("modelToWorldMatrix", mTransformMatrix); - - // Bind the vertices VBO - mVBOVertices.bind(); - - // Enable the vertex, normal and color arrays - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - // Set the arrays pointers - glVertexPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, position)); - glNormalPointer(GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal)); - glColorPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, color)); - - // Bind the indices VBO - mVBOIndices.bind(); - - // Draw the geometry of the box - glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (char*)NULL); - - // Unbind the VBOs - mVBOVertices.unbind(); - mVBOIndices.unbind(); - - // Disable the arrays - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - - // Unbind the shader - shader.unbind(); -} - -// Update the transform matrix of the box -void Box::updateTransform() { - - // Get the interpolated transform of the rigid body - rp3d::Transform transform = mRigidBody->getInterpolatedTransform(); - - // Compute the transform used for rendering the box - float matrix[16]; - transform.getOpenGLMatrix(matrix); - openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); - - // Apply the scaling matrix to have the correct box dimensions - mTransformMatrix = newMatrix * mScalingMatrix; -} - -// Create the Vertex Buffer Objects used to render to box with OpenGL. -/// We create two VBOs (one for vertices and one for indices) to render all the boxes -/// in the simulation. -void Box::createVBO() { - - // Create the VBOs - mVBOVertices.create(); - mVBOIndices.create(); - - // Copy the data into the VBOs - mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW); - mVBOIndices.copyDataIntoVBO(sizeof(mCubeIndices), mCubeIndices, GL_STATIC_DRAW); - - areVBOsCreated = true; -} diff --git a/examples/joints/CMakeLists.txt b/examples/joints/CMakeLists.txt new file mode 100644 index 00000000..dc2eed0c --- /dev/null +++ b/examples/joints/CMakeLists.txt @@ -0,0 +1,17 @@ +# Minimum cmake version required +cmake_minimum_required(VERSION 2.6) + +# Project configuration +PROJECT(Joints) + +# Copy the shaders used for the demo into the build directory +FILE(COPY "../common/opengl-framework/src/shaders/" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/shaders/") + +# Headers +INCLUDE_DIRECTORIES("../common/opengl-framework/src/" "../common/") + +# Create the example executable using the +# compiled reactphysics3d static library +ADD_EXECUTABLE(joints Joints.cpp Scene.cpp Scene.h "../common/Box.cpp" "../common/Box.h" "../common/Viewer.cpp" "../common/Viewer.h") + +TARGET_LINK_LIBRARIES(joints reactphysics3d openglframework) diff --git a/examples/joints/Joints.cpp b/examples/joints/Joints.cpp new file mode 100644 index 00000000..f42ffb97 --- /dev/null +++ b/examples/joints/Joints.cpp @@ -0,0 +1,151 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ * +* Copyright (c) 2010-2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Scene.h" +#include "Viewer.h" + +// Declarations +void simulate(); +void display(); +void finish(); +void reshape(int width, int height); +void mouseButton(int button, int state, int x, int y); +void mouseMotion(int x, int y); +void keyboard(unsigned char key, int x, int y); +void init(); + +// Namespaces +using namespace openglframework; + +// Global variables +Viewer* viewer; +Scene* scene; + +// Main function +int main(int argc, char** argv) { + + // Create and initialize the Viewer + viewer = new Viewer(); + Vector2 windowsSize = Vector2(800, 600); + Vector2 windowsPosition = Vector2(100, 100); + bool initOK = viewer->init(argc, argv, "ReactPhysics3D Examples - Joints", windowsSize, windowsPosition); + if (!initOK) return 1; + + // Create the scene + scene = new Scene(viewer); + + init(); + + // Glut Idle function that is continuously called + glutIdleFunc(simulate); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutMouseFunc(mouseButton); + glutMotionFunc(mouseMotion); + glutKeyboardFunc(keyboard); + glutCloseFunc(finish); + + // Glut main looop + glutMainLoop(); + + return 0; +} + +// Simulate function +void simulate() { + + // Physics simulation + scene->simulate(); + + viewer->computeFPS(); + + // Ask GLUT to render the scene + glutPostRedisplay (); +} + +// Initialization +void init() { + + // Define the background color (black) + glClearColor(0.0, 0.0, 0.0, 1.0); +} + +// Reshape function +void reshape(int newWidth, int newHeight) { + viewer->reshape(newWidth, newHeight); +} + +// Called when a mouse button event occurs +void mouseButton(int button, int state, int x, int y) { + viewer->mouseButtonEvent(button, state, x, y); +} + +// Called when a mouse motion event occurs +void mouseMotion(int x, int y) { + viewer->mouseMotionEvent(x, y); +} + +// Called when the user hits a special key on the keyboard +void keyboard(unsigned char key, int x, int y) { + switch(key) { + + // Escape key + case 27: + glutLeaveMainLoop(); + break; + + // Space bar + case 32: + scene->pauseContinueSimulation(); + break; + } +} + +// End of the application +void finish() { + + // Destroy the viewer and the scene + delete viewer; + delete scene; +} + +// Display the scene +void display() { + + // Render the scene + scene->render(); + + // Display the FPS + viewer->displayGUI(); + + // Swap the buffers + glutSwapBuffers(); + + // Check the OpenGL errors + GlutViewer::checkOpenGLErrors(); +} + + diff --git a/examples/joints/Scene.cpp b/examples/joints/Scene.cpp new file mode 100644 index 00000000..693a0fa5 --- /dev/null +++ b/examples/joints/Scene.cpp @@ -0,0 +1,182 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ * +* Copyright (c) 2010-2013 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Libraries +#include "Scene.h" + +// Namespaces +using namespace openglframework; + +// Constructor +Scene::Scene(GlutViewer* viewer) : mViewer(viewer), mLight0(0), + mPhongShader("shaders/phong.vert", + "shaders/phong.frag"), mIsRunning(false) { + + // Move the light 0 + mLight0.translateWorld(Vector3(7, 15, 15)); + + // Compute the radius and the center of the scene + float radiusScene = 10.0f; + openglframework::Vector3 center(0, 5, 0); + + // Set the center of the scene + mViewer->setScenePosition(center, radiusScene); + + // Gravity vector in the dynamics world + rp3d::Vector3 gravity(0, -9.81, 0); + + // Time step for the physics simulation + rp3d::decimal timeStep = 1.0f / 60.0f; + + // Create the dynamics world for the physics simulation + mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep); + + // Set the number of iterations of the constraint solver + mDynamicsWorld->setNbIterationsSolver(15); + + float radius = 2.0f; + + // Create all the cubes of the scene + for (int i=0; igetRigidBody()->setIsMotionEnabled(true); + + // Set the bouncing factor of the box + cube->getRigidBody()->setRestitution(0.4); + + // Add the box the list of box in the scene + mBoxes.push_back(cube); + } + + // Create the floor + openglframework::Vector3 floorPosition(0, 0, 0); + mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); + + // The floor must be a non-moving rigid body + mFloor->getRigidBody()->setIsMotionEnabled(false); + + // Set the bouncing factor of the floor + mFloor->getRigidBody()->setRestitution(0.3); + + // Start the simulation + startSimulation(); +} + +// Destructor +Scene::~Scene() { + + // Stop the physics simulation + stopSimulation(); + + // Destroy the shader + mPhongShader.destroy(); + + // Destroy all the cubes of the scene + for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { + + // Destroy the corresponding rigid body from the dynamics world + mDynamicsWorld->destroyRigidBody((*it)->getRigidBody()); + + // Destroy the cube + delete (*it); + } + + // Destroy the rigid body of the floor + mDynamicsWorld->destroyRigidBody(mFloor->getRigidBody()); + + // Destroy the floor + delete mFloor; + + // Destroy the dynamics world + delete mDynamicsWorld; +} + +// Take a step for the simulation +void Scene::simulate() { + + // If the physics simulation is running + if (mIsRunning) { + + // Take a simulation step + mDynamicsWorld->update(); + + // Update the position and orientation of the boxes + for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { + + // Update the transform used for the rendering + (*it)->updateTransform(); + } + + mFloor->updateTransform(); + + } +} + +// Render the scene +void Scene::render() { + + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_CULL_FACE); + + // Bind the shader + mPhongShader.bind(); + + // Set the variables of the shader + const Camera& camera = mViewer->getCamera(); + Matrix4 matrixIdentity; + matrixIdentity.setToIdentity(); + mPhongShader.setVector3Uniform("cameraWorldPosition", mViewer->getCamera().getOrigin()); + mPhongShader.setMatrix4x4Uniform("worldToCameraMatrix", camera.getTransformMatrix().getInverse()); + mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix()); + mPhongShader.setVector3Uniform("lightWorldPosition", mLight0.getOrigin()); + mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); + Color& diffCol = mLight0.getDiffuseColor(); + Color& specCol = mLight0.getSpecularColor(); + mPhongShader.setVector3Uniform("lightDiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); + mPhongShader.setVector3Uniform("lightSpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); + mPhongShader.setFloatUniform("shininess", 60.0f); + + // Render all the cubes of the scene + for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { + (*it)->render(mPhongShader); + } + + // Render the floor + mFloor->render(mPhongShader); + + // Unbind the shader + mPhongShader.unbind(); +} diff --git a/examples/fallingcubes/Box.h b/examples/joints/Scene.h similarity index 51% rename from examples/fallingcubes/Box.h rename to examples/joints/Scene.h index d287c3cb..3741962e 100644 --- a/examples/fallingcubes/Box.h +++ b/examples/joints/Scene.h @@ -23,89 +23,95 @@ * * ********************************************************************************/ -#ifndef BOX_H -#define BOX_H +#ifndef SCENE_H +#define SCENE_H // Libraries #include "openglframework.h" #include "reactphysics3d.h" +#include "Box.h" -// Structure VertexData -struct VertexData { +// Constants +const int NB_BOXES = 20; // Number of boxes in the scene +const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters +const openglframework::Vector3 FLOOR_SIZE(20, 0.5f, 20); // Floor dimensions in meters +const float BOX_MASS = 1.0f; // Box mass in kilograms +const float FLOOR_MASS = 100.0f; // Floor mass in kilograms - /// Vertex position - openglframework::Vector3 position; - - /// Vertex normal - openglframework::Vector3 normal; - - // Vertex color - openglframework::Color color; -}; - -// Class Box -class Box : public openglframework::Object3D { +// Class Scene +class Scene { private : // -------------------- Attributes -------------------- // - /// Size of each side of the box - float mSize[3]; + // Pointer to the viewer + openglframework::GlutViewer* mViewer; - /// Rigid body used to simulate the dynamics of the box - rp3d::RigidBody* mRigidBody; + // Light 0 + openglframework::Light mLight0; - /// Collision shape of the rigid body - rp3d::BoxShape* mCollisionShape; + // Phong shader + openglframework::Shader mPhongShader; - /// Scaling matrix (applied to a cube to obtain the correct box dimensions) - openglframework::Matrix4 mScalingMatrix; + /// All the boxes of the scene + std::vector mBoxes; - /// Vertex Buffer Object for the vertices data used to render the box with OpenGL - static openglframework::VertexBufferObject mVBOVertices; + /// Box for the floor + Box* mFloor; - /// Vertex Buffer Object for the indices used to render the box with OpenGL - static openglframework::VertexBufferObject mVBOIndices; + /// Dynamics world used for the physics simulation + rp3d::DynamicsWorld* mDynamicsWorld; - /// Vertex data for each vertex of the cube (used to render the box) - static VertexData mCubeVertices[8]; + /// True if the physics simulation is running + bool mIsRunning; - /// Indices of the cube (used to render the box) - static GLuint mCubeIndices[36]; - - /// True if the VBOs have already been created - static bool areVBOsCreated; - - // -------------------- Methods -------------------- // - - /// Create a Vertex Buffer Object to render to box with OpenGL - static void createVBO(); - - public : + public: // -------------------- Methods -------------------- // /// Constructor - Box(const openglframework::Vector3& size, const openglframework::Vector3& position, - float mass, rp3d::DynamicsWorld* dynamicsWorld); + Scene(openglframework::GlutViewer* viewer); /// Destructor - ~Box(); + ~Scene(); - /// Return a pointer to the rigid body of the box - rp3d::RigidBody* getRigidBody(); + /// Take a step for the simulation + void simulate(); - /// Update the transform matrix of the box - void updateTransform(); + /// Stop the simulation + void stopSimulation(); - /// Render the cube at the correct position and with the correct orientation - void render(openglframework::Shader& shader); + /// Start the simulation + void startSimulation(); + + /// Pause or continue simulation + void pauseContinueSimulation(); + + /// Render the scene + void render(); }; -// Return a pointer to the rigid body of the box -inline rp3d::RigidBody* Box::getRigidBody() { - return mRigidBody; +// Stop the simulation +inline void Scene::stopSimulation() { + mDynamicsWorld->stop(); + mIsRunning = false; +} + +// Start the simulation +inline void Scene::startSimulation() { + mDynamicsWorld->start(); + mIsRunning = true; +} + +// Pause or continue simulation +inline void Scene::pauseContinueSimulation() { + if (mIsRunning) { + stopSimulation(); + } + else { + startSimulation(); + } } #endif