@@ -35,44 +35,48 @@ namespace lol
#ifdef USE_LOL_CTRLR_CHARAC
#ifdef HAVE_PHYS_USE_BULLET
//SweepCallback used for Swweep Tests.
class ClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
{
public:
ClosestNotMeConvexResultCallback(btCollisionObject* NewMe, const vec3& NewUp, float MinSlopeDot) :
btCollisionWorld::ClosestConvexResultCallback(LOL2BTU_VEC3(vec3(.0f)), LOL2BTU_VEC3(vec3(.0f))),
m_me(NewMe),
m_up(NewUp),
m_min_slope_dot(MinSlopeDot) { }
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& ConvexResult, bool NormalInWorld)
//SweepCallback used for Swweep Tests.
class ClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
{
//We hit ourselves, FAIL
if (ConvexResult.m_hitCollisionObject == m_me)
return btScalar(1.f);
vec3 WorldHitNomal(.0f);
if (NormalInWorld)
WorldHitNomal = BT2LOL_VEC3(ConvexResult.m_hitNormalLocal);
else //need to transform Normal into worldspace
public:
ClosestNotMeConvexResultCallback(btCollisionObject* NewMe, const vec3& NewUp, float MinSlopeDot) :
btCollisionWorld::ClosestConvexResultCallback(LOL2BTU_VEC3(vec3(.0f)), LOL2BTU_VEC3(vec3(.0f))),
m_me(NewMe),
m_up(NewUp),
m_min_slope_dot(MinSlopeDot)
{
btVector3 TmpWorldHitNormal = ConvexResult.m_hitCollisionObject->getWorldTransform().getBasis() * ConvexResult.m_hitNormalLocal ;
WorldHitNomal = BT2LOL_VEC3(TmpWorldHitNormal) ;
m_collisionFilterGroup = NewMe->getBroadphaseHandle()->m_collisionFilterGroup;
m_collisionFilterMask = NewMe->getBroadphaseHandle()->m_collisionFilterMask ;
}
float DotUp = dot(m_up, WorldHitNomal);
//We hit below the accepted slope_dot, FAIL
if (DotUp < m_min_slope_dot)
return btScalar(1.f);
//Continue to next.
return ClosestConvexResultCallback::addSingleResult(ConvexResult, NormalInWorld);
}
protected:
btCollisionObject* m_me;
const vec3 m_up;
float m_min_slope_dot;
};
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& ConvexResult, bool NormalInWorld)
{
//We hit ourselves, FAIL
if (ConvexResult.m_hitCollisionObject == m_me)
return btScalar(1.f);
vec3 WorldHitNomal(.0f);
if (NormalInWorld)
WorldHitNomal = BT2LOL_VEC3(ConvexResult.m_hitNormalLocal);
else //need to transform Normal into worldspace
{
btVector3 TmpWorldHitNormal = ConvexResult.m_hitCollisionObject->getWorldTransform().getBasis() * ConvexResult.m_hitNormalLocal;
WorldHitNomal = BT2LOL_VEC3(TmpWorldHitNormal);
}
float DotUp = dot(m_up, WorldHitNomal);
//We hit below the accepted slope_dot, FAIL
if (DotUp < m_min_slope_dot)
return btScalar(1.f);
//Continue to next.
return ClosestConvexResultCallback::addSingleResult(ConvexResult, NormalInWorld);
}
protected:
btCollisionObject* m_me;
const vec3 m_up;
float m_min_slope_dot;
};
///BulletKinematicCharacterController is an object that supports a sliding motion in a world.
///It uses a ghost object and convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations.
@@ -80,8 +84,9 @@ namespace lol
class BulletKinematicCharacterController : public btActionInterface
{
public:
BulletKinematicCharacterController(btPairCachingGhostObject* NewGhostObject, btConvexShape* NewConvexShape, float NewStepHeight, int NewUpAxis=1)
BulletKinematicCharacterController(EasyCharacterController* NewCharacter, btPairCachingGhostObject* NewGhostObject, btConvexShape* NewConvexShape, float NewStepHeight, int NewUpAxis=1)
{
m_character = NewCharacter;
m_convex_shape = NewConvexShape;
m_i_up_axis = NewUpAxis;
m_ghost_object = NewGhostObject;
@@ -118,25 +123,13 @@ namespace lol
//--
//Returns the reflection Direction of a ray going 'Direction' hitting a surface with Normal 'Normal' from: http://www-cs-students.stanford.edu/~adityagp/final/node3.html
vec3 GetReflectedDir(const vec3& Direction, const vec3& Normal)
{
return Direction - (2.f * dot(Direction, Normal) * Normal);
}
vec3 GetReflectedDir(const vec3& Direction, const vec3& Normal) { return Direction - (2.f * dot(Direction, Normal) * Normal); }
//Returns the portion of 'direction' that is parallel to 'normal'
vec3 ProjectDirOnNorm(const vec3& Direction, const vec3& Normal)
{
return Normal * dot(Direction, Normal);
}
vec3 ProjectDirOnNorm(const vec3& Direction, const vec3& Normal) { return Normal * dot(Direction, Normal); }
//Returns the portion of 'Direction' that is perpindicular to 'Normal'
vec3 ProjectDirOnNormPerpindicular(const vec3& Direction, const vec3& Normal)
{
return Direction - ProjectDirOnNorm(Direction, Normal);
}
vec3 ProjectDirOnNormPerpindicular(const vec3& Direction, const vec3& Normal) { return Direction - ProjectDirOnNorm(Direction, Normal); }
//Returns Ghost Object. -duh-
btPairCachingGhostObject* GetGhostObject()
{
return m_ghost_object;
}
btPairCachingGhostObject* GetGhostObject() { return m_ghost_object; }
//"Real" war functions
bool RecoverFromPenetration(btCollisionWorld* CollisionWorld);
@@ -158,14 +151,7 @@ namespace lol
///btActionInterface interface : KEEP IN camelCase
void debugDraw(btIDebugDraw* debugDrawer) { }
void SetUpAxis(int NewAxis)
{
if (NewAxis < 0)
NewAxis = 0;
if (NewAxis > 2)
NewAxis = 2;
m_i_up_axis = NewAxis;
}
void SetUpAxis(int NewAxis) { m_i_up_axis = abs(NewAxis) % 3; }
//!!!!!! SHOULD DITCH THAT !!!!!!
//This should probably be called setPositionIncrementPerSimulatorStep.
@@ -229,6 +215,7 @@ namespace lol
private:
EasyCharacterController* m_character;
btPairCachingGhostObject* m_ghost_object;
btConvexShape* m_convex_shape; //is also in m_ghost_object, but it needs to be convex, so we store it here to avoid upcast