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 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  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. m_convex_shape = new btBoxShape(LOL2BT_VEC3(new_box_size));
  66. SetShapeTo(m_convex_shape);
  67. }
  68. void EasyPhysic::SetShapeToSphere(float radius)
  69. {
  70. m_convex_shape = new btSphereShape(radius * LOL2BT_UNIT * LOL2BT_SIZE);
  71. SetShapeTo(m_convex_shape);
  72. }
  73. void EasyPhysic::SetShapeToCone(float radius, float height)
  74. {
  75. m_convex_shape = new btConeShape( radius * LOL2BT_UNIT,
  76. height * LOL2BT_UNIT);
  77. SetShapeTo(m_convex_shape);
  78. }
  79. void EasyPhysic::SetShapeToCylinder(lol::vec3& cyl_size)
  80. {
  81. vec3 new_cyl_size = cyl_size * LOL2BT_UNIT;
  82. new_cyl_size.y *= LOL2BT_SIZE;
  83. m_convex_shape = new btCylinderShape(LOL2BT_VEC3(new_cyl_size));
  84. SetShapeTo(m_convex_shape);
  85. }
  86. void EasyPhysic::SetShapeToCapsule(float radius, float height)
  87. {
  88. m_convex_shape = new btCapsuleShape(radius * LOL2BT_UNIT * LOL2BT_SIZE,
  89. height * LOL2BT_UNIT * LOL2BT_SIZE);
  90. SetShapeTo(m_convex_shape);
  91. }
  92. //-------------------------------------------------------------------------
  93. //Base Location/Rotation setup
  94. //--
  95. void EasyPhysic::SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation)
  96. {
  97. m_local_to_world = lol::mat4::translate(base_location) * mat4(base_rotation);
  98. if (m_ghost_object)
  99. m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT)));
  100. else
  101. {
  102. if (m_motion_state)
  103. m_motion_state->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT)));
  104. else
  105. m_motion_state = new btDefaultMotionState(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT)));
  106. }
  107. }
  108. //-------------------------------------------------------------------------
  109. //Mass related functions
  110. //--
  111. //Set Shape functions
  112. void EasyPhysic::SetMass(float mass)
  113. {
  114. m_mass = mass;
  115. if (m_rigid_body)
  116. {
  117. SetLocalInertia(m_mass);
  118. m_rigid_body->setMassProps(mass, m_local_inertia);
  119. }
  120. }
  121. //-------------------------------------------------------------------------
  122. //Final conversion pass functons : Body related
  123. //--
  124. //Init to rigid body
  125. void EasyPhysic::InitBodyToRigid(bool SetToKinematic)
  126. {
  127. if (m_collision_object)
  128. delete m_collision_object;
  129. if (!m_motion_state)
  130. SetTransform(vec3(.0f));
  131. btRigidBody::btRigidBodyConstructionInfo NewInfos(m_mass, m_motion_state, m_collision_shape, m_local_inertia);
  132. m_rigid_body = new btRigidBody(NewInfos);
  133. m_collision_object = m_rigid_body;
  134. if (m_mass == .0f)
  135. {
  136. if (SetToKinematic)
  137. {
  138. m_rigid_body->setActivationState(DISABLE_DEACTIVATION);
  139. m_rigid_body->setCollisionFlags(m_rigid_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
  140. }
  141. }
  142. else
  143. SetMass(m_mass);
  144. }
  145. //Return correct Ghost Object
  146. btGhostObject* EasyPhysic::GetGhostObject()
  147. {
  148. return new btGhostObject();
  149. }
  150. //Init to Ghost object, for Overlap/Sweep Test/Touching logic
  151. void EasyPhysic::InitBodyToGhost()
  152. {
  153. if (m_collision_object)
  154. delete m_collision_object;
  155. m_ghost_object = GetGhostObject();
  156. m_ghost_object->setCollisionShape(m_collision_shape);
  157. m_collision_object = m_ghost_object;
  158. SetTransform(m_local_to_world.v3.xyz, lol::quat(m_local_to_world));
  159. m_ghost_object->setCollisionFlags(m_ghost_object->getCollisionFlags());
  160. }
  161. //Add Physic object to the simulation
  162. void EasyPhysic::AddToSimulation(class Simulation* current_simulation)
  163. {
  164. btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
  165. if (dynamics_world)
  166. {
  167. if (m_ghost_object)
  168. {
  169. dynamics_world->addCollisionObject(m_ghost_object, m_collision_group, m_collision_mask);
  170. current_simulation->AddToGhost(this);
  171. }
  172. else if (m_rigid_body)
  173. {
  174. dynamics_world->addRigidBody(m_rigid_body, m_collision_group, m_collision_mask);
  175. if (m_mass != .0f)
  176. current_simulation->AddToDynamic(this);
  177. else
  178. current_simulation->AddToStatic(this);
  179. }
  180. else
  181. dynamics_world->addCollisionObject(m_collision_object, m_collision_group, m_collision_mask);
  182. }
  183. }
  184. //Remove Physic object to the simulation
  185. void EasyPhysic::RemoveFromSimulation(class Simulation* current_simulation)
  186. {
  187. btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
  188. if (dynamics_world)
  189. {
  190. if (m_rigid_body)
  191. dynamics_world->removeRigidBody(m_rigid_body);
  192. else if (m_collision_object)
  193. dynamics_world->removeCollisionObject(m_collision_object);
  194. }
  195. }
  196. //-------------------------------------------------------------------------
  197. //Getter functons
  198. //--
  199. mat4 EasyPhysic::GetTransform()
  200. {
  201. m_local_to_world = lol::mat4(1.0f);
  202. if (m_rigid_body && m_motion_state)
  203. {
  204. btTransform CurTransform;
  205. m_motion_state->getWorldTransform(CurTransform);
  206. CurTransform.getOpenGLMatrix(&m_local_to_world[0][0]);
  207. }
  208. else if (m_collision_object)
  209. m_collision_object->getWorldTransform().getOpenGLMatrix(&m_local_to_world[0][0]);
  210. return m_local_to_world;
  211. }
  212. //Set Local Inertia
  213. void EasyPhysic::SetLocalInertia(float mass)
  214. {
  215. if (mass != .0f)
  216. m_collision_shape->calculateLocalInertia(mass, m_local_inertia);
  217. else
  218. m_local_inertia = btVector3(.0f, .0f, .0f);
  219. }
  220. //-------------------------------------------------------------------------
  221. //EASY_CHARACTER_CONTROLLER
  222. //--
  223. //Deactivated for Character controller
  224. void EasyCharacterController::InitBodyToRigid(bool ZeroMassIsKinematic)
  225. {
  226. }
  227. //Return correct Ghost Object
  228. btGhostObject* EasyCharacterController::GetGhostObject()
  229. {
  230. return new btPairCachingGhostObject();
  231. }
  232. //Init to Pair caching ghost object, since Character uses that one.
  233. void EasyCharacterController::InitBodyToGhost()
  234. {
  235. EasyPhysic::InitBodyToGhost();
  236. m_pair_caching_object = (btPairCachingGhostObject*)m_ghost_object;
  237. m_ghost_object->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT | m_ghost_object->getCollisionFlags());
  238. }
  239. //Add Physic object to the simulation
  240. void EasyCharacterController::AddToSimulation(class Simulation* current_simulation)
  241. {
  242. EasyPhysic::AddToSimulation(current_simulation);
  243. btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
  244. if (dynamics_world)
  245. {
  246. if (m_character)
  247. delete m_character;
  248. m_character = new btKinematicCharacterController(m_pair_caching_object, m_convex_shape, m_step_height, m_up_axis);
  249. dynamics_world->addAction(m_character);
  250. }
  251. }
  252. //Remove Physic object to the simulation
  253. void EasyCharacterController::RemoveFromSimulation(class Simulation* current_simulation)
  254. {
  255. EasyPhysic::RemoveFromSimulation(current_simulation);
  256. btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
  257. if (dynamics_world)
  258. {
  259. if (m_character)
  260. dynamics_world->removeAction(m_character);
  261. }
  262. }
  263. //Set movement for this frame
  264. void EasyCharacterController::SetMovementForFrame(vec3 const &MoveQuantity)
  265. {
  266. m_character->setWalkDirection(LOL2BT_VEC3(MoveQuantity));
  267. }
  268. //-------------------------------------------------------------------------
  269. //EASY_CONSTRAINT
  270. //--
  271. void EasyConstraint::AddToSimulation(class Simulation* current_simulation)
  272. {
  273. btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
  274. if (dynamics_world && m_typed_constraint)
  275. {
  276. dynamics_world->addConstraint(m_typed_constraint, m_disable_a2b_collision);
  277. current_simulation->AddToConstraint(this);
  278. }
  279. }
  280. void EasyConstraint::RemoveFromSimulation(class Simulation* current_simulation)
  281. {
  282. btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
  283. if (dynamics_world, m_typed_constraint)
  284. dynamics_world->removeConstraint(m_typed_constraint);
  285. }
  286. #endif // HAVE_PHYS_USE_BULLET
  287. } /* namespace phys */
  288. } /* namespace lol */