Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / AllBulletDemosOSX / src / BTDemo.mm
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 #import "BTDemo.h"
17
18 ///////////////////////////////////////////////////////////////////////
19 // Bullet includes
20
21 #include "LinearMath/btScalar.h"
22 #include "LinearMath/btMinMax.h"
23
24 #include "DemoApplication.h"
25 #include "DemoEntries.h"
26 #include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
27
28 #include "GLDebugDrawer.h"
29
30 #include "LinearMath/btQuickprof.h"
31
32
33 ///////////////////////////////////////////////////////////////////////
34
35 #pragma mark -
36 #pragma mark Globals
37
38 static NSPoint MousePosition;
39 static NSSize  ViewSize;
40 static int     NumIterations = 10;
41 static BOOL        DisableDeactivation = NO;
42 static BOOL        DrawAABBs = NO;
43 static BOOL        DebugDraw = NO;
44 static BOOL        SplitImpulse = NO;
45 static BOOL        DrawContacts = NO;
46
47 ///////////////////////////////////////////////////////////////////////
48
49 #pragma mark -
50 #pragma mark BTDemoEntry
51
52 @interface BTDemoEntry : NSObject {
53         btDemoEntry *ctor;
54         DemoApplication *demo;
55 }
56
57 - (id) initWithDemoEntry: (btDemoEntry*) constructor;
58 - (DemoApplication*) demo;
59 - (void) reset;
60
61 @end
62
63 @implementation BTDemoEntry
64
65 - (id) initWithDemoEntry: (btDemoEntry*) constructor
66 {
67         if ( self = [super init] )
68         {
69                 ctor = constructor;
70                 [self reset];
71         }
72         
73         return self;
74 }
75
76 - (void) dealloc
77 {
78         if ( demo ) delete demo;
79         [super dealloc];
80 }
81
82 - (DemoApplication*) demo
83 {
84         return demo;
85 }
86
87 - (void) reset
88 {
89         if ( demo ) 
90         {
91                 if (demo->getDynamicsWorld()->getDebugDrawer())
92                         delete demo->getDynamicsWorld()->getDebugDrawer();
93                 
94                 delete demo;
95                 demo = NULL;
96         }
97
98         demo = ctor->createFcn();
99         btAssert(demo);
100
101         if (demo->getDynamicsWorld())
102         {
103                 demo->getDynamicsWorld()->setDebugDrawer(new GLDebugDrawer());
104         }
105
106         #ifndef BT_NO_PROFILE
107                 CProfileManager::Reset();
108         #endif //BT_NO_PROFILE
109 }
110
111 @end
112
113 ///////////////////////////////////////////////////////////////////////
114
115 #pragma mark -
116 #pragma mark BTDemo
117
118
119 @implementation BTDemo
120
121 + (NSArray*) demoNames
122 {
123         static NSMutableArray *DEMOS = nil;
124         if ( !DEMOS )
125         {
126                 DEMOS = [[NSMutableArray alloc] init];
127         
128                 btDemoEntry* e = g_demoEntries;
129                 while (e->createFcn)
130                 {
131                         [DEMOS addObject: [NSString stringWithUTF8String: e->name]];
132                         ++e;
133                 }
134         }
135                 
136         return DEMOS;
137 }
138
139 + (BOOL) isDemo: (NSString *) demoName
140 {
141         return [[self demoNames] containsObject: demoName];
142 }
143
144 + (BTDemo*) demoWithName: (NSString *) demoName
145 {       
146         if ( [BTDemo isDemo: demoName] )
147         {
148                 return [[[BTDemo alloc] initWithDemoName: demoName] autorelease];
149         }
150         
151         return nil;
152 }
153
154 - (id) initWithDemoName: (NSString *) demoName
155 {
156         if ( self = [super init] )
157         {
158                 _demoName = [demoName copy];
159                 
160                 // now walk the constructor list and find this demo
161                 
162                 btDemoEntry* e = g_demoEntries;
163                 while (e->createFcn)
164                 {
165                         NSString *name = [NSString stringWithCString: e->name];
166                         if ( [name isEqualToString: demoName] )
167                         {
168                                 _demo = [[BTDemoEntry alloc] initWithDemoEntry: e];
169                                 break;
170                         }
171                         
172                         e++;
173                 }               
174         }
175
176         return self;
177 }
178
179 - (void) dealloc
180 {
181         [_demoName release];
182         [_demo release];
183         [super dealloc];
184 }
185
186 - (void) reset
187 {
188         [_demo reset];
189
190         [self contextWillResize];
191         [self contextResized: ViewSize];
192         [self contextDidResize];
193 }
194
195 - (NSString*) demoName
196 {
197         return _demoName;
198 }
199
200 #pragma mark -
201 #pragma mark BTOpenGLDisplayDelegate
202
203 - (void) contextCreated
204 {}
205
206 - (void) contextWillBeDestroyed
207 {}
208
209 - (void) contextWillResize
210 {}
211
212 - (void) contextResized: (NSSize) newSize
213 {
214         ViewSize = newSize;
215         glViewport( 0, 0, (int) newSize.width, (int) newSize.height );
216
217         glMatrixMode(GL_PROJECTION);
218         glLoadIdentity();
219
220         [_demo demo]->reshape( (int) newSize.width, (int) newSize.height );
221 }
222
223 - (void) contextDidResize
224 {}
225
226 - (void) contextStateInvalidated
227 {}
228
229 - (void) display: (float) deltaT
230 {
231         DemoApplication *demo = [_demo demo];
232
233         if ( !demo )
234         {
235                 glClearColor( 1, 0.5, 1, 1 );
236                 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
237                 return;
238         }
239
240         if (demo->getDynamicsWorld())
241         {
242                 if (SplitImpulse)
243                 {
244                         demo->getDynamicsWorld()->getSolverInfo().m_splitImpulse=1;
245                 } else
246                 {
247                         demo->getDynamicsWorld()->getSolverInfo().m_splitImpulse=0;
248                 }
249         }
250         if (DrawAABBs)
251         { 
252                 demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawAabb);
253         } 
254         else
255         {
256                 demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_DrawAabb));
257         }
258         
259         if (DebugDraw)
260         {
261                 demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawWireframe);
262         } 
263         else
264         {
265                 demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_DrawWireframe));          
266         }
267         
268         if (DrawContacts)
269         {
270                 demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawContactPoints);
271         } 
272         else
273         {
274                 demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_DrawContactPoints));
275         }
276         
277         if (DisableDeactivation)
278         {
279                 demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_NoDeactivation);
280         } 
281         else
282         {
283                 demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_NoDeactivation));
284         }
285         
286         if (demo->getDynamicsWorld() && demo->getDynamicsWorld()->getWorldType() == BT_DISCRETE_DYNAMICS_WORLD)
287         {
288                 btDiscreteDynamicsWorld* discreteWorld = (btDiscreteDynamicsWorld*) demo->getDynamicsWorld();
289                 discreteWorld->getSolverInfo().m_numIterations = NumIterations;
290         }
291                 
292         if (!demo->isIdle())
293         {
294                 demo->clientMoveAndDisplay();
295         }
296         else
297         {
298                 demo->displayCallback();
299         }
300         
301 }
302
303 - (void) keyPressed: (unsigned char) key
304 {
305         [_demo demo]->keyboardCallback(key, (int)MousePosition.x, (int)MousePosition.y );
306 }
307
308 - (void) keyReleased: (unsigned char) key
309 {}
310
311 - (void) specialKeyPressed: (unsigned) key
312 {
313         [_demo demo]->specialKeyboard(key,(int)MousePosition.x, (int)MousePosition.y );
314 }
315
316 - (void) specialKeyReleased: (unsigned) key
317 {
318         [_demo demo]->specialKeyboardUp(key,(int)MousePosition.x, (int)MousePosition.y );
319 }
320
321 - (void) mouseButtonPressed: (unsigned) mouseButton
322 {
323         [_demo demo]->mouseFunc( mouseButton, GLUT_DOWN, (int)MousePosition.x, (int)MousePosition.y );
324 }
325
326 - (void) mouseButtonReleased: (unsigned) mouseButton
327 {
328         [_demo demo]->mouseFunc( mouseButton, GLUT_UP, (int)MousePosition.x, (int)MousePosition.y );
329 }
330
331 - (void) mouseMoved: (NSPoint) delta
332 {
333         [_demo demo]->mouseMotionFunc((int)MousePosition.x, (int)MousePosition.y );
334 }
335
336 - (void) newMousePosition: (NSPoint) newMousePosition
337 {
338         // Need to invert Y, since DemoApplication assumes origin at top-left
339         MousePosition = NSMakePoint( newMousePosition.x, ViewSize.height - newMousePosition.y );
340 }
341
342 - (void) scrollWheel: (NSPoint) delta
343 {}
344
345 #pragma mark -
346 #pragma mark Global Simulation Properties
347
348 + (void) setIterations: (unsigned) iterations
349 {
350         NumIterations = iterations;
351 }
352
353 + (unsigned) iterations
354 {
355         return NumIterations;
356 }
357
358 + (unsigned) minIterations { return 1; }
359 + (unsigned) maxIterations { return 1000; }
360
361
362 + (void) setDisableDeactivation: (BOOL) disableDeactivation
363 {
364         DisableDeactivation = disableDeactivation;
365 }
366
367 + (BOOL) disableDeactivation
368 {
369         return DisableDeactivation;
370 }
371
372 + (void) setDrawAABBs: (BOOL) drawAABBs
373 {
374         DrawAABBs = drawAABBs;
375 }
376
377 + (BOOL) drawAABBs
378 {
379         return DrawAABBs;
380 }
381
382 + (void) setDebugDraw: (BOOL) debugDraw
383 {
384         DebugDraw = debugDraw;
385 }
386
387 + (BOOL) debugDraw
388 {
389         return DebugDraw;
390 }
391
392 + (void) setSplitImpulse: (BOOL) splitImpulse
393 {
394         SplitImpulse = splitImpulse;
395 }
396
397 + (BOOL) splitImpulse
398 {
399         return SplitImpulse;
400 }
401
402 + (void) setDrawContacts: (BOOL) drawContacts
403 {
404         DrawContacts = drawContacts;
405 }
406
407 + (BOOL) drawContacts
408 {
409         return DrawContacts;
410 }
411
412
413 @end