resetting manifest requested domain to floor
[platform/upstream/libbullet.git] / Demos / RaytestDemo / RaytestDemo.cpp
1 /*\r
2 Bullet Continuous Collision Detection and Physics Library\r
3 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/\r
4 \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
10 \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
14 */\r
15 \r
16 \r
17 \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
23 \r
24 #include <stdio.h> //printf debugging\r
25 #include "GLDebugDrawer.h"\r
26 static GLDebugDrawer sDebugDraw;\r
27 \r
28 \r
29 \r
30 void RaytestDemo::castRays() \r
31 {\r
32         \r
33         static float up = 0.f;\r
34         static float dir = 1.f;\r
35         //add some simple animation\r
36         if (!m_idle)\r
37         {\r
38                 up+=0.01*dir;\r
39 \r
40                 if (btFabs(up)>2)\r
41                 {\r
42                         dir*=-1.f;\r
43                 }\r
44 \r
45                 btTransform tr = m_dynamicsWorld->getCollisionObjectArray()[1]->getWorldTransform();\r
46                 static float angle = 0.f;\r
47                 angle+=0.01f;\r
48                 tr.setRotation(btQuaternion(btVector3(0,1,0),angle));\r
49                 m_dynamicsWorld->getCollisionObjectArray()[1]->setWorldTransform(tr);\r
50         }\r
51 \r
52         \r
53         ///step the simulation\r
54         if (m_dynamicsWorld)\r
55         {\r
56                 \r
57                 m_dynamicsWorld->updateAabbs();\r
58                 m_dynamicsWorld->computeOverlappingPairs();\r
59                 \r
60                 btVector3 red(1,0,0);\r
61                 btVector3 blue(0,0,1);\r
62 \r
63                 ///all hits\r
64                 {\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
71 \r
72                         for (int i=0;i<allResults.m_hitFractions.size();i++)\r
73                         {\r
74                                 btVector3 p = from.lerp(to,allResults.m_hitFractions[i]);\r
75                                 sDebugDraw.drawSphere(p,0.1,red);\r
76                         }\r
77                 }\r
78 \r
79                 ///first hit\r
80                 {\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
84 \r
85                         btCollisionWorld::ClosestRayResultCallback      closestResults(from,to);\r
86                         closestResults.m_flags |= btTriangleRaycastCallback::kF_FilterBackfaces;\r
87                         m_dynamicsWorld->rayTest(from,to,closestResults);\r
88 \r
89 \r
90                         if (closestResults.hasHit())\r
91                         {\r
92                                 \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
96 \r
97                         }\r
98                 }\r
99         }\r
100 \r
101 }\r
102 \r
103 \r
104 void RaytestDemo::clientMoveAndDisplay()\r
105 {\r
106         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); \r
107 \r
108         castRays();\r
109         \r
110         if (m_dynamicsWorld)\r
111         {\r
112                 float ms = getDeltaTimeMicroseconds();\r
113                 m_dynamicsWorld->stepSimulation(ms / 1000000.f);\r
114 \r
115                 m_dynamicsWorld->debugDrawWorld();\r
116         }\r
117 \r
118 \r
119                 \r
120         renderme(); \r
121 \r
122         glFlush();\r
123 \r
124         swapBuffers();\r
125 \r
126 }\r
127 \r
128 \r
129 \r
130 void RaytestDemo::displayCallback(void) {\r
131 \r
132         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); \r
133         \r
134         castRays();\r
135 \r
136         renderme();\r
137 \r
138         //optional but useful: debug drawing to detect problems\r
139         if (m_dynamicsWorld)\r
140                 m_dynamicsWorld->debugDrawWorld();\r
141 \r
142         glFlush();\r
143         swapBuffers();\r
144 }\r
145 \r
146 \r
147 \r
148 \r
149 \r
150 void    RaytestDemo::initPhysics()\r
151 {\r
152         m_ele = 10;\r
153         m_azi = 75;\r
154 \r
155         setTexturing(true);\r
156         setShadows(true);\r
157 \r
158         setCameraDistance(btScalar(20.));\r
159 \r
160         ///collision configuration contains default setup for memory, collision setup\r
161         m_collisionConfiguration = new btDefaultCollisionConfiguration();\r
162         //m_collisionConfiguration->setConvexConvexMultipointIterations();\r
163 \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
166 \r
167         m_broadphase = new btDbvtBroadphase();\r
168 \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
171         m_solver = sol;\r
172 \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
176 \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
180         \r
181         m_collisionShapes.push_back(groundShape);\r
182 \r
183         btTransform groundTransform;\r
184         groundTransform.setIdentity();\r
185         groundTransform.setOrigin(btVector3(0,-50,0));\r
186 \r
187         //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:\r
188         {\r
189                 btScalar mass(0.);\r
190 \r
191                 //rigidbody is dynamic if and only if mass is non zero, otherwise static\r
192                 bool isDynamic = (mass != 0.f);\r
193 \r
194                 btVector3 localInertia(0,0,0);\r
195                 if (isDynamic)\r
196                         groundShape->calculateLocalInertia(mass,localInertia);\r
197 \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
206         }\r
207 \r
208 \r
209         {\r
210                 btVector3 convexPoints[]={ btVector3(-1,-1,-1),btVector3(-1,-1,1),btVector3(-1,1,1),btVector3(-1,1,-1),\r
211                         btVector3(2,0,0)};\r
212 \r
213                 btVector3 quad[] = {\r
214                         btVector3(0,1,-1),\r
215                         btVector3(0,1,1),\r
216                         btVector3(0,-1,1),\r
217                         btVector3(0,-1,-1)};\r
218 \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
222 \r
223                 btBvhTriangleMeshShape* trimesh = new btBvhTriangleMeshShape(mesh,true,true);\r
224 \r
225 #define NUM_SHAPES 6\r
226                         btCollisionShape* colShapes[NUM_SHAPES] = {\r
227                                 trimesh,\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
233                         };\r
234 \r
235                 for (int i=0;i<NUM_SHAPES;i++)\r
236                         m_collisionShapes.push_back(colShapes[i]);\r
237 \r
238                 for (int i=0;i<6;i++)\r
239                 {\r
240                         //create a few dynamic rigidbodies\r
241                         // Re-using the same collision is better for memory usage and performance\r
242 \r
243         \r
244 \r
245                         /// Create Dynamic Objects\r
246                         btTransform startTransform;\r
247                         startTransform.setIdentity();\r
248                         startTransform.setOrigin(btVector3((i-3)*5,1,0));\r
249 \r
250 \r
251                         btScalar        mass(1.f);\r
252 \r
253                         if (!i)\r
254                                 mass=0.f;\r
255 \r
256                         //rigidbody is dynamic if and only if mass is non zero, otherwise static\r
257                         bool isDynamic = (mass != 0.f);\r
258 \r
259                         btVector3 localInertia(0,0,0);\r
260                         btCollisionShape* colShape = colShapes[i%NUM_SHAPES];\r
261                         if (isDynamic)\r
262                                 colShape->calculateLocalInertia(mass,localInertia);\r
263 \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
270                 \r
271                         m_dynamicsWorld->addRigidBody(body);\r
272         \r
273                 }\r
274 \r
275         }\r
276 }\r
277 void    RaytestDemo::clientResetScene()\r
278 {\r
279         exitPhysics();\r
280         initPhysics();\r
281 }\r
282         \r
283 \r
284 void    RaytestDemo::exitPhysics()\r
285 {\r
286 \r
287         //cleanup in the reverse order of creation/initialization\r
288 \r
289         //remove the rigidbodies from the dynamics world and delete them\r
290         int i;\r
291         for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)\r
292         {\r
293                 btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];\r
294                 btRigidBody* body = btRigidBody::upcast(obj);\r
295                 if (body && body->getMotionState())\r
296                 {\r
297                         delete body->getMotionState();\r
298                 }\r
299                 m_dynamicsWorld->removeCollisionObject( obj );\r
300                 delete obj;\r
301         }\r
302 \r
303         //delete collision shapes\r
304         for (int j=0;j<m_collisionShapes.size();j++)\r
305         {\r
306                 btCollisionShape* shape = m_collisionShapes[j];\r
307                 delete shape;\r
308         }\r
309         m_collisionShapes.clear();\r
310 \r
311         delete m_dynamicsWorld;\r
312         \r
313         delete m_solver;\r
314         \r
315         delete m_broadphase;\r
316         \r
317         delete m_dispatcher;\r
318 \r
319         delete m_collisionConfiguration;\r
320 \r
321         \r
322 }\r
323 \r
324 \r
325 \r
326 \r