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

Bullet Collision Detection & Physics Library

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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