rename ObsoleteDemos back to Demos
fix some relative path issues for loading assets
This commit is contained in:
204
Demos/CharacterDemo/DynamicCharacterController.cpp
Normal file
204
Demos/CharacterDemo/DynamicCharacterController.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
|
||||
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
|
||||
#include "LinearMath/btDefaultMotionState.h"
|
||||
#include "DynamicCharacterController.h"
|
||||
|
||||
DynamicCharacterController::DynamicCharacterController ()
|
||||
{
|
||||
m_rayLambda[0] = 1.0;
|
||||
m_rayLambda[1] = 1.0;
|
||||
m_halfHeight = 1.0;
|
||||
m_turnAngle = 0.0;
|
||||
m_maxLinearVelocity = 10.0;
|
||||
m_walkVelocity = 8.0; // meters/sec
|
||||
m_turnVelocity = 1.0; // radians/sec
|
||||
m_shape = NULL;
|
||||
m_rigidBody = NULL;
|
||||
}
|
||||
|
||||
DynamicCharacterController::~DynamicCharacterController ()
|
||||
{
|
||||
}
|
||||
|
||||
void DynamicCharacterController::setup (btScalar height, btScalar width, btScalar stepHeight)
|
||||
{
|
||||
btVector3 spherePositions[2];
|
||||
btScalar sphereRadii[2];
|
||||
|
||||
sphereRadii[0] = width;
|
||||
sphereRadii[1] = width;
|
||||
spherePositions[0] = btVector3 (0.0, (height/btScalar(2.0) - width), 0.0);
|
||||
spherePositions[1] = btVector3 (0.0, (-height/btScalar(2.0) + width), 0.0);
|
||||
|
||||
m_halfHeight = height/btScalar(2.0);
|
||||
|
||||
m_shape = new btMultiSphereShape (&spherePositions[0], &sphereRadii[0], 2);
|
||||
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity ();
|
||||
startTransform.setOrigin (btVector3(0.0, 2.0, 0.0));
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
|
||||
btRigidBody::btRigidBodyConstructionInfo cInfo(1.0, myMotionState, m_shape);
|
||||
m_rigidBody = new btRigidBody(cInfo);
|
||||
// kinematic vs. static doesn't work
|
||||
//m_rigidBody->setCollisionFlags( m_rigidBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
|
||||
m_rigidBody->setSleepingThresholds (0.0, 0.0);
|
||||
m_rigidBody->setAngularFactor (0.0);
|
||||
|
||||
}
|
||||
|
||||
void DynamicCharacterController::destroy ()
|
||||
{
|
||||
if (m_shape)
|
||||
{
|
||||
delete m_shape;
|
||||
}
|
||||
|
||||
if (m_rigidBody)
|
||||
{
|
||||
delete m_rigidBody;
|
||||
m_rigidBody = 0;
|
||||
}
|
||||
}
|
||||
|
||||
btCollisionObject* DynamicCharacterController::getCollisionObject ()
|
||||
{
|
||||
return m_rigidBody;
|
||||
}
|
||||
|
||||
void DynamicCharacterController::preStep (const btCollisionWorld* collisionWorld)
|
||||
{
|
||||
btTransform xform;
|
||||
m_rigidBody->getMotionState()->getWorldTransform (xform);
|
||||
btVector3 down = -xform.getBasis()[1];
|
||||
btVector3 forward = xform.getBasis()[2];
|
||||
down.normalize ();
|
||||
forward.normalize();
|
||||
|
||||
m_raySource[0] = xform.getOrigin();
|
||||
m_raySource[1] = xform.getOrigin();
|
||||
|
||||
m_rayTarget[0] = m_raySource[0] + down * m_halfHeight * btScalar(1.1);
|
||||
m_rayTarget[1] = m_raySource[1] + forward * m_halfHeight * btScalar(1.1);
|
||||
|
||||
class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback
|
||||
{
|
||||
public:
|
||||
ClosestNotMe (btRigidBody* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
|
||||
{
|
||||
m_me = me;
|
||||
}
|
||||
|
||||
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
|
||||
{
|
||||
if (rayResult.m_collisionObject == m_me)
|
||||
return 1.0;
|
||||
|
||||
return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace
|
||||
);
|
||||
}
|
||||
protected:
|
||||
btRigidBody* m_me;
|
||||
};
|
||||
|
||||
ClosestNotMe rayCallback(m_rigidBody);
|
||||
|
||||
int i = 0;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
rayCallback.m_closestHitFraction = 1.0;
|
||||
collisionWorld->rayTest (m_raySource[i], m_rayTarget[i], rayCallback);
|
||||
if (rayCallback.hasHit())
|
||||
{
|
||||
m_rayLambda[i] = rayCallback.m_closestHitFraction;
|
||||
} else {
|
||||
m_rayLambda[i] = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicCharacterController::playerStep (const btCollisionWorld* dynaWorld,btScalar dt,
|
||||
int forward,
|
||||
int backward,
|
||||
int left,
|
||||
int right,
|
||||
int jump)
|
||||
{
|
||||
btTransform xform;
|
||||
m_rigidBody->getMotionState()->getWorldTransform (xform);
|
||||
|
||||
/* Handle turning */
|
||||
if (left)
|
||||
m_turnAngle -= dt * m_turnVelocity;
|
||||
if (right)
|
||||
m_turnAngle += dt * m_turnVelocity;
|
||||
|
||||
xform.setRotation (btQuaternion (btVector3(0.0, 1.0, 0.0), m_turnAngle));
|
||||
|
||||
btVector3 linearVelocity = m_rigidBody->getLinearVelocity();
|
||||
btScalar speed = m_rigidBody->getLinearVelocity().length();
|
||||
|
||||
btVector3 forwardDir = xform.getBasis()[2];
|
||||
forwardDir.normalize ();
|
||||
btVector3 walkDirection = btVector3(0.0, 0.0, 0.0);
|
||||
btScalar walkSpeed = m_walkVelocity * dt;
|
||||
|
||||
if (forward)
|
||||
walkDirection += forwardDir;
|
||||
if (backward)
|
||||
walkDirection -= forwardDir;
|
||||
|
||||
|
||||
|
||||
if (!forward && !backward && onGround())
|
||||
{
|
||||
/* Dampen when on the ground and not being moved by the player */
|
||||
linearVelocity *= btScalar(0.2);
|
||||
m_rigidBody->setLinearVelocity (linearVelocity);
|
||||
} else {
|
||||
if (speed < m_maxLinearVelocity)
|
||||
{
|
||||
btVector3 velocity = linearVelocity + walkDirection * walkSpeed;
|
||||
m_rigidBody->setLinearVelocity (velocity);
|
||||
}
|
||||
}
|
||||
|
||||
m_rigidBody->getMotionState()->setWorldTransform (xform);
|
||||
m_rigidBody->setCenterOfMassTransform (xform);
|
||||
}
|
||||
|
||||
bool DynamicCharacterController::canJump () const
|
||||
{
|
||||
return onGround();
|
||||
}
|
||||
|
||||
void DynamicCharacterController::jump ()
|
||||
{
|
||||
if (!canJump())
|
||||
return;
|
||||
|
||||
btTransform xform;
|
||||
m_rigidBody->getMotionState()->getWorldTransform (xform);
|
||||
btVector3 up = xform.getBasis()[1];
|
||||
up.normalize ();
|
||||
btScalar magnitude = (btScalar(1.0)/m_rigidBody->getInvMass()) * btScalar(8.0);
|
||||
m_rigidBody->applyCentralImpulse (up * magnitude);
|
||||
}
|
||||
|
||||
bool DynamicCharacterController::onGround () const
|
||||
{
|
||||
return m_rayLambda[0] < btScalar(1.0);
|
||||
}
|
||||
|
||||
void DynamicCharacterController::reset ()
|
||||
{
|
||||
}
|
||||
void DynamicCharacterController::warp (const btVector3& origin)
|
||||
{
|
||||
}
|
||||
void DynamicCharacterController::registerPairCacheAndDispatcher (btOverlappingPairCache* pairCache, btCollisionDispatcher* dispatcher)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user