Browse Source

small tweak on BtPhysTest. does not work better.

legacy
Benjamin ‘Touky’ Huet touky 12 years ago
parent
commit
a11c50b3e7
4 changed files with 83 additions and 162 deletions
  1. +11
    -7
      test/BtPhysTest.cpp
  2. +12
    -6
      test/PhysicObject.h
  3. +57
    -10
      test/Physics/Include/BulletCharacterController.h
  4. +3
    -139
      test/Physics/Src/BulletCharacterController.cpp

+ 11
- 7
test/BtPhysTest.cpp View File

@@ -52,14 +52,16 @@ int gNumObjects = 64;
#define USE_WALL 1
#define USE_PLATFORM 1
#define USE_ROPE 0
#define USE_BODIES 0
#define USE_BODIES 1
#define USE_ROTATION 0
#define USE_CHARACTER 1

#define IPT_MOVE_FORWARD "Move_Forward"
#define IPT_MOVE_BACKWARD "Move_Backward"
#define IPT_MOVE_STRAFE_LEFT "Strafe_Left"
#define IPT_MOVE_STRAFE_RIGHT "Strafe_right"
#define IPT_MOVE_LEFT "Move_Left"
#define IPT_MOVE_RIGHT "Move_Right"
#define IPT_MOVE_UP "Move_Up"
#define IPT_MOVE_DOWN "Move_Down"
#define IPT_MOVE_JUMP "Move_Jump"

BtPhysTest::BtPhysTest(bool editor)
@@ -171,9 +173,11 @@ BtPhysTest::BtPhysTest(bool editor)

Input::LinkActionToKey(IPT_MOVE_FORWARD, Key::Up);
Input::LinkActionToKey(IPT_MOVE_BACKWARD, Key::Down);
Input::LinkActionToKey(IPT_MOVE_STRAFE_LEFT, Key::Left);
Input::LinkActionToKey(IPT_MOVE_STRAFE_RIGHT, Key::Right);
Input::LinkActionToKey(IPT_MOVE_LEFT, Key::Left);
Input::LinkActionToKey(IPT_MOVE_RIGHT, Key::Right);
Input::LinkActionToKey(IPT_MOVE_JUMP, Key::Space);
Input::LinkActionToKey(IPT_MOVE_UP, Key::PageUp);
Input::LinkActionToKey(IPT_MOVE_DOWN, Key::PageDown);

//NewPhyobj->GetCharacter()->AttachTo(BasePhyobj->GetPhysic(), true, true);
}
@@ -314,9 +318,9 @@ void BtPhysTest::TickGame(float seconds)
EasyCharacterController* Character = (EasyCharacterController*)PhysObj->GetCharacter();
mat4 CtlrMx = Character->GetTransform();
int HMovement = Input::GetStatus(IPT_MOVE_STRAFE_RIGHT) - Input::GetStatus(IPT_MOVE_STRAFE_LEFT);
int HMovement = Input::GetStatus(IPT_MOVE_RIGHT) - Input::GetStatus(IPT_MOVE_LEFT);
int VMovement = Input::GetStatus(IPT_MOVE_FORWARD) - Input::GetStatus(IPT_MOVE_BACKWARD);
int RMovement = 0;//Input::GetButtonState(280 /*SDLK_PAGEUP*/) - Input::GetButtonState(281 /*SDLK_PAGEDOWN*/);
int RMovement = Input::GetStatus(IPT_MOVE_UP) - Input::GetStatus(IPT_MOVE_DOWN);
vec3 CharMove = vec3((float)VMovement * seconds * 4.f, (float)RMovement * seconds * 10.f, (float)HMovement * seconds * 4.f);

if (Input::WasReleased(IPT_MOVE_JUMP))


+ 12
- 6
test/PhysicObject.h View File

@@ -96,12 +96,18 @@ public:
{
Array<char const *> MeshRand;

MeshRand << "[sc#add afcb2 2 2 -.1]";
MeshRand << "[sc#dad afcb2 2 2 -.1]";
MeshRand << "[sc#dda afcb2 2 2 -.1]";
MeshRand << "[sc#daa afcb2 2 2 -.1]";
MeshRand << "[sc#ada afcb2 2 2 -.1]";
MeshRand << "[sc#aad afcb2 2 2 -.1]";
//MeshRand << "[sc#add afcb2 2 2 -.1]";
//MeshRand << "[sc#dad afcb2 2 2 -.1]";
//MeshRand << "[sc#dda afcb2 2 2 -.1]";
//MeshRand << "[sc#daa afcb2 2 2 -.1]";
//MeshRand << "[sc#ada afcb2 2 2 -.1]";
//MeshRand << "[sc#aad afcb2 2 2 -.1]";
MeshRand << "[sc#add afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
MeshRand << "[sc#dad afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
MeshRand << "[sc#dda afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
MeshRand << "[sc#daa afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
MeshRand << "[sc#ada afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
MeshRand << "[sc#aad afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";

int SphereLimit = MeshRand.Count();



+ 57
- 10
test/Physics/Include/BulletCharacterController.h View File

@@ -35,6 +35,45 @@ 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)
{
//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.
///Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user.
@@ -44,7 +83,7 @@ namespace lol
BulletKinematicCharacterController(btPairCachingGhostObject* NewGhostObject, btConvexShape* NewConvexShape, float NewStepHeight, int NewUpAxis=1)
{
m_convex_shape = NewConvexShape;
m_up_axis = NewUpAxis;
m_i_up_axis = NewUpAxis;
m_ghost_object = NewGhostObject;
m_step_height = NewStepHeight;

@@ -56,7 +95,7 @@ namespace lol
m_velocity_time_interval = .0f;
m_vertical_velocity = .0f;
m_vertical_offset = .0f;
m_gravity = 9.8f * 3.f; // 3G acceleration.
m_f_gravity = 9.8f * 3.f; // 3G acceleration.
m_fall_speed = 55.f; // Terminal velocity of a sky diver in m/s.
m_jump_speed = 10.f; // ?
m_was_on_ground = false;
@@ -102,9 +141,7 @@ namespace lol
//"Real" war functions
bool RecoverFromPenetration(btCollisionWorld* CollisionWorld);
void UpdateTargetOnHit(const vec3& hit_normal, float TangentMag = .0f, float NormalMag = 1.f);
void StepUp(btCollisionWorld* CollisionWorld);
void StepForwardAndStrafe(btCollisionWorld* CollisionWorld, const vec3& MoveStep);
void StepDown(btCollisionWorld* CollisionWorld, float DeltaTime);
void DoMove(btCollisionWorld* CollisionWorld, const vec3& MoveStep, float DeltaTime);

public:
///btActionInterface interface : KEEP IN camelCase
@@ -127,7 +164,7 @@ namespace lol
NewAxis = 0;
if (NewAxis > 2)
NewAxis = 2;
m_up_axis = NewAxis;
m_i_up_axis = NewAxis;
}

//!!!!!! SHOULD DITCH THAT !!!!!!
@@ -178,8 +215,8 @@ namespace lol
void Jump();

//NewGravity functions
void SetGravity(float NewGravity) { m_gravity = NewGravity; }
float GetGravity() const { return m_gravity; }
void SetGravity(float NewGravity) { m_f_gravity = NewGravity; }
float GetGravity() const { return m_f_gravity; }

//The max slope determines the maximum angle that the controller can walk up.
//The slope angle is measured in radians.
@@ -207,7 +244,7 @@ namespace lol
float m_max_jump_height;
float m_max_slope_radians; // Slope angle that is set (used for returning the exact value)
float m_max_slope_cosine; // Cosine equivalent of m_max_slope_radians (calculated once when set, for optimization)
float m_gravity;
float m_f_gravity;
float m_turn_angle;
float m_step_height;
float m_added_margin;//@todo: remove this and fix the code
@@ -228,7 +265,17 @@ namespace lol
bool m_was_jumping;
bool m_do_gobject_sweep_test;
bool m_use_walk_direction;
int m_up_axis;
int m_i_up_axis;

//---------------------------------------------------------------------
//NEW INTERNAL VARS
//---------------------------------------------------------------------

//Gravity in vec3
vec3 m_gravity;

//Current Velocity
vec3 m_velocity;
};

#endif // HAVE_PHYS_USE_BULLET


+ 3
- 139
test/Physics/Src/BulletCharacterController.cpp View File

@@ -42,45 +42,6 @@ namespace phys
#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)
{
//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;
};

//When called, will try to remove Character controller from its collision.
bool BulletKinematicCharacterController::RecoverFromPenetration(btCollisionWorld* CollisionWorld)
{
@@ -152,53 +113,8 @@ void BulletKinematicCharacterController::UpdateTargetOnHit(const vec3& HitNormal
}
}

//Handles the Step-Up : Currently taking into account Stair step & Jump.
void BulletKinematicCharacterController::StepUp(btCollisionWorld* world)
{
// phase 1: up
vec3 UpDir = GetUpAxisDirections()[m_up_axis];
btTransform SweepStart, SweepEnd;
SweepStart.setIdentity();
SweepEnd.setIdentity();

m_target_position = m_current_position + UpDir * (m_step_height + (m_vertical_offset > 0.f ? m_vertical_offset : 0.f));

/* FIXME: Handle HasPenetration properly */
SweepStart.setOrigin(LOL2BTU_VEC3(m_current_position + UpDir * (m_convex_shape->getMargin() + m_added_margin)));
SweepEnd.setOrigin(LOL2BTU_VEC3(m_target_position));

ClosestNotMeConvexResultCallback SweepCallback(m_ghost_object, -UpDir, float(0.7071));
SweepCallback.m_collisionFilterGroup = GetGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
SweepCallback.m_collisionFilterMask = GetGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
if (m_do_gobject_sweep_test)
m_ghost_object->convexSweepTest(m_convex_shape, SweepStart, SweepEnd, SweepCallback, world->getDispatchInfo().m_allowedCcdPenetration);
else
world->convexSweepTest(m_convex_shape, SweepStart, SweepEnd, SweepCallback);
if (SweepCallback.hasHit())
{
// Only modify the position if the hit was a slope and not a wall or ceiling.
if(SweepCallback.m_hitNormalWorld.dot(LOL2BTU_VEC3(UpDir)) > .0f)
{
// we moved up only a Fraction of the step height
m_current_step_offset = m_step_height * SweepCallback.m_closestHitFraction;
btVector3 InterpolPos; //TODO : REPLACE BY INTERPOLATE3/LERP(VEC3)
InterpolPos.setInterpolate3(LOL2BTU_VEC3(m_current_position), LOL2BTU_VEC3(m_target_position), SweepCallback.m_closestHitFraction);
m_current_position = BT2LOLU_VEC3(InterpolPos);
}
m_vertical_velocity = .0f;
m_vertical_offset = .0f;
}
else
{
m_current_step_offset = m_step_height;
m_current_position = m_target_position;
}
}

//Handles the actual Movement. It actually moves in the 3 dimensions, function name is confusing.
void BulletKinematicCharacterController::StepForwardAndStrafe(btCollisionWorld* CollisionWorld, const vec3& MoveStep)
void BulletKinematicCharacterController::DoMove(btCollisionWorld* CollisionWorld, const vec3& MoveStep, float DeltaTime)
{
// phase 2: forward and strafe
m_target_position = m_current_position + MoveStep;
@@ -259,48 +175,6 @@ void BulletKinematicCharacterController::StepForwardAndStrafe(btCollisionWorld*
}
}

//Handles the Step-down : We go back on the ground at the end of the MoveStep.
void BulletKinematicCharacterController::StepDown(btCollisionWorld* CollisionWorld, float DeltaTime)
{
// phase 3: down
vec3 UpDir = GetUpAxisDirections()[m_up_axis];
btTransform SweepStart, SweepEnd;
SweepStart.setIdentity();
SweepEnd.setIdentity();

float DownVel = (m_vertical_velocity < 0.f ? -m_vertical_velocity : 0.f) * DeltaTime;
if (DownVel > .0f && DownVel < m_step_height && (m_was_on_ground || !m_was_jumping))
DownVel = m_step_height;

vec3 StepDrop = UpDir * (m_current_step_offset + DownVel);
m_target_position -= StepDrop;

SweepStart.setOrigin(LOL2BTU_VEC3(m_current_position));
SweepEnd.setOrigin(LOL2BTU_VEC3(m_target_position));

ClosestNotMeConvexResultCallback SweepCallback(m_ghost_object, UpDir, m_max_slope_cosine);
SweepCallback.m_collisionFilterGroup = GetGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
SweepCallback.m_collisionFilterMask = GetGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
if (m_do_gobject_sweep_test)
m_ghost_object->convexSweepTest(m_convex_shape, SweepStart, SweepEnd, SweepCallback, CollisionWorld->getDispatchInfo().m_allowedCcdPenetration);
else
CollisionWorld->convexSweepTest(m_convex_shape, SweepStart, SweepEnd, SweepCallback, CollisionWorld->getDispatchInfo().m_allowedCcdPenetration);

if (SweepCallback.hasHit())
{
// we dropped a Fraction of the height -> hit floor
btVector3 InterpolPos; //TODO : REPLACE BY INTERPOLATE3/LERP(VEC3)
InterpolPos.setInterpolate3(LOL2BTU_VEC3(m_current_position), LOL2BTU_VEC3(m_target_position), SweepCallback.m_closestHitFraction);
m_current_position = BT2LOLU_VEC3(InterpolPos);
m_vertical_velocity = .0f;
m_vertical_offset = .0f;
m_was_jumping = false;
}
else // we dropped the full height
m_current_position = m_target_position;
}

//The PreStepis done in order to recover from any HasPenetration.
void BulletKinematicCharacterController::PreStep(btCollisionWorld* CollisionWorld)
{
@@ -327,16 +201,8 @@ void BulletKinematicCharacterController::PlayerStep(btCollisionWorld* CollisionW
if (!m_use_walk_direction && m_velocity_time_interval <= .0f)
return; // no motion

m_was_on_ground = OnGround();

// Update fall velocity.
m_vertical_velocity -= m_gravity * DeltaTime;
if(m_vertical_velocity > .0f && m_vertical_velocity > m_jump_speed)
m_vertical_velocity = m_jump_speed;

if(m_vertical_velocity < .0f && btFabs(m_vertical_velocity) > btFabs(m_fall_speed))
m_vertical_velocity = -btFabs(m_fall_speed);
m_vertical_offset = m_vertical_velocity * DeltaTime;
//m_velocity -= m_gravity * DeltaTime;

btTransform NewTransform;
NewTransform = m_ghost_object->getWorldTransform();
@@ -355,9 +221,7 @@ void BulletKinematicCharacterController::PlayerStep(btCollisionWorld* CollisionW
}

//Okay, step !
StepUp(CollisionWorld);
StepForwardAndStrafe(CollisionWorld, MoveStep);
StepDown(CollisionWorld, DeltaTime);
DoMove(CollisionWorld, MoveStep, DeltaTime);

//Movement finished, update World transform
NewTransform.setOrigin(LOL2BTU_VEC3(m_current_position));


Loading…
Cancel
Save