diff --git a/test/BtPhysTest.cpp b/test/BtPhysTest.cpp index 9e1ad52e..522341ea 100644 --- a/test/BtPhysTest.cpp +++ b/test/BtPhysTest.cpp @@ -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)) diff --git a/test/PhysicObject.h b/test/PhysicObject.h index a11ce004..5813b44f 100644 --- a/test/PhysicObject.h +++ b/test/PhysicObject.h @@ -96,12 +96,18 @@ public: { Array 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(); diff --git a/test/Physics/Include/BulletCharacterController.h b/test/Physics/Include/BulletCharacterController.h index 1cb94b9c..6b04ac8c 100644 --- a/test/Physics/Include/BulletCharacterController.h +++ b/test/Physics/Include/BulletCharacterController.h @@ -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 diff --git a/test/Physics/Src/BulletCharacterController.cpp b/test/Physics/Src/BulletCharacterController.cpp index ec234b8d..82b01412 100644 --- a/test/Physics/Src/BulletCharacterController.cpp +++ b/test/Physics/Src/BulletCharacterController.cpp @@ -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));