RigidBody.h 12 KB

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