BodyInterface.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Physics/Body/BodyID.h>
  5. #include <Physics/EActivation.h>
  6. #include <Physics/Collision/ObjectLayer.h>
  7. #include <Physics/Body/MotionType.h>
  8. #include <Core/Reference.h>
  9. namespace JPH {
  10. class Body;
  11. class BodyCreationSettings;
  12. class BodyLockInterface;
  13. class BroadPhase;
  14. class BodyManager;
  15. class TransformedShape;
  16. class PhysicsMaterial;
  17. class SubShapeID;
  18. class Shape;
  19. /// Class that provides operations on bodies using a body ID. Note that if you need to do multiple operations on a single body, it is more efficient to lock the body once and combine the operations.
  20. /// All quantities are in world space unless otherwise specified.
  21. class BodyInterface : public NonCopyable
  22. {
  23. public:
  24. /// Constructor
  25. BodyInterface() = default;
  26. BodyInterface(BodyLockInterface &inBodyLockInterface, BodyManager &inBodyManager, BroadPhase &inBroadPhase) : mBodyLockInterface(&inBodyLockInterface), mBodyManager(&inBodyManager), mBroadPhase(&inBroadPhase) { }
  27. /// Create a body
  28. /// @return Created body or null when out of bodies
  29. Body * CreateBody(const BodyCreationSettings &inSettings);
  30. /// Destroy a body
  31. void DestroyBody(const BodyID &inBodyID);
  32. /// Destroy multiple bodies
  33. void DestroyBodies(const BodyID *inBodyIDs, int inNumber);
  34. /// Add body to the world.
  35. /// After adding, to get a body by ID use the BodyLockRead or BodyLockWrite interface!
  36. void AddBody(const BodyID &inBodyID, EActivation inActivationMode);
  37. /// Remove body from the world.
  38. void RemoveBody(const BodyID &inBodyID);
  39. /// Check if a body has been added to the world.
  40. bool IsAdded(const BodyID &inBodyID) const;
  41. /// Combines CreateBody and AddBody
  42. /// @return Created body ID or an invalid ID when out of bodies
  43. BodyID CreateAndAddBody(const BodyCreationSettings &inSettings, EActivation inActivationMode);
  44. /// Broadphase add state handle, used to keep track of a batch while ading to the broadphase.
  45. using AddState = void *;
  46. ///@name Batch adding interface, see Broadphase for further documentation.
  47. /// Note that ioBodies array must be kept constant while the add is in progress.
  48. ///@{
  49. AddState AddBodiesPrepare(BodyID *ioBodies, int inNumber);
  50. void AddBodiesFinalize(BodyID *ioBodies, int inNumber, AddState inAddState, EActivation inActivationMode);
  51. void AddBodiesAbort(BodyID *ioBodies, int inNumber, AddState inAddState);
  52. void RemoveBodies(BodyID *ioBodies, int inNumber);
  53. ///@}
  54. ///@name Activate / deactivate a body
  55. ///@{
  56. void ActivateBody(const BodyID &inBodyID);
  57. void ActivateBodies(const BodyID *inBodyIDs, int inNumber);
  58. void DeactivateBody(const BodyID &inBodyID);
  59. bool IsActive(const BodyID &inBodyID) const;
  60. ///@}
  61. ///@name Access to the shape of a body
  62. ///@{
  63. /// Get the current shape
  64. RefConst<Shape> GetShape(const BodyID &inBodyID) const;
  65. /// Set a new shape on the body
  66. /// @param inBodyID Body ID of body that had its shape changed
  67. /// @param inShape The new shape
  68. /// @param inUpdateMassProperties When true, the mass and inertia tensor is recalculated
  69. /// @param inActivationMode Weather or not to activate the body
  70. void SetShape(const BodyID &inBodyID, const Shape *inShape, bool inUpdateMassProperties, EActivation inActivationMode) const;
  71. /// Notify all systems to indicate that a shape has changed (usable for MutableCompoundShapes)
  72. /// @param inBodyID Body ID of body that had its shape changed
  73. /// @param inPreviousCenterOfMass Center of mass of the shape before the alterations
  74. /// @param inUpdateMassProperties When true, the mass and inertia tensor is recalculated
  75. /// @param inActivationMode Weather or not to activate the body
  76. void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inPreviousCenterOfMass, bool inUpdateMassProperties, EActivation inActivationMode) const;
  77. ///@}
  78. ///@name Object layer of a body
  79. ///@{
  80. void SetObjectLayer(const BodyID &inBodyID, ObjectLayer inLayer);
  81. ObjectLayer GetObjectLayer(const BodyID &inBodyID) const;
  82. ///@}
  83. ///@name Position and rotation of a body
  84. ///@{
  85. void SetPositionAndRotation(const BodyID &inBodyID, Vec3Arg inPosition, QuatArg inRotation, EActivation inActivationMode);
  86. void SetPositionAndRotationWhenChanged(const BodyID &inBodyID, Vec3Arg inPosition, QuatArg inRotation, EActivation inActivationMode); ///< Will only update the position/rotation and activate the body when the difference is larger than a very small number. This avoids updating the broadphase/waking up a body when the resulting position/orientation doesn't really change.
  87. void GetPositionAndRotation(const BodyID &inBodyID, Vec3 &outPosition, Quat &outRotation) const;
  88. void SetPosition(const BodyID &inBodyID, Vec3Arg inPosition, EActivation inActivationMode);
  89. Vec3 GetPosition(const BodyID &inBodyID) const;
  90. Vec3 GetCenterOfMassPosition(const BodyID &inBodyID) const;
  91. void SetRotation(const BodyID &inBodyID, QuatArg inRotation, EActivation inActivationMode);
  92. Quat GetRotation(const BodyID &inBodyID) const;
  93. Mat44 GetWorldTransform(const BodyID &inBodyID) const;
  94. ///@}
  95. /// Set velocity of body such that it will be positioned at inTargetPosition/Rotation in inDeltaTime seconds (will activate body if needed)
  96. void MoveKinematic(const BodyID &inBodyID, Vec3Arg inTargetPosition, QuatArg inTargetRotation, float inDeltaTime);
  97. /// Linear or angular velocity (functions will activate body if needed).
  98. /// Note that the linear velocity is the velocity of the center of mass, which may not coincide with the position of your object, to correct for this: \f$VelocityCOM = Velocity - AngularVelocity \times ShapeCOM\f$
  99. void SetLinearAndAngularVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity);
  100. void GetLinearAndAngularVelocity(const BodyID &inBodyID, Vec3 &outLinearVelocity, Vec3 &outAngularVelocity) const;
  101. void SetLinearVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity);
  102. Vec3 GetLinearVelocity(const BodyID &inBodyID) const;
  103. void AddLinearVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity); ///< Add velocity to current velocity
  104. void SetAngularVelocity(const BodyID &inBodyID, Vec3Arg inAngularVelocity);
  105. Vec3 GetAngularVelocity(const BodyID &inBodyID) const;
  106. Vec3 GetPointVelocity(const BodyID &inBodyID, Vec3Arg inPoint) const; ///< Velocity of point inPoint (in world space, e.g. on the surface of the body) of the body
  107. /// Set the complete motion state of a body.
  108. /// Note that the linear velocity is the velocity of the center of mass, which may not coincide with the position of your object, to correct for this: \f$VelocityCOM = Velocity - AngularVelocity \times ShapeCOM\f$
  109. void SetPositionRotationAndVelocity(const BodyID &inBodyID, Vec3Arg inPosition, QuatArg inRotation, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity);
  110. ///@name Add an impulse to the body
  111. ///@{
  112. void AddImpulse(const BodyID &inBodyID, Vec3Arg inImpulse); ///< Applied at center of mass
  113. void AddImpulse(const BodyID &inBodyID, Vec3Arg inImpulse, Vec3Arg inPoint); ///< Applied at inPoint
  114. void AddAngularImpulse(const BodyID &inBodyID, Vec3Arg inAngularImpulse);
  115. ///@}
  116. /// Update the body motion type
  117. void SetMotionType(const BodyID &inBodyID, EMotionType inMotionType, EActivation inActivationMode);
  118. /// Get inverse inertia tensor in world space
  119. Mat44 GetInverseInertia(const BodyID &inBodyID) const;
  120. ///@name Restitution
  121. ///@{
  122. void SetRestitution(const BodyID &inBodyID, float inRestitution);
  123. float GetRestitution(const BodyID &inBodyID) const;
  124. ///@}
  125. ///@name Friction
  126. ///@{
  127. void SetFriction(const BodyID &inBodyID, float inFriction);
  128. float GetFriction(const BodyID &inBodyID) const;
  129. ///@}
  130. ///@name Gravity factor
  131. ///@{
  132. void SetGravityFactor(const BodyID &inBodyID, float inGravityFactor);
  133. float GetGravityFactor(const BodyID &inBodyID) const;
  134. ///@}
  135. /// Get transform and shape for this body, used to perform collision detection
  136. TransformedShape GetTransformedShape(const BodyID &inBodyID) const;
  137. /// Get the user data for a body
  138. void * GetUserData(const BodyID &inBodyID) const;
  139. /// Get the material for a particular sub shape
  140. const PhysicsMaterial * GetMaterial(const BodyID &inBodyID, const SubShapeID &inSubShapeID) const;
  141. private:
  142. BodyLockInterface * mBodyLockInterface = nullptr;
  143. BodyManager * mBodyManager = nullptr;
  144. BroadPhase * mBroadPhase = nullptr;
  145. };
  146. } // JPH