PhysicsWorld.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. //
  2. // Copyright (c) 2008-2017 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. // ATOMIC BEGIN
  30. #include <Bullet/src/LinearMath/btIDebugDraw.h>
  31. // ATOMIC END
  32. class btCollisionConfiguration;
  33. class btCollisionShape;
  34. class btBroadphaseInterface;
  35. class btConstraintSolver;
  36. class btDiscreteDynamicsWorld;
  37. class btDispatcher;
  38. class btDynamicsWorld;
  39. class btPersistentManifold;
  40. namespace Atomic
  41. {
  42. class CollisionShape;
  43. class Deserializer;
  44. class Constraint;
  45. class Model;
  46. class Node;
  47. class Ray;
  48. class RigidBody;
  49. class Scene;
  50. class Serializer;
  51. class XMLElement;
  52. struct CollisionGeometryData;
  53. /// Physics raycast hit.
  54. struct ATOMIC_API PhysicsRaycastResult
  55. {
  56. /// Construct with defaults.
  57. PhysicsRaycastResult() :
  58. body_(0)
  59. {
  60. }
  61. /// Test for inequality, added to prevent GCC from complaining.
  62. bool operator !=(const PhysicsRaycastResult& rhs) const
  63. {
  64. return position_ != rhs.position_ || normal_ != rhs.normal_ || distance_ != rhs.distance_ || body_ != rhs.body_;
  65. }
  66. /// Hit worldspace position.
  67. Vector3 position_;
  68. /// Hit worldspace normal.
  69. Vector3 normal_;
  70. /// Hit distance from ray origin.
  71. float distance_;
  72. /// Hit fraction.
  73. float hitFraction_;
  74. /// Rigid body that was hit.
  75. RigidBody* body_;
  76. };
  77. /// Delayed world transform assignment for parented rigidbodies.
  78. struct DelayedWorldTransform
  79. {
  80. /// Rigid body.
  81. RigidBody* rigidBody_;
  82. /// Parent rigid body.
  83. RigidBody* parentRigidBody_;
  84. /// New world position.
  85. Vector3 worldPosition_;
  86. /// New world rotation.
  87. Quaternion worldRotation_;
  88. };
  89. /// Manifold pointers stored during collision processing.
  90. struct ManifoldPair
  91. {
  92. /// Construct with defaults.
  93. ManifoldPair() :
  94. manifold_(0),
  95. flippedManifold_(0)
  96. {
  97. }
  98. /// Manifold without the body pointers flipped.
  99. btPersistentManifold* manifold_;
  100. /// Manifold with the body pointers flipped.
  101. btPersistentManifold* flippedManifold_;
  102. };
  103. /// Custom overrides of physics internals. To use overrides, must be set before the physics component is created.
  104. struct PhysicsWorldConfig
  105. {
  106. PhysicsWorldConfig() :
  107. collisionConfig_(0)
  108. {
  109. }
  110. /// Override for the collision configuration (default btDefaultCollisionConfiguration).
  111. btCollisionConfiguration* collisionConfig_;
  112. };
  113. static const float DEFAULT_MAX_NETWORK_ANGULAR_VELOCITY = 100.0f;
  114. /// Physics simulation world component. Should be added only to the root scene node.
  115. class ATOMIC_API PhysicsWorld : public Component, public btIDebugDraw
  116. {
  117. ATOMIC_OBJECT(PhysicsWorld, Component);
  118. friend void InternalPreTickCallback(btDynamicsWorld* world, btScalar timeStep);
  119. friend void InternalTickCallback(btDynamicsWorld* world, btScalar timeStep);
  120. public:
  121. /// Construct.
  122. PhysicsWorld(Context* scontext);
  123. /// Destruct.
  124. virtual ~PhysicsWorld();
  125. /// Register object factory.
  126. static void RegisterObject(Context* context);
  127. /// Check if an AABB is visible for debug drawing.
  128. virtual bool isVisible(const btVector3& aabbMin, const btVector3& aabbMax);
  129. /// Draw a physics debug line.
  130. virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& color);
  131. /// Log warning from the physics engine.
  132. virtual void reportErrorWarning(const char* warningString);
  133. /// Draw a physics debug contact point. Not implemented.
  134. virtual void drawContactPoint
  135. (const btVector3& pointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color);
  136. /// Draw physics debug 3D text. Not implemented.
  137. virtual void draw3dText(const btVector3& location, const char* textString);
  138. /// Set debug draw flags.
  139. virtual void setDebugMode(int debugMode) { debugMode_ = debugMode; }
  140. /// Return debug draw flags.
  141. virtual int getDebugMode() const { return debugMode_; }
  142. /// Visualize the component as debug geometry.
  143. virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
  144. /// Step the simulation forward.
  145. void Update(float timeStep);
  146. /// Refresh collisions only without updating dynamics.
  147. void UpdateCollisions();
  148. /// Set simulation substeps per second.
  149. void SetFps(int fps);
  150. /// Set gravity.
  151. void SetGravity(const Vector3& gravity);
  152. /// 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.
  153. void SetMaxSubSteps(int num);
  154. /// Set number of constraint solver iterations.
  155. void SetNumIterations(int num);
  156. /// Enable or disable automatic physics simulation during scene update. Enabled by default.
  157. void SetUpdateEnabled(bool enable);
  158. /// Set whether to interpolate between simulation steps.
  159. void SetInterpolation(bool enable);
  160. /// Set whether to use Bullet's internal edge utility for trimesh collisions. Disabled by default.
  161. void SetInternalEdge(bool enable);
  162. /// Set split impulse collision mode. This is more accurate, but slower. Disabled by default.
  163. void SetSplitImpulse(bool enable);
  164. /// Set maximum angular velocity for network replication.
  165. void SetMaxNetworkAngularVelocity(float velocity);
  166. /// Perform a physics world raycast and return all hits.
  167. void Raycast
  168. (PODVector<PhysicsRaycastResult>& result, const Ray& ray, float maxDistance, unsigned collisionMask = M_MAX_UNSIGNED);
  169. /// Perform a physics world raycast and return the closest hit.
  170. void RaycastSingle(PhysicsRaycastResult& result, const Ray& ray, float maxDistance, unsigned collisionMask = M_MAX_UNSIGNED);
  171. /// Perform a physics world segmented raycast and return the closest hit. Useful for big scenes with many bodies.
  172. void RaycastSingleSegmented(PhysicsRaycastResult& result, const Ray& ray, float maxDistance, float segmentDistance, unsigned collisionMask = M_MAX_UNSIGNED);
  173. /// Perform a physics world swept sphere test and return the closest hit.
  174. void SphereCast
  175. (PhysicsRaycastResult& result, const Ray& ray, float radius, float maxDistance, unsigned collisionMask = M_MAX_UNSIGNED);
  176. /// Perform a physics world swept convex test using a user-supplied collision shape and return the first hit.
  177. void ConvexCast(PhysicsRaycastResult& result, CollisionShape* shape, const Vector3& startPos, const Quaternion& startRot,
  178. const Vector3& endPos, const Quaternion& endRot, unsigned collisionMask = M_MAX_UNSIGNED);
  179. /// Perform a physics world swept convex test using a user-supplied Bullet collision shape and return the first hit.
  180. void ConvexCast(PhysicsRaycastResult& result, btCollisionShape* shape, const Vector3& startPos, const Quaternion& startRot,
  181. const Vector3& endPos, const Quaternion& endRot, unsigned collisionMask = M_MAX_UNSIGNED);
  182. /// Invalidate cached collision geometry for a model.
  183. void RemoveCachedGeometry(Model* model);
  184. /// Return rigid bodies by a sphere query.
  185. void GetRigidBodies(PODVector<RigidBody*>& result, const Sphere& sphere, unsigned collisionMask = M_MAX_UNSIGNED);
  186. /// Return rigid bodies by a box query.
  187. void GetRigidBodies(PODVector<RigidBody*>& result, const BoundingBox& box, unsigned collisionMask = M_MAX_UNSIGNED);
  188. /// Return rigid bodies by contact test with the specified body. It needs to be active to return all contacts reliably.
  189. void GetRigidBodies(PODVector<RigidBody*>& result, const RigidBody* body);
  190. /// Return rigid bodies that have been in collision with the specified body on the last simulation step. Only returns collisions that were sent as events (depends on collision event mode) and excludes e.g. static-static collisions.
  191. void GetCollidingBodies(PODVector<RigidBody*>& result, const RigidBody* body);
  192. /// Return gravity.
  193. Vector3 GetGravity() const;
  194. /// Return maximum number of physics substeps per frame.
  195. int GetMaxSubSteps() const { return maxSubSteps_; }
  196. /// Return number of constraint solver iterations.
  197. int GetNumIterations() const;
  198. /// Return whether physics world will automatically simulate during scene update.
  199. bool IsUpdateEnabled() const { return updateEnabled_; }
  200. /// Return whether interpolation between simulation steps is enabled.
  201. bool GetInterpolation() const { return interpolation_; }
  202. /// Return whether Bullet's internal edge utility for trimesh collisions is enabled.
  203. bool GetInternalEdge() const { return internalEdge_; }
  204. /// Return whether split impulse collision mode is enabled.
  205. bool GetSplitImpulse() const;
  206. /// Return simulation steps per second.
  207. int GetFps() const { return fps_; }
  208. /// Return maximum angular velocity for network replication.
  209. float GetMaxNetworkAngularVelocity() const { return maxNetworkAngularVelocity_; }
  210. /// Add a rigid body to keep track of. Called by RigidBody.
  211. void AddRigidBody(RigidBody* body);
  212. /// Remove a rigid body. Called by RigidBody.
  213. void RemoveRigidBody(RigidBody* body);
  214. /// Add a collision shape to keep track of. Called by CollisionShape.
  215. void AddCollisionShape(CollisionShape* shape);
  216. /// Remove a collision shape. Called by CollisionShape.
  217. void RemoveCollisionShape(CollisionShape* shape);
  218. /// Add a constraint to keep track of. Called by Constraint.
  219. void AddConstraint(Constraint* joint);
  220. /// Remove a constraint. Called by Constraint.
  221. void RemoveConstraint(Constraint* joint);
  222. /// Add a delayed world transform assignment. Called by RigidBody.
  223. void AddDelayedWorldTransform(const DelayedWorldTransform& transform);
  224. /// Add debug geometry to the debug renderer.
  225. void DrawDebugGeometry(bool depthTest);
  226. /// Set debug renderer to use. Called both by PhysicsWorld itself and physics components.
  227. void SetDebugRenderer(DebugRenderer* debug);
  228. /// Set debug geometry depth test mode. Called both by PhysicsWorld itself and physics components.
  229. void SetDebugDepthTest(bool enable);
  230. /// Return the Bullet physics world.
  231. btDiscreteDynamicsWorld* GetWorld() { return world_.Get(); }
  232. /// Clean up the geometry cache.
  233. void CleanupGeometryCache();
  234. /// Return trimesh collision geometry cache.
  235. HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> >& GetTriMeshCache() { return triMeshCache_; }
  236. /// Return convex collision geometry cache.
  237. HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> >& GetConvexCache() { return convexCache_; }
  238. /// Set node dirtying to be disregarded.
  239. void SetApplyingTransforms(bool enable) { applyingTransforms_ = enable; }
  240. /// Return whether node dirtying should be disregarded.
  241. bool IsApplyingTransforms() const { return applyingTransforms_; }
  242. /// Return whether is currently inside the Bullet substep loop.
  243. bool IsSimulating() const { return simulating_; }
  244. /// Overrides of the internal configuration.
  245. static struct PhysicsWorldConfig config;
  246. protected:
  247. /// Handle scene being assigned.
  248. virtual void OnSceneSet(Scene* scene);
  249. private:
  250. /// Handle the scene subsystem update event, step simulation here.
  251. void HandleSceneSubsystemUpdate(StringHash eventType, VariantMap& eventData);
  252. /// Trigger update before each physics simulation step.
  253. void PreStep(float timeStep);
  254. /// Trigger update after each physics simulation step.
  255. void PostStep(float timeStep);
  256. /// Send accumulated collision events.
  257. void SendCollisionEvents();
  258. /// Bullet collision configuration.
  259. btCollisionConfiguration* collisionConfiguration_;
  260. /// Bullet collision dispatcher.
  261. UniquePtr<btDispatcher> collisionDispatcher_;
  262. /// Bullet collision broadphase.
  263. UniquePtr<btBroadphaseInterface> broadphase_;
  264. /// Bullet constraint solver.
  265. UniquePtr<btConstraintSolver> solver_;
  266. /// Bullet physics world.
  267. UniquePtr<btDiscreteDynamicsWorld> world_;
  268. /// Extra weak pointer to scene to allow for cleanup in case the world is destroyed before other components.
  269. WeakPtr<Scene> scene_;
  270. /// Rigid bodies in the world.
  271. PODVector<RigidBody*> rigidBodies_;
  272. /// Collision shapes in the world.
  273. PODVector<CollisionShape*> collisionShapes_;
  274. /// Constraints in the world.
  275. PODVector<Constraint*> constraints_;
  276. /// Collision pairs on this frame.
  277. HashMap<Pair<WeakPtr<RigidBody>, WeakPtr<RigidBody> >, ManifoldPair> currentCollisions_;
  278. /// Collision pairs on the previous frame. Used to check if a collision is "new." Manifolds are not guaranteed to exist anymore.
  279. HashMap<Pair<WeakPtr<RigidBody>, WeakPtr<RigidBody> >, ManifoldPair> previousCollisions_;
  280. /// Delayed (parented) world transform assignments.
  281. HashMap<RigidBody*, DelayedWorldTransform> delayedWorldTransforms_;
  282. /// Cache for trimesh geometry data by model and LOD level.
  283. HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> > triMeshCache_;
  284. /// Cache for convex geometry data by model and LOD level.
  285. HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> > convexCache_;
  286. /// Preallocated event data map for physics collision events.
  287. VariantMap physicsCollisionData_;
  288. /// Preallocated event data map for node collision events.
  289. VariantMap nodeCollisionData_;
  290. /// Preallocated buffer for physics collision contact data.
  291. VectorBuffer contacts_;
  292. /// Simulation substeps per second.
  293. unsigned fps_;
  294. /// Maximum number of simulation substeps per frame. 0 (default) unlimited, or negative values for adaptive timestep.
  295. int maxSubSteps_;
  296. /// Time accumulator for non-interpolated mode.
  297. float timeAcc_;
  298. /// Maximum angular velocity for network replication.
  299. float maxNetworkAngularVelocity_;
  300. /// Automatic simulation update enabled flag.
  301. bool updateEnabled_;
  302. /// Interpolation flag.
  303. bool interpolation_;
  304. /// Use internal edge utility flag.
  305. bool internalEdge_;
  306. /// Applying transforms flag.
  307. bool applyingTransforms_;
  308. /// Simulating flag.
  309. bool simulating_;
  310. /// Debug draw depth test mode.
  311. bool debugDepthTest_;
  312. /// Debug renderer.
  313. DebugRenderer* debugRenderer_;
  314. /// Debug draw flags.
  315. int debugMode_;
  316. };
  317. /// Register Physics library objects.
  318. void ATOMIC_API RegisterPhysicsLibrary(Context* context);
  319. }