PhysicsController.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. #ifndef PHYSICSCONTROLLER_H_
  2. #define PHYSICSCONTROLLER_H_
  3. #include "PhysicsConstraint.h"
  4. #include "PhysicsFixedConstraint.h"
  5. #include "PhysicsGenericConstraint.h"
  6. #include "PhysicsHingeConstraint.h"
  7. #include "PhysicsSocketConstraint.h"
  8. #include "PhysicsSpringConstraint.h"
  9. #include "PhysicsCollisionObject.h"
  10. #include "MeshBatch.h"
  11. namespace gameplay
  12. {
  13. /**
  14. * Defines a class for controlling game physics.
  15. */
  16. class PhysicsController : public btCollisionWorld::ContactResultCallback
  17. {
  18. friend class Game;
  19. friend class PhysicsConstraint;
  20. friend class PhysicsRigidBody;
  21. friend class PhysicsCharacter;
  22. friend class PhysicsCollisionObject;
  23. friend class PhysicsGhostObject;
  24. public:
  25. /**
  26. * Status listener interface.
  27. */
  28. class Listener
  29. {
  30. public:
  31. /**
  32. * The type of physics status event.
  33. */
  34. enum EventType
  35. {
  36. /**
  37. * Event fired when there were no active physics objects and at least one is now active.
  38. */
  39. ACTIVATED,
  40. /**
  41. * Event fired when there are no more active physics objects in the world.
  42. */
  43. DEACTIVATED
  44. };
  45. /**
  46. * Handles when a physics world status event occurs.
  47. */
  48. virtual void statusEvent(EventType type) = 0;
  49. protected:
  50. /**
  51. * Destructor.
  52. */
  53. virtual ~Listener();
  54. };
  55. /**
  56. * Stucture that stores hit test results for ray and sweep tests.
  57. */
  58. struct HitResult
  59. {
  60. /**
  61. * The collision object that was hit.
  62. */
  63. PhysicsCollisionObject* object;
  64. /**
  65. * The point where the collision occurred, in world space.
  66. */
  67. Vector3 point;
  68. /**
  69. * The fraction (0-1) of the test distance to the collision point.
  70. */
  71. float fraction;
  72. /**
  73. * The normal vector of the collision surface, in world space.
  74. */
  75. Vector3 normal;
  76. };
  77. /**
  78. * Adds a listener to the physics controller.
  79. *
  80. * @param listener The listener to add.
  81. */
  82. void addStatusListener(PhysicsController::Listener* listener);
  83. /**
  84. * Removes a listener to the physics controller.
  85. *
  86. * @param listener The listener to remove.
  87. */
  88. void removeStatusListener(Listener* listener);
  89. /**
  90. * Creates a fixed constraint.
  91. *
  92. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  93. * body specified the constraint applies between it and the global physics world object.
  94. * @param b The second rigid body to constrain (optional).
  95. * @return Pointer to the created PhysicsFixedConstraint object.
  96. */
  97. PhysicsFixedConstraint* createFixedConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b = NULL);
  98. /**
  99. * Creates a generic constraint so that the rigid body (or bodies) is
  100. * (are) constrained to its (their) current world position(s).
  101. *
  102. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  103. * body specified the constraint applies between it and the global physics world object.
  104. * @param b The second rigid body to constrain (optional).
  105. * @return Pointer to the created PhysicsGenericConstraint object.
  106. */
  107. PhysicsGenericConstraint* createGenericConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b = NULL);
  108. /**
  109. * Creates a generic constraint.
  110. *
  111. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  112. * body specified the constraint applies between it and the global physics world object.
  113. * @param rotationOffsetA The rotation offset for the first rigid body
  114. * (in its local space) with respect to the constraint joint.
  115. * @param translationOffsetA The translation offset for the first rigid body
  116. * (in its local space) with respect to the constraint joint.
  117. * @param b The second rigid body to constrain (optional).
  118. * @param rotationOffsetB The rotation offset for the second rigid body
  119. * (in its local space) with respect to the constraint joint (optional).
  120. * @param translationOffsetB The translation offset for the second rigid body
  121. * (in its local space) with respect to the constraint joint (optional).
  122. * @return Pointer to the created PhysicsGenericConstraint object.
  123. */
  124. PhysicsGenericConstraint* createGenericConstraint(PhysicsRigidBody* a, const Quaternion& rotationOffsetA, const Vector3& translationOffsetA,
  125. PhysicsRigidBody* b = NULL, const Quaternion& rotationOffsetB = Quaternion(), const Vector3& translationOffsetB = Vector3());
  126. /**
  127. * Creates a hinge constraint.
  128. *
  129. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  130. * body specified the constraint applies between it and the global physics world object.
  131. * @param rotationOffsetA The rotation offset for the first rigid body
  132. * (in its local space) with respect to the constraint joint.
  133. * @param translationOffsetA The translation offset for the first rigid body
  134. * (in its local space) with respect to the constraint joint.
  135. * @param b The second rigid body to constrain (optional).
  136. * @param rotationOffsetB The rotation offset for the second rigid body
  137. * (in its local space) with respect to the constraint joint (optional).
  138. * @param translationOffsetB The translation offset for the second rigid body
  139. * (in its local space) with respect to the constraint joint (optional).
  140. * @return Pointer to the created PhysicsHingeConstraint object.
  141. */
  142. PhysicsHingeConstraint* createHingeConstraint(PhysicsRigidBody* a, const Quaternion& rotationOffsetA, const Vector3& translationOffsetA,
  143. PhysicsRigidBody* b = NULL, const Quaternion& rotationOffsetB = Quaternion(), const Vector3& translationOffsetB = Vector3());
  144. /**
  145. * Creates a socket constraint so that the rigid body (or bodies) is
  146. * (are) constrained using its (their) current world position(s) for
  147. * the translation offset(s) to the constraint.
  148. *
  149. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  150. * body specified the constraint applies between it and the global physics world object.
  151. * @param b The second rigid body to constrain (optional).
  152. * @return Pointer to the created PhysicsSocketConstraint object.
  153. */
  154. PhysicsSocketConstraint* createSocketConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b = NULL);
  155. /**
  156. * Creates a socket constraint.
  157. *
  158. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  159. * body specified the constraint applies between it and the global physics world object.
  160. * @param translationOffsetA The translation offset for the first rigid body
  161. * (in its local space) with respect to the constraint joint.
  162. * @param b The second rigid body to constrain (optional).
  163. * @param translationOffsetB The translation offset for the second rigid body
  164. * (in its local space) with respect to the constraint joint (optional).
  165. * @return Pointer to the created PhysicsSocketConstraint object.
  166. */
  167. PhysicsSocketConstraint* createSocketConstraint(PhysicsRigidBody* a, const Vector3& translationOffsetA,
  168. PhysicsRigidBody* b = NULL, const Vector3& translationOffsetB = Vector3());
  169. /**
  170. * Creates a spring constraint so that the rigid body (or bodies) is
  171. * (are) constrained using its (their) current world position(s) for
  172. * the translation offset(s) to the constraint.
  173. *
  174. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  175. * body specified the constraint applies between it and the global physics world object.
  176. * @param b The second rigid body to constrain (optional).
  177. * @return Pointer to the created PhysicsSpringConstraint object.
  178. */
  179. PhysicsSpringConstraint* createSpringConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b);
  180. /**
  181. * Creates a spring constraint.
  182. *
  183. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  184. * body specified the constraint applies between it and the global physics world object.
  185. * @param rotationOffsetA The rotation offset for the first rigid body
  186. * (in its local space) with respect to the constraint joint.
  187. * @param translationOffsetA The translation offset for the first rigid body
  188. * (in its local space) with respect to the constraint joint.
  189. * @param b The second rigid body to constrain (optional).
  190. * @param rotationOffsetB The rotation offset for the second rigid body
  191. * (in its local space) with respect to the constraint joint (optional).
  192. * @param translationOffsetB The translation offset for the second rigid body
  193. * (in its local space) with respect to the constraint joint (optional).
  194. * @return Pointer to the created PhysicsSpringConstraint object.
  195. */
  196. PhysicsSpringConstraint* createSpringConstraint(PhysicsRigidBody* a, const Quaternion& rotationOffsetA, const Vector3& translationOffsetA,
  197. PhysicsRigidBody* b, const Quaternion& rotationOffsetB, const Vector3& translationOffsetB);
  198. /**
  199. * Gets the gravity vector for the simulated physics world.
  200. *
  201. * @return The gravity vector.
  202. */
  203. const Vector3& getGravity() const;
  204. /**
  205. * Sets the gravity vector for the simulated physics world.
  206. *
  207. * @param gravity The gravity vector.
  208. */
  209. void setGravity(const Vector3& gravity);
  210. /**
  211. * Draws debugging information (rigid body outlines, etc.) using the given view projection matrix.
  212. *
  213. * @param viewProjection The view projection matrix to use when drawing.
  214. */
  215. void drawDebug(const Matrix& viewProjection);
  216. /**
  217. * Performs a ray test on the physics world.
  218. *
  219. * @param ray The ray to test intersection with.
  220. * @param distance How far along the given ray to test for intersections.
  221. * @param result Optional pointer to a HitTest structure to store hit test result information in.
  222. * @return True if the ray test collided with a physics object, false otherwise.
  223. */
  224. bool rayTest(const Ray& ray, float distance, PhysicsController::HitResult* result = NULL);
  225. /**
  226. * Performs a sweep test of the given collision object on the physics world.
  227. *
  228. * The start position of the sweep test is defined by the current world position
  229. * of the specified collision object.
  230. *
  231. * @param object The collision object to test.
  232. * @param endPosition The end position of the sweep test, in world space.
  233. * @param result Optional pointer to a HitTest structure to store hit test result information in.
  234. * @return True if the object intersects any other physics objects, false otherwise.
  235. */
  236. bool sweepTest(PhysicsCollisionObject* object, const Vector3& endPosition, PhysicsController::HitResult* result = NULL);
  237. protected:
  238. /**
  239. * Internal function used for Bullet integration (do not use or override).
  240. */
  241. btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* a, int partIdA, int indexA, const btCollisionObject* b, int partIdB, int indexB);
  242. private:
  243. // Internal constants for the collision status cache.
  244. static const int DIRTY;
  245. static const int COLLISION;
  246. static const int REGISTERED;
  247. static const int REMOVE;
  248. // Represents the collision listeners and status for a given collision pair (used by the collision status cache).
  249. struct CollisionInfo
  250. {
  251. CollisionInfo() : _status(0) { }
  252. std::vector<PhysicsCollisionObject::CollisionListener*> _listeners;
  253. int _status;
  254. };
  255. /**
  256. * Constructor.
  257. */
  258. PhysicsController();
  259. /**
  260. * Destructor.
  261. */
  262. ~PhysicsController();
  263. /**
  264. * Controller initialize.
  265. */
  266. void initialize();
  267. /**
  268. * Controller finalize.
  269. */
  270. void finalize();
  271. /**
  272. * Controller pause.
  273. */
  274. void pause();
  275. /**
  276. * Controller resume.
  277. */
  278. void resume();
  279. /**
  280. * Controller update.
  281. */
  282. void update(long elapsedTime);
  283. // Adds the given collision listener for the two given collision objects.
  284. void addCollisionListener(PhysicsCollisionObject::CollisionListener* listener, PhysicsCollisionObject* objectA, PhysicsCollisionObject* objectB);
  285. // Removes the given collision listener.
  286. void removeCollisionListener(PhysicsCollisionObject::CollisionListener* listener, PhysicsCollisionObject* objectA, PhysicsCollisionObject* objectB);
  287. // Adds the given collision object to the world.
  288. void addCollisionObject(PhysicsCollisionObject* object);
  289. // Removes the given collision object from the simulated physics world.
  290. void removeCollisionObject(PhysicsCollisionObject* object);
  291. // Gets the corresponding GamePlay object for the given Bullet object.
  292. PhysicsCollisionObject* getCollisionObject(const btCollisionObject* collisionObject) const;
  293. // Creates a collision shape for the given node and gameplay shape definition.
  294. // Populates 'centerOfMassOffset' with the correct calculated center of mass offset.
  295. PhysicsCollisionShape* createShape(Node* node, const PhysicsCollisionShape::Definition& shape, Vector3* centerOfMassOffset);
  296. // Creates a box collision shape.
  297. PhysicsCollisionShape* createBox(const Vector3& extents, const Vector3& scale);
  298. // Creates a sphere collision shape.
  299. PhysicsCollisionShape* createSphere(float radius, const Vector3& scale);
  300. // Creates a capsule collision shape.
  301. PhysicsCollisionShape* createCapsule(float radius, float height, const Vector3& scale);
  302. // Creates a heightfield collision shape.
  303. PhysicsCollisionShape* createHeightfield(Node* node, Image* image, Vector3* centerOfMassOffset);
  304. // Creates a triangle mesh collision shape.
  305. PhysicsCollisionShape* createMesh(Mesh* mesh, const Vector3& scale);
  306. // Destroys a collision shape created through PhysicsController
  307. void destroyShape(PhysicsCollisionShape* shape);
  308. // Helper function for calculating heights from heightmap (image) or heightfield data.
  309. static float calculateHeight(float* data, unsigned int width, unsigned int height, float x, float y);
  310. // Sets up the given constraint for the given two rigid bodies.
  311. void addConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b, PhysicsConstraint* constraint);
  312. // Checks whether constraints are supported for the given rigid bodies and emits a warning if they are not.
  313. bool checkConstraintRigidBodies(PhysicsRigidBody* a, PhysicsRigidBody* b);
  314. // Removes the given constraint from the simulated physics world.
  315. void removeConstraint(PhysicsConstraint* constraint);
  316. // Draws Bullet debug information.
  317. class DebugDrawer : public btIDebugDraw
  318. {
  319. public:
  320. /**
  321. * DebugVertex.
  322. */
  323. struct DebugVertex
  324. {
  325. /**
  326. * The x coordinate of the vertex.
  327. */
  328. float x;
  329. /**
  330. * The y coordinate of the vertex.
  331. */
  332. float y;
  333. /**
  334. * The z coordinate of the vertex.
  335. */
  336. float z;
  337. /**
  338. * The red color component of the vertex.
  339. */
  340. float r;
  341. /**
  342. * The green color component of the vertex.
  343. */
  344. float g;
  345. /**
  346. * The blue color component of the vertex.
  347. */
  348. float b;
  349. /**
  350. * The alpha component of the vertex.
  351. */
  352. float a;
  353. };
  354. /**
  355. * Constructor.
  356. */
  357. DebugDrawer();
  358. /**
  359. * Destructor.
  360. */
  361. ~DebugDrawer();
  362. void begin(const Matrix& viewProjection);
  363. void end();
  364. // Overridden Bullet functions from btIDebugDraw.
  365. void drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor);
  366. void drawLine(const btVector3& from, const btVector3& to, const btVector3& color);
  367. void drawContactPoint(const btVector3& pointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color);
  368. void reportErrorWarning(const char* warningString);
  369. void draw3dText(const btVector3& location, const char* textString);
  370. void setDebugMode(int mode);
  371. int getDebugMode() const;
  372. private:
  373. int _mode;
  374. const Matrix* _viewProjection;
  375. MeshBatch* _meshBatch;
  376. };
  377. btDefaultCollisionConfiguration* _collisionConfiguration;
  378. btCollisionDispatcher* _dispatcher;
  379. btBroadphaseInterface* _overlappingPairCache;
  380. btSequentialImpulseConstraintSolver* _solver;
  381. btDynamicsWorld* _world;
  382. btGhostPairCallback* _ghostPairCallback;
  383. std::vector<PhysicsCollisionShape*> _shapes;
  384. DebugDrawer* _debugDrawer;
  385. Listener::EventType _status;
  386. std::vector<Listener*>* _listeners;
  387. Vector3 _gravity;
  388. std::map<PhysicsCollisionObject::CollisionPair, CollisionInfo> _collisionStatus;
  389. };
  390. }
  391. #endif