Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Apr 21, 2011, 6:58:23 PM (14 years ago)
Author:
rgrieder
Message:

Merged revisions 7978 - 8096 from kicklib to kicklib2.

Location:
code/branches/kicklib2
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • code/branches/kicklib2

  • code/branches/kicklib2/src/external/bullet/BulletDynamics/Character/btCharacterControllerInterface.h

    r5781 r8284  
    3131       
    3232        virtual void    setWalkDirection(const btVector3& walkDirection) = 0;
     33        virtual void    setVelocityForTimeInterval(const btVector3& velocity, btScalar timeInterval) = 0;
    3334        virtual void    reset () = 0;
    3435        virtual void    warp (const btVector3& origin) = 0;
  • code/branches/kicklib2/src/external/bullet/BulletDynamics/Character/btKinematicCharacterController.cpp

    r5781 r8284  
    13133. This notice may not be removed or altered from any source distribution.
    1414*/
     15
    1516
    1617#include "LinearMath/btIDebugDraw.h"
     
    2324#include "btKinematicCharacterController.h"
    2425
    25 static btVector3 upAxisDirection[3] = { btVector3(1.0f, 0.0f, 0.0f), btVector3(0.0f, 1.0f, 0.0f), btVector3(0.0f, 0.0f, 1.0f) };
     26
     27// static helper method
     28static btVector3
     29getNormalizedVector(const btVector3& v)
     30{
     31        btVector3 n = v.normalized();
     32        if (n.length() < SIMD_EPSILON) {
     33                n.setValue(0, 0, 0);
     34        }
     35        return n;
     36}
     37
    2638
    2739///@todo Interact with dynamic objects,
     
    5365{
    5466public:
    55         btKinematicClosestNotMeConvexResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
    56         {
    57                 m_me = me;
     67        btKinematicClosestNotMeConvexResultCallback (btCollisionObject* me, const btVector3& up, btScalar minSlopeDot)
     68        : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
     69        , m_me(me)
     70        , m_up(up)
     71        , m_minSlopeDot(minSlopeDot)
     72        {
    5873        }
    5974
     
    6176        {
    6277                if (convexResult.m_hitCollisionObject == m_me)
    63                         return 1.0;
     78                        return btScalar(1.0);
     79
     80                btVector3 hitNormalWorld;
     81                if (normalInWorldSpace)
     82                {
     83                        hitNormalWorld = convexResult.m_hitNormalLocal;
     84                } else
     85                {
     86                        ///need to transform normal into worldspace
     87                        hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal;
     88                }
     89
     90                btScalar dotUp = m_up.dot(hitNormalWorld);
     91                if (dotUp < m_minSlopeDot) {
     92                        return btScalar(1.0);
     93                }
    6494
    6595                return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
     
    6797protected:
    6898        btCollisionObject* m_me;
     99        const btVector3 m_up;
     100        btScalar m_minSlopeDot;
    69101};
    70102
     
    99131{
    100132        m_upAxis = upAxis;
    101         m_addedMargin = 0.02f;
     133        m_addedMargin = 0.02;
    102134        m_walkDirection.setValue(0,0,0);
    103135        m_useGhostObjectSweepTest = true;
     
    106138        m_turnAngle = btScalar(0.0);
    107139        m_convexShape=convexShape;     
     140        m_useWalkDirection = true;      // use walk direction by default, legacy behavior
     141        m_velocityTimeInterval = 0.0;
     142        m_verticalVelocity = 0.0;
     143        m_verticalOffset = 0.0;
     144        m_gravity = 9.8 * 3 ; // 3G acceleration.
     145        m_fallSpeed = 55.0; // Terminal velocity of a sky diver in m/s.
     146        m_jumpSpeed = 10.0; // ?
     147        m_wasOnGround = false;
     148        m_wasJumping = false;
     149        setMaxSlope(btRadians(45.0));
    108150}
    109151
     
    145187                                const btManifoldPoint&pt = manifold->getContactPoint(p);
    146188
    147                                 if (pt.getDistance() < 0.0)
     189                                btScalar dist = pt.getDistance();
     190
     191                                if (dist < 0.0)
    148192                                {
    149                                         if (pt.getDistance() < maxPen)
     193                                        if (dist < maxPen)
    150194                                        {
    151                                                 maxPen = pt.getDistance();
     195                                                maxPen = dist;
    152196                                                m_touchingNormal = pt.m_normalWorldOnB * directionSign;//??
    153197
    154198                                        }
    155                                         m_currentPosition += pt.m_normalWorldOnB * directionSign * pt.getDistance() * btScalar(0.2);
     199                                        m_currentPosition += pt.m_normalWorldOnB * directionSign * dist * btScalar(0.2);
    156200                                        penetration = true;
    157201                                } else {
    158                                         //printf("touching %f\n", pt.getDistance());
     202                                        //printf("touching %f\n", dist);
    159203                                }
    160204                        }
     
    174218        // phase 1: up
    175219        btTransform start, end;
    176         m_targetPosition = m_currentPosition + upAxisDirection[m_upAxis] * m_stepHeight;
     220        m_targetPosition = m_currentPosition + getUpAxisDirections()[m_upAxis] * (m_stepHeight + (m_verticalOffset > 0.f?m_verticalOffset:0.f));
    177221
    178222        start.setIdentity ();
     
    180224
    181225        /* FIXME: Handle penetration properly */
    182         start.setOrigin (m_currentPosition + upAxisDirection[m_upAxis] * btScalar(0.1f));
     226        start.setOrigin (m_currentPosition + getUpAxisDirections()[m_upAxis] * (m_convexShape->getMargin() + m_addedMargin));
    183227        end.setOrigin (m_targetPosition);
    184228
    185         btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject);
     229        btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, -getUpAxisDirections()[m_upAxis], btScalar(0.7071));
    186230        callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
    187231        callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
     
    198242        if (callback.hasHit())
    199243        {
    200                 // we moved up only a fraction of the step height
    201                 m_currentStepOffset = m_stepHeight * callback.m_closestHitFraction;
    202                 m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
     244                // Only modify the position if the hit was a slope and not a wall or ceiling.
     245                if(callback.m_hitNormalWorld.dot(getUpAxisDirections()[m_upAxis]) > 0.0)
     246                {
     247                        // we moved up only a fraction of the step height
     248                        m_currentStepOffset = m_stepHeight * callback.m_closestHitFraction;
     249                        m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
     250                }
     251                m_verticalVelocity = 0.0;
     252                m_verticalOffset = 0.0;
    203253        } else {
    204254                m_currentStepOffset = m_stepHeight;
     
    245295void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* collisionWorld, const btVector3& walkMove)
    246296{
    247 
    248         btVector3 originalDir = walkMove.normalized();
    249         if (walkMove.length() < SIMD_EPSILON)
    250         {
    251                 originalDir.setValue(0.f,0.f,0.f);
    252         }
    253 //      printf("originalDir=%f,%f,%f\n",originalDir[0],originalDir[1],originalDir[2]);
     297        // printf("m_normalizedDirection=%f,%f,%f\n",
     298        //      m_normalizedDirection[0],m_normalizedDirection[1],m_normalizedDirection[2]);
    254299        // phase 2: forward and strafe
    255300        btTransform start, end;
    256301        m_targetPosition = m_currentPosition + walkMove;
     302
    257303        start.setIdentity ();
    258304        end.setIdentity ();
     
    264310        if (m_touchingContact)
    265311        {
    266                 if (originalDir.dot(m_touchingNormal) > btScalar(0.0))
     312                if (m_normalizedDirection.dot(m_touchingNormal) > btScalar(0.0))
     313                {
    267314                        updateTargetPositionBasedOnCollision (m_touchingNormal);
     315                }
    268316        }
    269317
     
    274322                start.setOrigin (m_currentPosition);
    275323                end.setOrigin (m_targetPosition);
    276 
    277                 btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject);
     324                btVector3 sweepDirNegative(m_currentPosition - m_targetPosition);
     325
     326                btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, sweepDirNegative, btScalar(0.0));
    278327                callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
    279328                callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
     
    300349                {       
    301350                        // we moved only a fraction
    302                         btScalar hitDistance = (callback.m_hitPointWorld - m_currentPosition).length();
    303                         if (hitDistance<0.f)
    304                         {
    305 //                              printf("neg dist?\n");
    306                         }
    307 
    308                         /* If the distance is farther than the collision margin, move */
    309                         if (hitDistance > m_addedMargin)
    310                         {
    311 //                              printf("callback.m_closestHitFraction=%f\n",callback.m_closestHitFraction);
    312                                 m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
    313                         }
     351                        btScalar hitDistance;
     352                        hitDistance = (callback.m_hitPointWorld - m_currentPosition).length();
     353
     354//                      m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
    314355
    315356                        updateTargetPositionBasedOnCollision (callback.m_hitNormalWorld);
     
    320361                                currentDir.normalize();
    321362                                /* See Quake2: "If velocity is against original velocity, stop ead to avoid tiny oscilations in sloping corners." */
    322                                 if (currentDir.dot(originalDir) <= btScalar(0.0))
     363                                if (currentDir.dot(m_normalizedDirection) <= btScalar(0.0))
    323364                                {
    324365                                        break;
     
    329370                                break;
    330371                        }
     372
    331373                } else {
    332374                        // we moved whole way
     
    345387
    346388        // phase 3: down
    347         btVector3 step_drop = upAxisDirection[m_upAxis] * m_currentStepOffset;
    348         btVector3 gravity_drop = upAxisDirection[m_upAxis] * m_stepHeight;
    349         m_targetPosition -= (step_drop + gravity_drop);
     389        /*btScalar additionalDownStep = (m_wasOnGround && !onGround()) ? m_stepHeight : 0.0;
     390        btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + additionalDownStep);
     391        btScalar downVelocity = (additionalDownStep == 0.0 && m_verticalVelocity<0.0?-m_verticalVelocity:0.0) * dt;
     392        btVector3 gravity_drop = getUpAxisDirections()[m_upAxis] * downVelocity;
     393        m_targetPosition -= (step_drop + gravity_drop);*/
     394
     395        btScalar downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
     396        if(downVelocity > 0.0 && downVelocity < m_stepHeight
     397                && (m_wasOnGround || !m_wasJumping))
     398        {
     399                downVelocity = m_stepHeight;
     400        }
     401
     402        btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
     403        m_targetPosition -= step_drop;
    350404
    351405        start.setIdentity ();
     
    355409        end.setOrigin (m_targetPosition);
    356410
    357         btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject);
     411        btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
    358412        callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
    359413        callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
     
    371425                // we dropped a fraction of the height -> hit floor
    372426                m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
     427                m_verticalVelocity = 0.0;
     428                m_verticalOffset = 0.0;
     429                m_wasJumping = false;
    373430        } else {
    374431                // we dropped the full height
     
    378435}
    379436
     437
     438
     439void btKinematicCharacterController::setWalkDirection
     440(
     441const btVector3& walkDirection
     442)
     443{
     444        m_useWalkDirection = true;
     445        m_walkDirection = walkDirection;
     446        m_normalizedDirection = getNormalizedVector(m_walkDirection);
     447}
     448
     449
     450
     451void btKinematicCharacterController::setVelocityForTimeInterval
     452(
     453const btVector3& velocity,
     454btScalar timeInterval
     455)
     456{
     457//      printf("setVelocity!\n");
     458//      printf("  interval: %f\n", timeInterval);
     459//      printf("  velocity: (%f, %f, %f)\n",
     460//               velocity.x(), velocity.y(), velocity.z());
     461
     462        m_useWalkDirection = false;
     463        m_walkDirection = velocity;
     464        m_normalizedDirection = getNormalizedVector(m_walkDirection);
     465        m_velocityTimeInterval = timeInterval;
     466}
     467
     468
     469
    380470void btKinematicCharacterController::reset ()
    381471{
     
    402492                if (numPenetrationLoops > 4)
    403493                {
    404 //                      printf("character could not recover from penetration = %d\n", numPenetrationLoops);
     494                        //printf("character could not recover from penetration = %d\n", numPenetrationLoops);
    405495                        break;
    406496                }
     
    414504}
    415505
     506#include <stdio.h>
     507
    416508void btKinematicCharacterController::playerStep (  btCollisionWorld* collisionWorld, btScalar dt)
    417509{
     510//      printf("playerStep(): ");
     511//      printf("  dt = %f", dt);
     512
     513        // quick check...
     514        if (!m_useWalkDirection && m_velocityTimeInterval <= 0.0) {
     515//              printf("\n");
     516                return;         // no motion
     517        }
     518
     519        m_wasOnGround = onGround();
     520
     521        // Update fall velocity.
     522        m_verticalVelocity -= m_gravity * dt;
     523        if(m_verticalVelocity > 0.0 && m_verticalVelocity > m_jumpSpeed)
     524        {
     525                m_verticalVelocity = m_jumpSpeed;
     526        }
     527        if(m_verticalVelocity < 0.0 && btFabs(m_verticalVelocity) > btFabs(m_fallSpeed))
     528        {
     529                m_verticalVelocity = -btFabs(m_fallSpeed);
     530        }
     531        m_verticalOffset = m_verticalVelocity * dt;
     532
     533
    418534        btTransform xform;
    419535        xform = m_ghostObject->getWorldTransform ();
     
    423539
    424540        stepUp (collisionWorld);
    425         stepForwardAndStrafe (collisionWorld, m_walkDirection);
     541        if (m_useWalkDirection) {
     542                stepForwardAndStrafe (collisionWorld, m_walkDirection);
     543        } else {
     544                //printf("  time: %f", m_velocityTimeInterval);
     545                // still have some time left for moving!
     546                btScalar dtMoving =
     547                        (dt < m_velocityTimeInterval) ? dt : m_velocityTimeInterval;
     548                m_velocityTimeInterval -= dt;
     549
     550                // how far will we move while we are moving?
     551                btVector3 move = m_walkDirection * dtMoving;
     552
     553                //printf("  dtMoving: %f", dtMoving);
     554
     555                // okay, step
     556                stepForwardAndStrafe(collisionWorld, move);
     557        }
    426558        stepDown (collisionWorld, dt);
     559
     560        // printf("\n");
    427561
    428562        xform.setOrigin (m_currentPosition);
     
    454588        if (!canJump())
    455589                return;
     590
     591        m_verticalVelocity = m_jumpSpeed;
     592        m_wasJumping = true;
    456593
    457594#if 0
     
    466603}
    467604
     605void btKinematicCharacterController::setGravity(btScalar gravity)
     606{
     607        m_gravity = gravity;
     608}
     609
     610btScalar btKinematicCharacterController::getGravity() const
     611{
     612        return m_gravity;
     613}
     614
     615void btKinematicCharacterController::setMaxSlope(btScalar slopeRadians)
     616{
     617        m_maxSlopeRadians = slopeRadians;
     618        m_maxSlopeCosine = btCos(slopeRadians);
     619}
     620
     621btScalar btKinematicCharacterController::getMaxSlope() const
     622{
     623        return m_maxSlopeRadians;
     624}
     625
    468626bool btKinematicCharacterController::onGround () const
    469627{
    470         return true;
    471 }
    472 
    473 
    474 void    btKinematicCharacterController::debugDraw(btIDebugDraw* debugDrawer)
    475 {
    476 }
     628        return m_verticalVelocity == 0.0 && m_verticalOffset == 0.0;
     629}
     630
     631
     632btVector3* btKinematicCharacterController::getUpAxisDirections()
     633{
     634        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) };
     635       
     636        return sUpAxisDirection;
     637}
     638
     639void btKinematicCharacterController::debugDraw(btIDebugDraw* debugDrawer)
     640{
     641}
  • code/branches/kicklib2/src/external/bullet/BulletDynamics/Character/btKinematicCharacterController.h

    r5781 r8284  
    1414*/
    1515
     16
    1617#ifndef KINEMATIC_CHARACTER_CONTROLLER_H
    1718#define KINEMATIC_CHARACTER_CONTROLLER_H
     
    2021
    2122#include "btCharacterControllerInterface.h"
     23
     24#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
     25
    2226
    2327class btCollisionShape;
     
    3337{
    3438protected:
     39
    3540        btScalar m_halfHeight;
    3641       
     
    3843        btConvexShape*  m_convexShape;//is also in m_ghostObject, but it needs to be convex, so we store it here to avoid upcast
    3944       
     45        btScalar m_verticalVelocity;
     46        btScalar m_verticalOffset;
    4047        btScalar m_fallSpeed;
    4148        btScalar m_jumpSpeed;
    4249        btScalar m_maxJumpHeight;
     50        btScalar m_maxSlopeRadians; // Slope angle that is set (used for returning the exact value)
     51        btScalar m_maxSlopeCosine;  // Cosine equivalent of m_maxSlopeRadians (calculated once when set, for optimization)
     52        btScalar m_gravity;
    4353
    4454        btScalar m_turnAngle;
     
    5060        ///this is the desired walk direction, set by the user
    5161        btVector3       m_walkDirection;
     62        btVector3       m_normalizedDirection;
    5263
    5364        //some internal variables
     
    6273        btVector3 m_touchingNormal;
    6374
     75        bool  m_wasOnGround;
     76        bool  m_wasJumping;
    6477        bool    m_useGhostObjectSweepTest;
     78        bool    m_useWalkDirection;
     79        btScalar        m_velocityTimeInterval;
     80        int m_upAxis;
    6581
    66         int m_upAxis;
    67        
     82        static btVector3* getUpAxisDirections();
     83
    6884        btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal);
    6985        btVector3 parallelComponent (const btVector3& direction, const btVector3& normal);
     
    99115        }
    100116
    101         virtual void    setWalkDirection(const btVector3& walkDirection)
    102         {
    103                 m_walkDirection = walkDirection;
    104         }
     117        /// This should probably be called setPositionIncrementPerSimulatorStep.
     118        /// This is neither a direction nor a velocity, but the amount to
     119        ///     increment the position each simulation iteration, regardless
     120        ///     of dt.
     121        /// This call will reset any velocity set by setVelocityForTimeInterval().
     122        virtual void    setWalkDirection(const btVector3& walkDirection);
     123
     124        /// Caller provides a velocity with which the character should move for
     125        ///     the given time period.  After the time period, velocity is reset
     126        ///     to zero.
     127        /// This call will reset any walk direction set by setWalkDirection().
     128        /// Negative time intervals will result in no motion.
     129        virtual void setVelocityForTimeInterval(const btVector3& velocity,
     130                                btScalar timeInterval);
    105131
    106132        void reset ();
     
    114140        void setMaxJumpHeight (btScalar maxJumpHeight);
    115141        bool canJump () const;
     142
    116143        void jump ();
     144
     145        void setGravity(btScalar gravity);
     146        btScalar getGravity() const;
     147
     148        /// The max slope determines the maximum angle that the controller can walk up.
     149        /// The slope angle is measured in radians.
     150        void setMaxSlope(btScalar slopeRadians);
     151        btScalar getMaxSlope() const;
    117152
    118153        btPairCachingGhostObject* getGhostObject();
Note: See TracChangeset for help on using the changeset viewer.