Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Constraints/PulleyConstraint.h
9912 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2022 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Physics/Constraints/TwoBodyConstraint.h>7#include <Jolt/Physics/Constraints/ConstraintPart/IndependentAxisConstraintPart.h>89JPH_NAMESPACE_BEGIN1011/// Pulley constraint settings, used to create a pulley constraint.12/// A pulley connects two bodies via two fixed world points to each other similar to a distance constraint.13/// We define Length1 = |BodyPoint1 - FixedPoint1| where Body1 is a point on body 1 in world space and FixedPoint1 a fixed point in world space14/// Length2 = |BodyPoint2 - FixedPoint2|15/// The constraint keeps the two line segments constrained so that16/// MinDistance <= Length1 + Ratio * Length2 <= MaxDistance17class JPH_EXPORT PulleyConstraintSettings final : public TwoBodyConstraintSettings18{19JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, PulleyConstraintSettings)2021public:22// See: ConstraintSettings::SaveBinaryState23virtual void SaveBinaryState(StreamOut &inStream) const override;2425/// Create an instance of this constraint26virtual TwoBodyConstraint * Create(Body &inBody1, Body &inBody2) const override;2728/// This determines in which space the constraint is setup, specified properties below should be in the specified space29EConstraintSpace mSpace = EConstraintSpace::WorldSpace;3031/// Body 1 constraint attachment point (space determined by mSpace).32RVec3 mBodyPoint1 = RVec3::sZero();3334/// Fixed world point to which body 1 is connected (always world space)35RVec3 mFixedPoint1 = RVec3::sZero();3637/// Body 2 constraint attachment point (space determined by mSpace)38RVec3 mBodyPoint2 = RVec3::sZero();3940/// Fixed world point to which body 2 is connected (always world space)41RVec3 mFixedPoint2 = RVec3::sZero();4243/// Ratio between the two line segments (see formula above), can be used to create a block and tackle44float mRatio = 1.0f;4546/// The minimum length of the line segments (see formula above), use -1 to calculate the length based on the positions of the objects when the constraint is created.47float mMinLength = 0.0f;4849/// The maximum length of the line segments (see formula above), use -1 to calculate the length based on the positions of the objects when the constraint is created.50float mMaxLength = -1.0f;5152protected:53// See: ConstraintSettings::RestoreBinaryState54virtual void RestoreBinaryState(StreamIn &inStream) override;55};5657/// A pulley constraint.58class JPH_EXPORT PulleyConstraint final : public TwoBodyConstraint59{60public:61JPH_OVERRIDE_NEW_DELETE6263/// Construct distance constraint64PulleyConstraint(Body &inBody1, Body &inBody2, const PulleyConstraintSettings &inSettings);6566// Generic interface of a constraint67virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::Pulley; }68virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;69virtual void SetupVelocityConstraint(float inDeltaTime) override;70virtual void ResetWarmStart() override;71virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;72virtual bool SolveVelocityConstraint(float inDeltaTime) override;73virtual bool SolvePositionConstraint(float inDeltaTime, float inBaumgarte) override;74#ifdef JPH_DEBUG_RENDERER75virtual void DrawConstraint(DebugRenderer *inRenderer) const override;76#endif // JPH_DEBUG_RENDERER77virtual void SaveState(StateRecorder &inStream) const override;78virtual void RestoreState(StateRecorder &inStream) override;79virtual Ref<ConstraintSettings> GetConstraintSettings() const override;8081// See: TwoBodyConstraint82virtual Mat44 GetConstraintToBody1Matrix() const override { return Mat44::sTranslation(mLocalSpacePosition1); }83virtual Mat44 GetConstraintToBody2Matrix() const override { return Mat44::sTranslation(mLocalSpacePosition2); } // Note: Incorrect rotation as we don't track the original rotation difference, should not matter though as the constraint is not limiting rotation.8485/// Update the minimum and maximum length for the constraint86void SetLength(float inMinLength, float inMaxLength) { JPH_ASSERT(inMinLength >= 0.0f && inMinLength <= inMaxLength); mMinLength = inMinLength; mMaxLength = inMaxLength; }87float GetMinLength() const { return mMinLength; }88float GetMaxLength() const { return mMaxLength; }8990/// Get the current length of both segments (multiplied by the ratio for segment 2)91float GetCurrentLength() const { return Vec3(mWorldSpacePosition1 - mFixedPosition1).Length() + mRatio * Vec3(mWorldSpacePosition2 - mFixedPosition2).Length(); }9293///@name Get Lagrange multiplier from last physics update (the linear impulse applied to satisfy the constraint)94inline float GetTotalLambdaPosition() const { return mIndependentAxisConstraintPart.GetTotalLambda(); }9596private:97// Calculates world positions and normals and returns current length98float CalculatePositionsNormalsAndLength();99100// Internal helper function to calculate the values below101void CalculateConstraintProperties();102103// CONFIGURATION PROPERTIES FOLLOW104105// Local space constraint positions on the bodies106Vec3 mLocalSpacePosition1;107Vec3 mLocalSpacePosition2;108109// World space fixed positions110RVec3 mFixedPosition1;111RVec3 mFixedPosition2;112113/// Ratio between the two line segments114float mRatio;115116// The minimum/maximum length of the line segments117float mMinLength;118float mMaxLength;119120// RUN TIME PROPERTIES FOLLOW121122// World space positions and normal123RVec3 mWorldSpacePosition1;124RVec3 mWorldSpacePosition2;125Vec3 mWorldSpaceNormal1;126Vec3 mWorldSpaceNormal2;127128// Depending on if the length < min or length > max we can apply forces to prevent further violations129float mMinLambda;130float mMaxLambda;131132// The constraint part133IndependentAxisConstraintPart mIndependentAxisConstraintPart;134};135136JPH_NAMESPACE_END137138139