Initialize libbullet git in 2.0_beta.
[platform/upstream/libbullet.git] / Extras / PhysicsEffects / sample / api_physics_effects / 1_simple / main.cpp
1 /*\r
2 Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.\r
3 All rights reserved.\r
4 \r
5 Physics Effects is open software; you can redistribute it and/or\r
6 modify it under the terms of the BSD License.\r
7 \r
8 Physics Effects is distributed in the hope that it will be useful,\r
9 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r
11 See the BSD License for more details.\r
12 \r
13 A copy of the BSD License is distributed with\r
14 Physics Effects under the filename: physics_effects_license.txt\r
15 */\r
16 \r
17 #include "../common/common.h"\r
18 #include "../common/ctrl_func.h"\r
19 #include "../common/render_func.h"\r
20 #include "../common/perf_func.h"\r
21 #include "physics_func.h"\r
22 #include "barrel.h"\r
23 #include "landscape.h"\r
24 \r
25 #ifdef _WIN32\r
26         #include <gl/gl.h>\r
27         #include <gl/glu.h>\r
28 #endif\r
29 \r
30 // ARA begin insert new code\r
31 #ifdef __ANDROID__\r
32         #include <EGL/egl.h>\r
33         #include <GLES/gl.h>\r
34         #include <cpu-features.h>       // used to check for presence of NEON on device\r
35         #ifdef __ARM_NEON__\r
36                 #include <arm_neon.h>\r
37 #ifdef TEST_NEON_PERFORMANCE    // define this to run NEON performance tests\r
38                 #include "../../test_ARM_NEON_performance/test_neon.h"\r
39 #endif\r
40         #endif  // __ARM_NEON__\r
41 #endif // __ANDROID__\r
42 // ARA end\r
43 \r
44 #define SAMPLE_NAME "api_physics_effects/1_simple"\r
45 \r
46 static bool s_isRunning = true;\r
47 \r
48 int sceneId = 0;\r
49 bool simulating = false;\r
50 \r
51 int landscapeMeshId;\r
52 int convexMeshId;\r
53 \r
54 void render(void)\r
55 {\r
56         render_begin();\r
57         \r
58         for(int i=0;i<physics_get_num_rigidbodies();i++) {\r
59                 const PfxRigidState &state = physics_get_state(i);\r
60                 const PfxCollidable &coll = physics_get_collidable(i);\r
61 \r
62                 PfxTransform3 rbT(state.getOrientation(), state.getPosition());\r
63 \r
64                 PfxShapeIterator itrShape(coll);\r
65                 for(int j=0;j<coll.getNumShapes();j++,++itrShape) {\r
66                         const PfxShape &shape = *itrShape;\r
67                         PfxTransform3 offsetT = shape.getOffsetTransform();\r
68                         PfxTransform3 worldT = rbT * offsetT;\r
69 \r
70                         switch(shape.getType()) {\r
71                                 case kPfxShapeSphere:\r
72                                 render_sphere(\r
73                                         worldT,\r
74                                         PfxVector3(1,1,1),\r
75                                         PfxFloatInVec(shape.getSphere().m_radius));\r
76                                 break;\r
77 \r
78                                 case kPfxShapeBox:\r
79                                 render_box(\r
80                                         worldT,\r
81                                         PfxVector3(1,1,1),\r
82                                         shape.getBox().m_half);\r
83                                 break;\r
84 \r
85                                 case kPfxShapeCapsule:\r
86                                 render_capsule(\r
87                                         worldT,\r
88                                         PfxVector3(1,1,1),\r
89                                         PfxFloatInVec(shape.getCapsule().m_radius),\r
90                                         PfxFloatInVec(shape.getCapsule().m_halfLen));\r
91                                 break;\r
92 \r
93                                 case kPfxShapeCylinder:\r
94                                 render_cylinder(\r
95                                         worldT,\r
96                                         PfxVector3(1,1,1),\r
97                                         PfxFloatInVec(shape.getCylinder().m_radius),\r
98                                         PfxFloatInVec(shape.getCylinder().m_halfLen));\r
99                                 break;\r
100 \r
101                                 case kPfxShapeConvexMesh:\r
102                                 render_mesh(\r
103                                         worldT,\r
104                                         PfxVector3(1,1,1),\r
105                                         convexMeshId);\r
106                                 break;\r
107 \r
108                                 case kPfxShapeLargeTriMesh:\r
109                                 render_mesh(\r
110                                         worldT,\r
111                                         PfxVector3(1,1,1),\r
112                                         landscapeMeshId);\r
113                                 break;\r
114 \r
115                                 default:\r
116                                 break;\r
117                         }\r
118                 }\r
119         }\r
120 \r
121         render_end();\r
122 }\r
123 \r
124 // ARA begin insert new code\r
125 #ifdef __ANDROID__\r
126 static void runNEONTests()\r
127 {\r
128         uint64_t features = android_getCpuFeatures();\r
129         if ((features & ANDROID_CPU_ARM_FEATURE_NEON) == 0)\r
130         {\r
131                 SCE_PFX_PRINTF("CPU has NO support for NEON.");\r
132         }\r
133         else\r
134         {\r
135                 SCE_PFX_PRINTF("CPU HAS support for NEON.\n");\r
136 \r
137 #ifdef __ARM_NEON__\r
138 #ifdef TEST_NEON_PERFORMANCE\r
139                 SCE_PFX_PRINTF("Running NEON performance tests...\n");\r
140 \r
141                 TestNeonDotProduct();\r
142                 TestNeonCrossProduct();\r
143                 TestNeonMatrix3OperatorMultiply();\r
144                 TestNeonMatrix4OperatorMultiply();\r
145                 TestNeonOrthoInverseTransform3();\r
146                 TestNeonTransform3OperatorMultiply();\r
147                 TestNeonTransposeMatrix3();\r
148                 TestNeonSolveLinearConstraintRow();\r
149 \r
150                 SCE_PFX_PRINTF("Finished NEON performance tests.");\r
151 #endif  // TEST_NEON_PERFORMANCE\r
152 #endif  // __ARM_NEON__\r
153         }\r
154 }\r
155 #endif // __ANDROID__\r
156 // ARA end\r
157 \r
158 int init(void)\r
159 {\r
160 // ARA begin insert new code\r
161 #ifdef __ANDROID__\r
162         runNEONTests();\r
163 #endif\r
164 // ARA end\r
165 \r
166         perf_init();\r
167         ctrl_init();\r
168         render_init();\r
169         physics_init();\r
170 \r
171         landscapeMeshId = render_init_mesh(\r
172                 LargeMeshVtx,sizeof(float)*6,\r
173                 LargeMeshVtx+3,sizeof(float)*6,\r
174                 LargeMeshIdx,sizeof(unsigned short)*3,\r
175                 LargeMeshVtxCount,LargeMeshIdxCount/3);\r
176 \r
177         convexMeshId = render_init_mesh(\r
178                 BarrelVtx,sizeof(float)*6,\r
179                 BarrelVtx+3,sizeof(float)*6,\r
180                 BarrelIdx,sizeof(unsigned short)*3,\r
181                 BarrelVtxCount,BarrelIdxCount/3);\r
182 \r
183         return 0;\r
184 }\r
185 \r
186 static int shutdown(void)\r
187 {\r
188         ctrl_release();\r
189         render_release();\r
190         physics_release();\r
191         perf_release();\r
192 \r
193         return 0;\r
194 }\r
195 \r
196 void update(void)\r
197 {\r
198         float angX,angY,r;\r
199         render_get_view_angle(angX,angY,r);\r
200 \r
201         ctrl_update();\r
202         \r
203         if(ctrl_button_pressed(BTN_UP)) {\r
204                 angX -= 0.05f;\r
205                 if(angX < -1.4f) angX = -1.4f;\r
206                 if(angX > -0.01f) angX = -0.01f;\r
207         }\r
208 \r
209         if(ctrl_button_pressed(BTN_DOWN)) {\r
210                 angX += 0.05f;\r
211                 if(angX < -1.4f) angX = -1.4f;\r
212                 if(angX > -0.01f) angX = -0.01f;\r
213         }\r
214 \r
215         if(ctrl_button_pressed(BTN_LEFT)) {\r
216                 angY -= 0.05f;\r
217         }\r
218 \r
219         if(ctrl_button_pressed(BTN_RIGHT)) {\r
220                 angY += 0.05f;\r
221         }\r
222 \r
223         if(ctrl_button_pressed(BTN_ZOOM_OUT)) {\r
224                 r *= 1.1f;\r
225                 if(r > 500.0f) r = 500.0f;\r
226         }\r
227 \r
228         if(ctrl_button_pressed(BTN_ZOOM_IN)) {\r
229                 r *= 0.9f;\r
230                 if(r < 1.0f) r = 1.0f;\r
231         }\r
232 \r
233         if(ctrl_button_pressed(BTN_SCENE_RESET) == BTN_STAT_DOWN) {\r
234                 physics_create_scene(sceneId);\r
235         }\r
236 \r
237         if(ctrl_button_pressed(BTN_SCENE_NEXT) == BTN_STAT_DOWN) {\r
238                 physics_create_scene(++sceneId);\r
239         }\r
240 \r
241         if(ctrl_button_pressed(BTN_SIMULATION) == BTN_STAT_DOWN) {\r
242                 simulating = !simulating;\r
243         }\r
244 \r
245         if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_DOWN) {\r
246                 simulating = true;\r
247         }\r
248         else if(ctrl_button_pressed(BTN_STEP) == BTN_STAT_UP || ctrl_button_pressed(BTN_STEP) == BTN_STAT_KEEP) {\r
249                 simulating = false;\r
250         }\r
251 \r
252         render_set_view_angle(angX,angY,r);\r
253 }\r
254 \r
255 #ifndef _WIN32\r
256 \r
257 // ARA begin insert new code\r
258 #ifdef  __ANDROID__\r
259 \r
260 ///////////////////////////////////////////////////////////////////////////////\r
261 // sceneChange\r
262 //\r
263 /// This function is used to change the physics scene on Android devices\r
264 ///////////////////////////////////////////////////////////////////////////////\r
265 void sceneChange()\r
266 {\r
267         physics_create_scene(sceneId++);\r
268 }\r
269 \r
270 #else   // __ANDROID__\r
271 // ARA end\r
272 \r
273 ///////////////////////////////////////////////////////////////////////////////\r
274 // Main\r
275 \r
276 int main(void)\r
277 {\r
278         init();\r
279 \r
280         physics_create_scene(sceneId);\r
281         \r
282         printf("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME);\r
283 \r
284         while (s_isRunning) {\r
285                 update();\r
286                 if(simulating) physics_simulate();\r
287                 render();\r
288 \r
289                 perf_sync();\r
290         }\r
291 \r
292         shutdown();\r
293 \r
294         printf("## %s: FINISHED ##\n", SAMPLE_NAME);\r
295 \r
296         return 0;\r
297 }\r
298 \r
299 // ARA begin insert new code\r
300 #endif  // __ANDROID__\r
301 // ARA end\r
302 \r
303 #else   // _WIN32\r
304 \r
305 ///////////////////////////////////////////////////////////////////////////////\r
306 // WinMain\r
307 \r
308 extern HDC hDC;\r
309 extern HGLRC hRC;\r
310 HWND hWnd;\r
311 HINSTANCE hInstance;\r
312 \r
313 void releaseWindow()\r
314 {\r
315         if(hRC) {\r
316                 wglMakeCurrent(0,0);\r
317                 wglDeleteContext(hRC);\r
318         }\r
319         \r
320         if(hDC) ReleaseDC(hWnd,hDC);\r
321         if(hWnd) DestroyWindow(hWnd);\r
322         \r
323         UnregisterClass(SAMPLE_NAME,hInstance);\r
324 }\r
325 \r
326 LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM     wParam,LPARAM lParam)\r
327 {\r
328         switch(uMsg) {\r
329                 case WM_SYSCOMMAND:\r
330                 {\r
331                         switch (wParam) {\r
332                                 case SC_SCREENSAVE:\r
333                                 case SC_MONITORPOWER:\r
334                                 return 0;\r
335                         }\r
336                         break;\r
337                 }\r
338 \r
339                 case WM_CLOSE:\r
340                 PostQuitMessage(0);\r
341                 return 0;\r
342 \r
343                 case WM_SIZE:\r
344                 render_resize(LOWORD(lParam),HIWORD(lParam));\r
345                 return 0;\r
346         }\r
347 \r
348         return DefWindowProc(hWnd,uMsg,wParam,lParam);\r
349 }\r
350 \r
351 bool createWindow(char* title, int width, int height)\r
352 {\r
353         WNDCLASS wc;\r
354         RECT rect;\r
355         rect.left=0;\r
356         rect.right=width;\r
357         rect.top=0;\r
358         rect.bottom=height;\r
359 \r
360         hInstance = GetModuleHandle(NULL);\r
361         wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;\r
362         wc.lpfnWndProc = (WNDPROC) WndProc;\r
363         wc.cbClsExtra = 0;\r
364         wc.cbWndExtra = 0;\r
365         wc.hInstance = hInstance;\r
366         wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);\r
367         wc.hCursor = LoadCursor(NULL, IDC_ARROW);\r
368         wc.hbrBackground = NULL;\r
369         wc.lpszMenuName = NULL;\r
370         wc.lpszClassName = SAMPLE_NAME;\r
371 \r
372         if(!RegisterClass(&wc)) {\r
373                 return false;\r
374         }\r
375 \r
376         AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE);\r
377 \r
378         if(!(hWnd=CreateWindowEx(WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,SAMPLE_NAME,title,\r
379                                                         WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,\r
380                                                         0,0,rect.right-rect.left,rect.bottom-rect.top,\r
381                                                         NULL,NULL,hInstance,NULL))) {\r
382                 releaseWindow();\r
383                 return false;\r
384         }\r
385 \r
386     static PIXELFORMATDESCRIPTOR pfd = {\r
387                 sizeof(PIXELFORMATDESCRIPTOR),\r
388                 1,\r
389                 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,\r
390                 PFD_TYPE_RGBA,\r
391                 32,\r
392                 0, 0,\r
393                 0, 0,\r
394                 0, 0,\r
395                 0, 0,\r
396                 0,\r
397                 0, 0, 0, 0,\r
398                 32,\r
399                 0,\r
400                 0,\r
401                 PFD_MAIN_PLANE,\r
402                 0,\r
403                 0, 0, 0\r
404     };\r
405         \r
406         if(!(hDC=GetDC(hWnd)))\r
407         {\r
408                 releaseWindow();\r
409                 OutputDebugString("");\r
410                 return FALSE;\r
411         }\r
412         \r
413         int pixelformat;\r
414         \r
415     if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ){\r
416                 OutputDebugString("ChoosePixelFormat Failed....");\r
417         return FALSE;\r
418     }\r
419 \r
420     if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE){\r
421                 OutputDebugString("SetPixelFormat Failed....");\r
422         return FALSE;\r
423     }\r
424 \r
425         if (!(hRC=wglCreateContext(hDC))){\r
426                 OutputDebugString("Creating HGLRC Failed....");\r
427                 return FALSE;\r
428         }\r
429         \r
430         // Set Vsync\r
431         //BOOL (WINAPI *wglSwapIntervalEXT)(int) = NULL;\r
432 \r
433         //if(strstr((char*)glGetString( GL_EXTENSIONS ),"WGL_EXT_swap_control")== 0) {\r
434         //}\r
435         //else {\r
436                 //wglSwapIntervalEXT = (BOOL (WINAPI*)(int))wglGetProcAddress("wglSwapIntervalEXT");\r
437                 //if(wglSwapIntervalEXT) wglSwapIntervalEXT(1);\r
438         //}\r
439         \r
440         wglMakeCurrent(hDC,hRC);\r
441         \r
442         ShowWindow(hWnd,SW_SHOW);\r
443         SetForegroundWindow(hWnd);\r
444         SetFocus(hWnd);\r
445 \r
446         render_resize(width, height);\r
447         \r
448         glClearColor(0.0f,0.0f,0.0f,0.0f);\r
449         glClearDepth(1.0f);\r
450         \r
451         return TRUE;\r
452 }\r
453 \r
454 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)\r
455 {\r
456         if(!createWindow(SAMPLE_NAME,DISPLAY_WIDTH,DISPLAY_HEIGHT)) {\r
457                 MessageBox(NULL,"Can't create gl window.","ERROR",MB_OK|MB_ICONEXCLAMATION);\r
458                 return 0;\r
459         }\r
460         \r
461         init();\r
462         \r
463         physics_create_scene(sceneId);\r
464         \r
465         SCE_PFX_PRINTF("## %s: INIT SUCCEEDED ##\n", SAMPLE_NAME);\r
466         \r
467         MSG msg;\r
468         while(s_isRunning) {\r
469                 if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {\r
470                         if(msg.message==WM_QUIT) {\r
471                                 s_isRunning = false;\r
472                         }\r
473                         else {\r
474                                 TranslateMessage(&msg);\r
475                                 DispatchMessage(&msg);\r
476                         }\r
477                 }\r
478                 else {\r
479                         update();\r
480                         if(simulating) physics_simulate();\r
481                         render();\r
482 \r
483                         perf_sync();\r
484                 }\r
485         }\r
486 \r
487         shutdown();\r
488 \r
489         SCE_PFX_PRINTF("## %s: FINISHED ##\n", SAMPLE_NAME);\r
490 \r
491         releaseWindow();\r
492         return (msg.wParam);\r
493 }\r
494 \r
495 #endif\r