PhysicsController.h 16 KB

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