You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net>
  5. // (c) 2009-2012 Cdric Lecacheur <jordx@free.fr>
  6. // (c) 2009-2012 Benjamin Huet <huet.benjamin@gmail.com>
  7. // This program is free software; you can redistribute it and/or
  8. // modify it under the terms of the Do What The Fuck You Want To
  9. // Public License, Version 2, as published by Sam Hocevar. See
  10. // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  11. //
  12. #if defined HAVE_CONFIG_H
  13. # include "config.h"
  14. #endif
  15. #include "LolBtPhysicsIntegration.h"
  16. #include "LolPhysics.h"
  17. namespace lol
  18. {
  19. namespace phys
  20. {
  21. #ifdef HAVE_PHYS_USE_BULLET
  22. //-------------------------------------------------------------------------
  23. //EASY_PHYSIC
  24. //--
  25. EasyPhysic::EasyPhysic() :
  26. m_collision_object(NULL),
  27. m_rigid_body(NULL),
  28. m_ghost_object(NULL),
  29. m_collision_shape(NULL),
  30. m_motion_state(NULL),
  31. m_mass(.0f),
  32. m_local_inertia(btVector3(.0f, .0f, .0f)),
  33. m_collision_group(1),
  34. m_collision_mask(1)
  35. {
  36. }
  37. EasyPhysic::~EasyPhysic()
  38. {
  39. m_rigid_body = NULL;
  40. delete m_collision_object;
  41. delete m_collision_shape;
  42. delete m_motion_state;
  43. }
  44. //-------------------------------------------------------------------------
  45. //Set Shape functions
  46. //--
  47. void EasyPhysic::SetShapeTo(btCollisionShape* collision_shape)
  48. {
  49. bool bReinitToRigidBody = false;
  50. if (m_rigid_body)
  51. {
  52. bReinitToRigidBody = true;
  53. delete m_rigid_body;
  54. }
  55. if (m_collision_shape)
  56. delete m_collision_shape;
  57. m_collision_shape = collision_shape;
  58. if (bReinitToRigidBody)
  59. InitBodyToRigid();
  60. }
  61. //Box Shape support
  62. void EasyPhysic::SetShapeToBox(lol::vec3& box_size)
  63. {
  64. vec3 new_box_size = box_size * LOL2BT_UNIT * LOL2BT_SIZE;
  65. SetShapeTo(new btBoxShape(LOL2BT_VEC3(new_box_size)));
  66. }
  67. void EasyPhysic::SetShapeToSphere(float radius)
  68. {
  69. SetShapeTo(new btSphereShape(radius * LOL2BT_UNIT * LOL2BT_SIZE));
  70. }
  71. void EasyPhysic::SetShapeToCone(float radius, float height)
  72. {
  73. SetShapeTo(new btConeShape( radius * LOL2BT_UNIT,
  74. height * LOL2BT_UNIT));
  75. }
  76. void EasyPhysic::SetShapeToCylinder(lol::vec3& cyl_size)
  77. {
  78. vec3 new_cyl_size = cyl_size * LOL2BT_UNIT;
  79. new_cyl_size.y *= LOL2BT_SIZE;
  80. SetShapeTo(new btCylinderShape(LOL2BT_VEC3(new_cyl_size)));
  81. }
  82. void EasyPhysic::SetShapeToCapsule(float radius, float height)
  83. {
  84. SetShapeTo(new btCapsuleShape( radius * LOL2BT_UNIT * LOL2BT_SIZE,
  85. height * LOL2BT_UNIT * LOL2BT_SIZE));
  86. }
  87. //-------------------------------------------------------------------------
  88. //Base Location/Rotation setup
  89. //--
  90. void EasyPhysic::SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation)
  91. {
  92. if (m_ghost_object)
  93. m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT)));
  94. else
  95. {
  96. if (m_motion_state)
  97. m_motion_state->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT)));
  98. else
  99. m_motion_state = new btDefaultMotionState(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT)));
  100. }
  101. }
  102. //-------------------------------------------------------------------------
  103. //Mass related functions
  104. //--
  105. //Set Shape functions
  106. void EasyPhysic::SetMass(float mass)
  107. {
  108. m_mass = mass;
  109. if (m_rigid_body)
  110. {
  111. SetLocalInertia(m_mass);
  112. m_rigid_body->setMassProps(mass, m_local_inertia);
  113. }
  114. }
  115. //-------------------------------------------------------------------------
  116. //Final conversion pass functons : Body related
  117. //--
  118. //Init to rigid body
  119. void EasyPhysic::InitBodyToRigid(bool SetToKinematic)
  120. {
  121. if (m_collision_object)
  122. delete m_collision_object;
  123. if (!m_motion_state)
  124. SetTransform(vec3(.0f));
  125. btRigidBody::btRigidBodyConstructionInfo NewInfos(m_mass, m_motion_state, m_collision_shape, m_local_inertia);
  126. m_rigid_body = new btRigidBody(NewInfos);
  127. m_collision_object = m_rigid_body;
  128. if (m_mass == .0f && SetToKinematic)
  129. {
  130. m_rigid_body->setActivationState(DISABLE_DEACTIVATION);
  131. m_rigid_body->setCollisionFlags(m_rigid_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
  132. }
  133. }
  134. //Init to Ghost object, for Overlap/Sweep Test/Touching logic
  135. void EasyPhysic::InitBodyToGhost()
  136. {
  137. if (m_collision_object)
  138. delete m_collision_object;
  139. m_ghost_object = new btGhostObject();
  140. m_ghost_object->setCollisionShape(m_collision_shape);
  141. m_collision_object = m_ghost_object;
  142. SetTransform(vec3(.0f));
  143. m_ghost_object->setCollisionFlags(m_ghost_object->getCollisionFlags());
  144. //btCollisionObject::CF_CHARACTER_OBJECT
  145. }
  146. //Add Physic object to the simulation
  147. void EasyPhysic::AddToSimulation(class Simulation* current_simulation)
  148. {
  149. btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
  150. if (dynamics_world)
  151. {
  152. if (m_ghost_object)
  153. {
  154. dynamics_world->addCollisionObject(m_ghost_object, m_collision_group, m_collision_mask);
  155. current_simulation->AddToGhost(this);
  156. }
  157. else if (m_rigid_body)
  158. {
  159. dynamics_world->addRigidBody(m_rigid_body, m_collision_group, m_collision_mask);
  160. if (m_mass != .0f)
  161. current_simulation->AddToDynamic(this);
  162. else
  163. current_simulation->AddToStatic(this);
  164. }
  165. else
  166. dynamics_world->addCollisionObject(m_collision_object, m_collision_group, m_collision_mask);
  167. }
  168. }
  169. //Remove Physic object to the simulation
  170. void EasyPhysic::RemoveFromSimulation(class Simulation* current_simulation)
  171. {
  172. btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
  173. if (dynamics_world)
  174. {
  175. if (m_rigid_body)
  176. dynamics_world->removeRigidBody(m_rigid_body);
  177. else
  178. dynamics_world->removeCollisionObject(m_collision_object);
  179. }
  180. }
  181. //-------------------------------------------------------------------------
  182. //Getter functons
  183. //--
  184. mat4 EasyPhysic::GetTransform()
  185. {
  186. m_local_to_world = lol::mat4(1.0f);
  187. if (m_rigid_body && m_motion_state)
  188. {
  189. btTransform CurTransform;
  190. m_motion_state->getWorldTransform(CurTransform);
  191. CurTransform.getOpenGLMatrix(&m_local_to_world[0][0]);
  192. }
  193. else if (m_collision_object)
  194. m_collision_object->getWorldTransform().getOpenGLMatrix(&m_local_to_world[0][0]);
  195. return m_local_to_world;
  196. }
  197. //Set Local Inertia
  198. void EasyPhysic::SetLocalInertia(float mass)
  199. {
  200. if (mass != .0f)
  201. m_collision_shape->calculateLocalInertia(mass, m_local_inertia);
  202. else
  203. m_local_inertia = btVector3(.0f, .0f, .0f);
  204. }
  205. //-------------------------------------------------------------------------
  206. //EASY_CHARACTER_CONTROLLER
  207. //--
  208. void EasyCharacterController::SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation)
  209. {
  210. }
  211. void EasyCharacterController::SetMass(float mass)
  212. {
  213. }
  214. void EasyCharacterController::InitBodyToRigid(bool ZeroMassIsKinematic)
  215. {
  216. }
  217. void EasyCharacterController::InitBodyToGhost()
  218. {
  219. //btCollisionObject::CF_CHARACTER_OBJECT
  220. }
  221. void EasyCharacterController::AddToSimulation(class Simulation* current_simulation)
  222. {
  223. }
  224. void EasyCharacterController::RemoveFromSimulation(class Simulation* current_simulation)
  225. {
  226. }
  227. mat4 EasyCharacterController::GetTransform()
  228. {
  229. return mat4(1.f);
  230. }
  231. //-------------------------------------------------------------------------
  232. //EASY_CONSTRAINT
  233. //--
  234. void EasyConstraint::AddToSimulation(class Simulation* current_simulation)
  235. {
  236. btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
  237. if (dynamics_world && m_typed_constraint)
  238. {
  239. dynamics_world->addConstraint(m_typed_constraint, m_disable_a2b_collision);
  240. current_simulation->AddToConstraint(this);
  241. }
  242. }
  243. void EasyConstraint::RemoveFromSimulation(class Simulation* current_simulation)
  244. {
  245. btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
  246. if (dynamics_world, m_typed_constraint)
  247. dynamics_world->removeConstraint(m_typed_constraint);
  248. }
  249. #endif // HAVE_PHYS_USE_BULLET
  250. } /* namespace phys */
  251. } /* namespace lol */