Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Body/BodyInterface.h
9912 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Physics/Body/BodyID.h>7#include <Jolt/Physics/EActivation.h>8#include <Jolt/Physics/Collision/ObjectLayer.h>9#include <Jolt/Physics/Body/MotionType.h>10#include <Jolt/Physics/Body/MotionQuality.h>11#include <Jolt/Physics/Body/BodyType.h>12#include <Jolt/Core/Reference.h>1314JPH_NAMESPACE_BEGIN1516class Body;17class BodyCreationSettings;18class SoftBodyCreationSettings;19class BodyLockInterface;20class BroadPhase;21class BodyManager;22class TransformedShape;23class PhysicsMaterial;24class SubShapeID;25class Shape;26class TwoBodyConstraintSettings;27class TwoBodyConstraint;28class BroadPhaseLayerFilter;29class AABox;30class CollisionGroup;3132/// 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.33/// All quantities are in world space unless otherwise specified.34class JPH_EXPORT BodyInterface : public NonCopyable35{36public:37/// Initialize the interface (should only be called by PhysicsSystem)38void Init(BodyLockInterface &inBodyLockInterface, BodyManager &inBodyManager, BroadPhase &inBroadPhase) { mBodyLockInterface = &inBodyLockInterface; mBodyManager = &inBodyManager; mBroadPhase = &inBroadPhase; }3940/// Create a rigid body41/// @return Created body or null when out of bodies42Body * CreateBody(const BodyCreationSettings &inSettings);4344/// Create a soft body45/// @return Created body or null when out of bodies46Body * CreateSoftBody(const SoftBodyCreationSettings &inSettings);4748/// Create a rigid body with specified ID. This function can be used if a simulation is to run in sync between clients or if a simulation needs to be restored exactly.49/// The ID created on the server can be replicated to the client and used to create a deterministic simulation.50/// @return Created body or null when the body ID is invalid or a body of the same ID already exists.51Body * CreateBodyWithID(const BodyID &inBodyID, const BodyCreationSettings &inSettings);5253/// Create a soft body with specified ID. See comments at CreateBodyWithID.54Body * CreateSoftBodyWithID(const BodyID &inBodyID, const SoftBodyCreationSettings &inSettings);5556/// Advanced use only. Creates a rigid body without specifying an ID. This body cannot be added to the physics system until it has been assigned a body ID.57/// This can be used to decouple allocation from registering the body. A call to CreateBodyWithoutID followed by AssignBodyID is equivalent to calling CreateBodyWithID.58/// @return Created body59Body * CreateBodyWithoutID(const BodyCreationSettings &inSettings) const;6061/// Advanced use only. Creates a body without specifying an ID. See comments at CreateBodyWithoutID.62Body * CreateSoftBodyWithoutID(const SoftBodyCreationSettings &inSettings) const;6364/// Advanced use only. Destroy a body previously created with CreateBodyWithoutID that hasn't gotten an ID yet through the AssignBodyID function,65/// or a body that has had its body ID unassigned through UnassignBodyIDs. Bodies that have an ID should be destroyed through DestroyBody.66void DestroyBodyWithoutID(Body *inBody) const;6768/// Advanced use only. Assigns the next available body ID to a body that was created using CreateBodyWithoutID. After this call, the body can be added to the physics system.69/// @return false if the body already has an ID or out of body ids.70bool AssignBodyID(Body *ioBody);7172/// Advanced use only. Assigns a body ID to a body that was created using CreateBodyWithoutID. After this call, the body can be added to the physics system.73/// @return false if the body already has an ID or if the ID is not valid.74bool AssignBodyID(Body *ioBody, const BodyID &inBodyID);7576/// Advanced use only. See UnassignBodyIDs. Unassigns the ID of a single body.77Body * UnassignBodyID(const BodyID &inBodyID);7879/// Advanced use only. Removes a number of body IDs from their bodies and returns the body pointers. Before calling this, the body should have been removed from the physics system.80/// The body can be destroyed through DestroyBodyWithoutID. This can be used to decouple deallocation. A call to UnassignBodyIDs followed by calls to DestroyBodyWithoutID is equivalent to calling DestroyBodies.81/// @param inBodyIDs A list of body IDs82/// @param inNumber Number of bodies in the list83/// @param outBodies If not null on input, this will contain a list of body pointers corresponding to inBodyIDs that can be destroyed afterwards (caller assumes ownership over these).84void UnassignBodyIDs(const BodyID *inBodyIDs, int inNumber, Body **outBodies);8586/// Destroy a body.87/// Make sure that you remove the body from the physics system using BodyInterface::RemoveBody before calling this function.88void DestroyBody(const BodyID &inBodyID);8990/// Destroy multiple bodies91/// Make sure that you remove the bodies from the physics system using BodyInterface::RemoveBody before calling this function.92void DestroyBodies(const BodyID *inBodyIDs, int inNumber);9394/// Add body to the physics system.95/// Note that if you need to add multiple bodies, use the AddBodiesPrepare/AddBodiesFinalize function.96/// Adding many bodies, one at a time, results in a really inefficient broadphase until PhysicsSystem::OptimizeBroadPhase is called or when PhysicsSystem::Update rebuilds the tree!97/// After adding, to get a body by ID use the BodyLockRead or BodyLockWrite interface!98void AddBody(const BodyID &inBodyID, EActivation inActivationMode);99100/// Remove body from the physics system.101void RemoveBody(const BodyID &inBodyID);102103/// Check if a body has been added to the physics system.104bool IsAdded(const BodyID &inBodyID) const;105106/// Combines CreateBody and AddBody107/// @return Created body ID or an invalid ID when out of bodies108BodyID CreateAndAddBody(const BodyCreationSettings &inSettings, EActivation inActivationMode);109110/// Combines CreateSoftBody and AddBody111/// @return Created body ID or an invalid ID when out of bodies112BodyID CreateAndAddSoftBody(const SoftBodyCreationSettings &inSettings, EActivation inActivationMode);113114/// Add state handle, used to keep track of a batch of bodies while adding them to the PhysicsSystem.115using AddState = void *;116117///@name Batch adding interface118///@{119120/// Prepare adding inNumber bodies at ioBodies to the PhysicsSystem, returns a handle that should be used in AddBodiesFinalize/Abort.121/// This can be done on a background thread without influencing the PhysicsSystem.122/// ioBodies may be shuffled around by this function and should be kept that way until AddBodiesFinalize/Abort is called.123AddState AddBodiesPrepare(BodyID *ioBodies, int inNumber);124125/// Finalize adding bodies to the PhysicsSystem, supply the return value of AddBodiesPrepare in inAddState.126/// Please ensure that the ioBodies array passed to AddBodiesPrepare is unmodified and passed again to this function.127void AddBodiesFinalize(BodyID *ioBodies, int inNumber, AddState inAddState, EActivation inActivationMode);128129/// Abort adding bodies to the PhysicsSystem, supply the return value of AddBodiesPrepare in inAddState.130/// This can be done on a background thread without influencing the PhysicsSystem.131/// Please ensure that the ioBodies array passed to AddBodiesPrepare is unmodified and passed again to this function.132void AddBodiesAbort(BodyID *ioBodies, int inNumber, AddState inAddState);133134/// Remove inNumber bodies in ioBodies from the PhysicsSystem.135/// ioBodies may be shuffled around by this function.136void RemoveBodies(BodyID *ioBodies, int inNumber);137///@}138139///@name Activate / deactivate a body140///@{141void ActivateBody(const BodyID &inBodyID);142void ActivateBodies(const BodyID *inBodyIDs, int inNumber);143void ActivateBodiesInAABox(const AABox &inBox, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter);144void DeactivateBody(const BodyID &inBodyID);145void DeactivateBodies(const BodyID *inBodyIDs, int inNumber);146bool IsActive(const BodyID &inBodyID) const;147void ResetSleepTimer(const BodyID &inBodyID);148///@}149150/// Create a two body constraint151TwoBodyConstraint * CreateConstraint(const TwoBodyConstraintSettings *inSettings, const BodyID &inBodyID1, const BodyID &inBodyID2);152153/// Activate non-static bodies attached to a constraint154void ActivateConstraint(const TwoBodyConstraint *inConstraint);155156///@name Access to the shape of a body157///@{158159/// Get the current shape160RefConst<Shape> GetShape(const BodyID &inBodyID) const;161162/// Set a new shape on the body163/// @param inBodyID Body ID of body that had its shape changed164/// @param inShape The new shape165/// @param inUpdateMassProperties When true, the mass and inertia tensor is recalculated166/// @param inActivationMode Whether or not to activate the body167void SetShape(const BodyID &inBodyID, const Shape *inShape, bool inUpdateMassProperties, EActivation inActivationMode) const;168169/// Notify all systems to indicate that a shape has changed (usable for MutableCompoundShapes)170/// @param inBodyID Body ID of body that had its shape changed171/// @param inPreviousCenterOfMass Center of mass of the shape before the alterations172/// @param inUpdateMassProperties When true, the mass and inertia tensor is recalculated173/// @param inActivationMode Whether or not to activate the body174void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inPreviousCenterOfMass, bool inUpdateMassProperties, EActivation inActivationMode) const;175///@}176177///@name Object layer of a body178///@{179void SetObjectLayer(const BodyID &inBodyID, ObjectLayer inLayer);180ObjectLayer GetObjectLayer(const BodyID &inBodyID) const;181///@}182183///@name Position and rotation of a body184///@{185void SetPositionAndRotation(const BodyID &inBodyID, RVec3Arg inPosition, QuatArg inRotation, EActivation inActivationMode);186void SetPositionAndRotationWhenChanged(const BodyID &inBodyID, RVec3Arg 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.187void GetPositionAndRotation(const BodyID &inBodyID, RVec3 &outPosition, Quat &outRotation) const;188void SetPosition(const BodyID &inBodyID, RVec3Arg inPosition, EActivation inActivationMode);189RVec3 GetPosition(const BodyID &inBodyID) const;190RVec3 GetCenterOfMassPosition(const BodyID &inBodyID) const;191void SetRotation(const BodyID &inBodyID, QuatArg inRotation, EActivation inActivationMode);192Quat GetRotation(const BodyID &inBodyID) const;193RMat44 GetWorldTransform(const BodyID &inBodyID) const;194RMat44 GetCenterOfMassTransform(const BodyID &inBodyID) const;195///@}196197/// Set velocity of body such that it will be positioned at inTargetPosition/Rotation in inDeltaTime seconds (will activate body if needed)198void MoveKinematic(const BodyID &inBodyID, RVec3Arg inTargetPosition, QuatArg inTargetRotation, float inDeltaTime);199200/// Linear or angular velocity (functions will activate body if needed).201/// 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$202void SetLinearAndAngularVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity);203void GetLinearAndAngularVelocity(const BodyID &inBodyID, Vec3 &outLinearVelocity, Vec3 &outAngularVelocity) const;204void SetLinearVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity);205Vec3 GetLinearVelocity(const BodyID &inBodyID) const;206void AddLinearVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity); ///< Add velocity to current velocity207void AddLinearAndAngularVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity); ///< Add linear and angular to current velocities208void SetAngularVelocity(const BodyID &inBodyID, Vec3Arg inAngularVelocity);209Vec3 GetAngularVelocity(const BodyID &inBodyID) const;210Vec3 GetPointVelocity(const BodyID &inBodyID, RVec3Arg inPoint) const; ///< Velocity of point inPoint (in world space, e.g. on the surface of the body) of the body211212/// Set the complete motion state of a body.213/// 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$214void SetPositionRotationAndVelocity(const BodyID &inBodyID, RVec3Arg inPosition, QuatArg inRotation, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity);215216///@name Add forces to the body217///@{218void AddForce(const BodyID &inBodyID, Vec3Arg inForce, EActivation inActivationMode = EActivation::Activate); ///< See Body::AddForce219void AddForce(const BodyID &inBodyID, Vec3Arg inForce, RVec3Arg inPoint, EActivation inActivationMode = EActivation::Activate); ///< Applied at inPoint220void AddTorque(const BodyID &inBodyID, Vec3Arg inTorque, EActivation inActivationMode = EActivation::Activate); ///< See Body::AddTorque221void AddForceAndTorque(const BodyID &inBodyID, Vec3Arg inForce, Vec3Arg inTorque, EActivation inActivationMode = EActivation::Activate); ///< A combination of Body::AddForce and Body::AddTorque222///@}223224///@name Add an impulse to the body225///@{226void AddImpulse(const BodyID &inBodyID, Vec3Arg inImpulse); ///< Applied at center of mass227void AddImpulse(const BodyID &inBodyID, Vec3Arg inImpulse, RVec3Arg inPoint); ///< Applied at inPoint228void AddAngularImpulse(const BodyID &inBodyID, Vec3Arg inAngularImpulse);229bool ApplyBuoyancyImpulse(const BodyID &inBodyID, RVec3Arg inSurfacePosition, Vec3Arg inSurfaceNormal, float inBuoyancy, float inLinearDrag, float inAngularDrag, Vec3Arg inFluidVelocity, Vec3Arg inGravity, float inDeltaTime);230///@}231232///@name Body type233///@{234EBodyType GetBodyType(const BodyID &inBodyID) const;235///@}236237///@name Body motion type238///@{239void SetMotionType(const BodyID &inBodyID, EMotionType inMotionType, EActivation inActivationMode);240EMotionType GetMotionType(const BodyID &inBodyID) const;241///@}242243///@name Body motion quality244///@{245void SetMotionQuality(const BodyID &inBodyID, EMotionQuality inMotionQuality);246EMotionQuality GetMotionQuality(const BodyID &inBodyID) const;247///@}248249/// Get inverse inertia tensor in world space250Mat44 GetInverseInertia(const BodyID &inBodyID) const;251252///@name Restitution253///@{254void SetRestitution(const BodyID &inBodyID, float inRestitution);255float GetRestitution(const BodyID &inBodyID) const;256///@}257258///@name Friction259///@{260void SetFriction(const BodyID &inBodyID, float inFriction);261float GetFriction(const BodyID &inBodyID) const;262///@}263264///@name Gravity factor265///@{266void SetGravityFactor(const BodyID &inBodyID, float inGravityFactor);267float GetGravityFactor(const BodyID &inBodyID) const;268///@}269270///@name Manifold reduction271///@{272void SetUseManifoldReduction(const BodyID &inBodyID, bool inUseReduction);273bool GetUseManifoldReduction(const BodyID &inBodyID) const;274///@}275276///@name Collision group277///@{278void SetCollisionGroup(const BodyID &inBodyID, const CollisionGroup &inCollisionGroup);279const CollisionGroup & GetCollisionGroup(const BodyID &inBodyID) const;280///@}281282/// Get transform and shape for this body, used to perform collision detection283TransformedShape GetTransformedShape(const BodyID &inBodyID) const;284285/// Get the user data for a body286uint64 GetUserData(const BodyID &inBodyID) const;287void SetUserData(const BodyID &inBodyID, uint64 inUserData) const;288289/// Get the material for a particular sub shape290const PhysicsMaterial * GetMaterial(const BodyID &inBodyID, const SubShapeID &inSubShapeID) const;291292/// Set the Body::EFlags::InvalidateContactCache flag for the specified body. This means that the collision cache is invalid for any body pair involving that body until the next physics step.293void InvalidateContactCache(const BodyID &inBodyID);294295private:296/// Helper function to activate a single body297JPH_INLINE void ActivateBodyInternal(Body &ioBody) const;298299BodyLockInterface * mBodyLockInterface = nullptr;300BodyManager * mBodyManager = nullptr;301BroadPhase * mBroadPhase = nullptr;302};303304JPH_NAMESPACE_END305306307