resetting manifest requested domain to floor
[platform/upstream/libbullet.git] / Extras / CDTestFramework / CDTestFramework.cpp
1 /*
2 CDTestFramework http://codercorner.com
3 Copyright (c) 2007-2008 Pierre Terdiman,  pierre@codercorner.com
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 #include "stdafx.h"
17
18 #include "CollisionTest.h"
19 #include "SphereMeshQuery.h"
20 #include "OBBMeshQuery.h"
21 #include "CapsuleMeshQuery.h"
22 #include "CompleteBoxPruning.h"
23 #include "BulletSAPCompleteBoxPruningTest.h"
24 #include "BulletSAPCompleteBoxPruningTest.h"
25 #include "BipartiteBoxPruning.h"
26 #include "OpcodeArraySAPTest.h"
27 #include "RenderingHelpers.h"
28 #include "Terrain.h"
29 #include "Camera.h"
30 #include "GLFontRenderer.h"
31 #include "BulletCollision/BroadphaseCollision/btDbvtBroadphase.h"
32 #include "LinearMath/btQuickprof.h"
33
34 #define NUM_SAP_BOXES 8192
35 //#define NUM_SAP_BOXES 16384
36 //#define NUM_SAP_BOXES 1024
37
38 int             percentUpdate   =       100;
39 //float objectSpeed             =       0.005f;
40 float   objectSpeed             =       0.01f;
41 bool    enableDraw              =       true;
42
43 //Broadphase comparison
44 //Static case (updating 10% of objects to same position ( -> no swaps)
45 //number of objects //OPCODE BoxPruning / Bullet SAP / Bullet MultiSAP
46 //1024                     0.35ms, 0.03ms, 0.15ms
47 //8192                       21ms, 0.2ms, 5ms
48 //16384                   92ms , 0.5ms, 28ms
49
50 //Dynamic case, 10% objects are moving as fast as this testbed allows (0.01?)
51 //number of objects //OPCODE BoxPruning / Bullet SAP / Bullet MultiSAP
52 //1024                                          0.35ms, 0.2ms, 0.25ms
53 //8192                        21ms , 15ms , 13ms
54 //16384                    92ms,  80ms,  49ms
55
56
57 #define WINDOW_WIDTH    1024
58 #define WINDOW_HEIGHT   768
59
60 static int gMouseX = 0;
61 static int gMouseY = 0;
62 static int gButton = 0;
63
64 static TwBar* gMainBar = null;
65 enum TestIndex
66 {
67 //      TEST_SPHERE_MESH_QUERY,
68 //      TEST_OBB_MESH_QUERY,
69 //      TEST_CAPSULE_MESH_QUERY,
70 //      TEST_COMPLETE_BOX_PRUNING=0,
71         TEST_COMPLETE_BOX_PRUNING_8192,
72 //      TEST_BULLET_SAP_1024,
73 //      TEST_BULLET_SAP_8192,
74 //      TEST_BULLET_SAP_SORTEDPAIRS_8192,
75 //      TEST_BULLET_MULTISAP_8192,
76 //      TEST_BIPARTITE_BOX_PRUNING,
77         TEST_DBVT_8192,
78         TEST_BULLET_CUDA_8192,
79         TEST_BULLET_3DGRID_8192,
80         TEST_OPCODE_ARRAY_SAP,
81         MAX_NB_TESTS
82 };
83
84 //static int gTest = TEST_DBVT_8192;//TEST_BULLET_MULTISAP_8192;
85 //static int gSelectedTest = TEST_DBVT_8192;//TEST_BULLET_MULTISAP_8192;
86 static int gTest = TEST_BULLET_CUDA_8192;
87 static int gSelectedTest = TEST_BULLET_CUDA_8192;
88 static CollisionTest* gCollisionTests[MAX_NB_TESTS];
89
90 static GLFontRenderer gFnt;
91
92 /////////////////
93
94 static void KeyboardCallback(unsigned char key, int x, int y)
95 {
96         switch (key)
97         {
98                 case 27:        exit(0); break;
99
100                 case '+':
101                 {
102                         if(gTest!=MAX_NB_TESTS-1)
103                         {
104                                 gCollisionTests[gTest]->Deselect();
105                                 gTest++;
106                                 gSelectedTest++;
107                                 gCollisionTests[gTest]->Select();
108                         }
109                 }
110                 break;
111
112                 case '-':
113                 {
114                         if(gTest)
115                         {
116                                 gCollisionTests[gTest]->Deselect();
117                                 gTest--;
118                                 gSelectedTest--;
119                                 gCollisionTests[gTest]->Select();
120                         }
121                 }
122                 break;
123
124                 case 101:       MoveCameraForward();                                                                    break;
125                 case 103:       MoveCameraBackward();                                                                   break;
126                 case 100:       MoveCameraRight();                                                                              break;
127                 case 102:       MoveCameraLeft();                                                                               break;
128                 default:        gCollisionTests[gTest]->KeyboardCallback(key, x, y);    break;
129         }
130
131         TwEventKeyboardGLUT(key, x, y);
132 }
133
134 static void ArrowKeyCallback(int key, int x, int y)
135 {
136         KeyboardCallback(key, x, y);
137
138         TwEventSpecialGLUT(key, x, y);
139 }
140         
141 static void MouseCallback(int button, int state, int x, int y)
142 {
143         gButton = button;
144         gMouseX = x;
145         gMouseY = y;
146
147         if(!TwEventMouseButtonGLUT(button, state, x, y))
148         {
149                 gCollisionTests[gTest]->MouseCallback(button, state, x, y);
150         }
151 }
152
153 static void MotionCallback(int x, int y)
154 {
155         if(!TwEventMouseMotionGLUT(x, y))
156         {
157                 if(gButton==2)
158                 {
159                         int dx = gMouseX - x;
160                         int dy = gMouseY - y;
161                         
162                         RotateCamera(dx, dy);
163
164                         gMouseX = x;
165                         gMouseY = y;
166                 }
167                 else
168                         gCollisionTests[gTest]->MotionCallback(x, y);
169         }
170 }
171
172 static void RenderCallback()
173 {
174         // Clear buffers
175         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
176     
177         // Setup camera
178         glMatrixMode(GL_PROJECTION);
179         SetupCameraMatrix();
180
181         glMatrixMode(GL_MODELVIEW);
182         glLoadIdentity();
183
184         glEnable(GL_LIGHTING);
185
186         if(0 /*gRenderWireframe*/)
187                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
188         else
189                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
190
191         gCollisionTests[gTest]->PerformTest();
192
193         // Draw tweak bars
194         TwDraw();
195
196         glutSwapBuffers();
197         glutPostRedisplay();
198
199         if(gSelectedTest!=gTest)
200         {
201                 gCollisionTests[gTest]->Deselect();
202                 gTest = gSelectedTest;
203                 gCollisionTests[gTest]->Select();
204         }
205 }
206
207 static void ReshapeCallback(int width, int height)
208 {
209         glViewport(0, 0, width, height);
210
211         // Send the new window size to AntTweakBar
212         TwWindowSize(width, height);
213 }
214
215 static void IdleCallback()
216 {
217         glutPostRedisplay();
218 }
219
220 static void Terminate()
221 {
222         ReleaseTerrain();
223
224         for(int i=0;i<MAX_NB_TESTS;i++)
225         {
226                 gCollisionTests[i]->Release();
227                 DELETESINGLE(gCollisionTests[i]);
228         }
229
230         if(gMainBar)
231         {
232                 TwDeleteBar(gMainBar);
233                 gMainBar = null;
234         }
235
236         TwTerminate();
237 }
238
239 int myGlutModifiers()
240 {
241         return glutGetModifiers();
242 }
243 int main(int argc, char** argv)
244 {
245         {
246         ::SetPriorityClass(::GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
247         /*btDbvt::benchmark();
248         exit(0);*/
249         }
250         // Initialize AntTweakBar
251         // (note that AntTweakBar could also be intialize after GLUT, no matter)
252         if(!TwInit(TW_OPENGL, NULL))
253         {
254                 // A fatal error occured        
255                 fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError());
256         }
257
258         // Initialize Glut
259         glutInit(&argc, argv);
260         glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
261         glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
262         int mainHandle = glutCreateWindow("CD Test Framework");
263
264 /*      HWND hWnd;
265         hWnd = FindWindow("GLUT", "CD Test Framework");
266         RECT Rect;
267         GetWindowRect(hWnd, &Rect);
268 */
269         glutCreateMenu(NULL);
270         glutSetWindow(mainHandle);
271         glutDisplayFunc(RenderCallback);
272         glutReshapeFunc(ReshapeCallback);
273         glutIdleFunc(IdleCallback);
274         glutKeyboardFunc(KeyboardCallback);
275         glutSpecialFunc(ArrowKeyCallback);
276         glutMouseFunc(MouseCallback);
277         glutMotionFunc(MotionCallback);
278         atexit(Terminate);      // Called after glutMainLoop ends
279
280         glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT);
281         TwGLUTModifiersFunc(myGlutModifiers);
282
283         // Setup default render states
284         glClearColor(0.3f, 0.4f, 0.5f, 1.0);
285         glEnable(GL_DEPTH_TEST);
286         glEnable(GL_COLOR_MATERIAL);
287         glEnable(GL_CULL_FACE);
288         glDepthFunc(GL_LEQUAL);
289
290         // Setup lighting
291         glEnable(GL_LIGHTING);
292         float AmbientColor[] = { 0.0f, 0.1f, 0.2f, 0.0f };              glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientColor);
293         float DiffuseColor[] = { 1.0f, 1.0f, 1.0f, 0.0f };              glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseColor);
294         float SpecularColor[] = { 0.0f, 0.0f, 0.0f, 0.0f };             glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularColor);
295         float Position[] = { -10.0f, 1000.0f, -4.0f, 1.0f };    glLightfv(GL_LIGHT0, GL_POSITION, Position);
296         glEnable(GL_LIGHT0);
297
298         gFnt.init();
299         gFnt.setScreenResolution(WINDOW_WIDTH, WINDOW_HEIGHT);
300         gFnt.setColor(1.0f, 1.0f, 1.0f, 1.0f);
301
302         CreateTerrain();
303
304         // Create main tweak bar
305         {
306                 gMainBar = TwNewBar("CollisionTests");
307                 TwEnumVal testEV[MAX_NB_TESTS] = {
308 //                      {TEST_SPHERE_MESH_QUERY, "Sphere-mesh query"},
309 //                      {TEST_OBB_MESH_QUERY, "OBB-mesh query"},
310 //                      {TEST_CAPSULE_MESH_QUERY, "Capsule-mesh query"},
311 //                      {TEST_COMPLETE_BOX_PRUNING, "OPCODE SAP 1024"},
312                         {TEST_COMPLETE_BOX_PRUNING_8192, "OPCODE BOX PRUNING 8192"},
313 //                      {TEST_BULLET_SAP_1024, "Bullet SAP HASHPAIR 1024"},
314 //                      {TEST_BULLET_SAP_8192, "Bullet SAP HASHPAIR 8192"},
315 //                      {TEST_BULLET_SAP_SORTEDPAIRS_8192, "Bullet SAP SORTEDPAIR 8192"},
316 //                      {TEST_BULLET_MULTISAP_8192, "Bullet MultiSAP 8192"},
317 //                      {TEST_BIPARTITE_BOX_PRUNING, "Bipartite box pruning"},
318                         {TEST_DBVT_8192, "Bullet DBVT 8192"},
319                         {TEST_BULLET_CUDA_8192, "Bullet CUDA 8192"},
320                         {TEST_BULLET_3DGRID_8192, "Bullet 3D Grid 8192"},
321                         {TEST_OPCODE_ARRAY_SAP, "OPCODE ARRAY SAP"},
322                 };
323                 TwType testType = TwDefineEnum("CollisionTest", testEV, MAX_NB_TESTS);
324                 TwAddVarRW(gMainBar, "CollisionTests", testType, &gSelectedTest, "");           
325                 TwAddVarRW(gMainBar, "% of updates",TW_TYPE_INT32,&percentUpdate,"min=0 max=100");
326                 TwAddVarRW(gMainBar, "Draw",TW_TYPE_BOOLCPP,&enableDraw,"");
327         }
328
329         // Create tests
330         gTest = 0;
331 //      gCollisionTests[TEST_SPHERE_MESH_QUERY] = new SphereMeshQuery;
332 //      gCollisionTests[TEST_OBB_MESH_QUERY]    = new OBBMeshQuery;
333 //      gCollisionTests[TEST_CAPSULE_MESH_QUERY]        = new CapsuleMeshQuery;
334 //      gCollisionTests[TEST_COMPLETE_BOX_PRUNING]      = new CompleteBoxPruningTest(NUM_SAP_BOXES);
335  //     gCollisionTests[TEST_COMPLETE_BOX_PRUNING_8192] = new CompleteBoxPruningTest(NUM_SAP_BOXES);
336         gCollisionTests[TEST_COMPLETE_BOX_PRUNING_8192] = new CompleteBoxPruningTest(NUM_SAP_BOXES);
337 //      gCollisionTests[TEST_BULLET_SAP_1024]   = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,1);
338 //      gCollisionTests[TEST_BULLET_SAP_8192]   = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,1);
339 //      gCollisionTests[TEST_BULLET_SAP_SORTEDPAIRS_8192]       = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,3);
340 //      gCollisionTests[TEST_BULLET_MULTISAP_8192]      = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,6);
341 //      gCollisionTests[TEST_BIPARTITE_BOX_PRUNING]     = new BipartiteBoxPruningTest;
342         gCollisionTests[TEST_DBVT_8192] = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,7);
343         gCollisionTests[TEST_BULLET_CUDA_8192]  = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,8);
344         gCollisionTests[TEST_BULLET_3DGRID_8192]        = new BulletSAPCompleteBoxPruningTest(NUM_SAP_BOXES,9);
345         gCollisionTests[TEST_OPCODE_ARRAY_SAP]  = new OpcodeArraySAPTest(NUM_SAP_BOXES);
346
347         for(int i=0;i<MAX_NB_TESTS;i++)
348                 gCollisionTests[i]->Init();
349         gCollisionTests[gTest]->Select();
350
351         //
352         MotionCallback(0,0);
353
354         // Run
355         glutMainLoop();
356
357         return 0;
358 }
359
360
361 #ifdef OLDIES
362
363 #include "btBulletCollisionCommon.h"
364
365 class BulletMeshInterface : public btStridingMeshInterface
366 {
367         public:
368                 /// get read and write access to a subpart of a triangle mesh
369                 /// this subpart has a continuous array of vertices and indices
370                 /// in this way the mesh can be handled as chunks of memory with striding
371                 /// very similar to OpenGL vertexarray support
372                 /// make a call to unLockVertexBase when the read and write access is finished  
373                 virtual void    getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0)
374                 {
375                         numverts = gTerrainData->nbVerts;
376                         (*vertexbase) = (unsigned char *)gTerrainData->verts;
377                         type = PHY_FLOAT;
378                         stride = sizeof(Point);
379
380                         numfaces = gTerrainData->nbFaces;
381                         (*indexbase) = (unsigned char *)gTerrainData->faces;
382                         indicestype = PHY_INTEGER;
383                         indexstride = 3*sizeof(udword); // ??
384                 }
385                 
386                 virtual void    getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const
387                 {
388                         numverts = gTerrainData->nbVerts;
389                         (*vertexbase) = (unsigned char *)gTerrainData->verts;
390                         type = PHY_FLOAT;
391                         stride = sizeof(Point);
392
393                         numfaces = gTerrainData->nbFaces;
394                         (*indexbase) = (unsigned char *)gTerrainData->faces;
395                         indicestype = PHY_INTEGER;
396                         indexstride = 3*sizeof(udword); // ??
397                 }
398         
399                 /// unLockVertexBase finishes the access to a subpart of the triangle mesh
400                 /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished
401                 virtual void    unLockVertexBase(int subpart)
402                 {
403                 }
404
405                 virtual void    unLockReadOnlyVertexBase(int subpart) const
406                 {
407                 }
408
409
410                 /// getNumSubParts returns the number of seperate subparts
411                 /// each subpart has a continuous array of vertices and indices
412                 virtual int             getNumSubParts() const
413                 {
414                         return 1;
415                 }
416
417                 virtual void    preallocateVertices(int numverts)
418                 {
419                 }
420                 virtual void    preallocateIndices(int numindices)
421                 {
422                 }
423 };
424
425 void BuildBulletTree()
426 {
427 /*      BulletMeshInterface btMeshInterface;
428
429         btOptimizedBvh* btTree = new btOptimizedBvh;
430         btTree->build(&btMeshInterface, true);
431
432
433         struct MyNodeOverlapCallback : public btNodeOverlapCallback
434         {
435                 virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
436                 {
437                 }
438         };
439
440         MyNodeOverlapCallback   myNodeCallback(callback,m_meshInterface);
441
442         m_bvh->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
443 */
444
445
446 }
447
448 #endif