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 | #include "DemoApplication.h" |
---|
18 | #include "LinearMath/btIDebugDraw.h" |
---|
19 | #include "BulletDynamics/Dynamics/btDynamicsWorld.h" |
---|
20 | |
---|
21 | #include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"//picking |
---|
22 | #include "BulletCollision/CollisionShapes/btCollisionShape.h" |
---|
23 | #include "BulletCollision/CollisionShapes/btBoxShape.h" |
---|
24 | #include "BulletCollision/CollisionShapes/btSphereShape.h" |
---|
25 | #include "BulletCollision/CollisionShapes/btCompoundShape.h" |
---|
26 | #include "BulletCollision/CollisionShapes/btUniformScalingShape.h" |
---|
27 | #include "BulletDynamics/ConstraintSolver/btConstraintSolver.h" |
---|
28 | #include "GL_ShapeDrawer.h" |
---|
29 | #include "LinearMath/btQuickprof.h" |
---|
30 | #include "LinearMath/btDefaultMotionState.h" |
---|
31 | |
---|
32 | #include "GLDebugFont.h" |
---|
33 | |
---|
34 | |
---|
35 | extern bool gDisableDeactivation; |
---|
36 | int numObjects = 0; |
---|
37 | const int maxNumObjects = 16384; |
---|
38 | btTransform startTransforms[maxNumObjects]; |
---|
39 | btCollisionShape* gShapePtr[maxNumObjects];//1 rigidbody has 1 shape (no re-use of shapes) |
---|
40 | #define SHOW_NUM_DEEP_PENETRATIONS 1 |
---|
41 | |
---|
42 | extern int gNumClampedCcdMotions; |
---|
43 | |
---|
44 | #ifdef SHOW_NUM_DEEP_PENETRATIONS |
---|
45 | extern int gNumDeepPenetrationChecks; |
---|
46 | |
---|
47 | extern int gNumSplitImpulseRecoveries; |
---|
48 | extern int gNumGjkChecks; |
---|
49 | extern int gNumAlignedAllocs; |
---|
50 | extern int gNumAlignedFree; |
---|
51 | extern int gTotalBytesAlignedAllocs; |
---|
52 | |
---|
53 | #endif // |
---|
54 | |
---|
55 | |
---|
56 | DemoApplication::DemoApplication() |
---|
57 | //see btIDebugDraw.h for modes |
---|
58 | : |
---|
59 | m_dynamicsWorld(0), |
---|
60 | m_pickConstraint(0), |
---|
61 | m_shootBoxShape(0), |
---|
62 | m_cameraDistance(15.0), |
---|
63 | m_debugMode(0), |
---|
64 | m_ele(20.f), |
---|
65 | m_azi(0.f), |
---|
66 | m_cameraPosition(0.f,0.f,0.f), |
---|
67 | m_cameraTargetPosition(0.f,0.f,0.f), |
---|
68 | m_scaleBottom(0.5f), |
---|
69 | m_scaleFactor(2.f), |
---|
70 | m_cameraUp(0,1,0), |
---|
71 | m_forwardAxis(2), |
---|
72 | m_glutScreenWidth(0), |
---|
73 | m_glutScreenHeight(0), |
---|
74 | m_ShootBoxInitialSpeed(40.f), |
---|
75 | m_stepping(true), |
---|
76 | m_singleStep(false), |
---|
77 | m_idle(false), |
---|
78 | m_enableshadows(false), |
---|
79 | m_sundirection(btVector3(1,-2,1)*1000), |
---|
80 | m_ortho(0), |
---|
81 | m_mouseOldX(0), |
---|
82 | m_mouseOldY(0), |
---|
83 | m_mouseButtons(0), |
---|
84 | m_modifierKeys(0) |
---|
85 | { |
---|
86 | #ifndef BT_NO_PROFILE |
---|
87 | m_profileIterator = CProfileManager::Get_Iterator(); |
---|
88 | #endif //BT_NO_PROFILE |
---|
89 | |
---|
90 | m_shapeDrawer = new GL_ShapeDrawer (); |
---|
91 | m_shapeDrawer->enableTexture(true); |
---|
92 | m_enableshadows = false; |
---|
93 | } |
---|
94 | |
---|
95 | |
---|
96 | |
---|
97 | DemoApplication::~DemoApplication() |
---|
98 | { |
---|
99 | #ifndef BT_NO_PROFILE |
---|
100 | CProfileManager::Release_Iterator(m_profileIterator); |
---|
101 | #endif //BT_NO_PROFILE |
---|
102 | |
---|
103 | if (m_shootBoxShape) |
---|
104 | delete m_shootBoxShape; |
---|
105 | |
---|
106 | if (m_shapeDrawer) |
---|
107 | delete m_shapeDrawer; |
---|
108 | } |
---|
109 | |
---|
110 | |
---|
111 | void DemoApplication::overrideGLShapeDrawer (GL_ShapeDrawer* shapeDrawer) |
---|
112 | { |
---|
113 | shapeDrawer->enableTexture (m_shapeDrawer->hasTextureEnabled()); |
---|
114 | delete m_shapeDrawer; |
---|
115 | m_shapeDrawer = shapeDrawer; |
---|
116 | } |
---|
117 | |
---|
118 | void DemoApplication::myinit(void) |
---|
119 | { |
---|
120 | |
---|
121 | GLfloat light_ambient[] = { 0.2, 0.2, 0.2, 1.0 }; |
---|
122 | GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; |
---|
123 | GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; |
---|
124 | /* light_position is NOT default value */ |
---|
125 | GLfloat light_position0[] = { 1.0, 10.0, 1.0, 0.0 }; |
---|
126 | GLfloat light_position1[] = { -1.0, -10.0, -1.0, 0.0 }; |
---|
127 | |
---|
128 | glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); |
---|
129 | glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); |
---|
130 | glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); |
---|
131 | glLightfv(GL_LIGHT0, GL_POSITION, light_position0); |
---|
132 | |
---|
133 | glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); |
---|
134 | glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); |
---|
135 | glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); |
---|
136 | glLightfv(GL_LIGHT1, GL_POSITION, light_position1); |
---|
137 | |
---|
138 | glEnable(GL_LIGHTING); |
---|
139 | glEnable(GL_LIGHT0); |
---|
140 | glEnable(GL_LIGHT1); |
---|
141 | |
---|
142 | |
---|
143 | glShadeModel(GL_SMOOTH); |
---|
144 | glEnable(GL_DEPTH_TEST); |
---|
145 | glDepthFunc(GL_LESS); |
---|
146 | |
---|
147 | glClearColor(0.7,0.7,0.7,0); |
---|
148 | |
---|
149 | // glEnable(GL_CULL_FACE); |
---|
150 | // glCullFace(GL_BACK); |
---|
151 | } |
---|
152 | |
---|
153 | |
---|
154 | void DemoApplication::setCameraDistance(float dist) |
---|
155 | { |
---|
156 | m_cameraDistance = dist; |
---|
157 | } |
---|
158 | |
---|
159 | float DemoApplication::getCameraDistance() |
---|
160 | { |
---|
161 | return m_cameraDistance; |
---|
162 | } |
---|
163 | |
---|
164 | |
---|
165 | |
---|
166 | void DemoApplication::toggleIdle() { |
---|
167 | if (m_idle) { |
---|
168 | m_idle = false; |
---|
169 | } |
---|
170 | else { |
---|
171 | m_idle = true; |
---|
172 | } |
---|
173 | } |
---|
174 | |
---|
175 | |
---|
176 | |
---|
177 | |
---|
178 | void DemoApplication::updateCamera() { |
---|
179 | |
---|
180 | |
---|
181 | glMatrixMode(GL_PROJECTION); |
---|
182 | glLoadIdentity(); |
---|
183 | float rele = m_ele * 0.01745329251994329547;// rads per deg |
---|
184 | float razi = m_azi * 0.01745329251994329547;// rads per deg |
---|
185 | |
---|
186 | |
---|
187 | btQuaternion rot(m_cameraUp,razi); |
---|
188 | |
---|
189 | |
---|
190 | btVector3 eyePos(0,0,0); |
---|
191 | eyePos[m_forwardAxis] = -m_cameraDistance; |
---|
192 | |
---|
193 | btVector3 forward(eyePos[0],eyePos[1],eyePos[2]); |
---|
194 | if (forward.length2() < SIMD_EPSILON) |
---|
195 | { |
---|
196 | forward.setValue(1.f,0.f,0.f); |
---|
197 | } |
---|
198 | btVector3 right = m_cameraUp.cross(forward); |
---|
199 | btQuaternion roll(right,-rele); |
---|
200 | |
---|
201 | eyePos = btMatrix3x3(rot) * btMatrix3x3(roll) * eyePos; |
---|
202 | |
---|
203 | m_cameraPosition[0] = eyePos.getX(); |
---|
204 | m_cameraPosition[1] = eyePos.getY(); |
---|
205 | m_cameraPosition[2] = eyePos.getZ(); |
---|
206 | m_cameraPosition += m_cameraTargetPosition; |
---|
207 | |
---|
208 | if (m_glutScreenWidth == 0 && m_glutScreenHeight == 0) |
---|
209 | return; |
---|
210 | |
---|
211 | btScalar aspect; |
---|
212 | btVector3 extents; |
---|
213 | |
---|
214 | if (m_glutScreenWidth > m_glutScreenHeight) |
---|
215 | { |
---|
216 | aspect = m_glutScreenWidth / (btScalar)m_glutScreenHeight; |
---|
217 | extents.setValue(aspect * 1.0f, 1.0f,0); |
---|
218 | } else |
---|
219 | { |
---|
220 | aspect = m_glutScreenHeight / (btScalar)m_glutScreenWidth; |
---|
221 | extents.setValue(1.0f, aspect*1.f,0); |
---|
222 | } |
---|
223 | |
---|
224 | |
---|
225 | if (m_ortho) |
---|
226 | { |
---|
227 | // reset matrix |
---|
228 | glLoadIdentity(); |
---|
229 | |
---|
230 | |
---|
231 | extents *= m_cameraDistance; |
---|
232 | btVector3 lower = m_cameraTargetPosition - extents; |
---|
233 | btVector3 upper = m_cameraTargetPosition + extents; |
---|
234 | //gluOrtho2D(lower.x, upper.x, lower.y, upper.y); |
---|
235 | glOrtho(lower.getX(), upper.getX(), lower.getY(), upper.getY(),-1000,1000); |
---|
236 | |
---|
237 | glMatrixMode(GL_MODELVIEW); |
---|
238 | glLoadIdentity(); |
---|
239 | //glTranslatef(100,210,0); |
---|
240 | } else |
---|
241 | { |
---|
242 | if (m_glutScreenWidth > m_glutScreenHeight) |
---|
243 | { |
---|
244 | glFrustum (-aspect, aspect, -1.0, 1.0, 1.0, 10000.0); |
---|
245 | } else |
---|
246 | { |
---|
247 | glFrustum (-1.0, 1.0, -aspect, aspect, 1.0, 10000.0); |
---|
248 | } |
---|
249 | glMatrixMode(GL_MODELVIEW); |
---|
250 | glLoadIdentity(); |
---|
251 | gluLookAt(m_cameraPosition[0], m_cameraPosition[1], m_cameraPosition[2], |
---|
252 | m_cameraTargetPosition[0], m_cameraTargetPosition[1], m_cameraTargetPosition[2], |
---|
253 | m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ()); |
---|
254 | } |
---|
255 | |
---|
256 | } |
---|
257 | |
---|
258 | |
---|
259 | |
---|
260 | const float STEPSIZE = 5; |
---|
261 | |
---|
262 | void DemoApplication::stepLeft() |
---|
263 | { |
---|
264 | m_azi -= STEPSIZE; if (m_azi < 0) m_azi += 360; updateCamera(); |
---|
265 | } |
---|
266 | void DemoApplication::stepRight() |
---|
267 | { |
---|
268 | m_azi += STEPSIZE; if (m_azi >= 360) m_azi -= 360; updateCamera(); |
---|
269 | } |
---|
270 | void DemoApplication::stepFront() |
---|
271 | { |
---|
272 | m_ele += STEPSIZE; if (m_ele >= 360) m_ele -= 360; updateCamera(); |
---|
273 | } |
---|
274 | void DemoApplication::stepBack() |
---|
275 | { |
---|
276 | m_ele -= STEPSIZE; if (m_ele < 0) m_ele += 360; updateCamera(); |
---|
277 | } |
---|
278 | void DemoApplication::zoomIn() |
---|
279 | { |
---|
280 | m_cameraDistance -= 0.4; updateCamera(); |
---|
281 | if (m_cameraDistance < 0.1) |
---|
282 | m_cameraDistance = 0.1; |
---|
283 | |
---|
284 | } |
---|
285 | void DemoApplication::zoomOut() |
---|
286 | { |
---|
287 | m_cameraDistance += 0.4; updateCamera(); |
---|
288 | |
---|
289 | } |
---|
290 | |
---|
291 | |
---|
292 | |
---|
293 | |
---|
294 | |
---|
295 | |
---|
296 | |
---|
297 | |
---|
298 | |
---|
299 | |
---|
300 | void DemoApplication::reshape(int w, int h) |
---|
301 | { |
---|
302 | GLDebugResetFont(w,h); |
---|
303 | |
---|
304 | m_glutScreenWidth = w; |
---|
305 | m_glutScreenHeight = h; |
---|
306 | |
---|
307 | glViewport(0, 0, w, h); |
---|
308 | updateCamera(); |
---|
309 | } |
---|
310 | |
---|
311 | |
---|
312 | void DemoApplication::keyboardCallback(unsigned char key, int x, int y) |
---|
313 | { |
---|
314 | (void)x; |
---|
315 | (void)y; |
---|
316 | |
---|
317 | m_lastKey = 0; |
---|
318 | |
---|
319 | #ifndef BT_NO_PROFILE |
---|
320 | if (key >= 0x31 && key <= 0x39) |
---|
321 | { |
---|
322 | int child = key-0x31; |
---|
323 | m_profileIterator->Enter_Child(child); |
---|
324 | } |
---|
325 | if (key==0x30) |
---|
326 | { |
---|
327 | m_profileIterator->Enter_Parent(); |
---|
328 | } |
---|
329 | #endif //BT_NO_PROFILE |
---|
330 | |
---|
331 | switch (key) |
---|
332 | { |
---|
333 | case 'q' : |
---|
334 | #ifdef BT_USE_FREEGLUT |
---|
335 | //return from glutMainLoop(), detect memory leaks etc. |
---|
336 | glutLeaveMainLoop(); |
---|
337 | #else |
---|
338 | exit(0); |
---|
339 | #endif |
---|
340 | break; |
---|
341 | |
---|
342 | case 'l' : stepLeft(); break; |
---|
343 | case 'r' : stepRight(); break; |
---|
344 | case 'f' : stepFront(); break; |
---|
345 | case 'b' : stepBack(); break; |
---|
346 | case 'z' : zoomIn(); break; |
---|
347 | case 'x' : zoomOut(); break; |
---|
348 | case 'i' : toggleIdle(); break; |
---|
349 | case 'g' : m_enableshadows=!m_enableshadows;break; |
---|
350 | case 'u' : m_shapeDrawer->enableTexture(!m_shapeDrawer->enableTexture(false));break; |
---|
351 | case 'h': |
---|
352 | if (m_debugMode & btIDebugDraw::DBG_NoHelpText) |
---|
353 | m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoHelpText); |
---|
354 | else |
---|
355 | m_debugMode |= btIDebugDraw::DBG_NoHelpText; |
---|
356 | break; |
---|
357 | |
---|
358 | case 'w': |
---|
359 | if (m_debugMode & btIDebugDraw::DBG_DrawWireframe) |
---|
360 | m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawWireframe); |
---|
361 | else |
---|
362 | m_debugMode |= btIDebugDraw::DBG_DrawWireframe; |
---|
363 | break; |
---|
364 | |
---|
365 | case 'p': |
---|
366 | if (m_debugMode & btIDebugDraw::DBG_ProfileTimings) |
---|
367 | m_debugMode = m_debugMode & (~btIDebugDraw::DBG_ProfileTimings); |
---|
368 | else |
---|
369 | m_debugMode |= btIDebugDraw::DBG_ProfileTimings; |
---|
370 | break; |
---|
371 | |
---|
372 | case 'm': |
---|
373 | if (m_debugMode & btIDebugDraw::DBG_EnableSatComparison) |
---|
374 | m_debugMode = m_debugMode & (~btIDebugDraw::DBG_EnableSatComparison); |
---|
375 | else |
---|
376 | m_debugMode |= btIDebugDraw::DBG_EnableSatComparison; |
---|
377 | break; |
---|
378 | |
---|
379 | case 'n': |
---|
380 | if (m_debugMode & btIDebugDraw::DBG_DisableBulletLCP) |
---|
381 | m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DisableBulletLCP); |
---|
382 | else |
---|
383 | m_debugMode |= btIDebugDraw::DBG_DisableBulletLCP; |
---|
384 | break; |
---|
385 | |
---|
386 | case 't' : |
---|
387 | if (m_debugMode & btIDebugDraw::DBG_DrawText) |
---|
388 | m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawText); |
---|
389 | else |
---|
390 | m_debugMode |= btIDebugDraw::DBG_DrawText; |
---|
391 | break; |
---|
392 | case 'y': |
---|
393 | if (m_debugMode & btIDebugDraw::DBG_DrawFeaturesText) |
---|
394 | m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawFeaturesText); |
---|
395 | else |
---|
396 | m_debugMode |= btIDebugDraw::DBG_DrawFeaturesText; |
---|
397 | break; |
---|
398 | case 'a': |
---|
399 | if (m_debugMode & btIDebugDraw::DBG_DrawAabb) |
---|
400 | m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawAabb); |
---|
401 | else |
---|
402 | m_debugMode |= btIDebugDraw::DBG_DrawAabb; |
---|
403 | break; |
---|
404 | case 'c' : |
---|
405 | if (m_debugMode & btIDebugDraw::DBG_DrawContactPoints) |
---|
406 | m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawContactPoints); |
---|
407 | else |
---|
408 | m_debugMode |= btIDebugDraw::DBG_DrawContactPoints; |
---|
409 | break; |
---|
410 | case 'C' : |
---|
411 | if (m_debugMode & btIDebugDraw::DBG_DrawConstraints) |
---|
412 | m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawConstraints); |
---|
413 | else |
---|
414 | m_debugMode |= btIDebugDraw::DBG_DrawConstraints; |
---|
415 | break; |
---|
416 | case 'L' : |
---|
417 | if (m_debugMode & btIDebugDraw::DBG_DrawConstraintLimits) |
---|
418 | m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawConstraintLimits); |
---|
419 | else |
---|
420 | m_debugMode |= btIDebugDraw::DBG_DrawConstraintLimits; |
---|
421 | break; |
---|
422 | |
---|
423 | case 'd' : |
---|
424 | if (m_debugMode & btIDebugDraw::DBG_NoDeactivation) |
---|
425 | m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoDeactivation); |
---|
426 | else |
---|
427 | m_debugMode |= btIDebugDraw::DBG_NoDeactivation; |
---|
428 | if (m_debugMode & btIDebugDraw::DBG_NoDeactivation) |
---|
429 | { |
---|
430 | gDisableDeactivation = true; |
---|
431 | } else |
---|
432 | { |
---|
433 | gDisableDeactivation = false; |
---|
434 | } |
---|
435 | break; |
---|
436 | |
---|
437 | |
---|
438 | |
---|
439 | |
---|
440 | case 'o' : |
---|
441 | { |
---|
442 | m_ortho = !m_ortho;//m_stepping = !m_stepping; |
---|
443 | break; |
---|
444 | } |
---|
445 | case 's' : clientMoveAndDisplay(); break; |
---|
446 | // case ' ' : newRandom(); break; |
---|
447 | case ' ': |
---|
448 | clientResetScene(); |
---|
449 | break; |
---|
450 | case '1': |
---|
451 | { |
---|
452 | if (m_debugMode & btIDebugDraw::DBG_EnableCCD) |
---|
453 | m_debugMode = m_debugMode & (~btIDebugDraw::DBG_EnableCCD); |
---|
454 | else |
---|
455 | m_debugMode |= btIDebugDraw::DBG_EnableCCD; |
---|
456 | break; |
---|
457 | } |
---|
458 | |
---|
459 | case '.': |
---|
460 | { |
---|
461 | shootBox(getRayTo(x,y));//getCameraTargetPosition()); |
---|
462 | break; |
---|
463 | } |
---|
464 | |
---|
465 | case '+': |
---|
466 | { |
---|
467 | m_ShootBoxInitialSpeed += 10.f; |
---|
468 | break; |
---|
469 | } |
---|
470 | case '-': |
---|
471 | { |
---|
472 | m_ShootBoxInitialSpeed -= 10.f; |
---|
473 | break; |
---|
474 | } |
---|
475 | |
---|
476 | default: |
---|
477 | // std::cout << "unused key : " << key << std::endl; |
---|
478 | break; |
---|
479 | } |
---|
480 | |
---|
481 | if (getDynamicsWorld() && getDynamicsWorld()->getDebugDrawer()) |
---|
482 | getDynamicsWorld()->getDebugDrawer()->setDebugMode(m_debugMode); |
---|
483 | |
---|
484 | |
---|
485 | |
---|
486 | } |
---|
487 | |
---|
488 | void DemoApplication::setDebugMode(int mode) |
---|
489 | { |
---|
490 | m_debugMode = mode; |
---|
491 | if (getDynamicsWorld() && getDynamicsWorld()->getDebugDrawer()) |
---|
492 | getDynamicsWorld()->getDebugDrawer()->setDebugMode(mode); |
---|
493 | } |
---|
494 | |
---|
495 | |
---|
496 | |
---|
497 | |
---|
498 | |
---|
499 | |
---|
500 | void DemoApplication::moveAndDisplay() |
---|
501 | { |
---|
502 | if (!m_idle) |
---|
503 | clientMoveAndDisplay(); |
---|
504 | else |
---|
505 | displayCallback(); |
---|
506 | } |
---|
507 | |
---|
508 | |
---|
509 | |
---|
510 | |
---|
511 | void DemoApplication::displayCallback() |
---|
512 | { |
---|
513 | } |
---|
514 | |
---|
515 | #define NUM_SPHERES_ON_DIAGONAL 9 |
---|
516 | |
---|
517 | void DemoApplication::setShootBoxShape () |
---|
518 | { |
---|
519 | if (!m_shootBoxShape) |
---|
520 | { |
---|
521 | m_shootBoxShape = new btBoxShape(btVector3(.5f,.5f,.5f)); |
---|
522 | } |
---|
523 | } |
---|
524 | |
---|
525 | void DemoApplication::shootBox(const btVector3& destination) |
---|
526 | { |
---|
527 | |
---|
528 | if (m_dynamicsWorld) |
---|
529 | { |
---|
530 | float mass = 1.f; |
---|
531 | btTransform startTransform; |
---|
532 | startTransform.setIdentity(); |
---|
533 | btVector3 camPos = getCameraPosition(); |
---|
534 | startTransform.setOrigin(camPos); |
---|
535 | |
---|
536 | setShootBoxShape (); |
---|
537 | |
---|
538 | btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_shootBoxShape); |
---|
539 | body->setLinearFactor(btVector3(1,1,1)); |
---|
540 | |
---|
541 | btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]); |
---|
542 | linVel.normalize(); |
---|
543 | linVel*=m_ShootBoxInitialSpeed; |
---|
544 | |
---|
545 | body->getWorldTransform().setOrigin(camPos); |
---|
546 | body->getWorldTransform().setRotation(btQuaternion(0,0,0,1)); |
---|
547 | body->setLinearVelocity(linVel); |
---|
548 | body->setAngularVelocity(btVector3(0,0,0)); |
---|
549 | body->setCcdMotionThreshold(1.); |
---|
550 | body->setCcdSweptSphereRadius(0.2f); |
---|
551 | |
---|
552 | } |
---|
553 | } |
---|
554 | |
---|
555 | |
---|
556 | int gPickingConstraintId = 0; |
---|
557 | btVector3 gOldPickingPos; |
---|
558 | btVector3 gHitPos(-1,-1,-1); |
---|
559 | float gOldPickingDist = 0.f; |
---|
560 | btRigidBody* pickedBody = 0;//for deactivation state |
---|
561 | |
---|
562 | |
---|
563 | btVector3 DemoApplication::getRayTo(int x,int y) |
---|
564 | { |
---|
565 | |
---|
566 | |
---|
567 | |
---|
568 | if (m_ortho) |
---|
569 | { |
---|
570 | |
---|
571 | btScalar aspect; |
---|
572 | btVector3 extents; |
---|
573 | if (m_glutScreenWidth > m_glutScreenHeight) |
---|
574 | { |
---|
575 | aspect = m_glutScreenWidth / (btScalar)m_glutScreenHeight; |
---|
576 | extents.setValue(aspect * 1.0f, 1.0f,0); |
---|
577 | } else |
---|
578 | { |
---|
579 | aspect = m_glutScreenHeight / (btScalar)m_glutScreenWidth; |
---|
580 | extents.setValue(1.0f, aspect*1.f,0); |
---|
581 | } |
---|
582 | |
---|
583 | extents *= m_cameraDistance; |
---|
584 | btVector3 lower = m_cameraTargetPosition - extents; |
---|
585 | btVector3 upper = m_cameraTargetPosition + extents; |
---|
586 | |
---|
587 | btScalar u = x / btScalar(m_glutScreenWidth); |
---|
588 | btScalar v = (m_glutScreenHeight - y) / btScalar(m_glutScreenHeight); |
---|
589 | |
---|
590 | btVector3 p(0,0,0); |
---|
591 | p.setValue((1.0f - u) * lower.getX() + u * upper.getX(),(1.0f - v) * lower.getY() + v * upper.getY(),m_cameraTargetPosition.getZ()); |
---|
592 | return p; |
---|
593 | } |
---|
594 | |
---|
595 | float top = 1.f; |
---|
596 | float bottom = -1.f; |
---|
597 | float nearPlane = 1.f; |
---|
598 | float tanFov = (top-bottom)*0.5f / nearPlane; |
---|
599 | float fov = 2.0 * atanf (tanFov); |
---|
600 | |
---|
601 | btVector3 rayFrom = getCameraPosition(); |
---|
602 | btVector3 rayForward = (getCameraTargetPosition()-getCameraPosition()); |
---|
603 | rayForward.normalize(); |
---|
604 | float farPlane = 10000.f; |
---|
605 | rayForward*= farPlane; |
---|
606 | |
---|
607 | btVector3 rightOffset; |
---|
608 | btVector3 vertical = m_cameraUp; |
---|
609 | |
---|
610 | btVector3 hor; |
---|
611 | hor = rayForward.cross(vertical); |
---|
612 | hor.normalize(); |
---|
613 | vertical = hor.cross(rayForward); |
---|
614 | vertical.normalize(); |
---|
615 | |
---|
616 | float tanfov = tanf(0.5f*fov); |
---|
617 | |
---|
618 | |
---|
619 | hor *= 2.f * farPlane * tanfov; |
---|
620 | vertical *= 2.f * farPlane * tanfov; |
---|
621 | |
---|
622 | btScalar aspect; |
---|
623 | |
---|
624 | if (m_glutScreenWidth > m_glutScreenHeight) |
---|
625 | { |
---|
626 | aspect = m_glutScreenWidth / (btScalar)m_glutScreenHeight; |
---|
627 | |
---|
628 | hor*=aspect; |
---|
629 | } else |
---|
630 | { |
---|
631 | aspect = m_glutScreenHeight / (btScalar)m_glutScreenWidth; |
---|
632 | vertical*=aspect; |
---|
633 | } |
---|
634 | |
---|
635 | |
---|
636 | btVector3 rayToCenter = rayFrom + rayForward; |
---|
637 | btVector3 dHor = hor * 1.f/float(m_glutScreenWidth); |
---|
638 | btVector3 dVert = vertical * 1.f/float(m_glutScreenHeight); |
---|
639 | |
---|
640 | |
---|
641 | btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical; |
---|
642 | rayTo += x * dHor; |
---|
643 | rayTo -= y * dVert; |
---|
644 | return rayTo; |
---|
645 | } |
---|
646 | |
---|
647 | btScalar mousePickClamping = 30.f; |
---|
648 | |
---|
649 | |
---|
650 | void DemoApplication::mouseFunc(int button, int state, int x, int y) |
---|
651 | { |
---|
652 | if (state == 0) |
---|
653 | { |
---|
654 | m_mouseButtons |= 1<<button; |
---|
655 | } else |
---|
656 | { |
---|
657 | m_mouseButtons = 0; |
---|
658 | } |
---|
659 | |
---|
660 | m_mouseOldX = x; |
---|
661 | m_mouseOldY = y; |
---|
662 | |
---|
663 | updateModifierKeys(); |
---|
664 | if ((m_modifierKeys& BT_ACTIVE_ALT) && (state==0)) |
---|
665 | { |
---|
666 | return; |
---|
667 | } |
---|
668 | |
---|
669 | //printf("button %i, state %i, x=%i,y=%i\n",button,state,x,y); |
---|
670 | //button 0, state 0 means left mouse down |
---|
671 | |
---|
672 | btVector3 rayTo = getRayTo(x,y); |
---|
673 | |
---|
674 | switch (button) |
---|
675 | { |
---|
676 | case 2: |
---|
677 | { |
---|
678 | if (state==0) |
---|
679 | { |
---|
680 | |
---|
681 | shootBox(rayTo); |
---|
682 | } |
---|
683 | break; |
---|
684 | }; |
---|
685 | case 1: |
---|
686 | { |
---|
687 | |
---|
688 | |
---|
689 | if (state==0) |
---|
690 | { |
---|
691 | |
---|
692 | #if 0 |
---|
693 | //apply an impulse |
---|
694 | if (m_dynamicsWorld) |
---|
695 | { |
---|
696 | btCollisionWorld::ClosestRayResultCallback rayCallback(m_cameraPosition,rayTo); |
---|
697 | m_dynamicsWorld->rayTest(m_cameraPosition,rayTo,rayCallback); |
---|
698 | if (rayCallback.hasHit()) |
---|
699 | { |
---|
700 | |
---|
701 | btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); |
---|
702 | if (body) |
---|
703 | { |
---|
704 | body->setActivationState(ACTIVE_TAG); |
---|
705 | btVector3 impulse = rayTo; |
---|
706 | impulse.normalize(); |
---|
707 | float impulseStrength = 10.f; |
---|
708 | impulse *= impulseStrength; |
---|
709 | btVector3 relPos = rayCallback.m_hitPointWorld - body->getCenterOfMassPosition(); |
---|
710 | body->applyImpulse(impulse,relPos); |
---|
711 | } |
---|
712 | } |
---|
713 | } |
---|
714 | #endif |
---|
715 | |
---|
716 | |
---|
717 | |
---|
718 | } else |
---|
719 | { |
---|
720 | |
---|
721 | } |
---|
722 | break; |
---|
723 | } |
---|
724 | case 0: |
---|
725 | { |
---|
726 | if (state==0) |
---|
727 | { |
---|
728 | |
---|
729 | |
---|
730 | //add a point to point constraint for picking |
---|
731 | if (m_dynamicsWorld) |
---|
732 | { |
---|
733 | |
---|
734 | btVector3 rayFrom; |
---|
735 | if (m_ortho) |
---|
736 | { |
---|
737 | rayFrom = rayTo; |
---|
738 | rayFrom.setZ(-100.f); |
---|
739 | } else |
---|
740 | { |
---|
741 | rayFrom = m_cameraPosition; |
---|
742 | } |
---|
743 | |
---|
744 | btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo); |
---|
745 | m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback); |
---|
746 | if (rayCallback.hasHit()) |
---|
747 | { |
---|
748 | |
---|
749 | |
---|
750 | btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); |
---|
751 | if (body) |
---|
752 | { |
---|
753 | //other exclusions? |
---|
754 | if (!(body->isStaticObject() || body->isKinematicObject())) |
---|
755 | { |
---|
756 | pickedBody = body; |
---|
757 | pickedBody->setActivationState(DISABLE_DEACTIVATION); |
---|
758 | |
---|
759 | |
---|
760 | btVector3 pickPos = rayCallback.m_hitPointWorld; |
---|
761 | printf("pickPos=%f,%f,%f\n",pickPos.getX(),pickPos.getY(),pickPos.getZ()); |
---|
762 | |
---|
763 | |
---|
764 | btVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos; |
---|
765 | |
---|
766 | btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body,localPivot); |
---|
767 | p2p->m_setting.m_impulseClamp = mousePickClamping; |
---|
768 | |
---|
769 | m_dynamicsWorld->addConstraint(p2p); |
---|
770 | m_pickConstraint = p2p; |
---|
771 | |
---|
772 | //save mouse position for dragging |
---|
773 | gOldPickingPos = rayTo; |
---|
774 | gHitPos = pickPos; |
---|
775 | |
---|
776 | gOldPickingDist = (pickPos-rayFrom).length(); |
---|
777 | |
---|
778 | //very weak constraint for picking |
---|
779 | p2p->m_setting.m_tau = 0.1f; |
---|
780 | } |
---|
781 | } |
---|
782 | } |
---|
783 | } |
---|
784 | |
---|
785 | } else |
---|
786 | { |
---|
787 | |
---|
788 | if (m_pickConstraint && m_dynamicsWorld) |
---|
789 | { |
---|
790 | m_dynamicsWorld->removeConstraint(m_pickConstraint); |
---|
791 | delete m_pickConstraint; |
---|
792 | //printf("removed constraint %i",gPickingConstraintId); |
---|
793 | m_pickConstraint = 0; |
---|
794 | pickedBody->forceActivationState(ACTIVE_TAG); |
---|
795 | pickedBody->setDeactivationTime( 0.f ); |
---|
796 | pickedBody = 0; |
---|
797 | } |
---|
798 | |
---|
799 | |
---|
800 | } |
---|
801 | |
---|
802 | break; |
---|
803 | |
---|
804 | } |
---|
805 | default: |
---|
806 | { |
---|
807 | } |
---|
808 | } |
---|
809 | |
---|
810 | } |
---|
811 | |
---|
812 | void DemoApplication::mouseMotionFunc(int x,int y) |
---|
813 | { |
---|
814 | |
---|
815 | if (m_pickConstraint) |
---|
816 | { |
---|
817 | //move the constraint pivot |
---|
818 | btPoint2PointConstraint* p2p = static_cast<btPoint2PointConstraint*>(m_pickConstraint); |
---|
819 | if (p2p) |
---|
820 | { |
---|
821 | //keep it at the same picking distance |
---|
822 | |
---|
823 | btVector3 newRayTo = getRayTo(x,y); |
---|
824 | btVector3 rayFrom; |
---|
825 | btVector3 oldPivotInB = p2p->getPivotInB(); |
---|
826 | btVector3 newPivotB; |
---|
827 | if (m_ortho) |
---|
828 | { |
---|
829 | newPivotB = oldPivotInB; |
---|
830 | newPivotB.setX(newRayTo.getX()); |
---|
831 | newPivotB.setY(newRayTo.getY()); |
---|
832 | } else |
---|
833 | { |
---|
834 | rayFrom = m_cameraPosition; |
---|
835 | btVector3 dir = newRayTo-rayFrom; |
---|
836 | dir.normalize(); |
---|
837 | dir *= gOldPickingDist; |
---|
838 | |
---|
839 | newPivotB = rayFrom + dir; |
---|
840 | } |
---|
841 | |
---|
842 | |
---|
843 | |
---|
844 | p2p->setPivotB(newPivotB); |
---|
845 | } |
---|
846 | |
---|
847 | } |
---|
848 | |
---|
849 | float dx, dy; |
---|
850 | dx = x - m_mouseOldX; |
---|
851 | dy = y - m_mouseOldY; |
---|
852 | |
---|
853 | |
---|
854 | ///only if ALT key is pressed (Maya style) |
---|
855 | if (m_modifierKeys& BT_ACTIVE_ALT) |
---|
856 | { |
---|
857 | if(m_mouseButtons & 2) |
---|
858 | { |
---|
859 | btVector3 hor = getRayTo(0,0)-getRayTo(1,0); |
---|
860 | btVector3 vert = getRayTo(0,0)-getRayTo(0,1); |
---|
861 | btScalar multiplierX = 0.01; |
---|
862 | btScalar multiplierY = 0.01; |
---|
863 | if (m_ortho) |
---|
864 | { |
---|
865 | multiplierX = 1; |
---|
866 | multiplierY = 1; |
---|
867 | } |
---|
868 | |
---|
869 | |
---|
870 | m_cameraTargetPosition += hor* dx * multiplierX; |
---|
871 | m_cameraTargetPosition += vert* dy * multiplierY; |
---|
872 | } |
---|
873 | |
---|
874 | if(m_mouseButtons & (2 << 2) && m_mouseButtons & 1) |
---|
875 | { |
---|
876 | } |
---|
877 | else if(m_mouseButtons & 1) |
---|
878 | { |
---|
879 | m_azi += dx * 0.2; |
---|
880 | m_azi = fmodf(m_azi, 180.f); |
---|
881 | m_ele += dy * 0.2; |
---|
882 | m_ele = fmodf(m_ele, 180.f); |
---|
883 | } |
---|
884 | else if(m_mouseButtons & 4) |
---|
885 | { |
---|
886 | m_cameraDistance -= dy * 0.2f; |
---|
887 | if (m_cameraDistance<0.1) |
---|
888 | m_cameraDistance = 0.1; |
---|
889 | |
---|
890 | |
---|
891 | } |
---|
892 | } |
---|
893 | |
---|
894 | |
---|
895 | m_mouseOldX = x; |
---|
896 | m_mouseOldY = y; |
---|
897 | updateCamera(); |
---|
898 | |
---|
899 | |
---|
900 | } |
---|
901 | |
---|
902 | |
---|
903 | |
---|
904 | btRigidBody* DemoApplication::localCreateRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape) |
---|
905 | { |
---|
906 | btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE)); |
---|
907 | |
---|
908 | //rigidbody is dynamic if and only if mass is non zero, otherwise static |
---|
909 | bool isDynamic = (mass != 0.f); |
---|
910 | |
---|
911 | btVector3 localInertia(0,0,0); |
---|
912 | if (isDynamic) |
---|
913 | shape->calculateLocalInertia(mass,localInertia); |
---|
914 | |
---|
915 | //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects |
---|
916 | |
---|
917 | #define USE_MOTIONSTATE 1 |
---|
918 | #ifdef USE_MOTIONSTATE |
---|
919 | btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); |
---|
920 | |
---|
921 | btRigidBody::btRigidBodyConstructionInfo cInfo(mass,myMotionState,shape,localInertia); |
---|
922 | |
---|
923 | btRigidBody* body = new btRigidBody(cInfo); |
---|
924 | |
---|
925 | #else |
---|
926 | btRigidBody* body = new btRigidBody(mass,0,shape,localInertia); |
---|
927 | body->setWorldTransform(startTransform); |
---|
928 | #endif// |
---|
929 | |
---|
930 | m_dynamicsWorld->addRigidBody(body); |
---|
931 | |
---|
932 | return body; |
---|
933 | } |
---|
934 | |
---|
935 | //See http://www.lighthouse3d.com/opengl/glut/index.php?bmpfontortho |
---|
936 | void DemoApplication::setOrthographicProjection() |
---|
937 | { |
---|
938 | |
---|
939 | // switch to projection mode |
---|
940 | glMatrixMode(GL_PROJECTION); |
---|
941 | |
---|
942 | // save previous matrix which contains the |
---|
943 | //settings for the perspective projection |
---|
944 | glPushMatrix(); |
---|
945 | // reset matrix |
---|
946 | glLoadIdentity(); |
---|
947 | // set a 2D orthographic projection |
---|
948 | gluOrtho2D(0, m_glutScreenWidth, 0, m_glutScreenHeight); |
---|
949 | glMatrixMode(GL_MODELVIEW); |
---|
950 | glLoadIdentity(); |
---|
951 | |
---|
952 | // invert the y axis, down is positive |
---|
953 | glScalef(1, -1, 1); |
---|
954 | // mover the origin from the bottom left corner |
---|
955 | // to the upper left corner |
---|
956 | glTranslatef(0, -m_glutScreenHeight, 0); |
---|
957 | |
---|
958 | } |
---|
959 | |
---|
960 | void DemoApplication::resetPerspectiveProjection() |
---|
961 | { |
---|
962 | |
---|
963 | glMatrixMode(GL_PROJECTION); |
---|
964 | glPopMatrix(); |
---|
965 | glMatrixMode(GL_MODELVIEW); |
---|
966 | updateCamera(); |
---|
967 | } |
---|
968 | |
---|
969 | |
---|
970 | |
---|
971 | |
---|
972 | extern CProfileIterator * m_profileIterator; |
---|
973 | |
---|
974 | void DemoApplication::displayProfileString(int xOffset,int yStart,char* message) |
---|
975 | { |
---|
976 | glRasterPos3f(xOffset,yStart,0); |
---|
977 | GLDebugDrawString(xOffset,yStart,message); |
---|
978 | } |
---|
979 | |
---|
980 | |
---|
981 | void DemoApplication::showProfileInfo(int& xOffset,int& yStart, int yIncr) |
---|
982 | { |
---|
983 | #ifndef BT_NO_PROFILE |
---|
984 | |
---|
985 | static double time_since_reset = 0.f; |
---|
986 | if (!m_idle) |
---|
987 | { |
---|
988 | time_since_reset = CProfileManager::Get_Time_Since_Reset(); |
---|
989 | } |
---|
990 | |
---|
991 | |
---|
992 | { |
---|
993 | //recompute profiling data, and store profile strings |
---|
994 | |
---|
995 | char blockTime[128]; |
---|
996 | |
---|
997 | double totalTime = 0; |
---|
998 | |
---|
999 | int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset(); |
---|
1000 | |
---|
1001 | m_profileIterator->First(); |
---|
1002 | |
---|
1003 | double parent_time = m_profileIterator->Is_Root() ? time_since_reset : m_profileIterator->Get_Current_Parent_Total_Time(); |
---|
1004 | |
---|
1005 | { |
---|
1006 | sprintf(blockTime,"--- Profiling: %s (total running time: %.3f ms) ---", m_profileIterator->Get_Current_Parent_Name(), parent_time ); |
---|
1007 | displayProfileString(xOffset,yStart,blockTime); |
---|
1008 | yStart += yIncr; |
---|
1009 | sprintf(blockTime,"press number (1,2...) to display child timings, or 0 to go up to parent" ); |
---|
1010 | displayProfileString(xOffset,yStart,blockTime); |
---|
1011 | yStart += yIncr; |
---|
1012 | |
---|
1013 | } |
---|
1014 | |
---|
1015 | |
---|
1016 | double accumulated_time = 0.f; |
---|
1017 | |
---|
1018 | for (int i = 0; !m_profileIterator->Is_Done(); m_profileIterator->Next()) |
---|
1019 | { |
---|
1020 | double current_total_time = m_profileIterator->Get_Current_Total_Time(); |
---|
1021 | accumulated_time += current_total_time; |
---|
1022 | double fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f; |
---|
1023 | |
---|
1024 | sprintf(blockTime,"%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)", |
---|
1025 | ++i, m_profileIterator->Get_Current_Name(), fraction, |
---|
1026 | (current_total_time / (double)frames_since_reset),m_profileIterator->Get_Current_Total_Calls()); |
---|
1027 | displayProfileString(xOffset,yStart,blockTime); |
---|
1028 | yStart += yIncr; |
---|
1029 | totalTime += current_total_time; |
---|
1030 | } |
---|
1031 | |
---|
1032 | sprintf(blockTime,"%s (%.3f %%) :: %.3f ms", "Unaccounted", |
---|
1033 | // (min(0, time_since_reset - totalTime) / time_since_reset) * 100); |
---|
1034 | parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); |
---|
1035 | |
---|
1036 | displayProfileString(xOffset,yStart,blockTime); |
---|
1037 | yStart += yIncr; |
---|
1038 | |
---|
1039 | |
---|
1040 | |
---|
1041 | sprintf(blockTime,"-------------------------------------------------"); |
---|
1042 | displayProfileString(xOffset,yStart,blockTime); |
---|
1043 | yStart += yIncr; |
---|
1044 | |
---|
1045 | } |
---|
1046 | #endif//BT_NO_PROFILE |
---|
1047 | |
---|
1048 | |
---|
1049 | |
---|
1050 | |
---|
1051 | } |
---|
1052 | |
---|
1053 | |
---|
1054 | // |
---|
1055 | void DemoApplication::renderscene(int pass) |
---|
1056 | { |
---|
1057 | btScalar m[16]; |
---|
1058 | btMatrix3x3 rot;rot.setIdentity(); |
---|
1059 | const int numObjects=m_dynamicsWorld->getNumCollisionObjects(); |
---|
1060 | btVector3 wireColor(1,0,0); |
---|
1061 | for(int i=0;i<numObjects;i++) |
---|
1062 | { |
---|
1063 | btCollisionObject* colObj=m_dynamicsWorld->getCollisionObjectArray()[i]; |
---|
1064 | btRigidBody* body=btRigidBody::upcast(colObj); |
---|
1065 | if(body&&body->getMotionState()) |
---|
1066 | { |
---|
1067 | btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); |
---|
1068 | myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m); |
---|
1069 | rot=myMotionState->m_graphicsWorldTrans.getBasis(); |
---|
1070 | } |
---|
1071 | else |
---|
1072 | { |
---|
1073 | colObj->getWorldTransform().getOpenGLMatrix(m); |
---|
1074 | rot=colObj->getWorldTransform().getBasis(); |
---|
1075 | } |
---|
1076 | btVector3 wireColor(1.f,1.0f,0.5f); //wants deactivation |
---|
1077 | if(i&1) wireColor=btVector3(0.f,0.0f,1.f); |
---|
1078 | ///color differently for active, sleeping, wantsdeactivation states |
---|
1079 | if (colObj->getActivationState() == 1) //active |
---|
1080 | { |
---|
1081 | if (i & 1) |
---|
1082 | { |
---|
1083 | wireColor += btVector3 (1.f,0.f,0.f); |
---|
1084 | } |
---|
1085 | else |
---|
1086 | { |
---|
1087 | wireColor += btVector3 (.5f,0.f,0.f); |
---|
1088 | } |
---|
1089 | } |
---|
1090 | if(colObj->getActivationState()==2) //ISLAND_SLEEPING |
---|
1091 | { |
---|
1092 | if(i&1) |
---|
1093 | { |
---|
1094 | wireColor += btVector3 (0.f,1.f, 0.f); |
---|
1095 | } |
---|
1096 | else |
---|
1097 | { |
---|
1098 | wireColor += btVector3 (0.f,0.5f,0.f); |
---|
1099 | } |
---|
1100 | } |
---|
1101 | |
---|
1102 | btVector3 aabbMin,aabbMax; |
---|
1103 | m_dynamicsWorld->getBroadphase()->getBroadphaseAabb(aabbMin,aabbMax); |
---|
1104 | |
---|
1105 | aabbMin-=btVector3(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); |
---|
1106 | aabbMax+=btVector3(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); |
---|
1107 | // printf("aabbMin=(%f,%f,%f)\n",aabbMin.getX(),aabbMin.getY(),aabbMin.getZ()); |
---|
1108 | // printf("aabbMax=(%f,%f,%f)\n",aabbMax.getX(),aabbMax.getY(),aabbMax.getZ()); |
---|
1109 | // m_dynamicsWorld->getDebugDrawer()->drawAabb(aabbMin,aabbMax,btVector3(1,1,1)); |
---|
1110 | |
---|
1111 | |
---|
1112 | switch(pass) |
---|
1113 | { |
---|
1114 | case 0: m_shapeDrawer->drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode(),aabbMin,aabbMax);break; |
---|
1115 | case 1: m_shapeDrawer->drawShadow(m,m_sundirection*rot,colObj->getCollisionShape(),aabbMin,aabbMax);break; |
---|
1116 | case 2: m_shapeDrawer->drawOpenGL(m,colObj->getCollisionShape(),wireColor*0.3,0,aabbMin,aabbMax);break; |
---|
1117 | } |
---|
1118 | } |
---|
1119 | } |
---|
1120 | |
---|
1121 | // |
---|
1122 | void DemoApplication::renderme() |
---|
1123 | { |
---|
1124 | myinit(); |
---|
1125 | |
---|
1126 | updateCamera(); |
---|
1127 | |
---|
1128 | if (m_dynamicsWorld) |
---|
1129 | { |
---|
1130 | if(m_enableshadows) |
---|
1131 | { |
---|
1132 | glClear(GL_STENCIL_BUFFER_BIT); |
---|
1133 | glEnable(GL_CULL_FACE); |
---|
1134 | renderscene(0); |
---|
1135 | |
---|
1136 | glDisable(GL_LIGHTING); |
---|
1137 | glDepthMask(GL_FALSE); |
---|
1138 | glDepthFunc(GL_LEQUAL); |
---|
1139 | glEnable(GL_STENCIL_TEST); |
---|
1140 | glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); |
---|
1141 | glStencilFunc(GL_ALWAYS,1,0xFFFFFFFFL); |
---|
1142 | glFrontFace(GL_CCW); |
---|
1143 | glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); |
---|
1144 | renderscene(1); |
---|
1145 | glFrontFace(GL_CW); |
---|
1146 | glStencilOp(GL_KEEP,GL_KEEP,GL_DECR); |
---|
1147 | renderscene(1); |
---|
1148 | glFrontFace(GL_CCW); |
---|
1149 | |
---|
1150 | glPolygonMode(GL_FRONT,GL_FILL); |
---|
1151 | glPolygonMode(GL_BACK,GL_FILL); |
---|
1152 | glShadeModel(GL_SMOOTH); |
---|
1153 | glEnable(GL_DEPTH_TEST); |
---|
1154 | glDepthFunc(GL_LESS); |
---|
1155 | glEnable(GL_LIGHTING); |
---|
1156 | glDepthMask(GL_TRUE); |
---|
1157 | glCullFace(GL_BACK); |
---|
1158 | glFrontFace(GL_CCW); |
---|
1159 | glEnable(GL_CULL_FACE); |
---|
1160 | glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); |
---|
1161 | |
---|
1162 | glDepthFunc(GL_LEQUAL); |
---|
1163 | glStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFFL ); |
---|
1164 | glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); |
---|
1165 | glDisable(GL_LIGHTING); |
---|
1166 | renderscene(2); |
---|
1167 | glEnable(GL_LIGHTING); |
---|
1168 | glDepthFunc(GL_LESS); |
---|
1169 | glDisable(GL_STENCIL_TEST); |
---|
1170 | glDisable(GL_CULL_FACE); |
---|
1171 | } |
---|
1172 | else |
---|
1173 | { |
---|
1174 | glDisable(GL_CULL_FACE); |
---|
1175 | renderscene(0); |
---|
1176 | } |
---|
1177 | |
---|
1178 | int xOffset = 10; |
---|
1179 | int yStart = 20; |
---|
1180 | int yIncr = 20; |
---|
1181 | char buf[124]; |
---|
1182 | |
---|
1183 | glDisable(GL_LIGHTING); |
---|
1184 | glColor3f(0, 0, 0); |
---|
1185 | |
---|
1186 | if ((m_debugMode & btIDebugDraw::DBG_NoHelpText)==0) |
---|
1187 | { |
---|
1188 | setOrthographicProjection(); |
---|
1189 | |
---|
1190 | showProfileInfo(xOffset,yStart,yIncr); |
---|
1191 | |
---|
1192 | #ifdef USE_QUICKPROF |
---|
1193 | |
---|
1194 | |
---|
1195 | if ( getDebugMode() & btIDebugDraw::DBG_ProfileTimings) |
---|
1196 | { |
---|
1197 | static int counter = 0; |
---|
1198 | counter++; |
---|
1199 | std::map<std::string, hidden::ProfileBlock*>::iterator iter; |
---|
1200 | for (iter = btProfiler::mProfileBlocks.begin(); iter != btProfiler::mProfileBlocks.end(); ++iter) |
---|
1201 | { |
---|
1202 | char blockTime[128]; |
---|
1203 | sprintf(blockTime, "%s: %lf",&((*iter).first[0]),btProfiler::getBlockTime((*iter).first, btProfiler::BLOCK_CYCLE_SECONDS));//BLOCK_TOTAL_PERCENT)); |
---|
1204 | glRasterPos3f(xOffset,yStart,0); |
---|
1205 | GLDebugDrawString(BMF_GetFont(BMF_kHelvetica10),blockTime); |
---|
1206 | yStart += yIncr; |
---|
1207 | |
---|
1208 | } |
---|
1209 | |
---|
1210 | } |
---|
1211 | #endif //USE_QUICKPROF |
---|
1212 | |
---|
1213 | |
---|
1214 | sprintf(buf,"mouse to interact"); |
---|
1215 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1216 | yStart += yIncr; |
---|
1217 | |
---|
1218 | sprintf(buf,"ALT + mouse to move camera"); |
---|
1219 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1220 | yStart += yIncr; |
---|
1221 | |
---|
1222 | sprintf(buf,"space to reset"); |
---|
1223 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1224 | yStart += yIncr; |
---|
1225 | |
---|
1226 | sprintf(buf,"cursor keys and z,x to navigate"); |
---|
1227 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1228 | yStart += yIncr; |
---|
1229 | |
---|
1230 | sprintf(buf,"i to toggle simulation, s single step"); |
---|
1231 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1232 | yStart += yIncr; |
---|
1233 | |
---|
1234 | sprintf(buf,"q to quit"); |
---|
1235 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1236 | yStart += yIncr; |
---|
1237 | |
---|
1238 | sprintf(buf,". to shoot box"); |
---|
1239 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1240 | yStart += yIncr; |
---|
1241 | |
---|
1242 | // not yet hooked up again after refactoring... |
---|
1243 | |
---|
1244 | sprintf(buf,"d to toggle deactivation"); |
---|
1245 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1246 | yStart += yIncr; |
---|
1247 | |
---|
1248 | |
---|
1249 | sprintf(buf,"g to toggle mesh animation (ConcaveDemo)"); |
---|
1250 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1251 | yStart += yIncr; |
---|
1252 | |
---|
1253 | |
---|
1254 | sprintf(buf,"h to toggle help text"); |
---|
1255 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1256 | yStart += yIncr; |
---|
1257 | |
---|
1258 | sprintf(buf,"o to toggle orthogonal/perspective view"); |
---|
1259 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1260 | yStart += yIncr; |
---|
1261 | |
---|
1262 | |
---|
1263 | //bool useBulletLCP = !(getDebugMode() & btIDebugDraw::DBG_DisableBulletLCP); |
---|
1264 | //bool useCCD = (getDebugMode() & btIDebugDraw::DBG_EnableCCD); |
---|
1265 | //glRasterPos3f(xOffset,yStart,0); |
---|
1266 | //sprintf(buf,"1 CCD mode (adhoc) = %i",useCCD); |
---|
1267 | //GLDebugDrawString(BMF_GetFont(BMF_kHelvetica10),buf); |
---|
1268 | //yStart += yIncr; |
---|
1269 | |
---|
1270 | |
---|
1271 | |
---|
1272 | sprintf(buf,"+- shooting speed = %10.2f",m_ShootBoxInitialSpeed); |
---|
1273 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1274 | yStart += yIncr; |
---|
1275 | |
---|
1276 | #ifdef SHOW_NUM_DEEP_PENETRATIONS |
---|
1277 | |
---|
1278 | |
---|
1279 | sprintf(buf,"gNumDeepPenetrationChecks = %d",gNumDeepPenetrationChecks); |
---|
1280 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1281 | yStart += yIncr; |
---|
1282 | |
---|
1283 | sprintf(buf,"gNumGjkChecks= %d",gNumGjkChecks); |
---|
1284 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1285 | yStart += yIncr; |
---|
1286 | |
---|
1287 | sprintf(buf,"gNumClampedCcdMotions = %d",gNumClampedCcdMotions); |
---|
1288 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1289 | yStart += yIncr; |
---|
1290 | |
---|
1291 | sprintf(buf,"gNumSplitImpulseRecoveries= %d",gNumSplitImpulseRecoveries); |
---|
1292 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1293 | yStart += yIncr; |
---|
1294 | |
---|
1295 | sprintf(buf,"gNumAlignedAllocs = %d",gNumAlignedAllocs); |
---|
1296 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1297 | yStart += yIncr; |
---|
1298 | |
---|
1299 | sprintf(buf,"gNumAlignedFree= %d",gNumAlignedFree); |
---|
1300 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1301 | yStart += yIncr; |
---|
1302 | |
---|
1303 | sprintf(buf,"# alloc-free = %d",gNumAlignedAllocs-gNumAlignedFree); |
---|
1304 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1305 | yStart += yIncr; |
---|
1306 | |
---|
1307 | //enable BT_DEBUG_MEMORY_ALLOCATIONS define in Bullet/src/LinearMath/btAlignedAllocator.h for memory leak detection |
---|
1308 | #ifdef BT_DEBUG_MEMORY_ALLOCATIONS |
---|
1309 | glRasterPos3f(xOffset,yStart,0); |
---|
1310 | sprintf(buf,"gTotalBytesAlignedAllocs = %d",gTotalBytesAlignedAllocs); |
---|
1311 | GLDebugDrawString(BMF_GetFont(BMF_kHelvetica10),buf); |
---|
1312 | yStart += yIncr; |
---|
1313 | #endif //BT_DEBUG_MEMORY_ALLOCATIONS |
---|
1314 | |
---|
1315 | if (getDynamicsWorld()) |
---|
1316 | { |
---|
1317 | glRasterPos3f(xOffset,yStart,0); |
---|
1318 | sprintf(buf,"# objects = %d",getDynamicsWorld()->getNumCollisionObjects()); |
---|
1319 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1320 | yStart += yIncr; |
---|
1321 | glRasterPos3f(xOffset,yStart,0); |
---|
1322 | sprintf(buf,"# pairs = %d",getDynamicsWorld()->getBroadphase()->getOverlappingPairCache()->getNumOverlappingPairs()); |
---|
1323 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1324 | yStart += yIncr; |
---|
1325 | sprintf(buf,"# hitPos = %f,%f,%f",gHitPos.getX(),gHitPos.getY(),gHitPos.getZ()); |
---|
1326 | GLDebugDrawString(xOffset,yStart,buf); |
---|
1327 | yStart += yIncr; |
---|
1328 | |
---|
1329 | } |
---|
1330 | |
---|
1331 | |
---|
1332 | #endif //SHOW_NUM_DEEP_PENETRATIONS |
---|
1333 | |
---|
1334 | resetPerspectiveProjection(); |
---|
1335 | } |
---|
1336 | |
---|
1337 | glEnable(GL_LIGHTING); |
---|
1338 | |
---|
1339 | |
---|
1340 | } |
---|
1341 | |
---|
1342 | updateCamera(); |
---|
1343 | |
---|
1344 | } |
---|
1345 | #include "BulletCollision/BroadphaseCollision/btAxisSweep3.h" |
---|
1346 | |
---|
1347 | void DemoApplication::clientResetScene() |
---|
1348 | { |
---|
1349 | #ifdef SHOW_NUM_DEEP_PENETRATIONS |
---|
1350 | gNumDeepPenetrationChecks = 0; |
---|
1351 | gNumGjkChecks = 0; |
---|
1352 | #endif //SHOW_NUM_DEEP_PENETRATIONS |
---|
1353 | |
---|
1354 | gNumClampedCcdMotions = 0; |
---|
1355 | int numObjects = 0; |
---|
1356 | int i; |
---|
1357 | |
---|
1358 | if (m_dynamicsWorld) |
---|
1359 | { |
---|
1360 | numObjects = m_dynamicsWorld->getNumCollisionObjects(); |
---|
1361 | |
---|
1362 | ///create a copy of the array, not a reference! |
---|
1363 | btCollisionObjectArray copyArray = m_dynamicsWorld->getCollisionObjectArray(); |
---|
1364 | |
---|
1365 | |
---|
1366 | |
---|
1367 | |
---|
1368 | for (i=0;i<numObjects;i++) |
---|
1369 | { |
---|
1370 | btCollisionObject* colObj = copyArray[i]; |
---|
1371 | btRigidBody* body = btRigidBody::upcast(colObj); |
---|
1372 | if (body) |
---|
1373 | { |
---|
1374 | if (body->getMotionState()) |
---|
1375 | { |
---|
1376 | btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); |
---|
1377 | myMotionState->m_graphicsWorldTrans = myMotionState->m_startWorldTrans; |
---|
1378 | body->setCenterOfMassTransform( myMotionState->m_graphicsWorldTrans ); |
---|
1379 | colObj->setInterpolationWorldTransform( myMotionState->m_startWorldTrans ); |
---|
1380 | colObj->forceActivationState(ACTIVE_TAG); |
---|
1381 | colObj->activate(); |
---|
1382 | colObj->setDeactivationTime(0); |
---|
1383 | //colObj->setActivationState(WANTS_DEACTIVATION); |
---|
1384 | } |
---|
1385 | //removed cached contact points (this is not necessary if all objects have been removed from the dynamics world) |
---|
1386 | //m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(colObj->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); |
---|
1387 | |
---|
1388 | btRigidBody* body = btRigidBody::upcast(colObj); |
---|
1389 | if (body && !body->isStaticObject()) |
---|
1390 | { |
---|
1391 | btRigidBody::upcast(colObj)->setLinearVelocity(btVector3(0,0,0)); |
---|
1392 | btRigidBody::upcast(colObj)->setAngularVelocity(btVector3(0,0,0)); |
---|
1393 | } |
---|
1394 | } |
---|
1395 | |
---|
1396 | } |
---|
1397 | |
---|
1398 | ///reset some internal cached data in the broadphase |
---|
1399 | m_dynamicsWorld->getBroadphase()->resetPool(getDynamicsWorld()->getDispatcher()); |
---|
1400 | m_dynamicsWorld->getConstraintSolver()->reset(); |
---|
1401 | |
---|
1402 | } |
---|
1403 | |
---|
1404 | } |
---|