PhysicsWorld.h 15 KB

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