PhysicsWorld.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. //
  2. // Copyright (c) 2008-2015 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "../Container/HashSet.h"
  24. #include "../IO/VectorBuffer.h"
  25. #include "../Math/BoundingBox.h"
  26. #include "../Math/Sphere.h"
  27. #include "../Math/Vector3.h"
  28. #include "../Scene/Component.h"
  29. #include <Bullet/src/LinearMath/btIDebugDraw.h>
  30. class btCollisionConfiguration;
  31. class btCollisionShape;
  32. class btBroadphaseInterface;
  33. class btConstraintSolver;
  34. class btDiscreteDynamicsWorld;
  35. class btDispatcher;
  36. class btDynamicsWorld;
  37. class btPersistentManifold;
  38. namespace Atomic
  39. {
  40. class CollisionShape;
  41. class Deserializer;
  42. class Constraint;
  43. class Model;
  44. class Node;
  45. class Ray;
  46. class RigidBody;
  47. class Scene;
  48. class Serializer;
  49. class XMLElement;
  50. struct CollisionGeometryData;
  51. /// Physics raycast hit.
  52. struct ATOMIC_API PhysicsRaycastResult
  53. {
  54. /// Construct with defaults.
  55. PhysicsRaycastResult() :
  56. body_(0)
  57. {
  58. }
  59. /// Test for inequality, added to prevent GCC from complaining.
  60. bool operator !=(const PhysicsRaycastResult& rhs) const
  61. {
  62. return position_ != rhs.position_ || normal_ != rhs.normal_ || distance_ != rhs.distance_ || body_ != rhs.body_;
  63. }
  64. /// Hit worldspace position.
  65. Vector3 position_;
  66. /// Hit worldspace normal.
  67. Vector3 normal_;
  68. /// Hit distance from ray origin.
  69. float distance_;
  70. /// Rigid body that was hit.
  71. RigidBody* body_;
  72. };
  73. /// Delayed world transform assignment for parented rigidbodies.
  74. struct DelayedWorldTransform
  75. {
  76. /// Rigid body.
  77. RigidBody* rigidBody_;
  78. /// Parent rigid body.
  79. RigidBody* parentRigidBody_;
  80. /// New world position.
  81. Vector3 worldPosition_;
  82. /// New world rotation.
  83. Quaternion worldRotation_;
  84. };
  85. static const float DEFAULT_MAX_NETWORK_ANGULAR_VELOCITY = 100.0f;
  86. /// Physics simulation world component. Should be added only to the root scene node.
  87. class ATOMIC_API PhysicsWorld : public Component, public btIDebugDraw
  88. {
  89. OBJECT(PhysicsWorld);
  90. friend void InternalPreTickCallback(btDynamicsWorld* world, btScalar timeStep);
  91. friend void InternalTickCallback(btDynamicsWorld* world, btScalar timeStep);
  92. public:
  93. /// Construct.
  94. PhysicsWorld(Context* scontext);
  95. /// Destruct.
  96. virtual ~PhysicsWorld();
  97. /// Register object factory.
  98. static void RegisterObject(Context* context);
  99. /// Check if an AABB is visible for debug drawing.
  100. virtual bool isVisible(const btVector3& aabbMin, const btVector3& aabbMax);
  101. /// Draw a physics debug line.
  102. virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& color);
  103. /// Log warning from the physics engine.
  104. virtual void reportErrorWarning(const char* warningString);
  105. /// Draw a physics debug contact point. Not implemented.
  106. virtual void drawContactPoint
  107. (const btVector3& pointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color);
  108. /// Draw physics debug 3D text. Not implemented.
  109. virtual void draw3dText(const btVector3& location, const char* textString);
  110. /// Set debug draw flags.
  111. virtual void setDebugMode(int debugMode) { debugMode_ = debugMode; }
  112. /// Return debug draw flags.
  113. virtual int getDebugMode() const { return debugMode_; }
  114. /// Visualize the component as debug geometry.
  115. virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
  116. /// Step the simulation forward.
  117. void Update(float timeStep);
  118. /// Refresh collisions only without updating dynamics.
  119. void UpdateCollisions();
  120. /// Set simulation substeps per second.
  121. void SetFps(int fps);
  122. /// Set gravity.
  123. void SetGravity(const Vector3& gravity);
  124. /// Set maximum number of physics substeps per frame. 0 (default) is unlimited. Positive values cap the amount. Use a negative value to enable an adaptive timestep. This may cause inconsistent physics behavior.
  125. void SetMaxSubSteps(int num);
  126. /// Set number of constraint solver iterations.
  127. void SetNumIterations(int num);
  128. /// Set whether to interpolate between simulation steps.
  129. void SetInterpolation(bool enable);
  130. /// Set whether to use Bullet's internal edge utility for trimesh collisions. Disabled by default.
  131. void SetInternalEdge(bool enable);
  132. /// Set split impulse collision mode. This is more accurate, but slower. Disabled by default.
  133. void SetSplitImpulse(bool enable);
  134. /// Set maximum angular velocity for network replication.
  135. void SetMaxNetworkAngularVelocity(float velocity);
  136. /// Perform a physics world raycast and return all hits.
  137. void Raycast
  138. (PODVector<PhysicsRaycastResult>& result, const Ray& ray, float maxDistance, unsigned collisionMask = M_MAX_UNSIGNED);
  139. /// Perform a physics world raycast and return the closest hit.
  140. void RaycastSingle(PhysicsRaycastResult& result, const Ray& ray, float maxDistance, unsigned collisionMask = M_MAX_UNSIGNED);
  141. /// Perform a physics world swept sphere test and return the closest hit.
  142. void SphereCast
  143. (PhysicsRaycastResult& result, const Ray& ray, float radius, float maxDistance, unsigned collisionMask = M_MAX_UNSIGNED);
  144. /// Perform a physics world swept convex test using a user-supplied collision shape and return the first hit.
  145. void ConvexCast(PhysicsRaycastResult& result, CollisionShape* shape, const Vector3& startPos, const Quaternion& startRot,
  146. const Vector3& endPos, const Quaternion& endRot, unsigned collisionMask = M_MAX_UNSIGNED);
  147. /// Perform a physics world swept convex test using a user-supplied Bullet collision shape and return the first hit.
  148. void ConvexCast(PhysicsRaycastResult& result, btCollisionShape* shape, const Vector3& startPos, const Quaternion& startRot,
  149. const Vector3& endPos, const Quaternion& endRot, unsigned collisionMask = M_MAX_UNSIGNED);
  150. /// Invalidate cached collision geometry for a model.
  151. void RemoveCachedGeometry(Model* model);
  152. /// Return rigid bodies by a sphere query.
  153. void GetRigidBodies(PODVector<RigidBody*>& result, const Sphere& sphere, unsigned collisionMask = M_MAX_UNSIGNED);
  154. /// Return rigid bodies by a box query.
  155. void GetRigidBodies(PODVector<RigidBody*>& result, const BoundingBox& box, unsigned collisionMask = M_MAX_UNSIGNED);
  156. /// Return rigid bodies that have been in collision with a specific body on the last simulation step.
  157. void GetRigidBodies(PODVector<RigidBody*>& result, const RigidBody* body);
  158. /// Return gravity.
  159. Vector3 GetGravity() const;
  160. /// Return maximum number of physics substeps per frame.
  161. int GetMaxSubSteps() const { return maxSubSteps_; }
  162. /// Return number of constraint solver iterations.
  163. int GetNumIterations() const;
  164. /// Return whether interpolation between simulation steps is enabled.
  165. bool GetInterpolation() const { return interpolation_; }
  166. /// Return whether Bullet's internal edge utility for trimesh collisions is enabled.
  167. bool GetInternalEdge() const { return internalEdge_; }
  168. /// Return whether split impulse collision mode is enabled.
  169. bool GetSplitImpulse() const;
  170. /// Return simulation steps per second.
  171. int GetFps() const { return fps_; }
  172. /// Return maximum angular velocity for network replication.
  173. float GetMaxNetworkAngularVelocity() const { return maxNetworkAngularVelocity_; }
  174. /// Add a rigid body to keep track of. Called by RigidBody.
  175. void AddRigidBody(RigidBody* body);
  176. /// Remove a rigid body. Called by RigidBody.
  177. void RemoveRigidBody(RigidBody* body);
  178. /// Add a collision shape to keep track of. Called by CollisionShape.
  179. void AddCollisionShape(CollisionShape* shape);
  180. /// Remove a collision shape. Called by CollisionShape.
  181. void RemoveCollisionShape(CollisionShape* shape);
  182. /// Add a constraint to keep track of. Called by Constraint.
  183. void AddConstraint(Constraint* joint);
  184. /// Remove a constraint. Called by Constraint.
  185. void RemoveConstraint(Constraint* joint);
  186. /// Add a delayed world transform assignment. Called by RigidBody.
  187. void AddDelayedWorldTransform(const DelayedWorldTransform& transform);
  188. /// Add debug geometry to the debug renderer.
  189. void DrawDebugGeometry(bool depthTest);
  190. /// Set debug renderer to use. Called both by PhysicsWorld itself and physics components.
  191. void SetDebugRenderer(DebugRenderer* debug);
  192. /// Set debug geometry depth test mode. Called both by PhysicsWorld itself and physics components.
  193. void SetDebugDepthTest(bool enable);
  194. /// Return the Bullet physics world.
  195. btDiscreteDynamicsWorld* GetWorld() { return world_; }
  196. /// Clean up the geometry cache.
  197. void CleanupGeometryCache();
  198. /// Return trimesh collision geometry cache.
  199. HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> >& GetTriMeshCache() { return triMeshCache_; }
  200. /// Return convex collision geometry cache.
  201. HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> >& GetConvexCache() { return convexCache_; }
  202. /// Set node dirtying to be disregarded.
  203. void SetApplyingTransforms(bool enable) { applyingTransforms_ = enable; }
  204. /// Return whether node dirtying should be disregarded.
  205. bool IsApplyingTransforms() const { return applyingTransforms_; }
  206. protected:
  207. /// Handle scene being assigned.
  208. virtual void OnSceneSet(Scene* scene);
  209. private:
  210. /// Handle the scene subsystem update event, step simulation here.
  211. void HandleSceneSubsystemUpdate(StringHash eventType, VariantMap& eventData);
  212. /// Trigger update before each physics simulation step.
  213. void PreStep(float timeStep);
  214. /// Trigger update after each physics simulation step.
  215. void PostStep(float timeStep);
  216. /// Send accumulated collision events.
  217. void SendCollisionEvents();
  218. /// Bullet collision configuration.
  219. btCollisionConfiguration* collisionConfiguration_;
  220. /// Bullet collision dispatcher.
  221. btDispatcher* collisionDispatcher_;
  222. /// Bullet collision broadphase.
  223. btBroadphaseInterface* broadphase_;
  224. /// Bullet constraint solver.
  225. btConstraintSolver* solver_;
  226. /// Bullet physics world.
  227. btDiscreteDynamicsWorld* world_;
  228. /// Extra weak pointer to scene to allow for cleanup in case the world is destroyed before other components.
  229. WeakPtr<Scene> scene_;
  230. /// Rigid bodies in the world.
  231. PODVector<RigidBody*> rigidBodies_;
  232. /// Collision shapes in the world.
  233. PODVector<CollisionShape*> collisionShapes_;
  234. /// Constraints in the world.
  235. PODVector<Constraint*> constraints_;
  236. /// Collision pairs on this frame.
  237. HashMap<Pair<WeakPtr<RigidBody>, WeakPtr<RigidBody> >, btPersistentManifold*> currentCollisions_;
  238. /// Collision pairs on the previous frame. Used to check if a collision is "new." Manifolds are not guaranteed to exist anymore.
  239. HashMap<Pair<WeakPtr<RigidBody>, WeakPtr<RigidBody> >, btPersistentManifold*> previousCollisions_;
  240. /// Delayed (parented) world transform assignments.
  241. HashMap<RigidBody*, DelayedWorldTransform> delayedWorldTransforms_;
  242. /// Cache for trimesh geometry data by model and LOD level.
  243. HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> > triMeshCache_;
  244. /// Cache for convex geometry data by model and LOD level.
  245. HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> > convexCache_;
  246. /// Preallocated event data map for physics collision events.
  247. VariantMap physicsCollisionData_;
  248. /// Preallocated event data map for node collision events.
  249. VariantMap nodeCollisionData_;
  250. /// Preallocated buffer for physics collision contact data.
  251. VectorBuffer contacts_;
  252. /// Simulation substeps per second.
  253. unsigned fps_;
  254. /// Maximum number of simulation substeps per frame. 0 (default) unlimited, or negative values for adaptive timestep.
  255. int maxSubSteps_;
  256. /// Time accumulator for non-interpolated mode.
  257. float timeAcc_;
  258. /// Maximum angular velocity for network replication.
  259. float maxNetworkAngularVelocity_;
  260. /// Interpolation flag.
  261. bool interpolation_;
  262. /// Use internal edge utility flag.
  263. bool internalEdge_;
  264. /// Applying transforms flag.
  265. bool applyingTransforms_;
  266. /// Debug renderer.
  267. DebugRenderer* debugRenderer_;
  268. /// Debug draw flags.
  269. int debugMode_;
  270. /// Debug draw depth test mode.
  271. bool debugDepthTest_;
  272. };
  273. /// Register Physics library objects.
  274. void ATOMIC_API RegisterPhysicsLibrary(Context* context);
  275. }