Bullet Collision Detection & Physics Library: btKinematicCharacterController.cpp Source File

Bullet Collision Detection & Physics Library

btKinematicCharacterController.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.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
17 #include <stdio.h>
18 #include "LinearMath/btIDebugDraw.h"
19 #include "BulletCollision/CollisionDispatch/btGhostObject.h"
20 #include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
21 #include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
22 #include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
23 #include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
24 #include "LinearMath/btDefaultMotionState.h"
25 #include "btKinematicCharacterController.h"
26
27
28 // static helper method
29 static btVector3
30 getNormalizedVector(const btVector3& v)
31 {
32 btVector3 n(0, 0, 0);
33
34 if (v.length() > SIMD_EPSILON) {
35 n = v.normalized();
36 }
37 return n;
38 }
39
40
47 class btKinematicClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
48 {
49 public:
50 btKinematicClosestNotMeRayResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
51 {
52 m_me = me;
53 }
54
55 virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
56 {
57 if (rayResult.m_collisionObject == m_me)
58 return 1.0;
59
60 return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace);
61 }
62 protected:
63 btCollisionObject* m_me;
64 };
65
66 class btKinematicClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
67 {
68 public:
69 btKinematicClosestNotMeConvexResultCallback (btCollisionObject* me, const btVector3& up, btScalar minSlopeDot)
70 : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
71 , m_me(me)
72 , m_up(up)
73 , m_minSlopeDot(minSlopeDot)
74 {
75 }
76
77 virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
78 {
79 if (convexResult.m_hitCollisionObject == m_me)
80 return btScalar(1.0);
81
82 if (!convexResult.m_hitCollisionObject->hasContactResponse())
83 return btScalar(1.0);
84
85 btVector3 hitNormalWorld;
86 if (normalInWorldSpace)
87 {
88 hitNormalWorld = convexResult.m_hitNormalLocal;
89 } else
90 {
92 hitNormalWorld = convexResult.m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal;
93 }
94
95 btScalar dotUp = m_up.dot(hitNormalWorld);
96 if (dotUp < m_minSlopeDot) {
97 return btScalar(1.0);
98 }
99
100 return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
101 }
102 protected:
103 btCollisionObject* m_me;
104 const btVector3 m_up;
105 btScalar m_minSlopeDot;
106 };
107
108 /*
109 * Returns the reflection direction of a ray going 'direction' hitting a surface with normal 'normal'
110 *
111 * from: http://www-cs-students.stanford.edu/~adityagp/final/node3.html
112 */
113 btVector3 btKinematicCharacterController::computeReflectionDirection (const btVector3& direction, const btVector3& normal)
114 {
115 return direction - (btScalar(2.0) * direction.dot(normal)) * normal;
116 }
117
118 /*
119 * Returns the portion of 'direction' that is parallel to 'normal'
120 */
121 btVector3 btKinematicCharacterController::parallelComponent (const btVector3& direction, const btVector3& normal)
122 {
123 btScalar magnitude = direction.dot(normal);
124 return normal * magnitude;
125 }
126
127 /*
128 * Returns the portion of 'direction' that is perpindicular to 'normal'
129 */
130 btVector3 btKinematicCharacterController::perpindicularComponent (const btVector3& direction, const btVector3& normal)
131 {
132 return direction - parallelComponent(direction, normal);
133 }
134
135 btKinematicCharacterController::btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, const btVector3& up)
136 {
137 m_ghostObject = ghostObject;
138 m_up.setValue(0.0f, 0.0f, 1.0f);
139 m_jumpAxis.setValue(0.0f, 0.0f, 1.0f);
140 m_addedMargin = 0.02;
141 m_walkDirection.setValue(0.0,0.0,0.0);
142 m_AngVel.setValue(0.0, 0.0, 0.0);
143 m_useGhostObjectSweepTest = true;
144 m_turnAngle = btScalar(0.0);
145 m_convexShape=convexShape;
146 m_useWalkDirection = true; // use walk direction by default, legacy behavior
147 m_velocityTimeInterval = 0.0;
148 m_verticalVelocity = 0.0;
149 m_verticalOffset = 0.0;
150 m_gravity = 9.8 * 3.0 ; // 3G acceleration.
151 m_fallSpeed = 55.0; // Terminal velocity of a sky diver in m/s.
152 m_jumpSpeed = 10.0; // ?
153 m_SetjumpSpeed = m_jumpSpeed;
154 m_wasOnGround = false;
155 m_wasJumping = false;
156 m_interpolateUp = true;
157 m_currentStepOffset = 0.0;
158 m_maxPenetrationDepth = 0.2;
159 full_drop = false;
160 bounce_fix = false;
161 m_linearDamping = btScalar(0.0);
162 m_angularDamping = btScalar(0.0);
163
164 setUp(up);
165 setStepHeight(stepHeight);
166 setMaxSlope(btRadians(45.0));
167 }
168
169 btKinematicCharacterController::~btKinematicCharacterController ()
170 {
171 }
172
173 btPairCachingGhostObject* btKinematicCharacterController::getGhostObject()
174 {
175 return m_ghostObject;
176 }
177
178 bool btKinematicCharacterController::recoverFromPenetration ( btCollisionWorld* collisionWorld)
179 {
180 // Here we must refresh the overlapping paircache as the penetrating movement itself or the
181 // previous recovery iteration might have used setWorldTransform and pushed us into an object
182 // that is not in the previous cache contents from the last timestep, as will happen if we
183 // are pushed into a new AABB overlap. Unhandled this means the next convex sweep gets stuck.
184 //
185 // Do this by calling the broadphase's setAabb with the moved AABB, this will update the broadphase
186 // paircache and the ghostobject's internal paircache at the same time. /BW
187
188 btVector3 minAabb, maxAabb;
189 m_convexShape->getAabb(m_ghostObject->getWorldTransform(), minAabb,maxAabb);
190 collisionWorld->getBroadphase()->setAabb(m_ghostObject->getBroadphaseHandle(),
191 minAabb,
192 maxAabb,
193 collisionWorld->getDispatcher());
194
195 bool penetration = false;
196
197 collisionWorld->getDispatcher()->dispatchAllCollisionPairs(m_ghostObject->getOverlappingPairCache(), collisionWorld->getDispatchInfo(), collisionWorld->getDispatcher());
198
199 m_currentPosition = m_ghostObject->getWorldTransform().getOrigin();
200
201 // btScalar maxPen = btScalar(0.0);
202 for (int i = 0; i < m_ghostObject->getOverlappingPairCache()->getNumOverlappingPairs(); i++)
203 {
204 m_manifoldArray.resize(0);
205
206 btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
207
208 btCollisionObject* obj0 = static_cast<btCollisionObject*>(collisionPair->m_pProxy0->m_clientObject);
209 btCollisionObject* obj1 = static_cast<btCollisionObject*>(collisionPair->m_pProxy1->m_clientObject);
210
211 if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse()))
212 continue;
213
214 if (!needsCollision(obj0, obj1))
215 continue;
216
217 if (collisionPair->m_algorithm)
218 collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);
219
220
221 for (int j=0;j<m_manifoldArray.size();j++)
222 {
223 btPersistentManifold* manifold = m_manifoldArray[j];
224 btScalar directionSign = manifold->getBody0() == m_ghostObject ? btScalar(-1.0) : btScalar(1.0);
225 for (int p=0;p<manifold->getNumContacts();p++)
226 {
227 const btManifoldPoint&pt = manifold->getContactPoint(p);
228
229 btScalar dist = pt.getDistance();
230
231 if (dist < -m_maxPenetrationDepth)
232 {
233 // TODO: cause problems on slopes, not sure if it is needed
234 //if (dist < maxPen)
235 //{
236 // maxPen = dist;
237 // m_touchingNormal = pt.m_normalWorldOnB * directionSign;//??
238
239 //}
240 m_currentPosition += pt.m_normalWorldOnB * directionSign * dist * btScalar(0.2);
241 penetration = true;
242 } else {
243 //printf("touching %f\n", dist);
244 }
245 }
246
247 //manifold->clearManifold();
248 }
249 }
250 btTransform newTrans = m_ghostObject->getWorldTransform();
251 newTrans.setOrigin(m_currentPosition);
252 m_ghostObject->setWorldTransform(newTrans);
253 // printf("m_touchingNormal = %f,%f,%f\n",m_touchingNormal[0],m_touchingNormal[1],m_touchingNormal[2]);
254 return penetration;
255 }
256
257 void btKinematicCharacterController::stepUp ( btCollisionWorld* world)
258 {
259 btScalar stepHeight = 0.0f;
260 if (m_verticalVelocity < 0.0)
261 stepHeight = m_stepHeight;
262
263 // phase 1: up
264 btTransform start, end;
265
266 start.setIdentity ();
267 end.setIdentity ();
268
269 /* FIXME: Handle penetration properly */
270 start.setOrigin(m_currentPosition);
271
272 m_targetPosition = m_currentPosition + m_up * (stepHeight) + m_jumpAxis * ((m_verticalOffset > 0.f ? m_verticalOffset : 0.f));
273 m_currentPosition = m_targetPosition;
274
275 end.setOrigin (m_targetPosition);
276
277 start.setRotation(m_currentOrientation);
278 end.setRotation(m_targetOrientation);
279
280 btKinematicClosestNotMeConvexResultCallback callback(m_ghostObject, -m_up, m_maxSlopeCosine);
281 callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
282 callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
283
284 if (m_useGhostObjectSweepTest)
285 {
286 m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, world->getDispatchInfo().m_allowedCcdPenetration);
287 }
288 else
289 {
290 world->convexSweepTest(m_convexShape, start, end, callback, world->getDispatchInfo().m_allowedCcdPenetration);
291 }
292
293 if (callback.hasHit() && m_ghostObject->hasContactResponse() && needsCollision(m_ghostObject, callback.m_hitCollisionObject))
294 {
295 // Only modify the position if the hit was a slope and not a wall or ceiling.
296 if (callback.m_hitNormalWorld.dot(m_up) > 0.0)
297 {
298 // we moved up only a fraction of the step height
299 m_currentStepOffset = stepHeight * callback.m_closestHitFraction;
300 if (m_interpolateUp == true)
301 m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
302 else
303 m_currentPosition = m_targetPosition;
304 }
305
306 btTransform& xform = m_ghostObject->getWorldTransform();
307 xform.setOrigin(m_currentPosition);
308 m_ghostObject->setWorldTransform(xform);
309
310 // fix penetration if we hit a ceiling for example
311 int numPenetrationLoops = 0;
312 m_touchingContact = false;
313 while (recoverFromPenetration(world))
314 {
315 numPenetrationLoops++;
316 m_touchingContact = true;
317 if (numPenetrationLoops > 4)
318 {
319 //printf("character could not recover from penetration = %d\n", numPenetrationLoops);
320 break;
321 }
322 }
323 m_targetPosition = m_ghostObject->getWorldTransform().getOrigin();
324 m_currentPosition = m_targetPosition;
325
326 if (m_verticalOffset > 0)
327 {
328 m_verticalOffset = 0.0;
329 m_verticalVelocity = 0.0;
330 m_currentStepOffset = m_stepHeight;
331 }
332 } else {
333 m_currentStepOffset = stepHeight;
334 m_currentPosition = m_targetPosition;
335 }
336 }
337
338 bool btKinematicCharacterController::needsCollision(const btCollisionObject* body0, const btCollisionObject* body1)
339 {
340 bool collides = (body0->getBroadphaseHandle()->m_collisionFilterGroup & body1->getBroadphaseHandle()->m_collisionFilterMask) != 0;
341 collides = collides && (body1->getBroadphaseHandle()->m_collisionFilterGroup & body0->getBroadphaseHandle()->m_collisionFilterMask);
342 return collides;
343 }
344
345 void btKinematicCharacterController::updateTargetPositionBasedOnCollision (const btVector3& hitNormal, btScalar tangentMag, btScalar normalMag)
346 {
347 btVector3 movementDirection = m_targetPosition - m_currentPosition;
348 btScalar movementLength = movementDirection.length();
349 if (movementLength>SIMD_EPSILON)
350 {
351 movementDirection.normalize();
352
353 btVector3 reflectDir = computeReflectionDirection (movementDirection, hitNormal);
354 reflectDir.normalize();
355
356 btVector3 parallelDir, perpindicularDir;
357
358 parallelDir = parallelComponent (reflectDir, hitNormal);
359 perpindicularDir = perpindicularComponent (reflectDir, hitNormal);
360
361 m_targetPosition = m_currentPosition;
362 if (0)//tangentMag != 0.0)
363 {
364 btVector3 parComponent = parallelDir * btScalar (tangentMag*movementLength);
365 // printf("parComponent=%f,%f,%f\n",parComponent[0],parComponent[1],parComponent[2]);
366 m_targetPosition += parComponent;
367 }
368
369 if (normalMag != 0.0)
370 {
371 btVector3 perpComponent = perpindicularDir * btScalar (normalMag*movementLength);
372 // printf("perpComponent=%f,%f,%f\n",perpComponent[0],perpComponent[1],perpComponent[2]);
373 m_targetPosition += perpComponent;
374 }
375 } else
376 {
377 // printf("movementLength don't normalize a zero vector\n");
378 }
379 }
380
381 void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* collisionWorld, const btVector3& walkMove)
382 {
383 // printf("m_normalizedDirection=%f,%f,%f\n",
384 // m_normalizedDirection[0],m_normalizedDirection[1],m_normalizedDirection[2]);
385 // phase 2: forward and strafe
386 btTransform start, end;
387
388 m_targetPosition = m_currentPosition + walkMove;
389
390 start.setIdentity ();
391 end.setIdentity ();
392
393 btScalar fraction = 1.0;
394 btScalar distance2 = (m_currentPosition-m_targetPosition).length2();
395 // printf("distance2=%f\n",distance2);
396
397 int maxIter = 10;
398
399 while (fraction > btScalar(0.01) && maxIter-- > 0)
400 {
401 start.setOrigin (m_currentPosition);
402 end.setOrigin (m_targetPosition);
403 btVector3 sweepDirNegative(m_currentPosition - m_targetPosition);
404
405 start.setRotation(m_currentOrientation);
406 end.setRotation(m_targetOrientation);
407
408 btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, sweepDirNegative, btScalar(0.0));
409 callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
410 callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
411
412
413 btScalar margin = m_convexShape->getMargin();
414 m_convexShape->setMargin(margin + m_addedMargin);
415
416 if (!(start == end))
417 {
418 if (m_useGhostObjectSweepTest)
419 {
420 m_ghostObject->convexSweepTest(m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
421 }
422 else
423 {
424 collisionWorld->convexSweepTest(m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
425 }
426 }
427 m_convexShape->setMargin(margin);
428
429
430 fraction -= callback.m_closestHitFraction;
431
432 if (callback.hasHit() && m_ghostObject->hasContactResponse() && needsCollision(m_ghostObject, callback.m_hitCollisionObject))
433 {
434 // we moved only a fraction
435 //btScalar hitDistance;
436 //hitDistance = (callback.m_hitPointWorld - m_currentPosition).length();
437
438 // m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
439
440 updateTargetPositionBasedOnCollision (callback.m_hitNormalWorld);
441 btVector3 currentDir = m_targetPosition - m_currentPosition;
442 distance2 = currentDir.length2();
443 if (distance2 > SIMD_EPSILON)
444 {
445 currentDir.normalize();
446 /* See Quake2: "If velocity is against original velocity, stop ead to avoid tiny oscilations in sloping corners." */
447 if (currentDir.dot(m_normalizedDirection) <= btScalar(0.0))
448 {
449 break;
450 }
451 } else
452 {
453 // printf("currentDir: don't normalize a zero vector\n");
454 break;
455 }
456
457 }
458 else
459 {
460 m_currentPosition = m_targetPosition;
461 }
462 }
463 }
464
465 void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld, btScalar dt)
466 {
467 btTransform start, end, end_double;
468 bool runonce = false;
469
470 // phase 3: down
471 /*btScalar additionalDownStep = (m_wasOnGround && !onGround()) ? m_stepHeight : 0.0;
472 btVector3 step_drop = m_up * (m_currentStepOffset + additionalDownStep);
473 btScalar downVelocity = (additionalDownStep == 0.0 && m_verticalVelocity<0.0?-m_verticalVelocity:0.0) * dt;
474 btVector3 gravity_drop = m_up * downVelocity;
475 m_targetPosition -= (step_drop + gravity_drop);*/
476
477 btVector3 orig_position = m_targetPosition;
478
479 btScalar downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
480
481 if (m_verticalVelocity > 0.0)
482 return;
483
484 if(downVelocity > 0.0 && downVelocity > m_fallSpeed
485 && (m_wasOnGround || !m_wasJumping))
486 downVelocity = m_fallSpeed;
487
488 btVector3 step_drop = m_up * (m_currentStepOffset + downVelocity);
489 m_targetPosition -= step_drop;
490
491 btKinematicClosestNotMeConvexResultCallback callback(m_ghostObject, m_up, m_maxSlopeCosine);
492 callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
493 callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
494
495 btKinematicClosestNotMeConvexResultCallback callback2(m_ghostObject, m_up, m_maxSlopeCosine);
496 callback2.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
497 callback2.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
498
499 while (1)
500 {
501 start.setIdentity ();
502 end.setIdentity ();
503
504 end_double.setIdentity ();
505
506 start.setOrigin (m_currentPosition);
507 end.setOrigin (m_targetPosition);
508
509 start.setRotation(m_currentOrientation);
510 end.setRotation(m_targetOrientation);
511
512 //set double test for 2x the step drop, to check for a large drop vs small drop
513 end_double.setOrigin (m_targetPosition - step_drop);
514
515 if (m_useGhostObjectSweepTest)
516 {
517 m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
518
519 if (!callback.hasHit() && m_ghostObject->hasContactResponse())
520 {
521 //test a double fall height, to see if the character should interpolate it's fall (full) or not (partial)
522 m_ghostObject->convexSweepTest (m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
523 }
524 } else
525 {
526 collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
527
528 if (!callback.hasHit() && m_ghostObject->hasContactResponse())
529 {
530 //test a double fall height, to see if the character should interpolate it's fall (large) or not (small)
531 collisionWorld->convexSweepTest (m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
532 }
533 }
534
535 btScalar downVelocity2 = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
536 bool has_hit;
537 if (bounce_fix == true)
538 has_hit = (callback.hasHit() || callback2.hasHit()) && m_ghostObject->hasContactResponse() && needsCollision(m_ghostObject, callback.m_hitCollisionObject);
539 else
540 has_hit = callback2.hasHit() && m_ghostObject->hasContactResponse() && needsCollision(m_ghostObject, callback2.m_hitCollisionObject);
541
542 btScalar stepHeight = 0.0f;
543 if (m_verticalVelocity < 0.0)
544 stepHeight = m_stepHeight;
545
546 if (downVelocity2 > 0.0 && downVelocity2 < stepHeight && has_hit == true && runonce == false
547 && (m_wasOnGround || !m_wasJumping))
548 {
549 //redo the velocity calculation when falling a small amount, for fast stairs motion
550 //for larger falls, use the smoother/slower interpolated movement by not touching the target position
551
552 m_targetPosition = orig_position;
553 downVelocity = stepHeight;
554
555 step_drop = m_up * (m_currentStepOffset + downVelocity);
556 m_targetPosition -= step_drop;
557 runonce = true;
558 continue; //re-run previous tests
559 }
560 break;
561 }
562
563 if ((m_ghostObject->hasContactResponse() && (callback.hasHit() && needsCollision(m_ghostObject, callback.m_hitCollisionObject))) || runonce == true)
564 {
565 // we dropped a fraction of the height -> hit floor
566 btScalar fraction = (m_currentPosition.getY() - callback.m_hitPointWorld.getY()) / 2;
567
568 //printf("hitpoint: %g - pos %g\n", callback.m_hitPointWorld.getY(), m_currentPosition.getY());
569
570 if (bounce_fix == true)
571 {
572 if (full_drop == true)
573 m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
574 else
575 //due to errors in the closestHitFraction variable when used with large polygons, calculate the hit fraction manually
576 m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, fraction);
577 }
578 else
579 m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
580
581 full_drop = false;
582
583 m_verticalVelocity = 0.0;
584 m_verticalOffset = 0.0;
585 m_wasJumping = false;
586 } else {
587 // we dropped the full height
588
589 full_drop = true;
590
591 if (bounce_fix == true)
592 {
593 downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
594 if (downVelocity > m_fallSpeed && (m_wasOnGround || !m_wasJumping))
595 {
596 m_targetPosition += step_drop; //undo previous target change
597 downVelocity = m_fallSpeed;
598 step_drop = m_up * (m_currentStepOffset + downVelocity);
599 m_targetPosition -= step_drop;
600 }
601 }
602 //printf("full drop - %g, %g\n", m_currentPosition.getY(), m_targetPosition.getY());
603
604 m_currentPosition = m_targetPosition;
605 }
606 }
607
608
609
610 void btKinematicCharacterController::setWalkDirection
611 (
612 const btVector3& walkDirection
613 )
614 {
615 m_useWalkDirection = true;
616 m_walkDirection = walkDirection;
617 m_normalizedDirection = getNormalizedVector(m_walkDirection);
618 }
619
620
621
622 void btKinematicCharacterController::setVelocityForTimeInterval
623 (
624 const btVector3& velocity,
625 btScalar timeInterval
626 )
627 {
628 // printf("setVelocity!\n");
629 // printf(" interval: %f\n", timeInterval);
630 // printf(" velocity: (%f, %f, %f)\n",
631 // velocity.x(), velocity.y(), velocity.z());
632
633 m_useWalkDirection = false;
634 m_walkDirection = velocity;
635 m_normalizedDirection = getNormalizedVector(m_walkDirection);
636 m_velocityTimeInterval += timeInterval;
637 }
638
639 void btKinematicCharacterController::setAngularVelocity(const btVector3& velocity)
640 {
641 m_AngVel = velocity;
642 }
643
644 const btVector3& btKinematicCharacterController::getAngularVelocity() const
645 {
646 return m_AngVel;
647 }
648
649 void btKinematicCharacterController::setLinearVelocity(const btVector3& velocity)
650 {
651 m_walkDirection = velocity;
652
653 // HACK: if we are moving in the direction of the up, treat it as a jump :(
654 if (m_walkDirection.length2() > 0)
655 {
656 btVector3 w = velocity.normalized();
657 btScalar c = w.dot(m_up);
658 if (c != 0)
659 {
660 //there is a component in walkdirection for vertical velocity
661 btVector3 upComponent = m_up * (btSin(SIMD_HALF_PI - btAcos(c)) * m_walkDirection.length());
662 m_walkDirection -= upComponent;
663 m_verticalVelocity = (c < 0.0f ? -1 : 1) * upComponent.length();
664
665 if (c > 0.0f)
666 {
667 m_wasJumping = true;
668 m_jumpPosition = m_ghostObject->getWorldTransform().getOrigin();
669 }
670 }
671 }
672 else
673 m_verticalVelocity = 0.0f;
674 }
675
676 btVector3 btKinematicCharacterController::getLinearVelocity() const
677 {
678 return m_walkDirection + (m_verticalVelocity * m_up);
679 }
680
681 void btKinematicCharacterController::reset ( btCollisionWorld* collisionWorld )
682 {
683 m_verticalVelocity = 0.0;
684 m_verticalOffset = 0.0;
685 m_wasOnGround = false;
686 m_wasJumping = false;
687 m_walkDirection.setValue(0,0,0);
688 m_velocityTimeInterval = 0.0;
689
690 //clear pair cache
691 btHashedOverlappingPairCache *cache = m_ghostObject->getOverlappingPairCache();
692 while (cache->getOverlappingPairArray().size() > 0)
693 {
694 cache->removeOverlappingPair(cache->getOverlappingPairArray()[0].m_pProxy0, cache->getOverlappingPairArray()[0].m_pProxy1, collisionWorld->getDispatcher());
695 }
696 }
697
698 void btKinematicCharacterController::warp (const btVector3& origin)
699 {
700 btTransform xform;
701 xform.setIdentity();
702 xform.setOrigin (origin);
703 m_ghostObject->setWorldTransform (xform);
704 }
705
706
707 void btKinematicCharacterController::preStep ( btCollisionWorld* collisionWorld)
708 {
709 m_currentPosition = m_ghostObject->getWorldTransform().getOrigin();
710 m_targetPosition = m_currentPosition;
711
712 m_currentOrientation = m_ghostObject->getWorldTransform().getRotation();
713 m_targetOrientation = m_currentOrientation;
714 // printf("m_targetPosition=%f,%f,%f\n",m_targetPosition[0],m_targetPosition[1],m_targetPosition[2]);
715 }
716
717 void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWorld, btScalar dt)
718 {
719 // printf("playerStep(): ");
720 // printf(" dt = %f", dt);
721
722 if (m_AngVel.length2() > 0.0f)
723 {
724 m_AngVel *= btPow(btScalar(1) - m_angularDamping, dt);
725 }
726
727 // integrate for angular velocity
728 if (m_AngVel.length2() > 0.0f)
729 {
730 btTransform xform;
731 xform = m_ghostObject->getWorldTransform();
732
733 btQuaternion rot(m_AngVel.normalized(), m_AngVel.length() * dt);
734
735 btQuaternion orn = rot * xform.getRotation();
736
737 xform.setRotation(orn);
738 m_ghostObject->setWorldTransform(xform);
739
740 m_currentPosition = m_ghostObject->getWorldTransform().getOrigin();
741 m_targetPosition = m_currentPosition;
742 m_currentOrientation = m_ghostObject->getWorldTransform().getRotation();
743 m_targetOrientation = m_currentOrientation;
744 }
745
746 // quick check...
747 if (!m_useWalkDirection && (m_velocityTimeInterval <= 0.0)) {
748 // printf("\n");
749 return; // no motion
750 }
751
752 m_wasOnGround = onGround();
753
754 //btVector3 lvel = m_walkDirection;
755 //btScalar c = 0.0f;
756
757 if (m_walkDirection.length2() > 0)
758 {
759 // apply damping
760 m_walkDirection *= btPow(btScalar(1) - m_linearDamping, dt);
761 }
762
763 m_verticalVelocity *= btPow(btScalar(1) - m_linearDamping, dt);
764
765 // Update fall velocity.
766 m_verticalVelocity -= m_gravity * dt;
767 if (m_verticalVelocity > 0.0 && m_verticalVelocity > m_jumpSpeed)
768 {
769 m_verticalVelocity = m_jumpSpeed;
770 }
771 if (m_verticalVelocity < 0.0 && btFabs(m_verticalVelocity) > btFabs(m_fallSpeed))
772 {
773 m_verticalVelocity = -btFabs(m_fallSpeed);
774 }
775 m_verticalOffset = m_verticalVelocity * dt;
776
777 btTransform xform;
778 xform = m_ghostObject->getWorldTransform();
779
780 // printf("walkDirection(%f,%f,%f)\n",walkDirection[0],walkDirection[1],walkDirection[2]);
781 // printf("walkSpeed=%f\n",walkSpeed);
782
783 stepUp(collisionWorld);
784 //todo: Experimenting with behavior of controller when it hits a ceiling..
785 //bool hitUp = stepUp (collisionWorld);
786 //if (hitUp)
787 //{
788 // m_verticalVelocity -= m_gravity * dt;
789 // if (m_verticalVelocity > 0.0 && m_verticalVelocity > m_jumpSpeed)
790 // {
791 // m_verticalVelocity = m_jumpSpeed;
792 // }
793 // if (m_verticalVelocity < 0.0 && btFabs(m_verticalVelocity) > btFabs(m_fallSpeed))
794 // {
795 // m_verticalVelocity = -btFabs(m_fallSpeed);
796 // }
797 // m_verticalOffset = m_verticalVelocity * dt;
798
799 // xform = m_ghostObject->getWorldTransform();
800 //}
801
802 if (m_useWalkDirection) {
803 stepForwardAndStrafe (collisionWorld, m_walkDirection);
804 } else {
805 //printf(" time: %f", m_velocityTimeInterval);
806 // still have some time left for moving!
807 btScalar dtMoving =
808 (dt < m_velocityTimeInterval) ? dt : m_velocityTimeInterval;
809 m_velocityTimeInterval -= dt;
810
811 // how far will we move while we are moving?
812 btVector3 move = m_walkDirection * dtMoving;
813
814 //printf(" dtMoving: %f", dtMoving);
815
816 // okay, step
817 stepForwardAndStrafe(collisionWorld, move);
818 }
819 stepDown (collisionWorld, dt);
820
821 //todo: Experimenting with max jump height
822 //if (m_wasJumping)
823 //{
824 // btScalar ds = m_currentPosition[m_upAxis] - m_jumpPosition[m_upAxis];
825 // if (ds > m_maxJumpHeight)
826 // {
827 // // substract the overshoot
828 // m_currentPosition[m_upAxis] -= ds - m_maxJumpHeight;
829
830 // // max height was reached, so potential energy is at max
831 // // and kinematic energy is 0, thus velocity is 0.
832 // if (m_verticalVelocity > 0.0)
833 // m_verticalVelocity = 0.0;
834 // }
835 //}
836 // printf("\n");
837
838 xform.setOrigin (m_currentPosition);
839 m_ghostObject->setWorldTransform (xform);
840
841 int numPenetrationLoops = 0;
842 m_touchingContact = false;
843 while (recoverFromPenetration(collisionWorld))
844 {
845 numPenetrationLoops++;
846 m_touchingContact = true;
847 if (numPenetrationLoops > 4)
848 {
849 //printf("character could not recover from penetration = %d\n", numPenetrationLoops);
850 break;
851 }
852 }
853 }
854
855 void btKinematicCharacterController::setFallSpeed (btScalar fallSpeed)
856 {
857 m_fallSpeed = fallSpeed;
858 }
859
860 void btKinematicCharacterController::setJumpSpeed (btScalar jumpSpeed)
861 {
862 m_jumpSpeed = jumpSpeed;
863 m_SetjumpSpeed = m_jumpSpeed;
864 }
865
866 void btKinematicCharacterController::setMaxJumpHeight (btScalar maxJumpHeight)
867 {
868 m_maxJumpHeight = maxJumpHeight;
869 }
870
871 bool btKinematicCharacterController::canJump () const
872 {
873 return onGround();
874 }
875
876 void btKinematicCharacterController::jump(const btVector3& v)
877 {
878 m_jumpSpeed = v.length2() == 0 ? m_SetjumpSpeed : v.length();
879 m_verticalVelocity = m_jumpSpeed;
880 m_wasJumping = true;
881
882 m_jumpAxis = v.length2() == 0 ? m_up : v.normalized();
883
884 m_jumpPosition = m_ghostObject->getWorldTransform().getOrigin();
885
886 #if 0
887 currently no jumping.
888 btTransform xform;
889 m_rigidBody->getMotionState()->getWorldTransform (xform);
890 btVector3 up = xform.getBasis()[1];
891 up.normalize ();
892 btScalar magnitude = (btScalar(1.0)/m_rigidBody->getInvMass()) * btScalar(8.0);
893 m_rigidBody->applyCentralImpulse (up * magnitude);
894 #endif
895 }
896
897 void btKinematicCharacterController::setGravity(const btVector3& gravity)
898 {
899 if (gravity.length2() > 0) setUpVector(-gravity);
900
901 m_gravity = gravity.length();
902 }
903
904 btVector3 btKinematicCharacterController::getGravity() const
905 {
906 return -m_gravity * m_up;
907 }
908
909 void btKinematicCharacterController::setMaxSlope(btScalar slopeRadians)
910 {
911 m_maxSlopeRadians = slopeRadians;
912 m_maxSlopeCosine = btCos(slopeRadians);
913 }
914
915 btScalar btKinematicCharacterController::getMaxSlope() const
916 {
917 return m_maxSlopeRadians;
918 }
919
920 void btKinematicCharacterController::setMaxPenetrationDepth(btScalar d)
921 {
922 m_maxPenetrationDepth = d;
923 }
924
925 btScalar btKinematicCharacterController::getMaxPenetrationDepth() const
926 {
927 return m_maxPenetrationDepth;
928 }
929
930 bool btKinematicCharacterController::onGround () const
931 {
932 return (fabs(m_verticalVelocity) < SIMD_EPSILON) && (fabs(m_verticalOffset) < SIMD_EPSILON);
933 }
934
935 void btKinematicCharacterController::setStepHeight(btScalar h)
936 {
937 m_stepHeight = h;
938 }
939
940 btVector3* btKinematicCharacterController::getUpAxisDirections()
941 {
942 static btVector3 sUpAxisDirection[3] = { btVector3(1.0f, 0.0f, 0.0f), btVector3(0.0f, 1.0f, 0.0f), btVector3(0.0f, 0.0f, 1.0f) };
943
944 return sUpAxisDirection;
945 }
946
947 void btKinematicCharacterController::debugDraw(btIDebugDraw* debugDrawer)
948 {
949 }
950
951 void btKinematicCharacterController::setUpInterpolate(bool value)
952 {
953 m_interpolateUp = value;
954 }
955
956 void btKinematicCharacterController::setUp(const btVector3& up)
957 {
958 if (up.length2() > 0 && m_gravity > 0.0f)
959 {
960 setGravity(-m_gravity * up.normalized());
961 return;
962 }
963
964 setUpVector(up);
965 }
966
967 void btKinematicCharacterController::setUpVector(const btVector3& up)
968 {
969 if (m_up == up)
970 return;
971
972 btVector3 u = m_up;
973
974 if (up.length2() > 0)
975 m_up = up.normalized();
976 else
977 m_up = btVector3(0.0, 0.0, 0.0);
978
979 if (!m_ghostObject) return;
980 btQuaternion rot = getRotation(m_up, u);
981
982 //set orientation with new up
983 btTransform xform;
984 xform = m_ghostObject->getWorldTransform();
985 btQuaternion orn = rot.inverse() * xform.getRotation();
986 xform.setRotation(orn);
987 m_ghostObject->setWorldTransform(xform);
988 }
989
990 btQuaternion btKinematicCharacterController::getRotation(btVector3& v0, btVector3& v1) const
991 {
992 if (v0.length2() == 0.0f || v1.length2() == 0.0f)
993 {
994 btQuaternion q;
995 return q;
996 }
997
998 return shortestArcQuatNormalize2(v0, v1);
999 }
1000
btTransform::setOrigin
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:150
btGhostObject.h
SIMD_EPSILON
#define SIMD_EPSILON
Definition: btScalar.h:521
btPersistentManifold
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
Definition: btPersistentManifold.h:63
btKinematicCharacterController::onGround
bool onGround() const
Definition: btKinematicCharacterController.cpp:930
btKinematicCharacterController::playerStep
void playerStep(btCollisionWorld *collisionWorld, btScalar dt)
Definition: btKinematicCharacterController.cpp:717
btKinematicCharacterController::setUpVector
void setUpVector(const btVector3 &up)
Definition: btKinematicCharacterController.cpp:967
btCollisionWorld.h
btKinematicClosestNotMeRayResultCallback::addSingleResult
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult &rayResult, bool normalInWorldSpace)
Definition: btKinematicCharacterController.cpp:55
btKinematicCharacterController::stepDown
void stepDown(btCollisionWorld *collisionWorld, btScalar dt)
Definition: btKinematicCharacterController.cpp:465
btKinematicClosestNotMeRayResultCallback::btKinematicClosestNotMeRayResultCallback
btKinematicClosestNotMeRayResultCallback(btCollisionObject *me)
Definition: btKinematicCharacterController.cpp:50
btKinematicCharacterController::~btKinematicCharacterController
~btKinematicCharacterController()
Definition: btKinematicCharacterController.cpp:169
btKinematicClosestNotMeRayResultCallback
Definition: btKinematicCharacterController.cpp:47
btRadians
btScalar btRadians(btScalar x)
Definition: btScalar.h:566
btKinematicClosestNotMeConvexResultCallback::m_me
btCollisionObject * m_me
Definition: btKinematicCharacterController.cpp:103
btKinematicCharacterController::getLinearVelocity
virtual btVector3 getLinearVelocity() const
Definition: btKinematicCharacterController.cpp:676
btKinematicCharacterController::setJumpSpeed
void setJumpSpeed(btScalar jumpSpeed)
Definition: btKinematicCharacterController.cpp:860
btSin
btScalar btSin(btScalar x)
Definition: btScalar.h:477
btKinematicCharacterController::getRotation
btQuaternion getRotation(btVector3 &v0, btVector3 &v1) const
Definition: btKinematicCharacterController.cpp:990
btVector3::length2
btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:257
btDispatcher::dispatchAllCollisionPairs
virtual void dispatchAllCollisionPairs(btOverlappingPairCache *pairCache, const btDispatcherInfo &dispatchInfo, btDispatcher *dispatcher)=0
btKinematicClosestNotMeConvexResultCallback::m_up
const btVector3 m_up
Definition: btKinematicCharacterController.cpp:104
btKinematicCharacterController::computeReflectionDirection
btVector3 computeReflectionDirection(const btVector3 &direction, const btVector3 &normal)
Definition: btKinematicCharacterController.cpp:113
btPersistentManifold::getNumContacts
int getNumContacts() const
Definition: btPersistentManifold.h:117
btTransform::setIdentity
void setIdentity()
Set this transformation to the identity.
Definition: btTransform.h:172
btTransform::getRotation
btQuaternion getRotation() const
Return a quaternion representing the rotation.
Definition: btTransform.h:122
btHashedOverlappingPairCache::getOverlappingPairArray
btBroadphasePairArray & getOverlappingPairArray()
Definition: btOverlappingPairCache.h:157
btCollisionWorld::ConvexResultCallback::hasHit
bool hasHit() const
Definition: btCollisionWorld.h:357
btVector3::getY
const btScalar & getY() const
Return the y value.
Definition: btVector3.h:575
btKinematicCharacterController::getGravity
btVector3 getGravity() const
Definition: btKinematicCharacterController.cpp:904
btKinematicCharacterController::getMaxSlope
btScalar getMaxSlope() const
Definition: btKinematicCharacterController.cpp:915
btManifoldPoint
ManifoldContactPoint collects and maintains persistent contactpoints.
Definition: btManifoldPoint.h:49
btKinematicClosestNotMeConvexResultCallback
Definition: btKinematicCharacterController.cpp:66
btCollisionWorld::ClosestConvexResultCallback::m_hitPointWorld
btVector3 m_hitPointWorld
Definition: btCollisionWorld.h:387
btKinematicCharacterController::setVelocityForTimeInterval
virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval)
Caller provides a velocity with which the character should move for the given time period...
Definition: btKinematicCharacterController.cpp:623
SIMD_HALF_PI
#define SIMD_HALF_PI
Definition: btScalar.h:506
btKinematicCharacterController::debugDraw
void debugDraw(btIDebugDraw *debugDrawer)
btActionInterface interface
Definition: btKinematicCharacterController.cpp:947
btVector3::normalize
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:309
btVector3::normalized
btVector3 normalized() const
Return a normalized version of this vector.
Definition: btVector3.h:964
btConvexShape
The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape...
Definition: btConvexShape.h:31
btOverlappingPairCache.h
btPersistentManifold::getContactPoint
const btManifoldPoint & getContactPoint(int index) const
Definition: btPersistentManifold.h:125
btCollisionWorld::ConvexResultCallback::m_collisionFilterGroup
int m_collisionFilterGroup
Definition: btCollisionWorld.h:343
btCollisionWorld::LocalConvexResult::m_hitCollisionObject
const btCollisionObject * m_hitCollisionObject
Definition: btCollisionWorld.h:332
btQuaternion::inverse
btQuaternion inverse() const
Return the inverse of this quaternion.
Definition: btQuaternion.h:482
btBroadphaseProxy::m_collisionFilterMask
int m_collisionFilterMask
Definition: btBroadphaseProxy.h:105
btCollisionObject::getWorldTransform
btTransform & getWorldTransform()
Definition: btCollisionObject.h:372
btManifoldPoint::m_normalWorldOnB
btVector3 m_normalWorldOnB
Definition: btManifoldPoint.h:100
btCollisionObject::getBroadphaseHandle
btBroadphaseProxy * getBroadphaseHandle()
Definition: btCollisionObject.h:389
getNormalizedVector
static btVector3 getNormalizedVector(const btVector3 &v)
Definition: btKinematicCharacterController.cpp:30
btPersistentManifold::getBody0
const btCollisionObject * getBody0() const
Definition: btPersistentManifold.h:102
btCollisionWorld::LocalConvexResult::m_hitNormalLocal
btVector3 m_hitNormalLocal
Definition: btCollisionWorld.h:334
btKinematicCharacterController::setLinearVelocity
virtual void setLinearVelocity(const btVector3 &velocity)
Definition: btKinematicCharacterController.cpp:649
shortestArcQuatNormalize2
btQuaternion shortestArcQuatNormalize2(btVector3 &v0, btVector3 &v1)
Definition: btQuaternion.h:950
btCollisionWorld::RayResultCallback::needsCollision
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
Definition: btCollisionWorld.h:231
btVector3::dot
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:235
btKinematicCharacterController::setGravity
void setGravity(const btVector3 &gravity)
Definition: btKinematicCharacterController.cpp:897
btKinematicCharacterController::jump
void jump(const btVector3 &v=btVector3())
Definition: btKinematicCharacterController.cpp:876
btKinematicCharacterController::setMaxSlope
void setMaxSlope(btScalar slopeRadians)
The max slope determines the maximum angle that the controller can walk up.
Definition: btKinematicCharacterController.cpp:909
btCollisionObject
btCollisionObject can be used to manage collision detection objects.
Definition: btCollisionObject.h:49
btTransform::setRotation
void setRotation(const btQuaternion &q)
Set the rotational element by btQuaternion.
Definition: btTransform.h:165
btBroadphaseProxy::m_clientObject
void * m_clientObject
Definition: btBroadphaseProxy.h:103
btKinematicCharacterController::recoverFromPenetration
bool recoverFromPenetration(btCollisionWorld *collisionWorld)
Definition: btKinematicCharacterController.cpp:178
btCollisionWorld::ClosestRayResultCallback
Definition: btCollisionWorld.h:242
btTransform::getBasis
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:112
btCollisionObject::hasContactResponse
bool hasContactResponse() const
Definition: btCollisionObject.h:212
btCollisionWorld::LocalConvexResult
Definition: btCollisionWorld.h:316
btIDebugDraw
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations...
Definition: btIDebugDraw.h:29
btKinematicCharacterController::setFallSpeed
void setFallSpeed(btScalar fallSpeed)
Definition: btKinematicCharacterController.cpp:855
btCollisionWorld::ClosestConvexResultCallback::m_hitNormalWorld
btVector3 m_hitNormalWorld
Definition: btCollisionWorld.h:386
btCollisionWorld::LocalRayResult::m_collisionObject
const btCollisionObject * m_collisionObject
Definition: btCollisionWorld.h:196
btBroadphaseProxy::m_collisionFilterGroup
int m_collisionFilterGroup
Definition: btBroadphaseProxy.h:104
btCollisionWorld::getDispatcher
btDispatcher * getDispatcher()
Definition: btCollisionWorld.h:138
btKinematicCharacterController::parallelComponent
btVector3 parallelComponent(const btVector3 &direction, const btVector3 &normal)
Definition: btKinematicCharacterController.cpp:121
btKinematicClosestNotMeRayResultCallback::m_me
btCollisionObject * m_me
Definition: btKinematicCharacterController.cpp:63
btCollisionWorld::ConvexResultCallback::m_collisionFilterMask
int m_collisionFilterMask
Definition: btCollisionWorld.h:344
btKinematicCharacterController::setStepHeight
void setStepHeight(btScalar h)
Definition: btKinematicCharacterController.cpp:935
btBroadphasePair::m_pProxy1
btBroadphaseProxy * m_pProxy1
Definition: btBroadphaseProxy.h:226
btBroadphasePair::m_algorithm
btCollisionAlgorithm * m_algorithm
Definition: btBroadphaseProxy.h:228
btKinematicCharacterController::warp
void warp(const btVector3 &origin)
Definition: btKinematicCharacterController.cpp:698
btKinematicClosestNotMeConvexResultCallback::addSingleResult
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace)
Definition: btKinematicCharacterController.cpp:77
btVector3
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
btHashedOverlappingPairCache::removeOverlappingPair
virtual void * removeOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1, btDispatcher *dispatcher)
Definition: btOverlappingPairCache.cpp:272
btPow
btScalar btPow(btScalar x, btScalar y)
Definition: btScalar.h:499
btCollisionAlgorithm::getAllContactManifolds
virtual void getAllContactManifolds(btManifoldArray &manifoldArray)=0
btAcos
btScalar btAcos(btScalar x)
Definition: btScalar.h:479
btMultiSphereShape.h
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:155
btBroadphasePair::m_pProxy0
btBroadphaseProxy * m_pProxy0
Definition: btBroadphaseProxy.h:225
btTransform
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
btKinematicClosestNotMeConvexResultCallback::m_minSlopeDot
btScalar m_minSlopeDot
Definition: btKinematicCharacterController.cpp:105
btKinematicCharacterController::updateTargetPositionBasedOnCollision
void updateTargetPositionBasedOnCollision(const btVector3 &hit_normal, btScalar tangentMag=btScalar(0.0), btScalar normalMag=btScalar(1.0))
Definition: btKinematicCharacterController.cpp:345
btDefaultMotionState.h
btCollisionWorld
CollisionWorld is interface and container for the collision detection.
Definition: btCollisionWorld.h:88
btCollisionWorld::convexSweepTest
void convexSweepTest(const btConvexShape *castShape, const btTransform &from, const btTransform &to, ConvexResultCallback &resultCallback, btScalar allowedCcdPenetration=btScalar(0.)) const
convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultC...
Definition: btCollisionWorld.cpp:1086
btCollisionWorld::getDispatchInfo
btDispatcherInfo & getDispatchInfo()
Definition: btCollisionWorld.h:503
btKinematicCharacterController::getGhostObject
btPairCachingGhostObject * getGhostObject()
Definition: btKinematicCharacterController.cpp:173
btKinematicCharacterController::stepUp
void stepUp(btCollisionWorld *collisionWorld)
Definition: btKinematicCharacterController.cpp:257
btIDebugDraw.h
btDispatcherInfo::m_allowedCcdPenetration
btScalar m_allowedCcdPenetration
Definition: btDispatcher.h:62
btKinematicCharacterController::setAngularVelocity
virtual void setAngularVelocity(const btVector3 &velocity)
Definition: btKinematicCharacterController.cpp:639
btKinematicCharacterController::canJump
bool canJump() const
Definition: btKinematicCharacterController.cpp:871
btKinematicCharacterController::setMaxPenetrationDepth
void setMaxPenetrationDepth(btScalar d)
Definition: btKinematicCharacterController.cpp:920
btKinematicCharacterController::perpindicularComponent
btVector3 perpindicularComponent(const btVector3 &direction, const btVector3 &normal)
Definition: btKinematicCharacterController.cpp:130
btKinematicCharacterController::reset
void reset(btCollisionWorld *collisionWorld)
Definition: btKinematicCharacterController.cpp:681
btCollisionWorld::ClosestConvexResultCallback::m_hitCollisionObject
const btCollisionObject * m_hitCollisionObject
Definition: btCollisionWorld.h:388
btKinematicCharacterController::getAngularVelocity
virtual const btVector3 & getAngularVelocity() const
Definition: btKinematicCharacterController.cpp:644
btCollisionWorld::ConvexResultCallback::m_closestHitFraction
btScalar m_closestHitFraction
Definition: btCollisionWorld.h:342
btKinematicClosestNotMeConvexResultCallback::btKinematicClosestNotMeConvexResultCallback
btKinematicClosestNotMeConvexResultCallback(btCollisionObject *me, const btVector3 &up, btScalar minSlopeDot)
Definition: btKinematicCharacterController.cpp:69
btBroadphaseInterface::setAabb
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)=0
btKinematicCharacterController::stepForwardAndStrafe
void stepForwardAndStrafe(btCollisionWorld *collisionWorld, const btVector3 &walkMove)
Definition: btKinematicCharacterController.cpp:381
btKinematicCharacterController::getMaxPenetrationDepth
btScalar getMaxPenetrationDepth() const
Definition: btKinematicCharacterController.cpp:925
btKinematicCharacterController::preStep
void preStep(btCollisionWorld *collisionWorld)
Definition: btKinematicCharacterController.cpp:707
btQuaternion
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
Definition: btQuaternion.h:55
btKinematicCharacterController::setWalkDirection
virtual void setWalkDirection(const btVector3 &walkDirection)
This should probably be called setPositionIncrementPerSimulatorStep.
Definition: btKinematicCharacterController.cpp:611
btKinematicCharacterController::setUpInterpolate
void setUpInterpolate(bool value)
Definition: btKinematicCharacterController.cpp:951
btKinematicCharacterController::needsCollision
virtual bool needsCollision(const btCollisionObject *body0, const btCollisionObject *body1)
Definition: btKinematicCharacterController.cpp:338
btKinematicCharacterController::btKinematicCharacterController
btKinematicCharacterController(btPairCachingGhostObject *ghostObject, btConvexShape *convexShape, btScalar stepHeight, const btVector3 &up=btVector3(1.0, 0.0, 0.0))
Definition: btKinematicCharacterController.cpp:135
btKinematicCharacterController::setUp
void setUp(const btVector3 &up)
Definition: btKinematicCharacterController.cpp:956
btKinematicCharacterController::setMaxJumpHeight
void setMaxJumpHeight(btScalar maxJumpHeight)
Definition: btKinematicCharacterController.cpp:866
btVector3::setInterpolate3
void setInterpolate3(const btVector3 &v0, const btVector3 &v1, btScalar rt)
Definition: btVector3.h:503
btCollisionWorld::getBroadphase
const btBroadphaseInterface * getBroadphase() const
Definition: btCollisionWorld.h:122
btKinematicCharacterController::getUpAxisDirections
static btVector3 * getUpAxisDirections()
Definition: btKinematicCharacterController.cpp:940
btHashedOverlappingPairCache
Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman...
Definition: btOverlappingPairCache.h:94
btManifoldPoint::getDistance
btScalar getDistance() const
Definition: btManifoldPoint.h:146
btCollisionWorld::LocalRayResult
Definition: btCollisionWorld.h:183
btCollisionWorld::ClosestRayResultCallback::ClosestRayResultCallback
ClosestRayResultCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld)
Definition: btCollisionWorld.h:244
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
btCos
btScalar btCos(btScalar x)
Definition: btScalar.h:476
btKinematicCharacterController.h
btVector3::length
btScalar length() const
Return the length of the vector.
Definition: btVector3.h:263
btPairCachingGhostObject
Definition: btGhostObject.h:99
btCollisionAlgorithm.h
btCollisionWorld::ClosestConvexResultCallback
Definition: btCollisionWorld.h:374
btFabs
btScalar btFabs(btScalar x)
Definition: btScalar.h:475
btBroadphasePair
The btBroadphasePair class contains a pair of aabb-overlapping objects.
Definition: btBroadphaseProxy.h:185