190 lines
5.5 KiB
C++
190 lines
5.5 KiB
C++
#ifndef CC_PHYSICS_H
|
|
#define CC_PHYSICS_H
|
|
|
|
|
|
#include "BulletCollision/CollisionDispatch/btGhostObject.h"
|
|
#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
|
|
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
|
|
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
|
|
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
|
#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
|
|
#include "LinearMath/btDefaultMotionState.h"
|
|
#include "BulletDynamics/Character/btCharacterControllerInterface.h"
|
|
|
|
|
|
//
|
|
class btCustomCharacterController : public btCharacterControllerInterface
|
|
{
|
|
btScalar mHalfHeight;
|
|
|
|
btPairCachingGhostObject *mGhostObject;
|
|
btConvexShape *mConvexShape;
|
|
btConvexShape *mStandingConvexShape;
|
|
btConvexShape *mDuckingConvexShape;
|
|
|
|
btCollisionWorld *mCollisionWorld;
|
|
|
|
btVector3 mStepVelocity;
|
|
|
|
btScalar mVerticalVelocity;
|
|
btScalar mVerticalOffset;
|
|
btScalar mFallSpeed;
|
|
btScalar mJumpSpeed;
|
|
btScalar mMaxJumpHeight;
|
|
btScalar mMaxSlopeRadians;
|
|
btScalar mMaxSlopeCosine;
|
|
btScalar mGravity;
|
|
|
|
btScalar mTurnAngle;
|
|
|
|
btScalar mStepHeight;
|
|
|
|
btScalar mAddedMargin;
|
|
|
|
btVector3 mWalkDirection;
|
|
btVector3 mNormalizedDirection;
|
|
|
|
btVector3 mCurrentPosition;
|
|
|
|
btManifoldArray mManifoldArray;
|
|
|
|
bool mGroundContact;
|
|
btVector3 mGroundNormal;
|
|
|
|
bool mTouchingContact;
|
|
|
|
bool dbg_step_high;
|
|
bool dbg_down_sweep_hit;
|
|
void performStep(btScalar dt);
|
|
bool SweepAndSlide(btVector3 &from, btVector3 &to, int);
|
|
|
|
bool mUseWalkDirection;
|
|
btScalar mVelocityTimeInterval;
|
|
|
|
int mUpAxis;
|
|
|
|
btVector3 mLinearVelocity;
|
|
btScalar mMass;
|
|
|
|
class ClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
|
|
{
|
|
btCollisionObject *mMe;
|
|
|
|
public:
|
|
|
|
ClosestNotMeRayResultCallback(btCollisionObject * me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0, 0, 0), btVector3(0, 0, 0)), mMe(me) {}
|
|
|
|
btScalar addSingleResult(btCollisionWorld::LocalRayResult &rayResult, bool normalInWorldSpace)
|
|
{
|
|
if (rayResult.m_collisionObject == mMe)
|
|
return 1.0;
|
|
return btCollisionWorld::ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
|
|
}
|
|
};
|
|
|
|
class ClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
|
|
{
|
|
btCollisionObject *mMe;
|
|
const btVector3 mUp;
|
|
btScalar mMinSlopeDot;
|
|
|
|
public:
|
|
|
|
ClosestNotMeConvexResultCallback(btCollisionObject *me, const btVector3 &up, btScalar minSlopeDot) : btCollisionWorld::ClosestConvexResultCallback(btVector3(0, 0, 0), btVector3(0, 0, 0)), mMe(me), mUp(up), mMinSlopeDot(minSlopeDot) {}
|
|
|
|
btScalar addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace)
|
|
{
|
|
if (convexResult.m_hitCollisionObject == mMe)
|
|
return 1.0;
|
|
|
|
btVector3 hitNormalWorld;
|
|
if (normalInWorldSpace)
|
|
hitNormalWorld = convexResult.m_hitNormalLocal;
|
|
else
|
|
hitNormalWorld = convexResult.m_hitCollisionObject->getWorldTransform().getBasis() * convexResult.m_hitNormalLocal;
|
|
|
|
btScalar dotUp = mUp.dot(hitNormalWorld);
|
|
if (dotUp < mMinSlopeDot)
|
|
return 1.0;
|
|
|
|
return btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
|
|
}
|
|
};
|
|
|
|
static btVector3 *getUpAxisDirections()
|
|
{
|
|
static btVector3 sUpAxisDirection[3] = { btVector3(1, 0, 0), btVector3(0, 1, 0), btVector3(0, 0, 1) };
|
|
return sUpAxisDirection;
|
|
}
|
|
|
|
static btVector3 getNormalizedVector(const btVector3& v)
|
|
{
|
|
btVector3 n = v.normalized();
|
|
|
|
if (n.length() < SIMD_EPSILON)
|
|
n.setValue(0, 0, 0);
|
|
|
|
return n;
|
|
}
|
|
|
|
bool SweepTest(const btVector3 &, const btVector3 &, btScalar &fraction, btVector3 *normal = 0, btVector3 *hit = 0);
|
|
|
|
btVector3 computeReflectionDirection(const btVector3 & direction, const btVector3 & normal);
|
|
void setPlayerMode();
|
|
|
|
public:
|
|
|
|
btCustomCharacterController(btPairCachingGhostObject *ghostObject, btConvexShape *convexShape, btScalar stepHeight, btCollisionWorld *collisionWorld, int upAxis = 1);
|
|
|
|
btVector3 getUpAxisDirection() const { return getUpAxisDirections()[mUpAxis]; }
|
|
|
|
void setDuckingConvexShape(btConvexShape * shape);
|
|
bool recoverFromPenetration(const btVector3 &step_direction);
|
|
void stepUp(btCollisionWorld * collisionWorld);
|
|
void setRBForceImpulseBasedOnCollision();
|
|
void updateTargetPositionBasedOnCollision(const btVector3 & hitNormal, btScalar tangentMag = 0, btScalar normalMag = 1);
|
|
void stepForwardAndStrafe(btCollisionWorld * collisionWorld, const btVector3 & walkMove);
|
|
void stepDown(btCollisionWorld * collisionWorld, btScalar dt);
|
|
void setVelocityForTimeInterval(const btVector3 & velocity, btScalar timeInterval);
|
|
|
|
void reset() {}
|
|
|
|
void warp(const btVector3 & origin);
|
|
void preStep(btCollisionWorld * collisionWorld);
|
|
void playerStep(btCollisionWorld * collisionWorld, btScalar dt);
|
|
|
|
void setFallSpeed(btScalar fallSpeed);
|
|
void setJumpSpeed(btScalar jumpSpeed);
|
|
void setMaxJumpHeight(btScalar maxJumpHeight);
|
|
|
|
bool canJump() const;
|
|
void jump();
|
|
|
|
void duck();
|
|
|
|
void stand();
|
|
bool canStand();
|
|
|
|
void setGravity(const btScalar gravity);
|
|
btScalar getGravity() const;
|
|
|
|
void setMaxSlope(btScalar slopeRadians);
|
|
btScalar getMaxSlope() const;
|
|
|
|
bool onGround() const;
|
|
|
|
void setWalkDirection(const btVector3 & walkDirection);
|
|
void setWalkDirection(const btScalar x, const btScalar y, const btScalar z);
|
|
void setOrientation(const btQuaternion & orientation);
|
|
|
|
btVector3 getWalkDirection() const;
|
|
btVector3 getPosition() const;
|
|
|
|
void debugDraw(btIDebugDraw * debugDrawer);
|
|
|
|
void updateAction(btCollisionWorld * collisionWorld, btScalar dt);
|
|
};
|
|
|
|
|
|
#endif // CC_PHYSICS_H
|