PhysicsController.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  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. class ScriptListener;
  14. /**
  15. * Defines a class for controlling game physics.
  16. */
  17. class PhysicsController
  18. {
  19. friend class Game;
  20. friend class PhysicsConstraint;
  21. friend class PhysicsRigidBody;
  22. friend class PhysicsCharacter;
  23. friend class PhysicsCollisionObject;
  24. friend class PhysicsGhostObject;
  25. public:
  26. /**
  27. * Status listener interface.
  28. */
  29. class Listener
  30. {
  31. public:
  32. /**
  33. * The type of physics status event.
  34. */
  35. enum EventType
  36. {
  37. /**
  38. * Event fired when there were no active physics objects and at least one is now active.
  39. */
  40. ACTIVATED,
  41. /**
  42. * Event fired when there are no more active physics objects in the world.
  43. */
  44. DEACTIVATED
  45. };
  46. /**
  47. * Handles when a physics world status event occurs.
  48. */
  49. virtual void statusEvent(EventType type) = 0;
  50. protected:
  51. /**
  52. * Destructor.
  53. */
  54. virtual ~Listener();
  55. };
  56. /**
  57. * Stucture that stores hit test results for ray and sweep tests.
  58. */
  59. struct HitResult
  60. {
  61. /**
  62. * The collision object that was hit.
  63. */
  64. PhysicsCollisionObject* object;
  65. /**
  66. * The point where the collision occurred, in world space.
  67. */
  68. Vector3 point;
  69. /**
  70. * The fraction (0-1) of the test distance to the collision point.
  71. */
  72. float fraction;
  73. /**
  74. * The normal vector of the collision surface, in world space.
  75. */
  76. Vector3 normal;
  77. };
  78. /**
  79. * Class that can be overridden to provide custom hit test filters for ray
  80. * and sweep tests.
  81. *
  82. * The default implementation of this class returns only the closest object
  83. * that intersects a ray of volume.
  84. */
  85. class HitFilter
  86. {
  87. public:
  88. /**
  89. * Constructor.
  90. */
  91. HitFilter();
  92. /**
  93. * Virtual destructor.
  94. */
  95. virtual ~HitFilter();
  96. /**
  97. * Called before performing a hit test with an object to determine
  98. * whether or not the object should be tested.
  99. *
  100. * @param object Object to be queried.
  101. *
  102. * @return True if the object should be filtered out, or false to include the object in the test (default).
  103. */
  104. virtual bool filter(PhysicsCollisionObject* object);
  105. /**
  106. * Called when a ray or sweep test collides with a collision object.
  107. *
  108. * Each collision object that is hit during the ray or sweep test is passed
  109. * to this method, along with details of the hit result. Returning true to
  110. * this method will continue with normal hit test processing, where only
  111. * closer objects are returned. Returning false results in this method being
  112. * called for all objects that intersect the ray or volume.
  113. *
  114. * @param result HitResult object containing information about the hit.
  115. *
  116. * @return True (default) to continue with defautl behavior where closer
  117. * objects are processed, false to process all intersecting objects.
  118. */
  119. virtual bool hit(const HitResult& result);
  120. };
  121. /**
  122. * Adds a listener to the physics controller.
  123. *
  124. * @param listener The listener to add.
  125. */
  126. void addStatusListener(PhysicsController::Listener* listener);
  127. /**
  128. * Removes a listener to the physics controller.
  129. *
  130. * @param listener The listener to remove.
  131. */
  132. void removeStatusListener(Listener* listener);
  133. /**
  134. * Adds a listener to the physics controller.
  135. *
  136. * Note: the given Lua function must have the same function signature as PhysicsController::Listener::statusEvent.
  137. *
  138. * @param function The Lua script function to use as the listener callback.
  139. */
  140. void addStatusListener(const char* function);
  141. /**
  142. * Removes a listener to the physics controller.
  143. *
  144. * @param function The Lua script function (used as a listener callback) to remove.
  145. */
  146. void removeStatusListener(const char* function);
  147. /**
  148. * Creates a fixed constraint.
  149. *
  150. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  151. * body specified the constraint applies between it and the global physics world object.
  152. * @param b The second rigid body to constrain (optional).
  153. * @return Pointer to the created PhysicsFixedConstraint object.
  154. */
  155. PhysicsFixedConstraint* createFixedConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b = NULL);
  156. /**
  157. * Creates a generic constraint so that the rigid body (or bodies) is
  158. * (are) constrained to its (their) current world position(s).
  159. *
  160. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  161. * body specified the constraint applies between it and the global physics world object.
  162. * @param b The second rigid body to constrain (optional).
  163. * @return Pointer to the created PhysicsGenericConstraint object.
  164. */
  165. PhysicsGenericConstraint* createGenericConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b = NULL);
  166. /**
  167. * Creates a generic constraint.
  168. *
  169. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  170. * body specified the constraint applies between it and the global physics world object.
  171. * @param rotationOffsetA The rotation offset for the first rigid body
  172. * (in its local space) with respect to the constraint joint.
  173. * @param translationOffsetA The translation offset for the first rigid body
  174. * (in its local space) with respect to the constraint joint.
  175. * @param b The second rigid body to constrain (optional).
  176. * @param rotationOffsetB The rotation offset for the second rigid body
  177. * (in its local space) with respect to the constraint joint (optional).
  178. * @param translationOffsetB The translation offset for the second rigid body
  179. * (in its local space) with respect to the constraint joint (optional).
  180. * @return Pointer to the created PhysicsGenericConstraint object.
  181. */
  182. PhysicsGenericConstraint* createGenericConstraint(PhysicsRigidBody* a, const Quaternion& rotationOffsetA, const Vector3& translationOffsetA,
  183. PhysicsRigidBody* b = NULL, const Quaternion& rotationOffsetB = Quaternion(), const Vector3& translationOffsetB = Vector3());
  184. /**
  185. * Creates a hinge constraint.
  186. *
  187. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  188. * body specified the constraint applies between it and the global physics world object.
  189. * @param rotationOffsetA The rotation offset for the first rigid body
  190. * (in its local space) with respect to the constraint joint.
  191. * @param translationOffsetA The translation offset for the first rigid body
  192. * (in its local space) with respect to the constraint joint.
  193. * @param b The second rigid body to constrain (optional).
  194. * @param rotationOffsetB The rotation offset for the second rigid body
  195. * (in its local space) with respect to the constraint joint (optional).
  196. * @param translationOffsetB The translation offset for the second rigid body
  197. * (in its local space) with respect to the constraint joint (optional).
  198. * @return Pointer to the created PhysicsHingeConstraint object.
  199. */
  200. PhysicsHingeConstraint* createHingeConstraint(PhysicsRigidBody* a, const Quaternion& rotationOffsetA, const Vector3& translationOffsetA,
  201. PhysicsRigidBody* b = NULL, const Quaternion& rotationOffsetB = Quaternion(), const Vector3& translationOffsetB = Vector3());
  202. /**
  203. * Creates a socket constraint so that the rigid body (or bodies) is
  204. * (are) constrained using its (their) current world position(s) for
  205. * the translation offset(s) to the constraint.
  206. *
  207. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  208. * body specified the constraint applies between it and the global physics world object.
  209. * @param b The second rigid body to constrain (optional).
  210. * @return Pointer to the created PhysicsSocketConstraint object.
  211. */
  212. PhysicsSocketConstraint* createSocketConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b = NULL);
  213. /**
  214. * Creates a socket constraint.
  215. *
  216. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  217. * body specified the constraint applies between it and the global physics world object.
  218. * @param translationOffsetA The translation offset for the first rigid body
  219. * (in its local space) with respect to the constraint joint.
  220. * @param b The second rigid body to constrain (optional).
  221. * @param translationOffsetB The translation offset for the second rigid body
  222. * (in its local space) with respect to the constraint joint (optional).
  223. * @return Pointer to the created PhysicsSocketConstraint object.
  224. */
  225. PhysicsSocketConstraint* createSocketConstraint(PhysicsRigidBody* a, const Vector3& translationOffsetA,
  226. PhysicsRigidBody* b = NULL, const Vector3& translationOffsetB = Vector3());
  227. /**
  228. * Creates a spring constraint so that the rigid body (or bodies) is
  229. * (are) constrained using its (their) current world position(s) for
  230. * the translation offset(s) to the constraint.
  231. *
  232. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  233. * body specified the constraint applies between it and the global physics world object.
  234. * @param b The second rigid body to constrain (optional).
  235. * @return Pointer to the created PhysicsSpringConstraint object.
  236. */
  237. PhysicsSpringConstraint* createSpringConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b);
  238. /**
  239. * Creates a spring constraint.
  240. *
  241. * @param a The first (possibly only) rigid body to constrain. If this is the only rigid
  242. * body specified the constraint applies between it and the global physics world object.
  243. * @param rotationOffsetA The rotation offset for the first rigid body
  244. * (in its local space) with respect to the constraint joint.
  245. * @param translationOffsetA The translation offset for the first rigid body
  246. * (in its local space) with respect to the constraint joint.
  247. * @param b The second rigid body to constrain (optional).
  248. * @param rotationOffsetB The rotation offset for the second rigid body
  249. * (in its local space) with respect to the constraint joint (optional).
  250. * @param translationOffsetB The translation offset for the second rigid body
  251. * (in its local space) with respect to the constraint joint (optional).
  252. * @return Pointer to the created PhysicsSpringConstraint object.
  253. */
  254. PhysicsSpringConstraint* createSpringConstraint(PhysicsRigidBody* a, const Quaternion& rotationOffsetA, const Vector3& translationOffsetA,
  255. PhysicsRigidBody* b, const Quaternion& rotationOffsetB, const Vector3& translationOffsetB);
  256. /**
  257. * Gets the gravity vector for the simulated physics world.
  258. *
  259. * @return The gravity vector.
  260. */
  261. const Vector3& getGravity() const;
  262. /**
  263. * Sets the gravity vector for the simulated physics world.
  264. *
  265. * @param gravity The gravity vector.
  266. */
  267. void setGravity(const Vector3& gravity);
  268. /**
  269. * Draws debugging information (rigid body outlines, etc.) using the given view projection matrix.
  270. *
  271. * @param viewProjection The view projection matrix to use when drawing.
  272. */
  273. void drawDebug(const Matrix& viewProjection);
  274. /**
  275. * Performs a ray test on the physics world.
  276. *
  277. * @param ray The ray to test intersection with.
  278. * @param distance How far along the given ray to test for intersections.
  279. * @param result Optional pointer to a HitTest structure to store the hit test result information in.
  280. * When using a default (or no) filter, this will always be the closest object hit. Otherwise, if
  281. * using a custom filter, it will be the last object passed to the HitFilter::hit method (which
  282. * is not neccessarily the closest or furthest).
  283. * @param filter Optional filter pointer used to control which objects are tested.
  284. *
  285. * @return True if the ray test collided with a physics object, false otherwise.
  286. */
  287. bool rayTest(const Ray& ray, float distance, PhysicsController::HitResult* result = NULL, PhysicsController::HitFilter* filter = NULL);
  288. /**
  289. * Performs a sweep test of the given collision object on the physics world.
  290. *
  291. * The start position of the sweep test is defined by the current world position
  292. * of the specified collision object.
  293. *
  294. * @param object The collision object to test.
  295. * @param endPosition The end position of the sweep test, in world space.
  296. * @param result Optional pointer to a HitTest structure to store the hit test result information in.
  297. * When using a default (or no) filter, this will always be the closest object hit. Otherwise, if
  298. * using a custom filter, it will be the last object passed to the HitFilter::hit method (which
  299. * is not neccessarily the closest or furthest).
  300. * @param filter Optional filter pointer used to control which objects are tested.
  301. *
  302. * @return True if the object intersects any other physics objects, false otherwise.
  303. */
  304. bool sweepTest(PhysicsCollisionObject* object, const Vector3& endPosition, PhysicsController::HitResult* result = NULL, PhysicsController::HitFilter* filter = NULL);
  305. private:
  306. /**
  307. * Internal class used to integrate with Bullet collision callbacks.
  308. */
  309. class CollisionCallback : public btCollisionWorld::ContactResultCallback
  310. {
  311. public:
  312. /**
  313. * Constructor.
  314. *
  315. * @param pc The physics controller that owns the callback.
  316. */
  317. CollisionCallback(PhysicsController* pc) : _pc(pc) {}
  318. protected:
  319. /**
  320. * Internal function used for Bullet integration (do not use or override).
  321. */
  322. btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* a, int partIdA, int indexA, const btCollisionObject* b, int partIdB, int indexB);
  323. private:
  324. PhysicsController* _pc;
  325. };
  326. // Internal constants for the collision status cache.
  327. static const int DIRTY;
  328. static const int COLLISION;
  329. static const int REGISTERED;
  330. static const int REMOVE;
  331. // Represents the collision listeners and status for a given collision pair (used by the collision status cache).
  332. struct CollisionInfo
  333. {
  334. CollisionInfo() : _status(0) { }
  335. std::vector<PhysicsCollisionObject::CollisionListener*> _listeners;
  336. int _status;
  337. };
  338. /**
  339. * Constructor.
  340. */
  341. PhysicsController();
  342. /**
  343. * Destructor.
  344. */
  345. ~PhysicsController();
  346. /**
  347. * Controller initialize.
  348. */
  349. void initialize();
  350. /**
  351. * Controller finalize.
  352. */
  353. void finalize();
  354. /**
  355. * Controller pause.
  356. */
  357. void pause();
  358. /**
  359. * Controller resume.
  360. */
  361. void resume();
  362. /**
  363. * Controller update.
  364. */
  365. void update(float elapsedTime);
  366. // Adds the given collision listener for the two given collision objects.
  367. void addCollisionListener(PhysicsCollisionObject::CollisionListener* listener, PhysicsCollisionObject* objectA, PhysicsCollisionObject* objectB);
  368. // Removes the given collision listener.
  369. void removeCollisionListener(PhysicsCollisionObject::CollisionListener* listener, PhysicsCollisionObject* objectA, PhysicsCollisionObject* objectB);
  370. // Adds the given collision object to the world.
  371. void addCollisionObject(PhysicsCollisionObject* object);
  372. // Removes the given collision object from the simulated physics world.
  373. void removeCollisionObject(PhysicsCollisionObject* object);
  374. // Gets the corresponding GamePlay object for the given Bullet object.
  375. PhysicsCollisionObject* getCollisionObject(const btCollisionObject* collisionObject) const;
  376. // Creates a collision shape for the given node and gameplay shape definition.
  377. // Populates 'centerOfMassOffset' with the correct calculated center of mass offset.
  378. PhysicsCollisionShape* createShape(Node* node, const PhysicsCollisionShape::Definition& shape, Vector3* centerOfMassOffset);
  379. // Creates a box collision shape.
  380. PhysicsCollisionShape* createBox(const Vector3& extents, const Vector3& scale);
  381. // Creates a sphere collision shape.
  382. PhysicsCollisionShape* createSphere(float radius, const Vector3& scale);
  383. // Creates a capsule collision shape.
  384. PhysicsCollisionShape* createCapsule(float radius, float height, const Vector3& scale);
  385. // Creates a heightfield collision shape.
  386. PhysicsCollisionShape* createHeightfield(Node* node, Image* image, Vector3* centerOfMassOffset);
  387. // Creates a triangle mesh collision shape.
  388. PhysicsCollisionShape* createMesh(Mesh* mesh, const Vector3& scale);
  389. // Destroys a collision shape created through PhysicsController
  390. void destroyShape(PhysicsCollisionShape* shape);
  391. // Helper function for calculating heights from heightmap (image) or heightfield data.
  392. // The worldMatrix and normalData arguments are ignored if normalResult is NULL.
  393. static float calculateHeight(float* data, unsigned int width, unsigned int height, float x, float y,
  394. const Matrix* worldMatrix = NULL, Vector3* normalData = NULL, Vector3* normalResult = NULL);
  395. // Sets up the given constraint for the given two rigid bodies.
  396. void addConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b, PhysicsConstraint* constraint);
  397. // Checks whether constraints are supported for the given rigid bodies and emits a warning if they are not.
  398. bool checkConstraintRigidBodies(PhysicsRigidBody* a, PhysicsRigidBody* b);
  399. // Removes the given constraint from the simulated physics world.
  400. void removeConstraint(PhysicsConstraint* constraint);
  401. /**
  402. * Draws Bullet debug information.
  403. * @script{ignore}
  404. */
  405. class DebugDrawer : public btIDebugDraw
  406. {
  407. public:
  408. /**
  409. * DebugVertex.
  410. * @script{ignore}
  411. */
  412. struct DebugVertex
  413. {
  414. /**
  415. * The x coordinate of the vertex.
  416. */
  417. float x;
  418. /**
  419. * The y coordinate of the vertex.
  420. */
  421. float y;
  422. /**
  423. * The z coordinate of the vertex.
  424. */
  425. float z;
  426. /**
  427. * The red color component of the vertex.
  428. */
  429. float r;
  430. /**
  431. * The green color component of the vertex.
  432. */
  433. float g;
  434. /**
  435. * The blue color component of the vertex.
  436. */
  437. float b;
  438. /**
  439. * The alpha component of the vertex.
  440. */
  441. float a;
  442. };
  443. /**
  444. * Constructor.
  445. */
  446. DebugDrawer();
  447. /**
  448. * Destructor.
  449. */
  450. ~DebugDrawer();
  451. void begin(const Matrix& viewProjection);
  452. void end();
  453. // Overridden Bullet functions from btIDebugDraw.
  454. void drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor);
  455. void drawLine(const btVector3& from, const btVector3& to, const btVector3& color);
  456. void drawContactPoint(const btVector3& pointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color);
  457. void reportErrorWarning(const char* warningString);
  458. void draw3dText(const btVector3& location, const char* textString);
  459. void setDebugMode(int mode);
  460. int getDebugMode() const;
  461. private:
  462. int _mode;
  463. const Matrix* _viewProjection;
  464. MeshBatch* _meshBatch;
  465. };
  466. btDefaultCollisionConfiguration* _collisionConfiguration;
  467. btCollisionDispatcher* _dispatcher;
  468. btBroadphaseInterface* _overlappingPairCache;
  469. btSequentialImpulseConstraintSolver* _solver;
  470. btDynamicsWorld* _world;
  471. btGhostPairCallback* _ghostPairCallback;
  472. std::vector<PhysicsCollisionShape*> _shapes;
  473. DebugDrawer* _debugDrawer;
  474. Listener::EventType _status;
  475. std::vector<Listener*>* _listeners;
  476. Vector3 _gravity;
  477. std::map<PhysicsCollisionObject::CollisionPair, CollisionInfo> _collisionStatus;
  478. CollisionCallback* _collisionCallback;
  479. std::vector<ScriptListener*>* _scriptListeners;
  480. };
  481. }
  482. #endif