60 return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace);
73 , m_minSlopeDot(minSlopeDot)
86 if (normalInWorldSpace)
96 if (dotUp < m_minSlopeDot) {
100 return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
115 return direction - (
btScalar(2.0) * direction.
dot(normal)) * normal;
124 return normal * magnitude;
132 return direction - parallelComponent(direction, normal);
138 m_addedMargin = 0.02;
139 m_walkDirection.setValue(0,0,0);
140 m_useGhostObjectSweepTest =
true;
141 m_ghostObject = ghostObject;
142 m_stepHeight = stepHeight;
144 m_convexShape=convexShape;
145 m_useWalkDirection =
true;
146 m_velocityTimeInterval = 0.0;
147 m_verticalVelocity = 0.0;
148 m_verticalOffset = 0.0;
149 m_gravity = 9.8 * 3 ;
152 m_wasOnGround =
false;
153 m_wasJumping =
false;
154 m_interpolateUp =
true;
156 m_currentStepOffset = 0;
167 return m_ghostObject;
181 m_convexShape->getAabb(m_ghostObject->getWorldTransform(), minAabb,maxAabb);
187 bool penetration =
false;
191 m_currentPosition = m_ghostObject->getWorldTransform().getOrigin();
194 for (
int i = 0; i < m_ghostObject->getOverlappingPairCache()->getNumOverlappingPairs(); i++)
196 m_manifoldArray.resize(0);
198 btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
210 for (
int j=0;j<m_manifoldArray.size();j++)
238 btTransform newTrans = m_ghostObject->getWorldTransform();
240 m_ghostObject->setWorldTransform(newTrans);
249 m_targetPosition = m_currentPosition + getUpAxisDirections()[m_upAxis] * (m_stepHeight + (m_verticalOffset > 0.f?m_verticalOffset:0.f));
255 start.
setOrigin (m_currentPosition + getUpAxisDirections()[m_upAxis] * (m_convexShape->getMargin() + m_addedMargin));
262 if (m_useGhostObjectSweepTest)
278 if (m_interpolateUp ==
true)
279 m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.
m_closestHitFraction);
281 m_currentPosition = m_targetPosition;
283 m_verticalVelocity = 0.0;
284 m_verticalOffset = 0.0;
286 m_currentStepOffset = m_stepHeight;
287 m_currentPosition = m_targetPosition;
293 btVector3 movementDirection = m_targetPosition - m_currentPosition;
299 btVector3 reflectDir = computeReflectionDirection (movementDirection, hitNormal);
304 parallelDir = parallelComponent (reflectDir, hitNormal);
305 perpindicularDir = perpindicularComponent (reflectDir, hitNormal);
307 m_targetPosition = m_currentPosition;
312 m_targetPosition += parComponent;
315 if (normalMag != 0.0)
317 btVector3 perpComponent = perpindicularDir *
btScalar (normalMag*movementLength);
319 m_targetPosition += perpComponent;
333 m_targetPosition = m_currentPosition + walkMove;
339 btScalar distance2 = (m_currentPosition-m_targetPosition).length2();
342 if (m_touchingContact)
344 if (m_normalizedDirection.dot(m_touchingNormal) >
btScalar(0.0))
353 while (fraction >
btScalar(0.01) && maxIter-- > 0)
357 btVector3 sweepDirNegative(m_currentPosition - m_targetPosition);
364 btScalar margin = m_convexShape->getMargin();
365 m_convexShape->setMargin(margin + m_addedMargin);
368 if (m_useGhostObjectSweepTest)
376 m_convexShape->setMargin(margin);
390 btVector3 currentDir = m_targetPosition - m_currentPosition;
391 distance2 = currentDir.
length2();
396 if (currentDir.
dot(m_normalizedDirection) <=
btScalar(0.0))
408 m_currentPosition = m_targetPosition;
420 bool runonce =
false;
429 btVector3 orig_position = m_targetPosition;
431 btScalar downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
433 if(downVelocity > 0.0 && downVelocity > m_fallSpeed
434 && (m_wasOnGround || !m_wasJumping))
435 downVelocity = m_fallSpeed;
437 btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
438 m_targetPosition -= step_drop;
459 end_double.
setOrigin (m_targetPosition - step_drop);
461 if (m_useGhostObjectSweepTest)
481 btScalar downVelocity2 = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
482 bool has_hit =
false;
483 if (bounce_fix ==
true)
486 has_hit = callback2.
hasHit();
488 if(downVelocity2 > 0.0 && downVelocity2 < m_stepHeight && has_hit ==
true && runonce ==
false 489 && (m_wasOnGround || !m_wasJumping))
494 m_targetPosition = orig_position;
495 downVelocity = m_stepHeight;
497 btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
498 m_targetPosition -= step_drop;
505 if (callback.
hasHit() || runonce ==
true)
513 if (bounce_fix ==
true)
515 if (full_drop ==
true)
519 m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, fraction);
522 m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.
m_closestHitFraction);
526 m_verticalVelocity = 0.0;
527 m_verticalOffset = 0.0;
528 m_wasJumping =
false;
534 if (bounce_fix ==
true)
536 downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
537 if (downVelocity > m_fallSpeed && (m_wasOnGround || !m_wasJumping))
539 m_targetPosition += step_drop;
540 downVelocity = m_fallSpeed;
541 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
542 m_targetPosition -= step_drop;
547 m_currentPosition = m_targetPosition;
558 m_useWalkDirection =
true;
559 m_walkDirection = walkDirection;
576 m_useWalkDirection =
false;
577 m_walkDirection = velocity;
579 m_velocityTimeInterval += timeInterval;
584 m_verticalVelocity = 0.0;
585 m_verticalOffset = 0.0;
586 m_wasOnGround =
false;
587 m_wasJumping =
false;
588 m_walkDirection.setValue(0,0,0);
589 m_velocityTimeInterval = 0.0;
604 m_ghostObject->setWorldTransform (xform);
611 int numPenetrationLoops = 0;
612 m_touchingContact =
false;
613 while (recoverFromPenetration (collisionWorld))
615 numPenetrationLoops++;
616 m_touchingContact =
true;
617 if (numPenetrationLoops > 4)
624 m_currentPosition = m_ghostObject->getWorldTransform().getOrigin();
625 m_targetPosition = m_currentPosition;
639 if (!m_useWalkDirection && (m_velocityTimeInterval <= 0.0 || m_walkDirection.fuzzyZero())) {
644 m_wasOnGround = onGround();
647 m_verticalVelocity -= m_gravity * dt;
648 if(m_verticalVelocity > 0.0 && m_verticalVelocity > m_jumpSpeed)
650 m_verticalVelocity = m_jumpSpeed;
652 if(m_verticalVelocity < 0.0 &&
btFabs(m_verticalVelocity) >
btFabs(m_fallSpeed))
654 m_verticalVelocity = -
btFabs(m_fallSpeed);
656 m_verticalOffset = m_verticalVelocity * dt;
660 xform = m_ghostObject->getWorldTransform ();
665 stepUp (collisionWorld);
666 if (m_useWalkDirection) {
667 stepForwardAndStrafe (collisionWorld, m_walkDirection);
672 (dt < m_velocityTimeInterval) ? dt : m_velocityTimeInterval;
673 m_velocityTimeInterval -= dt;
676 btVector3 move = m_walkDirection * dtMoving;
681 stepForwardAndStrafe(collisionWorld, move);
683 stepDown (collisionWorld, dt);
688 m_ghostObject->setWorldTransform (xform);
693 m_fallSpeed = fallSpeed;
698 m_jumpSpeed = jumpSpeed;
703 m_maxJumpHeight = maxJumpHeight;
716 m_verticalVelocity = m_jumpSpeed;
720 currently no jumping.
722 m_rigidBody->getMotionState()->getWorldTransform (xform);
726 m_rigidBody->applyCentralImpulse (up * magnitude);
742 m_maxSlopeRadians = slopeRadians;
743 m_maxSlopeCosine =
btCos(slopeRadians);
748 return m_maxSlopeRadians;
753 return m_verticalVelocity == 0.0 && m_verticalOffset == 0.0;
761 return sUpAxisDirection;
770 m_interpolateUp = value;
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
void playerStep(btCollisionWorld *collisionWorld, btScalar dt)
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult &rayResult, bool normalInWorldSpace)
void stepDown(btCollisionWorld *collisionWorld, btScalar dt)
btKinematicClosestNotMeRayResultCallback(btCollisionObject *me)
~btKinematicCharacterController()
btScalar btRadians(btScalar x)
void setJumpSpeed(btScalar jumpSpeed)
short int m_collisionFilterGroup
virtual void dispatchAllCollisionPairs(btOverlappingPairCache *pairCache, const btDispatcherInfo &dispatchInfo, btDispatcher *dispatcher)=0
btVector3 computeReflectionDirection(const btVector3 &direction, const btVector3 &normal)
btKinematicCharacterController(btPairCachingGhostObject *ghostObject, btConvexShape *convexShape, btScalar stepHeight, int upAxis=1)
btBroadphasePairArray & getOverlappingPairArray()
ManifoldContactPoint collects and maintains persistent contactpoints.
const btCollisionObject * getBody0() const
btScalar getGravity() const
btVector3 m_hitPointWorld
virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval)
Caller provides a velocity with which the character should move for the given time period...
void debugDraw(btIDebugDraw *debugDrawer)
btActionInterface interface
btScalar dot(const btVector3 &v) const
Return the dot product.
bool hasContactResponse() const
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape...
const btCollisionObject * m_hitCollisionObject
btTransform & getWorldTransform()
btVector3 m_normalWorldOnB
int size() const
return the number of elements in the array
static btVector3 getNormalizedVector(const btVector3 &v)
btVector3 m_hitNormalLocal
void setMaxSlope(btScalar slopeRadians)
The max slope determines the maximum angle that the controller can walk up.
const btScalar & getY() const
Return the y value.
btCollisionObject can be used to manage collision detection objects.
bool recoverFromPenetration(btCollisionWorld *collisionWorld)
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations...
void setFallSpeed(btScalar fallSpeed)
btVector3 m_hitNormalWorld
btScalar length() const
Return the length of the vector.
const btCollisionObject * m_collisionObject
const btManifoldPoint & getContactPoint(int index) const
btDispatcher * getDispatcher()
btVector3 parallelComponent(const btVector3 &direction, const btVector3 &normal)
short int m_collisionFilterMask
btBroadphaseProxy * m_pProxy1
btCollisionAlgorithm * m_algorithm
void warp(const btVector3 &origin)
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace)
btVector3 can be used to represent 3D points and vectors.
virtual void * removeOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1, btDispatcher *dispatcher)
virtual void getAllContactManifolds(btManifoldArray &manifoldArray)=0
btScalar length2() const
Return the length of the vector squared.
btBroadphaseProxy * m_pProxy0
const btBroadphaseInterface * getBroadphase() const
void updateTargetPositionBasedOnCollision(const btVector3 &hit_normal, btScalar tangentMag=btScalar(0.0), btScalar normalMag=btScalar(1.0))
btScalar getMaxSlope() const
CollisionWorld is interface and container for the collision detection.
btDispatcherInfo & getDispatchInfo()
btPairCachingGhostObject * getGhostObject()
void stepUp(btCollisionWorld *collisionWorld)
btVector3 normalized() const
Return a normalized version of this vector.
btScalar m_allowedCcdPenetration
int getNumContacts() const
btVector3 perpindicularComponent(const btVector3 &direction, const btVector3 &normal)
void reset(btCollisionWorld *collisionWorld)
void setGravity(btScalar gravity)
btScalar m_closestHitFraction
btKinematicClosestNotMeConvexResultCallback(btCollisionObject *me, const btVector3 &up, btScalar minSlopeDot)
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)=0
void stepForwardAndStrafe(btCollisionWorld *collisionWorld, const btVector3 &walkMove)
void preStep(btCollisionWorld *collisionWorld)
virtual void setWalkDirection(const btVector3 &walkDirection)
This should probably be called setPositionIncrementPerSimulatorStep.
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...
void setUpInterpolate(bool value)
btScalar getDistance() const
void setMaxJumpHeight(btScalar maxJumpHeight)
void setInterpolate3(const btVector3 &v0, const btVector3 &v1, btScalar rt)
static btVector3 * getUpAxisDirections()
Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman...
ClosestRayResultCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
btScalar btCos(btScalar x)
btScalar btFabs(btScalar x)
The btBroadphasePair class contains a pair of aabb-overlapping objects.