/******************************************************************************** * 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 #include #include "Box.h" // Prototypes void init(); void display(); void simulate(); void clean(); void reshape(int w, int h); // Use the ReactPhysics3D namespace using namespace reactphysics3d; // Constants const double FLOOR_SIZE = 20; const double FLOOR_THICKNESS = 0.02; // Global variables DynamicsWorld* dynamicsWorld; // Dynamics world Box* boxes[2]; // Falling boxes BoxShape* collisionShapeBox1; // Collision shape of the first box BoxShape* collisionShapeBox2; // Collision shape of the second box BoxShape* collisionShapeFloor; // Collision shape of the floor RigidBody* floorRigidBody; // Rigid body corresponding the floor // Simulation function void simulate() { // Update the physics simulation dynamicsWorld->update(); // Display the scene display(); } // Main function int main(int argc, char** argv) { // Initialize GLUT glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowSize(800, 600); glutInitWindowPosition(100, 100); glutCreateWindow("ReactPhysics3D Example - Falling Cubes"); init(); glutIdleFunc(simulate); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMainLoop(); // Stop the physics simulation dynamicsWorld->stop(); clean(); return 0; } // Initialization function void init() { glClearColor(0.0, 0.0, 0.0, 0.0); // Light glShadeModel(GL_SMOOTH); GLfloat light_position[] = {5.0f, 5.0f, 5.0f, 1.0f}; glLightfv(GL_LIGHT0, GL_POSITION, light_position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); // Gravity vector of the physics world Vector3 gravity(0.0, -9.81, 0.0); // Timestep of the simulation decimal timeStep = 1.0/60.0; // Create the dynamics world dynamicsWorld = new DynamicsWorld(gravity, timeStep); // --- Create a falling box with a size of 1m and weight of 3kg --- // float size = 1.0f; // Initial position and orientation of the box Vector3 positionBox1(-2.0f, 7.0f, 0.0f); Quaternion orientationBox1(0.3, 1.0, 0.8, 0.0); Transform initTransform(positionBox1, orientationBox1); // Create a box collision shape for the box (used for collision detection) collisionShapeBox1 = new BoxShape(Vector3(size/2.0f, size/2.0f, size/2.0f)); // Compute the inertia tensor of the box using the collision shape Matrix3x3 inertiaTensorBox1; float massBox1 = 3.0f; collisionShapeBox1->computeLocalInertiaTensor(inertiaTensorBox1, massBox1); // Create the rigid body associated with the box in the dynamics world RigidBody* rigidBody = dynamicsWorld->createRigidBody(initTransform, massBox1, inertiaTensorBox1, collisionShapeBox1); // Set the contact velocity restitution factor of the rigid body rigidBody->setRestitution(0.5f); // Create the box object (used for display) boxes[0] = new Box(size, rigidBody); // --- Create a second falling box with a size of 1.5m and weight of 4.5kg --- // size = 1.5; // Initial position and orientation of the box Vector3 positionBox2(2.0, 4.0, 0.0); Quaternion orientationBox2(1.0, 1.0, 0.5, 0.0); Transform initTransform2(positionBox2, orientationBox2); // Create a box collision shape for the box (used for collision detection) collisionShapeBox2 = new BoxShape(Vector3(size/2.0f, size/2.0f, size/2.0f)); // Compute the inertia tensor using the collision shape Matrix3x3 inertiaTensorBox2; float massBox2 = 4.5f; collisionShapeBox2->computeLocalInertiaTensor(inertiaTensorBox2, massBox2); // Create the rigid body associated with the box in the dynamcis world RigidBody* rigidBody2 = dynamicsWorld->createRigidBody(initTransform2, massBox2, inertiaTensorBox2, collisionShapeBox2); // Set the contact velocity restitution factor of the rigid body rigidBody2->setRestitution(0.5); // Create the box object (used for display) boxes[1] = new Box(size, rigidBody2); // --- Create the rigid body corresponding to the floor --- // // Initial position and orientation of the floor Vector3 positionFloor(0.0, 0.0, 0.0); Quaternion orientationFloor(0.0, 1.0, 0.0, 0.0); Transform initTransformFloor(positionFloor, orientationFloor); // Create a box collision shape for the floor (used for collision detection) collisionShapeFloor = new BoxShape(Vector3(FLOOR_SIZE, FLOOR_THICKNESS, FLOOR_SIZE)); // Compute the inertia tensor of the floor using the collision shape float massFloor = 100.0f; rp3d::Matrix3x3 inertiaTensorFloor; collisionShapeFloor->computeLocalInertiaTensor(inertiaTensorFloor, massFloor); // Create the rigid body associated with the floor in the dynamcis world floorRigidBody = dynamicsWorld->createRigidBody(initTransformFloor, massFloor, inertiaTensorFloor, collisionShapeFloor); // The floor is a rigid body that cannot move floorRigidBody->setIsMotionEnabled(false); // Set the contact velocity restitution factor of the floor floorRigidBody->setRestitution(0.5); // Start the dynamics simulation dynamicsWorld->start(); } // Display function void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Display each falling box of the scene for (int i=0; i<2; i++) { boxes[i]->draw(); } // Display the plane for the floor glBegin(GL_POLYGON); glNormal3f(0.0, 1.0, 0.0); glVertex3f(-FLOOR_SIZE/2, 0.0, -FLOOR_SIZE/2); glVertex3f(-FLOOR_SIZE/2, 0.0, FLOOR_SIZE/2); glVertex3f(FLOOR_SIZE/2, 0.0, FLOOR_SIZE/2); glVertex3f(FLOOR_SIZE/2, 0.0, -FLOOR_SIZE/2); glEnd(); glutSwapBuffers(); } // Reshape function void reshape(int w, int h) { float ratio = ((float)w / h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0, 0, w, h); gluPerspective(45, ratio,1,1000); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(20.0, 4.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } // Clean the memory allocation void clean() { // Destroy the rigid bodies from the dynamics world dynamicsWorld->destroyRigidBody(boxes[0]->getRigidBodyPointer()); dynamicsWorld->destroyRigidBody(boxes[1]->getRigidBodyPointer()); dynamicsWorld->destroyRigidBody(floorRigidBody); // Destroy the dynamics world delete dynamicsWorld; // Destroy the boxes delete boxes[0]; delete boxes[1]; // Destroy the collision shapes delete collisionShapeBox1; delete collisionShapeBox2; delete collisionShapeFloor; }