From 6838ab89d5a47dcd7ce3e00fbe5dc49d42ecf31b Mon Sep 17 00:00:00 2001 From: "chappuis.daniel" Date: Fri, 14 Jan 2011 15:34:53 +0000 Subject: [PATCH] Add the example demo fallingbox git-svn-id: https://reactphysics3d.googlecode.com/svn/trunk@410 92aac97c-a6ce-11dd-a772-7fcde58d38e6 --- examples/fallingbox/Box.cpp | 87 ++++++++++++++++ examples/fallingbox/Box.h | 52 ++++++++++ examples/fallingbox/main.cpp | 194 +++++++++++++++++++++++++++++++++++ 3 files changed, 333 insertions(+) create mode 100644 examples/fallingbox/Box.cpp create mode 100644 examples/fallingbox/Box.h create mode 100644 examples/fallingbox/main.cpp diff --git a/examples/fallingbox/Box.cpp b/examples/fallingbox/Box.cpp new file mode 100644 index 00000000..1ded020e --- /dev/null +++ b/examples/fallingbox/Box.cpp @@ -0,0 +1,87 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ * +* Copyright (c) 2010 Daniel Chappuis * +********************************************************************************* +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy * +* of this software and associated documentation files (the "Software"), to deal * +* in the Software without restriction, including without limitation the rights * +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * +* copies of the Software, and to permit persons to whom the Software is * +* furnished to do so, subject to the following conditions: * +* * +* The above copyright notice and this permission notice shall be included in * +* all copies or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * +* THE SOFTWARE. * +********************************************************************************/ + +// Libraries +#include "Box.h" +#include + +// Use the ReactPhysics3D namespace +using namespace reactphysics3d; + +// Constructor +Box::Box(double size, double mass, Vector3D& position, rp3d::Quaternion& orientation) { + this->size = size; + + // Local inertia tensor of a cube + rp3d::Matrix3x3 inertiaTensor(1.0/12.0*mass*2*size*size, 0.0, 0.0, + 0.0, 1.0/12.0*mass*2*size*size, 0.0, + 0.0, 0.0, 1.0/12.0*mass*2*size*size); + + // Creation of the bounding volume for the collision + // The bounding volume is an Oriented Bounding Box (OBB) + // The first three arguments are the three axis direction of the OBB (here the x,y and z axis) + // and the last three arguments are the corresponding half extents of the OBB in those direction. + // Here the rigid body is a cube and therefore the three half extents are the half of the size + // of the cube in all OBB directions. + rp3d::OBB* boundingVolume = new OBB(position, Vector3D(1.0, 0.0, 0.0), Vector3D(0.0, 1.0, 0.0), Vector3D(0.0, 0.0, 1.0), size/2.0, size/2.0, size/2); + + // Create the rigid body that will be used to simulate the physics of the box + rigidBody = new RigidBody(position, orientation, mass, inertiaTensor, boundingVolume); +} + +// Destructor +Box::~Box() { + // Delete the physics body + delete rigidBody; +} + +// Draw the box +void Box::draw() const { + + // Get the current position of the rigid body (for animation you should use the + // getInterpolatedPosition() function instead of getPosition() + Vector3D position = rigidBody->getInterpolatedPosition(); + + // Get the current orientation of the rigid body (represented by a quaternion) + Quaternion orientation = rigidBody->getInterpolatedOrientation(); + + // Use the returned quaternion to get the rotation axis and rotation angle + Vector3D orientationAxis; + double orientationAngle; + orientation.getRotationAngleAxis(orientationAngle, orientationAxis); + + glPushMatrix(); + + // Translation of the box to its position + glTranslatef(position.getValue(0), position.getValue(1), position.getValue(2)); + + // Rotation of the box according to its orientation + glRotatef(orientationAngle/PI*180.0, orientationAxis.getX(), orientationAxis.getY(), orientationAxis.getZ()); + + // Draw the cube + glutSolidCube(size); + + glPopMatrix(); +} + diff --git a/examples/fallingbox/Box.h b/examples/fallingbox/Box.h new file mode 100644 index 00000000..07ffcbf8 --- /dev/null +++ b/examples/fallingbox/Box.h @@ -0,0 +1,52 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ * +* Copyright (c) 2010 Daniel Chappuis * +********************************************************************************* +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy * +* of this software and associated documentation files (the "Software"), to deal * +* in the Software without restriction, including without limitation the rights * +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * +* copies of the Software, and to permit persons to whom the Software is * +* furnished to do so, subject to the following conditions: * +* * +* The above copyright notice and this permission notice shall be included in * +* all copies or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * +* THE SOFTWARE. * +********************************************************************************/ + +// Libraries +#include + +#ifndef BOX_H +#define BOX_H + +class Box { + private: + double size; + double mass; + rp3d::RigidBody* rigidBody; + + public: + Box(double size, double mass, rp3d::Vector3D& position, rp3d::Quaternion& orientation); // Constructor + ~Box(); // Destructor + + rp3d::RigidBody* getRigidBodyPointer() const; // Return the pointer to the rigid body + + void draw() const; // Draw the box +}; + + // Return the pointer to the rigid body +inline rp3d::RigidBody* Box::getRigidBodyPointer() const { + return rigidBody; +} + +#endif + diff --git a/examples/fallingbox/main.cpp b/examples/fallingbox/main.cpp new file mode 100644 index 00000000..4c2f7246 --- /dev/null +++ b/examples/fallingbox/main.cpp @@ -0,0 +1,194 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ * +* Copyright (c) 2010 Daniel Chappuis * +********************************************************************************* +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy * +* of this software and associated documentation files (the "Software"), to deal * +* in the Software without restriction, including without limitation the rights * +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * +* copies of the Software, and to permit persons to whom the Software is * +* furnished to do so, subject to the following conditions: * +* * +* The above copyright notice and this permission notice shall be included in * +* all copies or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * +* THE SOFTWARE. * +********************************************************************************/ + +// Libraries +#include +#include +#include +#include "Box.h" +#include + +// 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.2; + +// Global variables +PhysicsWorld* physicsWorld; // Physics world +PhysicsEngine* physicsEngine; // Physics engine +Box* boxes[2]; // Falling boxes +RigidBody* floorRigidBody; // Rigid body corresponding the floor + + +// Simulation function +void simulate() { + + // Update the physics simulation + physicsEngine->update(); + + // Display the scene + display(); +} + +// Main function +int main(int argc, char** argv) { + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); + glutInitWindowSize(600, 600); + glutInitWindowPosition(100, 100); + glutCreateWindow("ReactPhysics3D Example - Falling Cubes"); + init(); + glutIdleFunc(simulate); + glutReshapeFunc(reshape); + glutMainLoop(); + physicsEngine->stop(); // Stop the physics simulation + 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 + Vector3D gravity(0.0, -9.81, 0.0); + + // Create the physics world + physicsWorld = new PhysicsWorld(gravity); + + // Create the physics engine with the previous physis world and a timestep + // of 0.005 seconds + physicsEngine = new PhysicsEngine(physicsWorld, 0.005); + + // Create a falling box with a size of 1m and weight of 3kg + Vector3D position1(-2.0, 15.0, 0.0); // Position of the box + Quaternion orientation(0.2, 1.0, 0.6, 0.0); // Orientation of the box + boxes[0] = new Box(1.0, 3.0, position1, orientation); // Creation of the box + boxes[0]->getRigidBodyPointer()->setRestitution(0.5); // How bouncy is the rigid body + physicsWorld->addBody(boxes[0]->getRigidBodyPointer()); // Add the rigid body created in the constructor + // of the Box to the physics world + + + // Create a second falling box with a size of 2m and weight of 4.5kg + Vector3D position2 = Vector3D(2.0, 10.0, 0.0); // Position of the box + orientation = Quaternion(1.0, 1.0, 0.5, 0.0); // Orientation of the box + boxes[1] = new Box(2.0, 4.5, position2, orientation); // Creation of the box + boxes[1]->getRigidBodyPointer()->setRestitution(0.5); // How bouncy is the rigid body + physicsWorld->addBody(boxes[1]->getRigidBodyPointer()); // Add the rigid body created in the constructor + // of the Box to the physics world + + // Create the rigid body corresponding to the floor + Vector3D positionFloor = Vector3D(0.0, 0.0, 0.0); + orientation = Quaternion(0.0, 1.0, 0.0, 0.0); + double mass = 100.0; + + // Local inertia tensor of a cube + rp3d::Matrix3x3 inertiaTensor(1.0/12.0*mass*2*FLOOR_SIZE*FLOOR_SIZE, 0.0, 0.0, + 0.0, 1.0/12.0*mass*2*FLOOR_SIZE*FLOOR_SIZE, 0.0, + 0.0, 0.0, 1.0/12.0*mass*2*FLOOR_SIZE*FLOOR_SIZE); + + // Creation of the bounding volume for the collision + // The bounding volume is an Oriented Bounding Box (OBB) + // The first three arguments are the three axis direction of the OBB (here the x,y and z axis) + // and the last three arguments are the corresponding half extents of the OBB in those direction. + // Here the rigid body is a cube and therefore the three half extents are the half of the size + // of the cube in all OBB directions. + rp3d::OBB* boundingVolume = new OBB(positionFloor, Vector3D(1.0, 0.0, 0.0), Vector3D(0.0, 1.0, 0.0), Vector3D(0.0, 0.0, 1.0), FLOOR_SIZE, FLOOR_THICKNESS, FLOOR_SIZE); + + // Create the rigid body that will be used to simulate the physics of the box + floorRigidBody = new RigidBody(positionFloor, orientation, mass, inertiaTensor, boundingVolume); + + // The floor is a rigid body that cannot move + floorRigidBody->setIsMotionEnabled(false); + + // Set the bouncing restitution factor of the floor + floorRigidBody->setRestitution(0.5); + + // Add the floor rigid body to the physics world + physicsWorld->addBody(floorRigidBody); + + // Start the physics simulation + physicsEngine->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, 5.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); +} + +// Clean the memory allocation +void clean() { + delete physicsEngine; + delete physicsWorld; + delete boxes[0]; + delete boxes[1]; + delete floorRigidBody; +} \ No newline at end of file