From a93067b19a24d9bf9af1086ed0803a1eb26964fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20=E2=80=98Touky=E2=80=99=20Huet?= Date: Sun, 15 Jul 2012 10:28:41 +0000 Subject: [PATCH] Small refactor of the Phys::Simulation. Phys::Simulation is now an entity. Phys::Simulation now implements timesteps correctly. --- test/BtPhysTest.cpp | 7 ++- test/Physics/EasyPhysics.cpp | 1 + test/Physics/LolPhysics.h | 103 ++++++++++++++++++++++++----------- 3 files changed, 77 insertions(+), 34 deletions(-) diff --git a/test/BtPhysTest.cpp b/test/BtPhysTest.cpp index 2a8c4db1..dd5ab330 100644 --- a/test/BtPhysTest.cpp +++ b/test/BtPhysTest.cpp @@ -67,10 +67,12 @@ BtPhysTest::BtPhysTest(bool editor) m_ready = false; m_simulation = new Simulation(); - m_simulation->InitContext(); + m_simulation->Init(); vec3 NewGravity = vec3(.0f, -10.0f, .0f); m_simulation->SetGravity(NewGravity); m_simulation->SetContinuousDetection(true); + m_simulation->SetTimestep(1.f / 120.f); + Ticker::Ref(m_simulation); float offset = 29.5f; vec3 pos_offset = vec3(.0f, 30.f, .0f); @@ -266,8 +268,6 @@ void BtPhysTest::TickGame(float seconds) if (Input::GetButtonState(27 /*SDLK_ESCAPE*/)) Ticker::Shutdown(); - m_simulation->TickContext(seconds); - vec3 GroundBarycenter = vec3(.0f); vec3 PhysObjBarycenter = vec3(.0f); float factor = .0f; @@ -415,6 +415,7 @@ BtPhysTest::~BtPhysTest() m_physobj_list.Pop(); Ticker::Unref(CurPop); } + Ticker::Unref(m_simulation); #if 0 //Exit Physics diff --git a/test/Physics/EasyPhysics.cpp b/test/Physics/EasyPhysics.cpp index 686b7095..7d6a5e12 100644 --- a/test/Physics/EasyPhysics.cpp +++ b/test/Physics/EasyPhysics.cpp @@ -42,6 +42,7 @@ EasyPhysics::EasyPhysics() : EasyPhysics::~EasyPhysics() { + m_rigid_body = NULL; delete m_collision_object; delete m_collision_shape; delete m_motion_state; diff --git a/test/Physics/LolPhysics.h b/test/Physics/LolPhysics.h index cb6ca67a..74278a56 100644 --- a/test/Physics/LolPhysics.h +++ b/test/Physics/LolPhysics.h @@ -21,26 +21,30 @@ namespace lol namespace phys { -class Simulation +class Simulation : public Entity { + friend class EasyPhysics; + public: Simulation() : m_broadphase(0), m_collision_configuration(0), m_dispatcher(0), m_solver(0), - m_dynamics_world(0) + m_dynamics_world(0), + m_timestep(1.f/60.f) { } ~Simulation() { - ExitContext(); + Exit(); } char const *GetName() { return ""; } #ifdef HAVE_PHYS_USE_BULLET - void InitContext() +public: + void Init() { // Build the broadphase m_broadphase = new btDbvtBroadphase(); @@ -56,30 +60,18 @@ public: m_dynamics_world = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collision_configuration); } - void SetContinuousDetection(bool ShouldUseCCD) - { - if (m_dynamics_world) - m_dynamics_world->getDispatchInfo().m_useContinuous = ShouldUseCCD; - } - - void SetGravity(vec3 &NewGravity) - { - if (m_dynamics_world) - m_dynamics_world->setGravity(LOL2BT_VEC3(NewGravity)); - } - - void TickContext(float seconds) + virtual void TickGame(float seconds) { //step the simulation if (m_dynamics_world) { - int steps = (int)(seconds / 0.005f); - for (int i = 0; i < steps; i++) - m_dynamics_world->stepSimulation(seconds / steps); + //the "+1" is to have at least one Timestep and to ensure float to int .5f conversion. + int steps = (int)(seconds / m_timestep) + 1; + m_dynamics_world->stepSimulation(seconds, steps, m_timestep); } } - void ExitContext() + void Exit() { delete m_dynamics_world; delete m_solver; @@ -92,16 +84,21 @@ public: { return m_dynamics_world; } - void AddToDynamic(EasyPhysics* dynamic_EP) + +private: + void CustomSetContinuousDetection(bool ShouldUseCCD) { - m_dynamic_list << dynamic_EP; + if (m_dynamics_world) + m_dynamics_world->getDispatchInfo().m_useContinuous = ShouldUseCCD; } - void AddToStatic(EasyPhysics* static_EP) + + void CustomSetGravity(vec3 &NewGravity) { - m_static_list << static_EP; + if (m_dynamics_world) + m_dynamics_world->setGravity(LOL2BT_VEC3(NewGravity)); } -private: + void CustomSetTimestep(float NewTimestep) { } //broadphase btBroadphaseInterface* m_broadphase; @@ -112,15 +109,59 @@ private: btSequentialImpulseConstraintSolver* m_solver; // The world. btDiscreteDynamicsWorld* m_dynamics_world; +#else +public: + void Init() { } + void TickGame(float seconds) { } + void Exit() { } +private: + void CustomSetContinuousDetection(bool ShouldUseCCD) { } + void CustomSetGravity(vec3 &NewGravity) { } + void CustomSetTimestep(float NewTimestep) { } +#endif //HAVE_PHYS_USE_BULLET + +public: + //Main logic : + //The Set*() functions do the all-lib-independent data storage. + //And then it calls the CustomSet*() which are the specialized versions. + + //Sets the continuous collision detection flag. + void SetContinuousDetection(bool ShouldUseCCD) + { + m_using_CCD = ShouldUseCCD; + CustomSetContinuousDetection(ShouldUseCCD); + } + + //Sets the simulation gravity. + void SetGravity(vec3 &NewGravity) + { + m_gravity = NewGravity; + CustomSetGravity(NewGravity); + } + + //Sets the simulation fixed timestep. + void SetTimestep(float NewTimestep) + { + if (NewTimestep > .0f) + { + m_timestep = NewTimestep; + CustomSetTimestep(NewTimestep); + } + } + +private: + //Adds the given EasyPhysics to the correct list. + void AddToDynamic(EasyPhysics* dynamic_EP) { m_dynamic_list << dynamic_EP; } + void AddToStatic(EasyPhysics* static_EP) { m_static_list << static_EP; } //Easy Physics body List Array m_dynamic_list; Array m_static_list; -#else - void InitContext() { } - void TickContext(float seconds) { } - void ExitContext() { } -#endif //HAVE_PHYS_USE_BULLET + + //Easy Physics data storage + float m_timestep; + bool m_using_CCD; + vec3 m_gravity; }; } /* namespace phys */