Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Body/BodyInterface.h
21732 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. Note that you need to add a body to the physics system before you can remove it.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. Note that bodies need to be added to the physics system before they can be removed.135/// ioBodies may be shuffled around by this function.136void RemoveBodies(BodyID *ioBodies, int inNumber);137///@}138139///@name Activate / deactivate a body. Note that you need to add a body to the physics system before you can activate it.140///@{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 constraint.154/// Note that the bodies involved in the constraint should be added to the physics system before activating a constraint.155void ActivateConstraint(const TwoBodyConstraint *inConstraint);156157///@name Access to the shape of a body158///@{159160/// Get the current shape161RefConst<Shape> GetShape(const BodyID &inBodyID) const;162163/// Set a new shape on the body164/// @param inBodyID Body ID of body that had its shape changed165/// @param inShape The new shape166/// @param inUpdateMassProperties When true, the mass and inertia tensor is recalculated167/// @param inActivationMode Whether or not to activate the body168void SetShape(const BodyID &inBodyID, const Shape *inShape, bool inUpdateMassProperties, EActivation inActivationMode) const;169170/// Notify all systems to indicate that a shape has changed (usable for MutableCompoundShapes)171/// @param inBodyID Body ID of body that had its shape changed172/// @param inPreviousCenterOfMass Center of mass of the shape before the alterations173/// @param inUpdateMassProperties When true, the mass and inertia tensor is recalculated174/// @param inActivationMode Whether or not to activate the body175void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inPreviousCenterOfMass, bool inUpdateMassProperties, EActivation inActivationMode) const;176///@}177178///@name Object layer of a body179///@{180void SetObjectLayer(const BodyID &inBodyID, ObjectLayer inLayer);181ObjectLayer GetObjectLayer(const BodyID &inBodyID) const;182///@}183184///@name Position and rotation of a body185///@{186void SetPositionAndRotation(const BodyID &inBodyID, RVec3Arg inPosition, QuatArg inRotation, EActivation inActivationMode);187void 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.188void GetPositionAndRotation(const BodyID &inBodyID, RVec3 &outPosition, Quat &outRotation) const;189void SetPosition(const BodyID &inBodyID, RVec3Arg inPosition, EActivation inActivationMode);190RVec3 GetPosition(const BodyID &inBodyID) const;191RVec3 GetCenterOfMassPosition(const BodyID &inBodyID) const;192void SetRotation(const BodyID &inBodyID, QuatArg inRotation, EActivation inActivationMode);193Quat GetRotation(const BodyID &inBodyID) const;194RMat44 GetWorldTransform(const BodyID &inBodyID) const;195RMat44 GetCenterOfMassTransform(const BodyID &inBodyID) const;196///@}197198/// Set velocity of body such that it will be positioned at inTargetPosition/Rotation in inDeltaTime seconds (will activate body if needed)199void MoveKinematic(const BodyID &inBodyID, RVec3Arg inTargetPosition, QuatArg inTargetRotation, float inDeltaTime);200201/// Linear or angular velocity (functions will activate body if needed).202/// 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$203void SetLinearAndAngularVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity);204void GetLinearAndAngularVelocity(const BodyID &inBodyID, Vec3 &outLinearVelocity, Vec3 &outAngularVelocity) const;205void SetLinearVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity);206Vec3 GetLinearVelocity(const BodyID &inBodyID) const;207void AddLinearVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity); ///< Add velocity to current velocity208void AddLinearAndAngularVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity); ///< Add linear and angular to current velocities209void SetAngularVelocity(const BodyID &inBodyID, Vec3Arg inAngularVelocity);210Vec3 GetAngularVelocity(const BodyID &inBodyID) const;211Vec3 GetPointVelocity(const BodyID &inBodyID, RVec3Arg inPoint) const; ///< Velocity of point inPoint (in world space, e.g. on the surface of the body) of the body212213/// Set the complete motion state of a body.214/// 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$215void SetPositionRotationAndVelocity(const BodyID &inBodyID, RVec3Arg inPosition, QuatArg inRotation, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity);216217///@name Add forces to the body. Note that you should add a body to the physics system before applying forces or torques.218///@{219void AddForce(const BodyID &inBodyID, Vec3Arg inForce, EActivation inActivationMode = EActivation::Activate); ///< See Body::AddForce220void AddForce(const BodyID &inBodyID, Vec3Arg inForce, RVec3Arg inPoint, EActivation inActivationMode = EActivation::Activate); ///< Applied at inPoint221void AddTorque(const BodyID &inBodyID, Vec3Arg inTorque, EActivation inActivationMode = EActivation::Activate); ///< See Body::AddTorque222void AddForceAndTorque(const BodyID &inBodyID, Vec3Arg inForce, Vec3Arg inTorque, EActivation inActivationMode = EActivation::Activate); ///< A combination of Body::AddForce and Body::AddTorque223///@}224225///@name Add an impulse to the body. Note that you should add a body to the physics system before applying impulses.226///@{227void AddImpulse(const BodyID &inBodyID, Vec3Arg inImpulse); ///< Applied at center of mass228void AddImpulse(const BodyID &inBodyID, Vec3Arg inImpulse, RVec3Arg inPoint); ///< Applied at inPoint229void AddAngularImpulse(const BodyID &inBodyID, Vec3Arg inAngularImpulse);230bool ApplyBuoyancyImpulse(const BodyID &inBodyID, RVec3Arg inSurfacePosition, Vec3Arg inSurfaceNormal, float inBuoyancy, float inLinearDrag, float inAngularDrag, Vec3Arg inFluidVelocity, Vec3Arg inGravity, float inDeltaTime);231///@}232233///@name Body type234///@{235EBodyType GetBodyType(const BodyID &inBodyID) const;236///@}237238///@name Body motion type239///@{240void SetMotionType(const BodyID &inBodyID, EMotionType inMotionType, EActivation inActivationMode);241EMotionType GetMotionType(const BodyID &inBodyID) const;242///@}243244///@name Body motion quality245///@{246void SetMotionQuality(const BodyID &inBodyID, EMotionQuality inMotionQuality);247EMotionQuality GetMotionQuality(const BodyID &inBodyID) const;248///@}249250/// Get inverse inertia tensor in world space251Mat44 GetInverseInertia(const BodyID &inBodyID) const;252253///@name Restitution254///@{255void SetRestitution(const BodyID &inBodyID, float inRestitution);256float GetRestitution(const BodyID &inBodyID) const;257///@}258259///@name Friction260///@{261void SetFriction(const BodyID &inBodyID, float inFriction);262float GetFriction(const BodyID &inBodyID) const;263///@}264265///@name Gravity factor266///@{267void SetGravityFactor(const BodyID &inBodyID, float inGravityFactor);268float GetGravityFactor(const BodyID &inBodyID) const;269///@}270271///@name Max linear velocity272///@{273void SetMaxLinearVelocity(const BodyID &inBodyID, float inLinearVelocity);274float GetMaxLinearVelocity(const BodyID &inBodyID) const;275///@}276277///@name Max angular velocity278///@{279void SetMaxAngularVelocity(const BodyID &inBodyID, float inAngularVelocity);280float GetMaxAngularVelocity(const BodyID &inBodyID) const;281///@}282283///@name Manifold reduction284///@{285void SetUseManifoldReduction(const BodyID &inBodyID, bool inUseReduction);286bool GetUseManifoldReduction(const BodyID &inBodyID) const;287///@}288289///@name Sensor290///@{291void SetIsSensor(const BodyID &inBodyID, bool inIsSensor);292bool IsSensor(const BodyID &inBodyID) const;293///@}294295///@name Collision group296///@{297void SetCollisionGroup(const BodyID &inBodyID, const CollisionGroup &inCollisionGroup);298const CollisionGroup & GetCollisionGroup(const BodyID &inBodyID) const;299///@}300301/// Get transform and shape for this body, used to perform collision detection302TransformedShape GetTransformedShape(const BodyID &inBodyID) const;303304/// Get the user data for a body305uint64 GetUserData(const BodyID &inBodyID) const;306void SetUserData(const BodyID &inBodyID, uint64 inUserData) const;307308/// Get the material for a particular sub shape309const PhysicsMaterial * GetMaterial(const BodyID &inBodyID, const SubShapeID &inSubShapeID) const;310311/// 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.312void InvalidateContactCache(const BodyID &inBodyID);313314private:315/// Helper function to activate a single body316JPH_INLINE void ActivateBodyInternal(Body &ioBody) const;317318BodyLockInterface * mBodyLockInterface = nullptr;319BodyManager * mBodyManager = nullptr;320BroadPhase * mBroadPhase = nullptr;321};322323JPH_NAMESPACE_END324325326