RigidBody.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. /// \file
  4. #pragma once
  5. #include "../IO/VectorBuffer.h"
  6. #include "../Scene/Component.h"
  7. #include <Bullet/LinearMath/btMotionState.h>
  8. #include <memory>
  9. class btCompoundShape;
  10. class btRigidBody;
  11. namespace Urho3D
  12. {
  13. class CollisionShape;
  14. class Constraint;
  15. class PhysicsWorld;
  16. class SmoothedTransform;
  17. /// Rigid body collision event signaling mode.
  18. enum CollisionEventMode
  19. {
  20. COLLISION_NEVER = 0,
  21. COLLISION_ACTIVE,
  22. COLLISION_ALWAYS
  23. };
  24. /// Physics rigid body component.
  25. class URHO3D_API RigidBody : public Component, public btMotionState
  26. {
  27. URHO3D_OBJECT(RigidBody, Component);
  28. public:
  29. /// Construct.
  30. explicit RigidBody(Context* context);
  31. /// Destruct. Free the rigid body and geometries.
  32. ~RigidBody() override;
  33. /// Register object factory.
  34. /// @nobind
  35. static void RegisterObject(Context* context);
  36. /// Apply attribute changes that can not be applied immediately. Called after scene load or a network update.
  37. void ApplyAttributes() override;
  38. /// Handle enabled/disabled state change.
  39. void OnSetEnabled() override;
  40. /// Return initial world transform to Bullet.
  41. /// @nobind
  42. void getWorldTransform(btTransform& worldTrans) const override;
  43. /// Update world transform from Bullet.
  44. /// @nobind
  45. void setWorldTransform(const btTransform& worldTrans) override;
  46. /// Visualize the component as debug geometry.
  47. void DrawDebugGeometry(DebugRenderer* debug, bool depthTest) override;
  48. /// Set mass. Zero mass makes the body static.
  49. /// @property
  50. void SetMass(float mass);
  51. /// Set rigid body position in world space.
  52. /// @property
  53. void SetPosition(const Vector3& position);
  54. /// Set rigid body rotation in world space.
  55. /// @property
  56. void SetRotation(const Quaternion& rotation);
  57. /// Set rigid body position and rotation in world space as an atomic operation.
  58. void SetTransform(const Vector3& position, const Quaternion& rotation);
  59. /// Set linear velocity.
  60. /// @property
  61. void SetLinearVelocity(const Vector3& velocity);
  62. /// Set linear degrees of freedom. Use 1 to enable an axis or 0 to disable. Default is all axes enabled (1, 1, 1).
  63. /// @property
  64. void SetLinearFactor(const Vector3& factor);
  65. /// Set linear velocity deactivation threshold.
  66. /// @property
  67. void SetLinearRestThreshold(float threshold);
  68. /// Set linear velocity damping factor.
  69. /// @property
  70. void SetLinearDamping(float damping);
  71. /// Set angular velocity.
  72. /// @property
  73. void SetAngularVelocity(const Vector3& velocity);
  74. /// Set angular degrees of freedom. Use 1 to enable an axis or 0 to disable. Default is all axes enabled (1, 1, 1).
  75. /// @property
  76. void SetAngularFactor(const Vector3& factor);
  77. /// Set angular velocity deactivation threshold.
  78. /// @property
  79. void SetAngularRestThreshold(float threshold);
  80. /// Set angular velocity damping factor.
  81. /// @property
  82. void SetAngularDamping(float damping);
  83. /// Set friction coefficient.
  84. /// @property
  85. void SetFriction(float friction);
  86. /// Set anisotropic friction.
  87. /// @property
  88. void SetAnisotropicFriction(const Vector3& friction);
  89. /// Set rolling friction coefficient.
  90. /// @property
  91. void SetRollingFriction(float friction);
  92. /// Set restitution coefficient.
  93. /// @property
  94. void SetRestitution(float restitution);
  95. /// Set contact processing threshold.
  96. /// @property
  97. void SetContactProcessingThreshold(float threshold);
  98. /// Set continuous collision detection swept sphere radius.
  99. /// @property
  100. void SetCcdRadius(float radius);
  101. /// Set continuous collision detection motion-per-simulation-step threshold. 0 disables, which is the default.
  102. /// @property
  103. void SetCcdMotionThreshold(float threshold);
  104. /// Set whether gravity is applied to rigid body.
  105. /// @property
  106. void SetUseGravity(bool enable);
  107. /// Set gravity override. If zero, uses physics world's gravity.
  108. /// @property
  109. void SetGravityOverride(const Vector3& gravity);
  110. /// Set rigid body kinematic mode. In kinematic mode forces are not applied to the rigid body.
  111. /// @property
  112. void SetKinematic(bool enable);
  113. /// Set rigid body trigger mode. In trigger mode collisions are reported but do not apply forces.
  114. /// @property
  115. void SetTrigger(bool enable);
  116. /// Set collision layer.
  117. /// @property
  118. void SetCollisionLayer(unsigned layer);
  119. /// Set collision mask.
  120. /// @property
  121. void SetCollisionMask(unsigned mask);
  122. /// Set collision group and mask.
  123. void SetCollisionLayerAndMask(unsigned layer, unsigned mask);
  124. /// Set collision event signaling mode. Default is to signal when rigid bodies are active.
  125. /// @property
  126. void SetCollisionEventMode(CollisionEventMode mode);
  127. /// Apply force to center of mass.
  128. void ApplyForce(const Vector3& force);
  129. /// Apply force at local position.
  130. void ApplyForce(const Vector3& force, const Vector3& position);
  131. /// Apply torque.
  132. void ApplyTorque(const Vector3& torque);
  133. /// Apply impulse to center of mass.
  134. void ApplyImpulse(const Vector3& impulse);
  135. /// Apply impulse at local position.
  136. void ApplyImpulse(const Vector3& impulse, const Vector3& position);
  137. /// Apply torque impulse.
  138. void ApplyTorqueImpulse(const Vector3& torque);
  139. /// Reset accumulated forces.
  140. void ResetForces();
  141. /// Activate rigid body if it was resting.
  142. void Activate();
  143. /// Readd rigid body to the physics world to clean up internal state like stale contacts.
  144. void ReAddBodyToWorld();
  145. /// Disable mass update. Call this to optimize performance when adding or editing multiple collision shapes in the same node.
  146. void DisableMassUpdate();
  147. /// Re-enable mass update and recalculate the mass/inertia by calling UpdateMass(). Call when collision shape changes are finished.
  148. void EnableMassUpdate();
  149. /// Return physics world.
  150. PhysicsWorld* GetPhysicsWorld() const { return physicsWorld_; }
  151. /// Return Bullet rigid body.
  152. btRigidBody* GetBody() const { return body_.get(); }
  153. /// Return Bullet compound collision shape.
  154. btCompoundShape* GetCompoundShape() const { return compoundShape_.get(); }
  155. /// Return mass.
  156. /// @property
  157. float GetMass() const { return mass_; }
  158. /// Return rigid body position in world space.
  159. /// @property
  160. Vector3 GetPosition() const;
  161. /// Return rigid body rotation in world space.
  162. /// @property
  163. Quaternion GetRotation() const;
  164. /// Return linear velocity.
  165. /// @property
  166. Vector3 GetLinearVelocity() const;
  167. /// Return linear degrees of freedom.
  168. /// @property
  169. Vector3 GetLinearFactor() const;
  170. /// Return linear velocity at local point.
  171. Vector3 GetVelocityAtPoint(const Vector3& position) const;
  172. /// Return linear velocity deactivation threshold.
  173. /// @property
  174. float GetLinearRestThreshold() const;
  175. /// Return linear velocity damping factor.
  176. /// @property
  177. float GetLinearDamping() const;
  178. /// Return angular velocity.
  179. /// @property
  180. Vector3 GetAngularVelocity() const;
  181. /// Return angular degrees of freedom.
  182. /// @property
  183. Vector3 GetAngularFactor() const;
  184. /// Return angular velocity deactivation threshold.
  185. /// @property
  186. float GetAngularRestThreshold() const;
  187. /// Return angular velocity damping factor.
  188. /// @property
  189. float GetAngularDamping() const;
  190. /// Return friction coefficient.
  191. /// @property
  192. float GetFriction() const;
  193. /// Return anisotropic friction.
  194. /// @property
  195. Vector3 GetAnisotropicFriction() const;
  196. /// Return rolling friction coefficient.
  197. /// @property
  198. float GetRollingFriction() const;
  199. /// Return restitution coefficient.
  200. /// @property
  201. float GetRestitution() const;
  202. /// Return contact processing threshold.
  203. /// @property
  204. float GetContactProcessingThreshold() const;
  205. /// Return continuous collision detection swept sphere radius.
  206. /// @property
  207. float GetCcdRadius() const;
  208. /// Return continuous collision detection motion-per-simulation-step threshold.
  209. /// @property
  210. float GetCcdMotionThreshold() const;
  211. /// Return whether rigid body uses gravity.
  212. /// @property
  213. bool GetUseGravity() const { return useGravity_; }
  214. /// Return gravity override. If zero (default), uses the physics world's gravity.
  215. /// @property
  216. const Vector3& GetGravityOverride() const { return gravityOverride_; }
  217. /// Return center of mass offset.
  218. /// @property
  219. const Vector3& GetCenterOfMass() const { return centerOfMass_; }
  220. /// Return kinematic mode flag.
  221. /// @property
  222. bool IsKinematic() const { return kinematic_; }
  223. /// Return whether this RigidBody is acting as a trigger.
  224. /// @property
  225. bool IsTrigger() const { return trigger_; }
  226. /// Return whether rigid body is active (not sleeping).
  227. /// @property
  228. bool IsActive() const;
  229. /// Return collision layer.
  230. /// @property
  231. unsigned GetCollisionLayer() const { return collisionLayer_; }
  232. /// Return collision mask.
  233. /// @property
  234. unsigned GetCollisionMask() const { return collisionMask_; }
  235. /// Return collision event signaling mode.
  236. /// @property
  237. CollisionEventMode GetCollisionEventMode() const { return collisionEventMode_; }
  238. /// Return colliding rigid bodies from the last simulation step. Only returns collisions that were sent as events (depends on collision event mode) and excludes e.g. static-static collisions.
  239. void GetCollidingBodies(Vector<RigidBody*>& result) const;
  240. /// Apply new world transform after a simulation step. Called internally.
  241. void ApplyWorldTransform(const Vector3& newWorldPosition, const Quaternion& newWorldRotation);
  242. /// Update mass and inertia to the Bullet rigid body. Readd body to world if necessary: if was in world and the Bullet collision shape to use changed.
  243. void UpdateMass();
  244. /// Update gravity parameters to the Bullet rigid body.
  245. void UpdateGravity();
  246. /// Set network angular velocity attribute.
  247. void SetNetAngularVelocityAttr(const Vector<byte>& value);
  248. /// Return network angular velocity attribute.
  249. const Vector<byte>& GetNetAngularVelocityAttr() const;
  250. /// Add a constraint that refers to this rigid body.
  251. void AddConstraint(Constraint* constraint);
  252. /// Remove a constraint that refers to this rigid body.
  253. void RemoveConstraint(Constraint* constraint);
  254. /// Remove the rigid body.
  255. void ReleaseBody();
  256. protected:
  257. /// Handle node being assigned.
  258. void OnNodeSet(Node* node) override;
  259. /// Handle scene being assigned.
  260. void OnSceneSet(Scene* scene) override;
  261. /// Handle node transform being dirtied.
  262. void OnMarkedDirty(Node* node) override;
  263. private:
  264. /// Create the rigid body, or re-add to the physics world with changed flags. Calls UpdateMass().
  265. void AddBodyToWorld();
  266. /// Remove the rigid body from the physics world.
  267. void RemoveBodyFromWorld();
  268. /// Handle SmoothedTransform target position update.
  269. void HandleTargetPosition(StringHash eventType, VariantMap& eventData);
  270. /// Handle SmoothedTransform target rotation update.
  271. void HandleTargetRotation(StringHash eventType, VariantMap& eventData);
  272. /// Mark body dirty.
  273. void MarkBodyDirty() { readdBody_ = true; }
  274. /// Bullet rigid body.
  275. std::unique_ptr<btRigidBody> body_;
  276. /// Bullet compound collision shape.
  277. std::unique_ptr<btCompoundShape> compoundShape_;
  278. /// Compound collision shape with center of mass offset applied.
  279. std::unique_ptr<btCompoundShape> shiftedCompoundShape_;
  280. /// Physics world.
  281. WeakPtr<PhysicsWorld> physicsWorld_;
  282. /// Smoothed transform, if has one.
  283. WeakPtr<SmoothedTransform> smoothedTransform_;
  284. /// Constraints that refer to this rigid body.
  285. Vector<Constraint*> constraints_;
  286. /// Gravity override vector.
  287. Vector3 gravityOverride_;
  288. /// Center of mass offset.
  289. Vector3 centerOfMass_;
  290. /// Mass.
  291. float mass_;
  292. /// Attribute buffer for network replication.
  293. mutable VectorBuffer attrBuffer_;
  294. /// Collision layer.
  295. unsigned collisionLayer_;
  296. /// Collision mask.
  297. unsigned collisionMask_;
  298. /// Collision event signaling mode.
  299. CollisionEventMode collisionEventMode_;
  300. /// Last interpolated position from the simulation.
  301. mutable Vector3 lastPosition_;
  302. /// Last interpolated rotation from the simulation.
  303. mutable Quaternion lastRotation_;
  304. /// Kinematic flag.
  305. bool kinematic_;
  306. /// Trigger flag.
  307. bool trigger_;
  308. /// Use gravity flag.
  309. bool useGravity_;
  310. /// Readd body to world flag.
  311. bool readdBody_;
  312. /// Body exists in world flag.
  313. bool inWorld_;
  314. /// Mass update enable flag.
  315. bool enableMassUpdate_;
  316. /// Internal flag whether has simulated at least once.
  317. mutable bool hasSimulated_;
  318. };
  319. }