From 11ddba1864e38126801a967a283df3fc7ff96714 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20=E2=80=98Touky=E2=80=99=20Huet?= Date: Fri, 17 Aug 2012 17:41:36 +0000 Subject: [PATCH] =?UTF-8?q?Added=20Attachment/base=20logic=20with=20workin?= =?UTF-8?q?g=20attachment=20with=20EasyCharacterController.=20Added=20RayC?= =?UTF-8?q?astResult=20&=20a=20na=C3=AFve=20integration=20for=20EasyCharac?= =?UTF-8?q?terController.=20Enjoy=20!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/entity.h | 6 +- src/input/input.h | 5 +- test/BtPhysTest.cpp | 56 ++++--- test/PhysicObject.h | 8 - .../Physics/Include/EasyCharacterController.h | 22 ++- test/Physics/Include/EasyPhysics.h | 19 +-- .../Physics/Include/LolBtPhysicsIntegration.h | 11 ++ test/Physics/Include/LolPhysics.h | 145 ++++++++++++++++++ test/Physics/Src/EasyCharacterController.cpp | 41 ++++- test/Physics/Src/EasyPhysics.cpp | 50 +++--- 10 files changed, 292 insertions(+), 71 deletions(-) diff --git a/src/entity.h b/src/entity.h index 3b97001b..cdbcac60 100644 --- a/src/entity.h +++ b/src/entity.h @@ -45,8 +45,10 @@ protected: { GAMEGROUP_BEFORE = 0, GAMEGROUP_DEFAULT, - GAMEGROUP_AFTER, - // Must be the last element + GAMEGROUP_AFTER, + GAMEGROUP_AFTER_POST, + + // Must be the last element GAMEGROUP_END } m_gamegroup; diff --git a/src/input/input.h b/src/input/input.h index 9c4df482..0d3194d8 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -16,6 +16,7 @@ #if !defined __LOL_INPUT_INPUT_H__ #define __LOL_INPUT_INPUT_H__ +#include #include "lol/math/vector.h" #include "input/stick.h" @@ -108,7 +109,7 @@ struct ActionSetting ActionSetting(int NewActionId) { - //memset(this, 0, sizeof(ActionSetting)); + memset(this, 0, sizeof(ActionSetting)); ActionId = NewActionId; } }; @@ -122,7 +123,7 @@ struct ButtonSetting ButtonSetting(int NewRawButtonId) { - //memset(this, 0, sizeof(ButtonSetting)); + memset(this, 0, sizeof(ButtonSetting)); RawButtonId = NewRawButtonId; } int GetActionSettingIdx(int ActionId) diff --git a/test/BtPhysTest.cpp b/test/BtPhysTest.cpp index 379ffdac..bb708e83 100644 --- a/test/BtPhysTest.cpp +++ b/test/BtPhysTest.cpp @@ -51,13 +51,15 @@ int gNumObjects = 64; #define USE_WALL 1 #define USE_PLATFORM 1 -#define USE_ROPE 1 -#define USE_BODIES 1 +#define USE_ROPE 0 +#define USE_BODIES 0 #define USE_ROTATION 0 #define USE_CHARACTER 1 BtPhysTest::BtPhysTest(bool editor) { + m_loop_value = .0f; + /* Create a camera that matches the settings of XNA BtPhysTest */ m_camera = new Camera(vec3(0.f, 600.f, 0.f), vec3(0.f, 0.f, 0.f), @@ -107,6 +109,7 @@ BtPhysTest::BtPhysTest(bool editor) } } + PhysicsObject* BasePhyobj = NULL; if (USE_PLATFORM) { quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f); @@ -117,16 +120,16 @@ BtPhysTest::BtPhysTest(bool editor) m_platform_list << NewPhyobj; Ticker::Ref(NewPhyobj); - NewPosition = pos_offset + vec3(-20.0f, -25.0f, 5.0f); + NewPosition = pos_offset + vec3(-15.0f, -25.0f, 5.0f); NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); - PhysicsObject* BasePhyobj = NewPhyobj; + BasePhyobj = NewPhyobj; m_platform_list << NewPhyobj; Ticker::Ref(NewPhyobj); NewRotation = quat::fromeuler_xyz(0.f, 0.f, 90.f); - NewPosition = pos_offset + vec3(-25.0f, -25.0f, 5.0f); + NewPosition = pos_offset + vec3(-20.0f, -25.0f, 5.0f); NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); @@ -134,30 +137,32 @@ BtPhysTest::BtPhysTest(bool editor) m_platform_list << NewPhyobj; Ticker::Ref(NewPhyobj); - NewPosition += vec3(-0.0f, .0f, .0f); - NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); + //NewPosition += vec3(-0.0f, .0f, .0f); + //NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); - NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, false); - m_platform_list << NewPhyobj; - Ticker::Ref(NewPhyobj); + //NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, false); + //m_platform_list << NewPhyobj; + //Ticker::Ref(NewPhyobj); - NewPosition += vec3(-2.0f, .0f, .0f); - NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); + //NewPosition += vec3(-2.0f, .0f, .0f); + //NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); - NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), false, false); - m_platform_list << NewPhyobj; - Ticker::Ref(NewPhyobj); + //NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), false, false); + //m_platform_list << NewPhyobj; + //Ticker::Ref(NewPhyobj); } if (USE_CHARACTER) { quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f); - vec3 NewPosition = pos_offset + vec3(-15.0f, 20.0f, .0f); + vec3 NewPosition = pos_offset + vec3(-15.0f, -10.0f, .0f); PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 2); m_character_list << NewPhyobj; Ticker::Ref(NewPhyobj); + + //NewPhyobj->GetCharacter()->AttachTo(BasePhyobj->GetPhysic(), true, true); } if (USE_BODIES) @@ -280,8 +285,9 @@ void BtPhysTest::TickGame(float seconds) } else if (i == 1) { - GroundMat = mat4::translate(vec3(-15.0f, 5.0f, lol::cos(m_loop_value) * 8.f)) * - mat4(quat::fromeuler_xyz(vec3(.0f, lol::cos(m_loop_value) * 20.f, .0f))); + GroundMat = + mat4::translate(vec3(-15.0f, 5.0f, lol::cos(m_loop_value) * 8.f)) * + mat4(quat::fromeuler_xyz(vec3(.0f, lol::cos(m_loop_value) * 20.f, .0f))); PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat)); } } @@ -293,12 +299,20 @@ void BtPhysTest::TickGame(float seconds) { PhysicsObject* PhysObj = m_character_list[i]; EasyCharacterController* Character = (EasyCharacterController*)PhysObj->GetCharacter(); + mat4 CtlrMx = Character->GetTransform(); int HMovement = Input::GetButtonState(275 /*SDLK_RIGHT*/) - Input::GetButtonState(276 /*SDLK_LEFT*/); int VMovement = Input::GetButtonState(273 /*SDLK_UP*/) - Input::GetButtonState(274 /*SDLK_DOWN*/); int RMovement = Input::GetButtonState(280 /*SDLK_PAGEUP*/) - Input::GetButtonState(281 /*SDLK_PAGEDOWN*/); + vec3 CharMove = vec3((float)VMovement * seconds * 4.f, (float)RMovement * seconds * 10.f, (float)HMovement * seconds * 4.f); + + Character->SetMovementForFrame(CharMove); - Character->SetMovementForFrame(vec3((float)VMovement * seconds * 4.f, (float)RMovement * seconds * 10.f, (float)HMovement * seconds * 4.f)); + RayCastResult HitResult; + if (m_simulation->RayHits(HitResult, ERT_Closest, Character->GetTransform().v3.xyz, (Character->GetTransform().v3.xyz + vec3(.0f, -1.f, .0f)), Character)) + Character->AttachTo(HitResult.m_collider_list[0], true, true); + else + Character->AttachTo(NULL); } } @@ -319,8 +333,8 @@ void BtPhysTest::TickGame(float seconds) PhysObjBarycenter /= factor; m_camera->SetTarget(m_camera->GetTarget() + (seconds / (seconds + 0.18f)) * (PhysObjBarycenter - m_camera->GetTarget())); - vec3 CamPosCenter = m_camera->GetTarget() + vec3(.0f, 20.0f, .0f); - m_camera->SetPosition(CamPosCenter + normalize(m_camera->GetPosition() - CamPosCenter) * 5.0f); + vec3 CamPosCenter = m_camera->GetTarget() + vec3(.0f, 5.0f, .0f); + m_camera->SetPosition(CamPosCenter + normalize(m_camera->GetPosition() - CamPosCenter) * 20.0f); } else { diff --git a/test/PhysicObject.h b/test/PhysicObject.h index 7aba56dc..4240a49e 100644 --- a/test/PhysicObject.h +++ b/test/PhysicObject.h @@ -219,14 +219,6 @@ public: m_physics->SetTransform(base_location, base_rotation); } - void SetLinearVelocity(const lol::vec3& NewVelocity, bool bIsLocal=false) - { - //if (m_is_character) - // m_character->SetLinearVelocity(NewVelocity); - //else - // m_physics->SetLinearVelocity(NewVelocity); - } - lol::mat4 GetTransform() { if (m_is_character) diff --git a/test/Physics/Include/EasyCharacterController.h b/test/Physics/Include/EasyCharacterController.h index 812d5526..d6e11b18 100644 --- a/test/Physics/Include/EasyCharacterController.h +++ b/test/Physics/Include/EasyCharacterController.h @@ -29,7 +29,8 @@ namespace lol namespace phys { -class EasyCharacterController : public EasyPhysic +class EasyCharacterController : public EasyPhysic, + public Entity { #ifdef HAVE_PHYS_USE_BULLET @@ -37,8 +38,14 @@ class EasyCharacterController : public EasyPhysic public: EasyCharacterController(WorldEntity* NewOwnerEntity) : EasyPhysic(NewOwnerEntity), - m_character(NULL) + m_pair_caching_object(NULL), + m_character(NULL), + m_step_height(.0f), + m_base_is_updating(false), + m_base_cached_movement(vec3(0.f)), + m_frame_cached_movement(vec3(0.f)) { + m_gamegroup = GAMEGROUP_EZP_CHAR_CTRLR; m_up_axis = 1; } ~EasyCharacterController() @@ -52,15 +59,24 @@ public: virtual void RemoveFromSimulation(class Simulation* current_simulation); virtual void SetMovementForFrame(vec3 const &MoveQuantity); + virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation); +protected: + virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix); +public: + virtual void TickGame(float seconds); + protected: - virtual btGhostObject* GetGhostObject(); + virtual btGhostObject* GetGhostObjectInstance(); btPairCachingGhostObject* m_pair_caching_object; btKinematicCharacterController* m_character; float m_step_height; int m_up_axis; + bool m_base_is_updating; + vec3 m_base_cached_movement; + vec3 m_frame_cached_movement; #else // NO PHYSIC IMPLEMENTATION diff --git a/test/Physics/Include/EasyPhysics.h b/test/Physics/Include/EasyPhysics.h index a494c49a..909ef6ae 100644 --- a/test/Physics/Include/EasyPhysics.h +++ b/test/Physics/Include/EasyPhysics.h @@ -34,6 +34,7 @@ class EasyPhysic { friend class EasyConstraint; + friend class Simulation; #ifdef HAVE_PHYS_USE_BULLET @@ -48,8 +49,9 @@ public: virtual void SetShapeToCapsule(float radius, float height); virtual bool CanChangeCollisionChannel() { return (m_rigid_body == NULL); } + virtual mat4 GetTransform(); virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f))); -private: +protected: virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix); public: virtual void SetMass(float mass); @@ -57,13 +59,12 @@ public: virtual void InitBodyToGhost(); virtual void AddToSimulation(class Simulation* current_simulation); virtual void RemoveFromSimulation(class Simulation* current_simulation); - virtual mat4 GetTransform(); protected: virtual void SetLocalInertia(float mass); virtual void SetShapeTo(btCollisionShape* collision_shape); - virtual btGhostObject* GetGhostObject(); + virtual btGhostObject* GetGhostObjectInstance(); btCollisionObject* m_collision_object; @@ -88,6 +89,7 @@ public: virtual void SetShapeToCapsule(float radius, float height) { } virtual bool CanChangeCollisionChannel() { return true; } + virtual mat4 GetTransform() { return mat4(1.0f); } virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f))) { } private: virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix) { } @@ -97,7 +99,6 @@ public: virtual void InitBodyToGhost() { } virtual void AddToSimulation(class Simulation* current_simulation) { } virtual void RemoveFromSimulation(class Simulation* current_simulation) { } - virtual mat4 GetTransform() { return mat4(1.0f); } virtual void InitBodyToGhost() { } @@ -122,7 +123,7 @@ public: //Base/Attachment logic virtual void AttachTo(EasyPhysic* NewBase, bool NewBaseLockLocation = true, bool NewBaseLockRotation = true) { - if (NewBase == this || NewBase->m_base_physic == this) + if (NewBase == this || (NewBase && NewBase->m_base_physic == this)) return; if (NewBase) @@ -137,11 +138,11 @@ public: m_base_lock_location = NewBaseLockLocation; m_base_lock_rotation = NewBaseLockRotation; } - else + else if (m_base_physic) { - for (int i = 0; i < NewBase->m_based_physic_list.Count(); ++i) - if (NewBase->m_based_physic_list[i] == this) - NewBase->m_based_physic_list.Remove(i--); + for (int i = 0; i < m_base_physic->m_based_physic_list.Count(); ++i) + if (m_base_physic->m_based_physic_list[i] == this) + m_base_physic->m_based_physic_list.Remove(i--); m_base_physic = NULL; } } diff --git a/test/Physics/Include/LolBtPhysicsIntegration.h b/test/Physics/Include/LolBtPhysicsIntegration.h index aa7c16bb..7b1f6fe9 100644 --- a/test/Physics/Include/LolBtPhysicsIntegration.h +++ b/test/Physics/Include/LolBtPhysicsIntegration.h @@ -19,6 +19,13 @@ namespace lol { + //Override Gamegroups names for Physic-useage + //"_ENT_" means that this is a group for Entities that use EasyPhysic primitives. + //"_EZP_" means that this is a group for EasyPhysic primitives. +#define GAMEGROUP_ENT_PLATFORM GAMEGROUP_BEFORE +#define GAMEGROUP_ENT_MAIN GAMEGROUP_DEFAULT +#define GAMEGROUP_EZP_CHAR_CTRLR GAMEGROUP_AFTER +#define GAMEGROUP_SIMULATION GAMEGROUP_AFTER_POST #ifdef HAVE_PHYS_USE_BULLET @@ -31,6 +38,10 @@ namespace lol #define LOL2BT_VEC3(ELEMENT) btVector3((ELEMENT).x, (ELEMENT).y, (ELEMENT).z) #define BT2LOL_VEC3(ELEMENT) (*(lol::vec3*)(&(ELEMENT))) +//Same as above with Unit taken into account +#define LOL2BTU_VEC3(ELEMENT) btVector3((ELEMENT).x * LOL2BT_UNIT, (ELEMENT).y * LOL2BT_UNIT, (ELEMENT).z * LOL2BT_UNIT) +#define BT2LOLU_VEC3(ELEMENT) (*(lol::vec3*)(&(ELEMENT))) * BT2LOL_UNIT + #define LOL2BT_QUAT(ELEMENT) btQuaternion((ELEMENT).x, (ELEMENT).y, (ELEMENT).z, (ELEMENT).w) #define BT2LOL_QUAT(ELEMENT) lol::quat((ELEMENT).getW(), BT2LOL_VEC3((ELEMENT).getAxis()) diff --git a/test/Physics/Include/LolPhysics.h b/test/Physics/Include/LolPhysics.h index 745969c4..7958d731 100644 --- a/test/Physics/Include/LolPhysics.h +++ b/test/Physics/Include/LolPhysics.h @@ -9,8 +9,10 @@ #define __LOLPHYSICS_H__ #ifdef HAVE_PHYS_USE_BULLET +#include #include #include +#include #include "LolBtPhysicsIntegration.h" #include "EasyPhysics.h" #include "EasyConstraint.h" @@ -22,6 +24,42 @@ namespace lol namespace phys { +enum eRaycastType +{ + ERT_Closest, + ERT_AllHit, + ERT_AnyHit, //Will stop at the first hit. Hit data are supposed to be irrelevant + + ERT_MAX +}; + +struct RayCastResult +{ + RayCastResult(int CollisionFilterGroup=1, int CollisionFilterMask=(0xFF)) + { + memset(this, 0, sizeof(RayCastResult)); + + m_collision_filter_group = CollisionFilterGroup; + m_collision_filter_mask = CollisionFilterMask; + } + void Reset() + { + m_collider_list.Empty(); + m_hit_normal_list.Empty(); + m_hit_point_list.Empty(); + m_hit_fraction_list.Empty(); + } + + Array m_collider_list; + Array m_hit_normal_list; + Array m_hit_point_list; + Array m_hit_fraction_list; + + short int m_collision_filter_group; + short int m_collision_filter_mask; + unsigned int m_flags; //??? +}; + class Simulation : public Entity { public: @@ -33,6 +71,7 @@ public: m_dynamics_world(0), m_timestep(1.f/60.f) { + m_gamegroup = GAMEGROUP_SIMULATION; } ~Simulation() { @@ -79,6 +118,111 @@ public: } } + //Reap-Off of the btKinematicClosestNotMeRayResultCallback + class LolClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback + { + public: + LolClosestNotMeRayResultCallback(btCollisionObject* Me, const btVector3& rayFromWorld, const btVector3& rayToWorld) : + btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld) + { + 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: + btCollisionObject* m_me; + }; + + //Will stop at the first hit. Hit data are supposed to be irrelevant + class AnyHitRayResultCallback : public btCollisionWorld::ClosestRayResultCallback + { + public: + AnyHitRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld) : + btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld) + { + } + + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) + { + return .0f; + } + }; + + //Returns true when hitting something. If SourceCaster is set, it will be ignored by Raycast. + bool RayHits(RayCastResult& HitResult, eRaycastType RaycastType, const vec3& RayFrom, const vec3& RayTo, EasyPhysic* SourceCaster=NULL) + { + bool bResult = false; + + btCollisionWorld::RayResultCallback* BtRayResult = NULL; + btCollisionWorld::ClosestRayResultCallback* BtRayResult_Closest; + btCollisionWorld::AllHitsRayResultCallback* BtRayResult_AllHits; + + switch (RaycastType) + { + case ERT_Closest: + { + if (SourceCaster) + BtRayResult_Closest = new LolClosestNotMeRayResultCallback(SourceCaster->m_collision_object, LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo)); + else + BtRayResult_Closest = new btCollisionWorld::ClosestRayResultCallback(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo)); + BtRayResult = BtRayResult_Closest; + break; + } + case ERT_AllHit: + { + BtRayResult_AllHits = new btCollisionWorld::AllHitsRayResultCallback(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo)); + BtRayResult = BtRayResult_AllHits; + break; + } + case ERT_AnyHit: + { + BtRayResult_Closest = new AnyHitRayResultCallback(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo)); + BtRayResult = BtRayResult_Closest; + break; + } + } + + m_dynamics_world->rayTest(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo), *BtRayResult); + if (BtRayResult->hasHit()) + { + bResult = true; + + switch (RaycastType) + { + case ERT_Closest: + { + HitResult.m_collider_list << (EasyPhysic*)BtRayResult_Closest->m_collisionObject->getUserPointer(); + HitResult.m_hit_normal_list << BT2LOLU_VEC3(BtRayResult_Closest->m_hitNormalWorld); + HitResult.m_hit_point_list << BT2LOLU_VEC3(BtRayResult_Closest->m_hitPointWorld); + HitResult.m_hit_fraction_list << BtRayResult_Closest->m_closestHitFraction; + break; + } + case ERT_AllHit: + { + for (int i = 0; i < BtRayResult_AllHits->m_collisionObjects.size(); i++) + { + HitResult.m_collider_list << (EasyPhysic*)BtRayResult_AllHits->m_collisionObjects[i]->getUserPointer(); + HitResult.m_hit_normal_list << BT2LOLU_VEC3(BtRayResult_AllHits->m_hitNormalWorld[i]); + HitResult.m_hit_point_list << BT2LOLU_VEC3(BtRayResult_AllHits->m_hitPointWorld[i]); + HitResult.m_hit_fraction_list << BtRayResult_AllHits->m_hitFractions[i]; + } + break; + } + } + } + + delete BtRayResult; + + return bResult; + } + + void Exit() { delete m_dynamics_world; @@ -128,6 +272,7 @@ private: public: void Init() { } void TickGame(float seconds) { } + bool RayHits(RayCastResult& HitResult, eRaycastType RaycastType, const vec3& RayFrom, const vec3& RayTo, EasyPhysic* SourceCaster=NULL) { return false; } void Exit() { } private: void CustomSetContinuousDetection(bool ShouldUseCCD) { } diff --git a/test/Physics/Src/EasyCharacterController.cpp b/test/Physics/Src/EasyCharacterController.cpp index d0221f19..0855d824 100644 --- a/test/Physics/Src/EasyCharacterController.cpp +++ b/test/Physics/Src/EasyCharacterController.cpp @@ -36,7 +36,7 @@ void EasyCharacterController::InitBodyToRigid(bool ZeroMassIsKinematic) } //Return correct Ghost Object -btGhostObject* EasyCharacterController::GetGhostObject() +btGhostObject* EasyCharacterController::GetGhostObjectInstance() { return new btPairCachingGhostObject(); } @@ -63,6 +63,7 @@ void EasyCharacterController::AddToSimulation(class Simulation* current_simulati m_character = new btKinematicCharacterController(m_pair_caching_object, m_convex_shape, m_step_height, m_up_axis); dynamics_world->addAction(m_character); + Ticker::Ref(this); } } @@ -75,14 +76,50 @@ void EasyCharacterController::RemoveFromSimulation(class Simulation* current_sim if (dynamics_world) { if (m_character) + { dynamics_world->removeAction(m_character); + Ticker::Unref(this); + } } } //Set movement for this frame void EasyCharacterController::SetMovementForFrame(vec3 const &MoveQuantity) { - m_character->setWalkDirection(LOL2BT_VEC3(MoveQuantity)); + m_frame_cached_movement = MoveQuantity; +} + +//------------------------------------------------------------------------- +//Base Location/Rotation setup +//-- +void EasyCharacterController::SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation) +{ + if (m_base_is_updating) + { + m_base_cached_movement = base_location - m_local_to_world.v3.xyz; + m_local_to_world = lol::mat4::translate(m_local_to_world.v3.xyz) * lol::mat4(base_rotation); + if (m_ghost_object) + m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * m_local_to_world.v3.xyz))); + } + else + EasyPhysic::SetTransform(base_location, base_rotation); +} + +//Internal callback when Base transform has changed. +void EasyCharacterController::BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix) +{ + m_base_is_updating = true; + EasyPhysic::BaseTransformChanged(PreviousMatrix, NewMatrix); + m_base_is_updating = false; +} + +//Physic Tick +void EasyCharacterController::TickGame(float seconds) +{ + Entity::TickGame(seconds); + + m_character->setVelocityForTimeInterval(LOL2BT_VEC3(LOL2BT_UNIT * /*0.1f **/ (m_base_cached_movement + m_frame_cached_movement)) / seconds, seconds); + //m_character->setWalkDirection(); } #endif // HAVE_PHYS_USE_BULLET diff --git a/test/Physics/Src/EasyPhysics.cpp b/test/Physics/Src/EasyPhysics.cpp index 8fe6fdd5..7e796b7d 100644 --- a/test/Physics/Src/EasyPhysics.cpp +++ b/test/Physics/Src/EasyPhysics.cpp @@ -40,7 +40,8 @@ EasyPhysic::EasyPhysic(WorldEntity* NewOwnerEntity) : m_mass(.0f), m_collision_group(1), m_collision_mask(1), - m_owner_entity(NewOwnerEntity) + m_owner_entity(NewOwnerEntity), + m_base_physic(NULL) { } @@ -112,26 +113,45 @@ void EasyPhysic::SetShapeToCapsule(float radius, float height) //------------------------------------------------------------------------- //Base Location/Rotation setup //-- + +//Getter +mat4 EasyPhysic::GetTransform() +{ + m_local_to_world = lol::mat4(1.0f); + if (m_rigid_body && m_motion_state) + { + btTransform CurTransform; + m_motion_state->getWorldTransform(CurTransform); + CurTransform.getOpenGLMatrix(&m_local_to_world[0][0]); + } + else if (m_collision_object) + m_collision_object->getWorldTransform().getOpenGLMatrix(&m_local_to_world[0][0]); + return m_local_to_world; +} + +//Setter void EasyPhysic::SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation) { lol::mat4 PreviousMatrix = m_local_to_world; m_local_to_world = lol::mat4::translate(base_location) * lol::mat4(base_rotation); if (m_ghost_object) - m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT))); + m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * base_location))); else { if (m_motion_state) - m_motion_state->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT))); + m_motion_state->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * base_location))); else - m_motion_state = new btDefaultMotionState(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT))); + m_motion_state = new btDefaultMotionState(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * base_location))); } for (int i = 0; i < m_based_physic_list.Count(); i++) + { if (m_based_physic_list[i]) m_based_physic_list[i]->BaseTransformChanged(PreviousMatrix, m_local_to_world); else m_based_physic_list.Remove(i--); + } } //Internal callback when Base transform has changed. @@ -196,7 +216,7 @@ void EasyPhysic::InitBodyToRigid(bool SetToKinematic) } //Return correct Ghost Object -btGhostObject* EasyPhysic::GetGhostObject() +btGhostObject* EasyPhysic::GetGhostObjectInstance() { return new btGhostObject(); } @@ -207,7 +227,7 @@ void EasyPhysic::InitBodyToGhost() if (m_collision_object) delete m_collision_object; - m_ghost_object = GetGhostObject(); + m_ghost_object = GetGhostObjectInstance(); m_ghost_object->setCollisionShape(m_collision_shape); m_collision_object = m_ghost_object; m_collision_object->setUserPointer(this); @@ -294,24 +314,6 @@ void EasyPhysic::RemoveFromSimulation(class Simulation* current_simulation) } } -//------------------------------------------------------------------------- -//Getter functons -//-- - -mat4 EasyPhysic::GetTransform() -{ - m_local_to_world = lol::mat4(1.0f); - if (m_rigid_body && m_motion_state) - { - btTransform CurTransform; - m_motion_state->getWorldTransform(CurTransform); - CurTransform.getOpenGLMatrix(&m_local_to_world[0][0]); - } - else if (m_collision_object) - m_collision_object->getWorldTransform().getOpenGLMatrix(&m_local_to_world[0][0]); - return m_local_to_world; -} - //Set Local Inertia void EasyPhysic::SetLocalInertia(float mass) {