Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

206 рядки
4.9 KiB

  1. //
  2. // LolPhysics
  3. //
  4. // Copyright: (c) 2009-2012 Benjamin Huet <huet.benjamin@gmail.com>
  5. // (c) 2012 Sam Hocevar <sam@hocevar.net>
  6. //
  7. #if !defined __LOLPHYSICS_H__
  8. #define __LOLPHYSICS_H__
  9. #ifdef HAVE_PHYS_USE_BULLET
  10. #include <bullet/btBulletDynamicsCommon.h>
  11. #include <bullet/btBulletCollisionCommon.h>
  12. #include "LolBtPhysicsIntegration.h"
  13. #include "EasyPhysics.h"
  14. #endif
  15. namespace lol
  16. {
  17. namespace phys
  18. {
  19. class Simulation : public Entity
  20. {
  21. public:
  22. Simulation() :
  23. m_broadphase(0),
  24. m_collision_configuration(0),
  25. m_dispatcher(0),
  26. m_solver(0),
  27. m_dynamics_world(0),
  28. m_timestep(1.f/60.f)
  29. {
  30. }
  31. ~Simulation()
  32. {
  33. Exit();
  34. }
  35. char const *GetName() { return "<Simulation>"; }
  36. #ifdef HAVE_PHYS_USE_BULLET
  37. public:
  38. void Init()
  39. {
  40. // Build the broadphase
  41. if (1)
  42. {
  43. m_Sweep_broadphase = new btAxisSweep3(LOL2BT_VEC3(m_world_min), LOL2BT_VEC3(m_world_max));
  44. m_Sweep_broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
  45. m_broadphase = m_Sweep_broadphase;
  46. }
  47. else
  48. m_broadphase = new btDbvtBroadphase();
  49. // Set up the collision configuration and dispatcher
  50. m_collision_configuration = new btDefaultCollisionConfiguration();
  51. m_dispatcher = new btCollisionDispatcher(m_collision_configuration);
  52. // The actual physics solver
  53. m_solver = new btSequentialImpulseConstraintSolver;
  54. // The world.
  55. m_dynamics_world = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collision_configuration);
  56. }
  57. virtual void TickGame(float seconds)
  58. {
  59. Entity::TickGame(seconds);
  60. //step the simulation
  61. if (m_dynamics_world)
  62. {
  63. //the "+1" is to have at least one Timestep and to ensure float to int .5f conversion.
  64. int steps = (int)(seconds / m_timestep) + 1;
  65. m_dynamics_world->stepSimulation(seconds, steps, m_timestep);
  66. }
  67. }
  68. void Exit()
  69. {
  70. delete m_dynamics_world;
  71. delete m_solver;
  72. delete m_dispatcher;
  73. delete m_collision_configuration;
  74. delete m_broadphase;
  75. }
  76. btDiscreteDynamicsWorld* GetWorld()
  77. {
  78. return m_dynamics_world;
  79. }
  80. private:
  81. void CustomSetContinuousDetection(bool ShouldUseCCD)
  82. {
  83. if (m_dynamics_world)
  84. m_dynamics_world->getDispatchInfo().m_useContinuous = ShouldUseCCD;
  85. }
  86. void CustomSetGravity(vec3 &NewGravity)
  87. {
  88. if (m_dynamics_world)
  89. m_dynamics_world->setGravity(LOL2BT_VEC3(NewGravity * LOL2BT_UNIT));
  90. }
  91. void CustomSetWorldLimit(vec3 const &NewWorldMin, vec3 const &NewWorldMax)
  92. {
  93. }
  94. void CustomSetTimestep(float NewTimestep) { }
  95. //broadphase
  96. btBroadphaseInterface* m_broadphase;
  97. btAxisSweep3* m_Sweep_broadphase;
  98. // Set up the collision configuration and dispatc
  99. btDefaultCollisionConfiguration* m_collision_configuration;
  100. btCollisionDispatcher* m_dispatcher;
  101. // The actual physics solver
  102. btSequentialImpulseConstraintSolver* m_solver;
  103. // The world.
  104. btDiscreteDynamicsWorld* m_dynamics_world;
  105. #else // NO PHYSIC IMPLEMENTATION
  106. public:
  107. void Init() { }
  108. void TickGame(float seconds) { }
  109. void Exit() { }
  110. private:
  111. void CustomSetContinuousDetection(bool ShouldUseCCD) { }
  112. void CustomSetGravity(vec3 &NewGravity) { }
  113. void CustomSetWorldLimit(vec3 &NewWorldMin, vec3 &NewWorldMax) { }
  114. void CustomSetTimestep(float NewTimestep) { }
  115. #endif // PHYSIC IMPLEMENTATION
  116. public:
  117. //Main logic :
  118. //The Set*() functions do the all-lib-independent data storage.
  119. //And then it calls the CustomSet*() which are the specialized versions.
  120. //Sets the continuous collision detection flag.
  121. void SetContinuousDetection(bool ShouldUseCCD)
  122. {
  123. m_using_CCD = ShouldUseCCD;
  124. CustomSetContinuousDetection(ShouldUseCCD);
  125. }
  126. //Sets the simulation gravity.
  127. void SetGravity(vec3 &NewGravity)
  128. {
  129. m_gravity = NewGravity;
  130. CustomSetGravity(NewGravity);
  131. }
  132. //Sets the simulation gravity.
  133. void SetWorldLimit(vec3 const &NewWorldMin, vec3 const &NewWorldMax)
  134. {
  135. m_world_min = NewWorldMin;
  136. m_world_max = NewWorldMax;
  137. CustomSetWorldLimit(NewWorldMin, NewWorldMax);
  138. }
  139. //Sets the simulation fixed timestep.
  140. void SetTimestep(float NewTimestep)
  141. {
  142. if (NewTimestep > .0f)
  143. {
  144. m_timestep = NewTimestep;
  145. CustomSetTimestep(NewTimestep);
  146. }
  147. }
  148. private:
  149. friend class EasyPhysic;
  150. friend class EasyConstraint;
  151. //Adds the given EasyPhysic to the correct list.
  152. void AddToDynamic(EasyPhysic* NewEPDynamic) { m_dynamic_list << NewEPDynamic; }
  153. void AddToStatic(EasyPhysic* NewEPStatic) { m_static_list << NewEPStatic; }
  154. void AddToGhost(EasyPhysic* NewEPGhost) { m_ghost_list << NewEPGhost; }
  155. void AddToConstraint(EasyConstraint* NewEC) { m_constraint_list << NewEC; }
  156. //Easy Physics body List
  157. Array<EasyPhysic*> m_dynamic_list;
  158. Array<EasyPhysic*> m_static_list;
  159. Array<EasyPhysic*> m_ghost_list;
  160. Array<EasyConstraint*> m_constraint_list;
  161. //Easy Physics data storage
  162. float m_timestep;
  163. bool m_using_CCD;
  164. vec3 m_gravity;
  165. vec3 m_world_min;
  166. vec3 m_world_max;
  167. };
  168. } /* namespace phys */
  169. } /* namespace lol */
  170. #endif // __LOLPHYSICS_H__