2 Bullet Continuous Collision Detection and Physics Library
\r
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
\r
5 This software is provided 'as-is', without any express or implied warranty.
\r
6 In no event will the authors be held liable for any damages arising from the use of this software.
\r
7 Permission is granted to anyone to use this software for any purpose,
\r
8 including commercial applications, and to alter it and redistribute it freely,
\r
9 subject to the following restrictions:
\r
11 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.
\r
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
\r
13 3. This notice may not be removed or altered from any source distribution.
\r
18 #include "RaytestDemo.h"
\r
19 #include "GlutStuff.h"
\r
20 ///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
\r
21 #include "btBulletDynamicsCommon.h"
\r
22 #include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
\r
24 #include <stdio.h> //printf debugging
\r
25 #include "GLDebugDrawer.h"
\r
26 static GLDebugDrawer sDebugDraw;
\r
30 void RaytestDemo::castRays()
\r
33 static float up = 0.f;
\r
34 static float dir = 1.f;
\r
35 //add some simple animation
\r
45 btTransform tr = m_dynamicsWorld->getCollisionObjectArray()[1]->getWorldTransform();
\r
46 static float angle = 0.f;
\r
48 tr.setRotation(btQuaternion(btVector3(0,1,0),angle));
\r
49 m_dynamicsWorld->getCollisionObjectArray()[1]->setWorldTransform(tr);
\r
53 ///step the simulation
\r
54 if (m_dynamicsWorld)
\r
57 m_dynamicsWorld->updateAabbs();
\r
58 m_dynamicsWorld->computeOverlappingPairs();
\r
60 btVector3 red(1,0,0);
\r
61 btVector3 blue(0,0,1);
\r
65 btVector3 from(-30,1+up,0);
\r
66 btVector3 to(30,1,0);
\r
67 sDebugDraw.drawLine(from,to,btVector4(0,0,0,1));
\r
68 btCollisionWorld::AllHitsRayResultCallback allResults(from,to);
\r
69 allResults.m_flags |= btTriangleRaycastCallback::kF_KeepUnflippedNormal;
\r
70 m_dynamicsWorld->rayTest(from,to,allResults);
\r
72 for (int i=0;i<allResults.m_hitFractions.size();i++)
\r
74 btVector3 p = from.lerp(to,allResults.m_hitFractions[i]);
\r
75 sDebugDraw.drawSphere(p,0.1,red);
\r
81 btVector3 from(-30,1.2,0);
\r
82 btVector3 to(30,1.2,0);
\r
83 sDebugDraw.drawLine(from,to,btVector4(0,0,1,1));
\r
85 btCollisionWorld::ClosestRayResultCallback closestResults(from,to);
\r
86 closestResults.m_flags |= btTriangleRaycastCallback::kF_FilterBackfaces;
\r
87 m_dynamicsWorld->rayTest(from,to,closestResults);
\r
90 if (closestResults.hasHit())
\r
93 btVector3 p = from.lerp(to,closestResults.m_closestHitFraction);
\r
94 sDebugDraw.drawSphere(p,0.1,blue);
\r
95 sDebugDraw.drawLine(p,p+closestResults.m_hitNormalWorld,blue);
\r
104 void RaytestDemo::clientMoveAndDisplay()
\r
106 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
\r
110 if (m_dynamicsWorld)
\r
112 float ms = getDeltaTimeMicroseconds();
\r
113 m_dynamicsWorld->stepSimulation(ms / 1000000.f);
\r
115 m_dynamicsWorld->debugDrawWorld();
\r
130 void RaytestDemo::displayCallback(void) {
\r
132 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
\r
138 //optional but useful: debug drawing to detect problems
\r
139 if (m_dynamicsWorld)
\r
140 m_dynamicsWorld->debugDrawWorld();
\r
150 void RaytestDemo::initPhysics()
\r
155 setTexturing(true);
\r
158 setCameraDistance(btScalar(20.));
\r
160 ///collision configuration contains default setup for memory, collision setup
\r
161 m_collisionConfiguration = new btDefaultCollisionConfiguration();
\r
162 //m_collisionConfiguration->setConvexConvexMultipointIterations();
\r
164 ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
\r
165 m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
\r
167 m_broadphase = new btDbvtBroadphase();
\r
169 ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
\r
170 btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
\r
173 m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
\r
174 m_dynamicsWorld ->setDebugDrawer(&sDebugDraw);
\r
175 m_dynamicsWorld->setGravity(btVector3(0,-10,0));
\r
177 ///create a few basic rigid bodies
\r
178 btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
\r
179 // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50);
\r
181 m_collisionShapes.push_back(groundShape);
\r
183 btTransform groundTransform;
\r
184 groundTransform.setIdentity();
\r
185 groundTransform.setOrigin(btVector3(0,-50,0));
\r
187 //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
\r
191 //rigidbody is dynamic if and only if mass is non zero, otherwise static
\r
192 bool isDynamic = (mass != 0.f);
\r
194 btVector3 localInertia(0,0,0);
\r
196 groundShape->calculateLocalInertia(mass,localInertia);
\r
198 //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
\r
199 btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
\r
200 btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
\r
201 btRigidBody* body = new btRigidBody(rbInfo);
\r
202 body->setRollingFriction(1);
\r
203 body->setFriction(1);
\r
204 //add the body to the dynamics world
\r
205 m_dynamicsWorld->addRigidBody(body);
\r
210 btVector3 convexPoints[]={ btVector3(-1,-1,-1),btVector3(-1,-1,1),btVector3(-1,1,1),btVector3(-1,1,-1),
\r
213 btVector3 quad[] = {
\r
217 btVector3(0,-1,-1)};
\r
219 btTriangleMesh* mesh = new btTriangleMesh();
\r
220 mesh->addTriangle(quad[0],quad[1],quad[2],true);
\r
221 mesh->addTriangle(quad[0],quad[2],quad[3],true);
\r
223 btBvhTriangleMeshShape* trimesh = new btBvhTriangleMeshShape(mesh,true,true);
\r
225 #define NUM_SHAPES 6
\r
226 btCollisionShape* colShapes[NUM_SHAPES] = {
\r
228 new btConvexHullShape(&convexPoints[0].getX(),sizeof(convexPoints)/sizeof(btVector3),sizeof(btVector3)),
\r
229 new btSphereShape(1),
\r
230 new btCapsuleShape(0.2,1),
\r
231 new btCylinderShape(btVector3(0.2,1,0.2)),
\r
232 new btBoxShape(btVector3(1,1,1))
\r
235 for (int i=0;i<NUM_SHAPES;i++)
\r
236 m_collisionShapes.push_back(colShapes[i]);
\r
238 for (int i=0;i<6;i++)
\r
240 //create a few dynamic rigidbodies
\r
241 // Re-using the same collision is better for memory usage and performance
\r
245 /// Create Dynamic Objects
\r
246 btTransform startTransform;
\r
247 startTransform.setIdentity();
\r
248 startTransform.setOrigin(btVector3((i-3)*5,1,0));
\r
251 btScalar mass(1.f);
\r
256 //rigidbody is dynamic if and only if mass is non zero, otherwise static
\r
257 bool isDynamic = (mass != 0.f);
\r
259 btVector3 localInertia(0,0,0);
\r
260 btCollisionShape* colShape = colShapes[i%NUM_SHAPES];
\r
262 colShape->calculateLocalInertia(mass,localInertia);
\r
264 btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape,localInertia);
\r
265 rbInfo.m_startWorldTransform = startTransform;
\r
266 btRigidBody* body = new btRigidBody(rbInfo);
\r
267 body->setRollingFriction(0.03);
\r
268 body->setFriction(1);
\r
269 body->setAnisotropicFriction(colShape->getAnisotropicRollingFrictionDirection(),btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
\r
271 m_dynamicsWorld->addRigidBody(body);
\r
277 void RaytestDemo::clientResetScene()
\r
284 void RaytestDemo::exitPhysics()
\r
287 //cleanup in the reverse order of creation/initialization
\r
289 //remove the rigidbodies from the dynamics world and delete them
\r
291 for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
\r
293 btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
\r
294 btRigidBody* body = btRigidBody::upcast(obj);
\r
295 if (body && body->getMotionState())
\r
297 delete body->getMotionState();
\r
299 m_dynamicsWorld->removeCollisionObject( obj );
\r
303 //delete collision shapes
\r
304 for (int j=0;j<m_collisionShapes.size();j++)
\r
306 btCollisionShape* shape = m_collisionShapes[j];
\r
309 m_collisionShapes.clear();
\r
311 delete m_dynamicsWorld;
\r
315 delete m_broadphase;
\r
317 delete m_dispatcher;
\r
319 delete m_collisionConfiguration;
\r