Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Constraints/SliderConstraint.h
9913 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Physics/Constraints/TwoBodyConstraint.h>7#include <Jolt/Physics/Constraints/MotorSettings.h>8#include <Jolt/Physics/Constraints/ConstraintPart/DualAxisConstraintPart.h>9#include <Jolt/Physics/Constraints/ConstraintPart/RotationEulerConstraintPart.h>10#include <Jolt/Physics/Constraints/ConstraintPart/AxisConstraintPart.h>1112JPH_NAMESPACE_BEGIN1314/// Slider constraint settings, used to create a slider constraint15class JPH_EXPORT SliderConstraintSettings final : public TwoBodyConstraintSettings16{17JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, SliderConstraintSettings)1819public:20// See: ConstraintSettings::SaveBinaryState21virtual void SaveBinaryState(StreamOut &inStream) const override;2223/// Create an instance of this constraint.24/// Note that the rotation constraint will be solved from body 1. This means that if body 1 and body 2 have different masses / inertias (kinematic body = infinite mass / inertia), body 1 should be the heaviest body.25virtual TwoBodyConstraint * Create(Body &inBody1, Body &inBody2) const override;2627/// Simple way of setting the slider and normal axis in world space (assumes the bodies are already oriented correctly when the constraint is created)28void SetSliderAxis(Vec3Arg inSliderAxis);2930/// This determines in which space the constraint is setup, all properties below should be in the specified space31EConstraintSpace mSpace = EConstraintSpace::WorldSpace;3233/// When mSpace is WorldSpace mPoint1 and mPoint2 can be automatically calculated based on the positions of the bodies when the constraint is created (the current relative position/orientation is chosen as the '0' position). Set this to false if you want to supply the attachment points yourself.34bool mAutoDetectPoint = false;3536/// Body 1 constraint reference frame (space determined by mSpace).37/// Slider axis is the axis along which movement is possible (direction), normal axis is a perpendicular vector to define the frame.38RVec3 mPoint1 = RVec3::sZero();39Vec3 mSliderAxis1 = Vec3::sAxisX();40Vec3 mNormalAxis1 = Vec3::sAxisY();4142/// Body 2 constraint reference frame (space determined by mSpace)43RVec3 mPoint2 = RVec3::sZero();44Vec3 mSliderAxis2 = Vec3::sAxisX();45Vec3 mNormalAxis2 = Vec3::sAxisY();4647/// When the bodies move so that mPoint1 coincides with mPoint2 the slider position is defined to be 0, movement will be limited between [mLimitsMin, mLimitsMax] where mLimitsMin e [-inf, 0] and mLimitsMax e [0, inf]48float mLimitsMin = -FLT_MAX;49float mLimitsMax = FLT_MAX;5051/// When enabled, this makes the limits soft. When the constraint exceeds the limits, a spring force will pull it back.52SpringSettings mLimitsSpringSettings;5354/// Maximum amount of friction force to apply (N) when not driven by a motor.55float mMaxFrictionForce = 0.0f;5657/// In case the constraint is powered, this determines the motor settings around the sliding axis58MotorSettings mMotorSettings;5960protected:61// See: ConstraintSettings::RestoreBinaryState62virtual void RestoreBinaryState(StreamIn &inStream) override;63};6465/// A slider constraint allows movement in only 1 axis (and no rotation). Also known as a prismatic constraint.66class JPH_EXPORT SliderConstraint final : public TwoBodyConstraint67{68public:69JPH_OVERRIDE_NEW_DELETE7071/// Construct slider constraint72SliderConstraint(Body &inBody1, Body &inBody2, const SliderConstraintSettings &inSettings);7374// Generic interface of a constraint75virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::Slider; }76virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;77virtual void SetupVelocityConstraint(float inDeltaTime) override;78virtual void ResetWarmStart() override;79virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;80virtual bool SolveVelocityConstraint(float inDeltaTime) override;81virtual bool SolvePositionConstraint(float inDeltaTime, float inBaumgarte) override;82#ifdef JPH_DEBUG_RENDERER83virtual void DrawConstraint(DebugRenderer *inRenderer) const override;84virtual void DrawConstraintLimits(DebugRenderer *inRenderer) const override;85#endif // JPH_DEBUG_RENDERER86virtual void SaveState(StateRecorder &inStream) const override;87virtual void RestoreState(StateRecorder &inStream) override;88virtual Ref<ConstraintSettings> GetConstraintSettings() const override;8990// See: TwoBodyConstraint91virtual Mat44 GetConstraintToBody1Matrix() const override;92virtual Mat44 GetConstraintToBody2Matrix() const override;9394/// Get the current distance from the rest position95float GetCurrentPosition() const;9697/// Friction control98void SetMaxFrictionForce(float inFrictionForce) { mMaxFrictionForce = inFrictionForce; }99float GetMaxFrictionForce() const { return mMaxFrictionForce; }100101/// Motor settings102MotorSettings & GetMotorSettings() { return mMotorSettings; }103const MotorSettings & GetMotorSettings() const { return mMotorSettings; }104105// Motor controls106void SetMotorState(EMotorState inState) { JPH_ASSERT(inState == EMotorState::Off || mMotorSettings.IsValid()); mMotorState = inState; }107EMotorState GetMotorState() const { return mMotorState; }108void SetTargetVelocity(float inVelocity) { mTargetVelocity = inVelocity; }109float GetTargetVelocity() const { return mTargetVelocity; }110void SetTargetPosition(float inPosition) { mTargetPosition = mHasLimits? Clamp(inPosition, mLimitsMin, mLimitsMax) : inPosition; }111float GetTargetPosition() const { return mTargetPosition; }112113/// Update the limits of the slider constraint (see SliderConstraintSettings)114void SetLimits(float inLimitsMin, float inLimitsMax);115float GetLimitsMin() const { return mLimitsMin; }116float GetLimitsMax() const { return mLimitsMax; }117bool HasLimits() const { return mHasLimits; }118119/// Update the limits spring settings120const SpringSettings & GetLimitsSpringSettings() const { return mLimitsSpringSettings; }121SpringSettings & GetLimitsSpringSettings() { return mLimitsSpringSettings; }122void SetLimitsSpringSettings(const SpringSettings &inLimitsSpringSettings) { mLimitsSpringSettings = inLimitsSpringSettings; }123124///@name Get Lagrange multiplier from last physics update (the linear/angular impulse applied to satisfy the constraint)125inline Vector<2> GetTotalLambdaPosition() const { return mPositionConstraintPart.GetTotalLambda(); }126inline float GetTotalLambdaPositionLimits() const { return mPositionLimitsConstraintPart.GetTotalLambda(); }127inline Vec3 GetTotalLambdaRotation() const { return mRotationConstraintPart.GetTotalLambda(); }128inline float GetTotalLambdaMotor() const { return mMotorConstraintPart.GetTotalLambda(); }129130private:131// Internal helper function to calculate the values below132void CalculateR1R2U(Mat44Arg inRotation1, Mat44Arg inRotation2);133void CalculateSlidingAxisAndPosition(Mat44Arg inRotation1);134void CalculatePositionConstraintProperties(Mat44Arg inRotation1, Mat44Arg inRotation2);135void CalculatePositionLimitsConstraintProperties(float inDeltaTime);136void CalculateMotorConstraintProperties(float inDeltaTime);137138// CONFIGURATION PROPERTIES FOLLOW139140// Local space constraint positions141Vec3 mLocalSpacePosition1;142Vec3 mLocalSpacePosition2;143144// Local space sliding direction145Vec3 mLocalSpaceSliderAxis1;146147// Local space normals to the sliding direction (in body 1 space)148Vec3 mLocalSpaceNormal1;149Vec3 mLocalSpaceNormal2;150151// Inverse of initial rotation from body 1 to body 2 in body 1 space152Quat mInvInitialOrientation;153154// Slider limits155bool mHasLimits;156float mLimitsMin;157float mLimitsMax;158159// Soft constraint limits160SpringSettings mLimitsSpringSettings;161162// Friction163float mMaxFrictionForce;164165// Motor controls166MotorSettings mMotorSettings;167EMotorState mMotorState = EMotorState::Off;168float mTargetVelocity = 0.0f;169float mTargetPosition = 0.0f;170171// RUN TIME PROPERTIES FOLLOW172173// Positions where the point constraint acts on (middle point between center of masses)174Vec3 mR1;175Vec3 mR2;176177// X2 + R2 - X1 - R1178Vec3 mU;179180// World space sliding direction181Vec3 mWorldSpaceSliderAxis;182183// Normals to the slider axis184Vec3 mN1;185Vec3 mN2;186187// Distance along the slide axis188float mD = 0.0f;189190// The constraint parts191DualAxisConstraintPart mPositionConstraintPart;192RotationEulerConstraintPart mRotationConstraintPart;193AxisConstraintPart mPositionLimitsConstraintPart;194AxisConstraintPart mMotorConstraintPart;195};196197JPH_NAMESPACE_END198199200