PhysicsWorld.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2012 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #pragma once
  24. #include "Component.h"
  25. #include "HashSet.h"
  26. #include "Vector3.h"
  27. #include <LinearMath/btIDebugDraw.h>
  28. class CollisionShape;
  29. class DebugRenderer;
  30. class Deserializer;
  31. class Joint;
  32. class Node;
  33. class Ray;
  34. class RigidBody;
  35. class Scene;
  36. class Serializer;
  37. class XMLElement;
  38. class btCollisionConfiguration;
  39. class btBroadphaseInterface;
  40. class btConstraintSolver;
  41. class btDiscreteDynamicsWorld;
  42. class btDispatcher;
  43. class btDynamicsWorld;
  44. struct CollisionGeometryData;
  45. /// Physics raycast hit.
  46. struct PhysicsRaycastResult
  47. {
  48. PhysicsRaycastResult() :
  49. body_(0)
  50. {
  51. }
  52. /// Hit position.
  53. Vector3 position_;
  54. /// Hit normal.
  55. Vector3 normal_;
  56. /// Hit distance from ray origin.
  57. float distance_;
  58. /// Rigid body that was hit.
  59. RigidBody* body_;
  60. };
  61. /// Delayed world transform assignment for parented rigidbodies.
  62. struct DelayedWorldTransform
  63. {
  64. /// Rigid body.
  65. RigidBody* rigidBody_;
  66. /// Parent rigid body.
  67. RigidBody* parentRigidBody_;
  68. /// New world position.
  69. Vector3 worldPosition_;
  70. /// New world rotation.
  71. Quaternion worldRotation_;
  72. };
  73. static const float DEFAULT_MAX_NETWORK_ANGULAR_VELOCITY = 100.0f;
  74. /// Physics simulation world component. Should be added only to the root scene node.
  75. class PhysicsWorld : public Component, public btIDebugDraw
  76. {
  77. friend void InternalPreTickCallback(btDynamicsWorld *world, btScalar timeStep);
  78. friend void InternalTickCallback(btDynamicsWorld *world, btScalar timeStep);
  79. OBJECT(PhysicsWorld);
  80. public:
  81. /// Construct.
  82. PhysicsWorld(Context* scontext);
  83. /// Destruct.
  84. virtual ~PhysicsWorld();
  85. /// Register object factory.
  86. static void RegisterObject(Context* context);
  87. /// Draw a physics debug line.
  88. virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& color);
  89. /// Log warning from the physics engine.
  90. virtual void reportErrorWarning(const char* warningString);
  91. /// Draw a physics debug contact point. Not implemented.
  92. virtual void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) {}
  93. /// Draw physics debug 3D text. Not implemented.
  94. virtual void draw3dText(const btVector3& location,const char* textString) {}
  95. /// %Set debug draw flags.
  96. virtual void setDebugMode(int debugMode) { debugMode_ = debugMode; }
  97. /// Return debug draw flags.
  98. virtual int getDebugMode() const { return debugMode_; }
  99. /// Step the simulation forward.
  100. void Update(float timeStep);
  101. /// Refresh collisions only without updating dynamics.
  102. void UpdateCollisions();
  103. /// %Set simulation steps per second.
  104. void SetFps(int fps);
  105. /// %Set gravity.
  106. void SetGravity(Vector3 gravity);
  107. /// %Set whether to interpolate between simulation steps.
  108. void SetInterpolation(bool enable);
  109. /// %Set maximum angular velocity for network replication.
  110. void SetMaxNetworkAngularVelocity(float velocity);
  111. /// %Set simulation step time accumulator.
  112. void SetTimeAccumulator(float time);
  113. /// Perform a physics world raycast and return all hits.
  114. void Raycast(PODVector<PhysicsRaycastResult>& result, const Ray& ray, float maxDistance, unsigned collisionMask =
  115. M_MAX_UNSIGNED);
  116. /// Perform a physics world raycast and return the closest hit.
  117. void RaycastSingle(PhysicsRaycastResult& result, const Ray& ray, float maxDistance, unsigned collisionMask =
  118. M_MAX_UNSIGNED);
  119. /// Perform a physics world swept sphere test and return the closest hit.
  120. void SphereCast(PhysicsRaycastResult& result, const Ray& ray, float radius, float maxDistance, unsigned collisionMask =
  121. M_MAX_UNSIGNED);
  122. /// Return gravity.
  123. Vector3 GetGravity() const;
  124. /// Return whether interpolation between simulation steps is enabled.
  125. bool GetInterpolation() const { return interpolation_; }
  126. /// Return simulation steps per second.
  127. int GetFps() const { return fps_; }
  128. /// Return maximum angular velocity for network replication.
  129. float GetMaxNetworkAngularVelocity() const { return maxNetworkAngularVelocity_; }
  130. /// Add a rigid body to keep track of. Called by RigidBody.
  131. void AddRigidBody(RigidBody* body);
  132. /// Remove a rigid body. Called by RigidBody.
  133. void RemoveRigidBody(RigidBody* body);
  134. /// Add a collision shape to keep track of. Called by CollisionShape.
  135. void AddCollisionShape(CollisionShape* shape);
  136. /// Remove a collision shape. Called by CollisionShape.
  137. void RemoveCollisionShape(CollisionShape* shape);
  138. /// Add a joint to keep track of. Called by Joint.
  139. void AddJoint(Joint* joint);
  140. /// Remove a joint. Called by Joint.
  141. void RemoveJoint(Joint* joint);
  142. /// Add a delayed world transform assignment. Called by RigidBody.
  143. void AddDelayedWorldTransform(const DelayedWorldTransform& transform);
  144. /// Add debug geometry to the debug renderer.
  145. void DrawDebugGeometry(bool depthTest);
  146. /// %Set debug renderer to use. Called both by PhysicsWorld itself and physics components.
  147. void SetDebugRenderer(DebugRenderer* debug);
  148. /// %Set debug geometry depth test mode. Called both by PhysicsWorld itself and physics components.
  149. void SetDebugDepthTest(bool enable);
  150. /// Return the Bullet physics world.
  151. btDiscreteDynamicsWorld* GetWorld() { return world_; }
  152. /// Clean up the geometry cache.
  153. void CleanupGeometryCache();
  154. /// Return the collision geometry cache.
  155. Map<String, SharedPtr<CollisionGeometryData> >& GetGeometryCache() { return geometryCache_; }
  156. protected:
  157. /// Handle node being assigned.
  158. virtual void OnNodeSet(Node* node);
  159. private:
  160. /// Handle the scene subsystem update event, step simulation here.
  161. void HandleSceneSubsystemUpdate(StringHash eventType, VariantMap& eventData);
  162. /// Trigger update before each physics simulation step.
  163. void PreStep(float timeStep);
  164. /// Trigger update after ecah physics simulation step.
  165. void PostStep(float timeStep);
  166. /// Send accumulated collision events.
  167. void SendCollisionEvents();
  168. /// Bullet collision configuration.
  169. btCollisionConfiguration* collisionConfiguration_;
  170. /// Bullet collision dispatcher.
  171. btDispatcher* collisionDispatcher_;
  172. /// Bullet collision broadphase.
  173. btBroadphaseInterface* broadphase_;
  174. /// Bullet constraint solver.
  175. btConstraintSolver* solver_;
  176. /// Bullet physics world.
  177. btDiscreteDynamicsWorld* world_;
  178. /// Extra weak pointer to scene to allow for cleanup in case the world is destroyed before other components.
  179. WeakPtr<Scene> scene_;
  180. /// Rigid bodies in the world.
  181. PODVector<RigidBody*> rigidBodies_;
  182. /// Collision shapes in the world.
  183. PODVector<CollisionShape*> collisionShapes_;
  184. /// Joints in the world.
  185. PODVector<Joint*> joints_;
  186. /// Collision pairs on this frame.
  187. HashSet<Pair<RigidBody*, RigidBody*> > currentCollisions_;
  188. /// Collision pairs on the previous frame. Used to check if a collision is "new."
  189. HashSet<Pair<RigidBody*, RigidBody*> > previousCollisions_;
  190. /// Delayed (parented) world transform assignments.
  191. HashMap<RigidBody*, DelayedWorldTransform> delayedWorldTransforms_;
  192. /// Cache for collision geometry data.
  193. Map<String, SharedPtr<CollisionGeometryData> > geometryCache_;
  194. /// Simulation steps per second.
  195. unsigned fps_;
  196. /// Time accumulator for non-interpolated mode.
  197. float timeAcc_;
  198. /// Maximum angular velocity for network replication.
  199. float maxNetworkAngularVelocity_;
  200. /// Interpolation flag.
  201. bool interpolation_;
  202. /// Debug renderer.
  203. DebugRenderer* debugRenderer_;
  204. /// Debug draw flags.
  205. int debugMode_;
  206. /// Debug draw depth test mode.
  207. bool debugDepthTest_;
  208. };
  209. /// Register Physics library objects.
  210. void RegisterPhysicsLibrary(Context* context);