Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Demos / DoublePrecisionDemo / DoublePrecisionDemo.cpp
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose, 
8 including commercial applications, and to alter it and redistribute it freely, 
9 subject to the following restrictions:
10
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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
16
17 ///
18 /// DoublePrecisionDemo shows high level usage of the Collision Detection.
19 ///
20
21 #include "GL_Simplex1to4.h"
22
23 //include common Bullet Collision Detection headerfiles
24 #include "btBulletCollisionCommon.h"
25
26 #include "LinearMath/btIDebugDraw.h"
27 #include "GLDebugFont.h"
28
29
30 #include "GL_ShapeDrawer.h"
31 #include "DoublePrecisionDemo.h"
32 #include "GlutStuff.h"
33 #include "GLDebugDrawer.h"
34
35 btScalar yaw=btScalar(0.);
36 btScalar pitch=btScalar(0.);
37 btScalar roll=btScalar(0.);
38 const int maxNumObjects = 4;
39 const int numObjects = 2;
40
41 GL_Simplex1to4 simplex;
42
43
44 btCollisionObject       objects[maxNumObjects];
45 btCollisionWorld*       collisionWorld = 0;
46
47 // so pixel ratio is 1:1
48 int screenWidth = 640;
49 int screenHeight = 640;
50 GLDebugDrawer debugDrawer;
51
52 const btScalar LARGE_DISTANCE_FROM_ORIGIN = btScalar(999999.0);
53 const btScalar VERY_SMALL_INCREMENT = btScalar(0.000009);
54
55 int main(int argc,char** argv)
56 {
57         DoublePrecisionDemo* doublePrecisionDemo = new DoublePrecisionDemo();
58
59         doublePrecisionDemo->initPhysics();
60         doublePrecisionDemo->setCameraDistance(btScalar(2.0));
61
62         doublePrecisionDemo->clientResetScene();
63
64         return glutmain(argc, argv,screenWidth,screenHeight,"Double Precision Demo",doublePrecisionDemo);
65 }
66
67 void    DoublePrecisionDemo::initPhysics()
68 {
69   m_debugMode |= btIDebugDraw::DBG_DrawWireframe;
70         
71         btMatrix3x3 basisA;
72         basisA.setIdentity();
73
74         btMatrix3x3 basisB;
75         basisB.setIdentity();
76
77         objects[0].getWorldTransform().setBasis(basisA);
78         objects[1].getWorldTransform().setBasis(basisB);
79         
80
81         btBoxShape* boxA = new btBoxShape(btVector3(0.5,0.5,0.5));
82         btBoxShape* boxB = new btBoxShape(btVector3(0.5,0.5,0.5));
83
84         objects[0].setCollisionShape(boxA);//&hullA;
85         objects[1].setCollisionShape(boxB);//&hullB;
86
87         btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
88         btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
89         btVector3       worldAabbMin(80000,80000,80000);
90         btVector3       worldAabbMax(120000,120000,120000);
91
92         btAxisSweep3*   broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax);
93         
94         collisionWorld = new btCollisionWorld(dispatcher,broadphase,collisionConfiguration);
95                 
96         collisionWorld->addCollisionObject(&objects[0]);
97         collisionWorld->addCollisionObject(&objects[1]);
98
99 }
100
101
102 //to be implemented by the demo
103
104 void DoublePrecisionDemo::clientMoveAndDisplay()
105 {
106         
107         displayCallback();
108 }
109
110
111 static btVoronoiSimplexSolver sGjkSimplexSolver;
112 btSimplexSolverInterface& gGjkSimplexSolver = sGjkSimplexSolver;
113
114 void DoublePrecisionDemo::displayCallback(void) 
115 {
116   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
117         glDisable(GL_LIGHTING);
118
119         collisionWorld->getDispatchInfo().m_debugDraw = &debugDrawer;
120         
121   if (collisionWorld)
122     collisionWorld->performDiscreteCollisionDetection();
123
124   int i;
125
126         btVector3       worldBoundsMin,worldBoundsMax;
127         collisionWorld->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax);
128
129
130   ///one way to draw all the contact points is iterating over contact manifolds / points:
131   int numManifolds = collisionWorld->getDispatcher()->getNumManifolds();
132   for (i=0;i<numManifolds;i++)
133   {
134     btPersistentManifold* contactManifold = collisionWorld->getDispatcher()->getManifoldByIndexInternal(i);
135     const btCollisionObject* obA = static_cast<const btCollisionObject*>(contactManifold->getBody0());
136     const btCollisionObject* obB = static_cast<const btCollisionObject*>(contactManifold->getBody1());
137     contactManifold->refreshContactPoints(obA->getWorldTransform(),obB->getWorldTransform());
138
139     int numContacts = contactManifold->getNumContacts();
140     for (int j=0;j<numContacts;j++)
141     {
142       btManifoldPoint& pt = contactManifold->getContactPoint(j);
143
144       glBegin(GL_LINES);
145       glColor3f(1, 1, 1);
146
147       btVector3 ptA = pt.getPositionWorldOnA() - m_cameraPosition;
148       btVector3 ptB = pt.getPositionWorldOnB() - m_cameraPosition;
149
150       glVertex3d(ptA.x(),ptA.y(),ptA.z());
151       glVertex3d(ptB.x(),ptB.y(),ptB.z());
152       glEnd();
153     }
154
155     //you can un-comment out this line, and then all points are removed
156     //contactManifold->clearManifold(); 
157   }
158
159         btScalar m[16];
160         btTransform temp;
161         
162
163   btVector3 color;
164   //int i;
165         for (i=0;i<numObjects;i++)
166         {
167           if (i % 2)
168           {
169             color = btVector3(1,0,0);
170           }
171           else
172           {
173       color = btVector3(0,0,1);
174           }
175           temp = objects[i].getWorldTransform();
176           temp.setOrigin(temp.getOrigin() - m_cameraPosition);
177                 temp.getOpenGLMatrix( m );
178                 m_shapeDrawer->drawOpenGL(m,objects[i].getCollisionShape(),color,getDebugMode(),worldBoundsMin,worldBoundsMax);
179         }
180
181   objects[1].getWorldTransform().setOrigin(objects[1].getWorldTransform().getOrigin()+btVector3(-VERY_SMALL_INCREMENT,-VERY_SMALL_INCREMENT,0));
182   objects[0].getWorldTransform().setOrigin(objects[0].getWorldTransform().getOrigin()+btVector3(VERY_SMALL_INCREMENT,VERY_SMALL_INCREMENT,0));
183   
184   float yStart = 20.f;
185   float yIncr = 20.f;
186   char buf[124];
187
188   glColor3f(0, 0, 0);
189
190   setOrthographicProjection();
191
192   glRasterPos3f(10.0f,yStart,0);
193   #ifdef BT_USE_DOUBLE_PRECISION
194   GLDebugDrawString(10.f,yStart,"Double Precision Mode");
195   #else
196   GLDebugDrawString(10.f,yStart,"Single Precision Mode");
197   #endif
198   yStart += yIncr;
199   
200   glRasterPos3f(10.0f,yStart,0);
201   sprintf(buf,"Movement distance in x and y axis = %lf", VERY_SMALL_INCREMENT);
202
203   GLDebugDrawString(10.f,yStart,buf);
204   yStart += yIncr;
205   
206   glRasterPos3f(10.0f,yStart,0);
207   btScalar xValue = objects[0].getWorldTransform().getOrigin().x();
208   btScalar yValue = objects[0].getWorldTransform().getOrigin().y();
209   btScalar zValue = objects[0].getWorldTransform().getOrigin().z();
210   sprintf(buf,"Cube 0 location = ( %lf, %lf, %lf )", xValue, yValue, zValue);
211   GLDebugDrawString(10.f,yStart,buf);
212   yStart += yIncr;
213
214   xValue = objects[1].getWorldTransform().getOrigin().x();
215   yValue = objects[1].getWorldTransform().getOrigin().y();
216   zValue = objects[1].getWorldTransform().getOrigin().z();
217   glRasterPos3f(10.0f,yStart,0);
218   sprintf(buf,"Cube 1 location = ( %lf, %lf, %lf )", xValue, yValue, zValue);
219   GLDebugDrawString(10.f,yStart,buf);
220   yStart += yIncr;
221
222   glRasterPos3f(10.0f,yStart,0);
223   GLDebugDrawString(10.f,yStart,"w=toggle wireframe/solid");
224
225   resetPerspectiveProjection();
226
227         glFlush();
228   glutSwapBuffers();
229 }
230
231 void DoublePrecisionDemo::clientResetScene()
232 {
233         objects[0].getWorldTransform().setOrigin(btVector3(LARGE_DISTANCE_FROM_ORIGIN,LARGE_DISTANCE_FROM_ORIGIN,LARGE_DISTANCE_FROM_ORIGIN));
234         objects[1].getWorldTransform().setOrigin(btVector3(LARGE_DISTANCE_FROM_ORIGIN-VERY_SMALL_INCREMENT,LARGE_DISTANCE_FROM_ORIGIN-VERY_SMALL_INCREMENT,LARGE_DISTANCE_FROM_ORIGIN));
235 }
236
237
238
239 void DoublePrecisionDemo::updateCamera() 
240 {
241   glMatrixMode(GL_PROJECTION);
242   glLoadIdentity();
243
244   // look at the stationary cube
245   m_cameraTargetPosition = objects[0].getWorldTransform().getOrigin();
246
247   m_cameraPosition = m_cameraTargetPosition;
248   m_cameraPosition[2] = m_cameraTargetPosition[2] - m_cameraDistance;
249
250   //update OpenGL camera settings
251   glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10000.0);
252
253   // To not loose precision in the rendering process, we shift the object to the origin
254   gluLookAt(0.0, 0.0, 0.0,
255     m_cameraTargetPosition[0]-m_cameraPosition[0],m_cameraTargetPosition[1]-m_cameraPosition[1], m_cameraTargetPosition[2]-m_cameraPosition[2],
256     m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ());
257   glMatrixMode(GL_MODELVIEW);
258 }
259
260 void DoublePrecisionDemo::keyboardCallback(unsigned char key, int x, int y)
261 {
262   if (key == 'w')
263   {
264     if (m_debugMode & btIDebugDraw::DBG_DrawWireframe)
265     {
266       m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawWireframe);
267       m_debugMode |= btIDebugDraw::DBG_DrawAabb;
268     }
269     else
270     {
271       m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawAabb);
272       m_debugMode |= btIDebugDraw::DBG_DrawWireframe;
273     }
274     return;
275   }
276   
277   DemoApplication::keyboardCallback(key, x, y);
278 }
279
280