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 #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
27 static btVector3
28 getNormalizedVector(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 {
47 public:
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
61 protected:
62 btCollisionObject* m_me;
63 };
64
65 class btKinematicClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
66 {
67 public:
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
101 protected:
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
134 btKinematicCharacterController::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
168 btKinematicCharacterController::~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 }
btTransform::setOrigin
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:146
btKinematicCharacterController::m_fallSpeed
btScalar m_fallSpeed
Definition: btKinematicCharacterController.h:47
btKinematicCharacterController::m_touchingContact
bool m_touchingContact
Definition: btKinematicCharacterController.h:79
btGhostObject.h
SIMD_EPSILON
#define SIMD_EPSILON
Definition: btScalar.h:523
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:927
btKinematicCharacterController::playerStep
void playerStep(btCollisionWorld *collisionWorld, btScalar dt)
Definition: btKinematicCharacterController.cpp:710
btKinematicCharacterController::m_ghostObject
btPairCachingGhostObject * m_ghostObject
Definition: btKinematicCharacterController.h:41
btKinematicCharacterController::setUpVector
void setUpVector(const btVector3 &up)
Definition: btKinematicCharacterController.cpp:964
btCollisionWorld.h
btKinematicClosestNotMeRayResultCallback::addSingleResult
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult &rayResult, bool normalInWorldSpace)
Definition: btKinematicCharacterController.cpp:53
btKinematicCharacterController::stepDown
void stepDown(btCollisionWorld *collisionWorld, btScalar dt)
Definition: btKinematicCharacterController.cpp:466
btKinematicClosestNotMeRayResultCallback::btKinematicClosestNotMeRayResultCallback
btKinematicClosestNotMeRayResultCallback(btCollisionObject *me)
Definition: btKinematicCharacterController.cpp:48
btKinematicCharacterController::~btKinematicCharacterController
~btKinematicCharacterController()
Definition: btKinematicCharacterController.cpp:168
btKinematicClosestNotMeRayResultCallback
Definition: btKinematicCharacterController.cpp:45
btRadians
btScalar btRadians(btScalar x)
Definition: btScalar.h:568
btVector3::setValue
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:640
btKinematicClosestNotMeConvexResultCallback::m_me
btCollisionObject * m_me
Definition: btKinematicCharacterController.cpp:102
btKinematicCharacterController::m_jumpAxis
btVector3 m_jumpAxis
Definition: btKinematicCharacterController.h:91
btHashedOverlappingPairCache::getNumOverlappingPairs
int getNumOverlappingPairs() const
Definition: btOverlappingPairCache.h:171
btKinematicCharacterController::m_velocityTimeInterval
btScalar m_velocityTimeInterval
Definition: btKinematicCharacterController.h:89
btKinematicCharacterController::getLinearVelocity
virtual btVector3 getLinearVelocity() const
Definition: btKinematicCharacterController.cpp:670
btKinematicCharacterController::setJumpSpeed
void setJumpSpeed(btScalar jumpSpeed)
Definition: btKinematicCharacterController.cpp:857
btSin
btScalar btSin(btScalar x)
Definition: btScalar.h:479
btKinematicCharacterController::getRotation
btQuaternion getRotation(btVector3 &v0, btVector3 &v1) const
Definition: btKinematicCharacterController.cpp:987
btKinematicCharacterController::bounce_fix
bool bounce_fix
Definition: btKinematicCharacterController.h:96
btVector3::length2
btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:251
btDispatcher::dispatchAllCollisionPairs
virtual void dispatchAllCollisionPairs(btOverlappingPairCache *pairCache, const btDispatcherInfo &dispatchInfo, btDispatcher *dispatcher)=0
btKinematicClosestNotMeConvexResultCallback::m_up
const btVector3 m_up
Definition: btKinematicCharacterController.cpp:103
btKinematicCharacterController::m_linearDamping
btScalar m_linearDamping
Definition: btKinematicCharacterController.h:82
btKinematicCharacterController::computeReflectionDirection
btVector3 computeReflectionDirection(const btVector3 &direction, const btVector3 &normal)
Definition: btKinematicCharacterController.cpp:112
btPersistentManifold::getNumContacts
int getNumContacts() const
Definition: btPersistentManifold.h:120
btTransform::setIdentity
void setIdentity()
Set this transformation to the identity.
Definition: btTransform.h:166
btTransform::getRotation
btQuaternion getRotation() const
Return a quaternion representing the rotation.
Definition: btTransform.h:118
btHashedOverlappingPairCache::getOverlappingPairArray
btBroadphasePairArray & getOverlappingPairArray()
Definition: btOverlappingPairCache.h:144
btKinematicCharacterController::m_maxSlopeRadians
btScalar m_maxSlopeRadians
Definition: btKinematicCharacterController.h:51
btKinematicCharacterController::m_wasOnGround
bool m_wasOnGround
Definition: btKinematicCharacterController.h:85
btCollisionWorld::ConvexResultCallback::hasHit
bool hasHit() const
Definition: btCollisionWorld.h:347
btVector3::getY
const btScalar & getY() const
Return the y value.
Definition: btVector3.h:563
btKinematicCharacterController::getGravity
btVector3 getGravity() const
Definition: btKinematicCharacterController.cpp:901
btKinematicCharacterController::getMaxSlope
btScalar getMaxSlope() const
Definition: btKinematicCharacterController.cpp:912
btManifoldPoint
ManifoldContactPoint collects and maintains persistent contactpoints.
Definition: btManifoldPoint.h:51
btKinematicClosestNotMeConvexResultCallback
Definition: btKinematicCharacterController.cpp:65
btKinematicCharacterController::m_wasJumping
bool m_wasJumping
Definition: btKinematicCharacterController.h:86
btKinematicCharacterController::m_normalizedDirection
btVector3 m_normalizedDirection
Definition: btKinematicCharacterController.h:63
btKinematicCharacterController::m_maxSlopeCosine
btScalar m_maxSlopeCosine
Definition: btKinematicCharacterController.h:52
btCollisionWorld::ClosestConvexResultCallback::m_hitPointWorld
btVector3 m_hitPointWorld
Definition: btCollisionWorld.h:375
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
SIMD_HALF_PI
#define SIMD_HALF_PI
Definition: btScalar.h:508
btKinematicCharacterController::debugDraw
void debugDraw(btIDebugDraw *debugDrawer)
btActionInterface interface
Definition: btKinematicCharacterController.cpp:944
btVector3::normalize
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:303
btVector3::fuzzyZero
bool fuzzyZero() const
Definition: btVector3.h:688
btVector3::normalized
btVector3 normalized() const
Return a normalized version of this vector.
Definition: btVector3.h:949
btKinematicCharacterController::m_maxJumpHeight
btScalar m_maxJumpHeight
Definition: btKinematicCharacterController.h:50
btConvexShape
The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape...
Definition: btConvexShape.h:31
btKinematicCharacterController::m_stepHeight
btScalar m_stepHeight
Definition: btKinematicCharacterController.h:57
btKinematicCharacterController::m_verticalVelocity
btScalar m_verticalVelocity
Definition: btKinematicCharacterController.h:45
btOverlappingPairCache.h
btPersistentManifold::getContactPoint
const btManifoldPoint & getContactPoint(int index) const
Definition: btPersistentManifold.h:130
btCollisionWorld::ConvexResultCallback::m_collisionFilterGroup
int m_collisionFilterGroup
Definition: btCollisionWorld.h:333
btPairCachingGhostObject::getOverlappingPairCache
btHashedOverlappingPairCache * getOverlappingPairCache()
Definition: btGhostObject.h:110
btCollisionWorld::LocalConvexResult::m_hitCollisionObject
const btCollisionObject * m_hitCollisionObject
Definition: btCollisionWorld.h:322
btKinematicCharacterController::m_maxPenetrationDepth
btScalar m_maxPenetrationDepth
Definition: btKinematicCharacterController.h:44
btQuaternion::inverse
btQuaternion inverse() const
Return the inverse of this quaternion.
Definition: btQuaternion.h:497
btBroadphaseProxy::m_collisionFilterMask
int m_collisionFilterMask
Definition: btBroadphaseProxy.h:104
btCollisionObject::getWorldTransform
btTransform & getWorldTransform()
Definition: btCollisionObject.h:365
btManifoldPoint::m_normalWorldOnB
btVector3 m_normalWorldOnB
Definition: btManifoldPoint.h:98
btKinematicCharacterController::m_jumpSpeed
btScalar m_jumpSpeed
Definition: btKinematicCharacterController.h:48
btKinematicCharacterController::m_currentStepOffset
btScalar m_currentStepOffset
Definition: btKinematicCharacterController.h:70
btTransform::getOrigin
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:113
btConvexShape::getAabb
void getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const =0
getAabb&#39;s default implementation is brute force, expected derived classes to implement a fast dedicat...
btCollisionObject::getBroadphaseHandle
btBroadphaseProxy * getBroadphaseHandle()
Definition: btCollisionObject.h:381
getNormalizedVector
static btVector3 getNormalizedVector(const btVector3 &v)
Definition: btKinematicCharacterController.cpp:28
btKinematicCharacterController::m_interpolateUp
bool m_interpolateUp
Definition: btKinematicCharacterController.h:94
btKinematicCharacterController::full_drop
bool full_drop
Definition: btKinematicCharacterController.h:95
btKinematicCharacterController::m_useGhostObjectSweepTest
bool m_useGhostObjectSweepTest
Definition: btKinematicCharacterController.h:87
btKinematicCharacterController::m_angularDamping
btScalar m_angularDamping
Definition: btKinematicCharacterController.h:83
btPersistentManifold::getBody0
const btCollisionObject * getBody0() const
Definition: btPersistentManifold.h:105
btCollisionWorld::LocalConvexResult::m_hitNormalLocal
btVector3 m_hitNormalLocal
Definition: btCollisionWorld.h:324
btKinematicCharacterController::setLinearVelocity
virtual void setLinearVelocity(const btVector3 &velocity)
Definition: btKinematicCharacterController.cpp:643
shortestArcQuatNormalize2
btQuaternion shortestArcQuatNormalize2(btVector3 &v0, btVector3 &v1)
Definition: btQuaternion.h:959
btVector3::dot
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:229
btKinematicCharacterController::setGravity
void setGravity(const btVector3 &gravity)
Definition: btKinematicCharacterController.cpp:894
btKinematicCharacterController::m_up
btVector3 m_up
Definition: btKinematicCharacterController.h:90
btCollisionWorld::ClosestConvexResultCallback::ClosestConvexResultCallback
ClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld)
Definition: btCollisionWorld.h:364
btKinematicCharacterController::setMaxSlope
void setMaxSlope(btScalar slopeRadians)
The max slope determines the maximum angle that the controller can walk up.
Definition: btKinematicCharacterController.cpp:906
btKinematicCharacterController::m_useWalkDirection
bool m_useWalkDirection
Definition: btKinematicCharacterController.h:88
btCollisionObject
btCollisionObject can be used to manage collision detection objects.
Definition: btCollisionObject.h:48
btTransform::setRotation
void setRotation(const btQuaternion &q)
Set the rotational element by btQuaternion.
Definition: btTransform.h:160
btBroadphaseProxy::m_clientObject
void * m_clientObject
Definition: btBroadphaseProxy.h:102
btKinematicCharacterController::recoverFromPenetration
bool recoverFromPenetration(btCollisionWorld *collisionWorld)
Definition: btKinematicCharacterController.cpp:177
btCollisionWorld::ClosestRayResultCallback
Definition: btCollisionWorld.h:232
btTransform::getBasis
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:108
btCollisionObject::hasContactResponse
bool hasContactResponse() const
Definition: btCollisionObject.h:208
btCollisionWorld::LocalConvexResult
Definition: btCollisionWorld.h:307
btIDebugDraw
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations...
Definition: btIDebugDraw.h:26
btKinematicCharacterController::setFallSpeed
void setFallSpeed(btScalar fallSpeed)
Definition: btKinematicCharacterController.cpp:852
btCollisionWorld::ClosestConvexResultCallback::m_hitNormalWorld
btVector3 m_hitNormalWorld
Definition: btCollisionWorld.h:374
btCollisionWorld::LocalRayResult::m_collisionObject
const btCollisionObject * m_collisionObject
Definition: btCollisionWorld.h:188
btBroadphaseProxy::m_collisionFilterGroup
int m_collisionFilterGroup
Definition: btBroadphaseProxy.h:103
btKinematicCharacterController::m_currentPosition
btVector3 m_currentPosition
Definition: btKinematicCharacterController.h:69
btCollisionObject::setWorldTransform
void setWorldTransform(const btTransform &worldTrans)
Definition: btCollisionObject.h:375
btCollisionWorld::getDispatcher
btDispatcher * getDispatcher()
Definition: btCollisionWorld.h:132
btConvexShape::getMargin
virtual btScalar getMargin() const =0
btKinematicCharacterController::parallelComponent
btVector3 parallelComponent(const btVector3 &direction, const btVector3 &normal)
Definition: btKinematicCharacterController.cpp:120
btKinematicClosestNotMeRayResultCallback::m_me
btCollisionObject * m_me
Definition: btKinematicCharacterController.cpp:62
btCollisionWorld::ConvexResultCallback::m_collisionFilterMask
int m_collisionFilterMask
Definition: btCollisionWorld.h:334
btKinematicCharacterController::m_convexShape
btConvexShape * m_convexShape
Definition: btKinematicCharacterController.h:42
btKinematicCharacterController::setStepHeight
void setStepHeight(btScalar h)
Definition: btKinematicCharacterController.cpp:932
btBroadphasePair::m_pProxy1
btBroadphaseProxy * m_pProxy1
Definition: btBroadphaseProxy.h:216
btBroadphasePair::m_algorithm
btCollisionAlgorithm * m_algorithm
Definition: btBroadphaseProxy.h:218
btKinematicCharacterController::warp
void warp(const btVector3 &origin)
Definition: btKinematicCharacterController.cpp:692
btKinematicClosestNotMeConvexResultCallback::addSingleResult
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace)
Definition: btKinematicCharacterController.cpp:73
btVector3
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:80
btKinematicCharacterController::m_manifoldArray
btManifoldArray m_manifoldArray
keep track of the contact manifolds
Definition: btKinematicCharacterController.h:77
btHashedOverlappingPairCache::removeOverlappingPair
virtual void * removeOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1, btDispatcher *dispatcher)
Definition: btOverlappingPairCache.cpp:229
btPow
btScalar btPow(btScalar x, btScalar y)
Definition: btScalar.h:501
btCollisionAlgorithm::getAllContactManifolds
virtual void getAllContactManifolds(btManifoldArray &manifoldArray)=0
btAcos
btScalar btAcos(btScalar x)
Definition: btScalar.h:481
btMultiSphereShape.h
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:149
btKinematicCharacterController::m_AngVel
btVector3 m_AngVel
Definition: btKinematicCharacterController.h:64
btKinematicCharacterController::m_walkDirection
btVector3 m_walkDirection
this is the desired walk direction, set by the user
Definition: btKinematicCharacterController.h:62
btBroadphasePair::m_pProxy0
btBroadphaseProxy * m_pProxy0
Definition: btBroadphaseProxy.h:215
btTransform
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:28
btKinematicClosestNotMeConvexResultCallback::m_minSlopeDot
btScalar m_minSlopeDot
Definition: btKinematicCharacterController.cpp:104
btKinematicCharacterController::updateTargetPositionBasedOnCollision
void updateTargetPositionBasedOnCollision(const btVector3 &hit_normal, btScalar tangentMag=btScalar(0.0), btScalar normalMag=btScalar(1.0))
Definition: btKinematicCharacterController.cpp:347
btKinematicCharacterController::m_targetPosition
btVector3 m_targetPosition
Definition: btKinematicCharacterController.h:71
btKinematicCharacterController::m_verticalOffset
btScalar m_verticalOffset
Definition: btKinematicCharacterController.h:46
btDefaultMotionState.h
btCollisionWorld
CollisionWorld is interface and container for the collision detection.
Definition: btCollisionWorld.h:85
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:1061
btCollisionWorld::getDispatchInfo
btDispatcherInfo & getDispatchInfo()
Definition: btCollisionWorld.h:490
btKinematicCharacterController::getGhostObject
btPairCachingGhostObject * getGhostObject()
Definition: btKinematicCharacterController.cpp:172
btKinematicCharacterController::stepUp
void stepUp(btCollisionWorld *collisionWorld)
Definition: btKinematicCharacterController.cpp:257
btIDebugDraw.h
btDispatcherInfo::m_allowedCcdPenetration
btScalar m_allowedCcdPenetration
Definition: btDispatcher.h:62
btAlignedObjectArray::resize
void resize(int newsize, const T &fillData=T())
Definition: btAlignedObjectArray.h:210
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
btKinematicCharacterController::setAngularVelocity
virtual void setAngularVelocity(const btVector3 &velocity)
Definition: btKinematicCharacterController.cpp:633
btKinematicCharacterController::canJump
bool canJump() const
Definition: btKinematicCharacterController.cpp:868
btKinematicCharacterController::setMaxPenetrationDepth
void setMaxPenetrationDepth(btScalar d)
Definition: btKinematicCharacterController.cpp:917
btKinematicCharacterController::perpindicularComponent
btVector3 perpindicularComponent(const btVector3 &direction, const btVector3 &normal)
Definition: btKinematicCharacterController.cpp:129
btKinematicCharacterController::reset
void reset(btCollisionWorld *collisionWorld)
Definition: btKinematicCharacterController.cpp:675
btCollisionWorld::ClosestConvexResultCallback::m_hitCollisionObject
const btCollisionObject * m_hitCollisionObject
Definition: btCollisionWorld.h:376
btKinematicCharacterController::getAngularVelocity
virtual const btVector3 & getAngularVelocity() const
Definition: btKinematicCharacterController.cpp:638
btKinematicCharacterController::m_SetjumpSpeed
btScalar m_SetjumpSpeed
Definition: btKinematicCharacterController.h:49
btKinematicCharacterController::m_targetOrientation
btQuaternion m_targetOrientation
Definition: btKinematicCharacterController.h:74
btCollisionWorld::ConvexResultCallback::m_closestHitFraction
btScalar m_closestHitFraction
Definition: btCollisionWorld.h:332
btKinematicClosestNotMeConvexResultCallback::btKinematicClosestNotMeConvexResultCallback
btKinematicClosestNotMeConvexResultCallback(btCollisionObject *me, const btVector3 &up, btScalar minSlopeDot)
Definition: btKinematicCharacterController.cpp:68
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:384
btKinematicCharacterController::getMaxPenetrationDepth
btScalar getMaxPenetrationDepth() const
Definition: btKinematicCharacterController.cpp:922
btKinematicCharacterController::m_currentOrientation
btQuaternion m_currentOrientation
Definition: btKinematicCharacterController.h:73
btKinematicCharacterController::preStep
void preStep(btCollisionWorld *collisionWorld)
Definition: btKinematicCharacterController.cpp:700
btQuaternion
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
Definition: btQuaternion.h:49
btKinematicCharacterController::m_jumpPosition
btVector3 m_jumpPosition
Definition: btKinematicCharacterController.h:66
btKinematicCharacterController::m_addedMargin
btScalar m_addedMargin
Definition: btKinematicCharacterController.h:59
btKinematicCharacterController::setWalkDirection
virtual void setWalkDirection(const btVector3 &walkDirection)
This should probably be called setPositionIncrementPerSimulatorStep.
Definition: btKinematicCharacterController.cpp:610
btConvexShape::setMargin
virtual void setMargin(btScalar margin)=0
btKinematicCharacterController::setUpInterpolate
void setUpInterpolate(bool value)
Definition: btKinematicCharacterController.cpp:948
btKinematicCharacterController::jump
void jump(const btVector3 &v=btVector3(0, 0, 0))
Definition: btKinematicCharacterController.cpp:873
btKinematicCharacterController::needsCollision
virtual bool needsCollision(const btCollisionObject *body0, const btCollisionObject *body1)
Definition: btKinematicCharacterController.cpp:340
btKinematicCharacterController::m_gravity
btScalar m_gravity
Definition: btKinematicCharacterController.h:53
btKinematicCharacterController::btKinematicCharacterController
btKinematicCharacterController(btPairCachingGhostObject *ghostObject, btConvexShape *convexShape, btScalar stepHeight, const btVector3 &up=btVector3(1.0, 0.0, 0.0))
Definition: btKinematicCharacterController.cpp:134
btKinematicCharacterController::setUp
void setUp(const btVector3 &up)
Definition: btKinematicCharacterController.cpp:953
btKinematicCharacterController::setMaxJumpHeight
void setMaxJumpHeight(btScalar maxJumpHeight)
Definition: btKinematicCharacterController.cpp:863
btVector3::setInterpolate3
void setInterpolate3(const btVector3 &v0, const btVector3 &v1, btScalar rt)
Definition: btVector3.h:492
btCollisionWorld::getBroadphase
const btBroadphaseInterface * getBroadphase() const
Definition: btCollisionWorld.h:117
btKinematicCharacterController::getUpAxisDirections
static btVector3 * getUpAxisDirections()
Definition: btKinematicCharacterController.cpp:937
btHashedOverlappingPairCache
Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman...
Definition: btOverlappingPairCache.h:86
btManifoldPoint::getDistance
btScalar getDistance() const
Definition: btManifoldPoint.h:139
btCollisionWorld::LocalRayResult
Definition: btCollisionWorld.h:175
btCollisionWorld::ClosestRayResultCallback::ClosestRayResultCallback
ClosestRayResultCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld)
Definition: btCollisionWorld.h:234
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:294
btCos
btScalar btCos(btScalar x)
Definition: btScalar.h:478
btKinematicCharacterController::m_turnAngle
btScalar m_turnAngle
Definition: btKinematicCharacterController.h:55
btKinematicCharacterController.h
btVector3::length
btScalar length() const
Return the length of the vector.
Definition: btVector3.h:257
btPairCachingGhostObject
Definition: btGhostObject.h:96
btCollisionAlgorithm.h
btCollisionWorld::ClosestConvexResultCallback
Definition: btCollisionWorld.h:362
btFabs
btScalar btFabs(btScalar x)
Definition: btScalar.h:477
btBroadphasePair
The btBroadphasePair class contains a pair of aabb-overlapping objects.
Definition: btBroadphaseProxy.h:177