File indexing completed on 2025-08-03 03:49:59

0001 /*
0002 * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
0003 *
0004 * This software is provided 'as-is', without any express or implied
0005 * warranty.  In no event will the authors be held liable for any damages
0006 * arising from the use of this software.
0007 * Permission is granted to anyone to use this software for any purpose,
0008 * including commercial applications, and to alter it and redistribute it
0009 * freely, subject to the following restrictions:
0010 * 1. The origin of this software must not be misrepresented; you must not
0011 * claim that you wrote the original software. If you use this software
0012 * in a product, an acknowledgment in the product documentation would be
0013 * appreciated but is not required.
0014 * 2. Altered source versions must be plainly marked as such, and must not be
0015 * misrepresented as being the original software.
0016 * 3. This notice may not be removed or altered from any source distribution.
0017 */
0018 
0019 #ifndef B2_PULLEY_JOINT_H
0020 #define B2_PULLEY_JOINT_H
0021 
0022 #include <Box2D/Dynamics/Joints/b2Joint.h>
0023 
0024 const qreal b2_minPulleyLength = 2.0f;
0025 
0026 /// Pulley joint definition. This requires two ground anchors,
0027 /// two dynamic body anchor points, max lengths for each side,
0028 /// and a pulley ratio.
0029 struct b2PulleyJointDef : public b2JointDef
0030 {
0031     b2PulleyJointDef()
0032     {
0033         type = e_pulleyJoint;
0034         groundAnchorA.Set(-1.0f, 1.0f);
0035         groundAnchorB.Set(1.0f, 1.0f);
0036         localAnchorA.Set(-1.0f, 0.0f);
0037         localAnchorB.Set(1.0f, 0.0f);
0038         lengthA = 0.0f;
0039         maxLengthA = 0.0f;
0040         lengthB = 0.0f;
0041         maxLengthB = 0.0f;
0042         ratio = 1.0f;
0043         collideConnected = true;
0044     }
0045 
0046     /// Initialize the bodies, anchors, lengths, max lengths, and ratio using the world anchors.
0047     void Initialize(b2Body* bodyA, b2Body* bodyB,
0048                     const b2Vec2& groundAnchorA, const b2Vec2& groundAnchorB,
0049                     const b2Vec2& anchorA, const b2Vec2& anchorB,
0050                     qreal ratio);
0051 
0052     /// The first ground anchor in world coordinates. This point never moves.
0053     b2Vec2 groundAnchorA;
0054 
0055     /// The second ground anchor in world coordinates. This point never moves.
0056     b2Vec2 groundAnchorB;
0057 
0058     /// The local anchor point relative to bodyA's origin.
0059     b2Vec2 localAnchorA;
0060 
0061     /// The local anchor point relative to bodyB's origin.
0062     b2Vec2 localAnchorB;
0063 
0064     /// The a reference length for the segment attached to bodyA.
0065     qreal lengthA;
0066 
0067     /// The maximum length of the segment attached to bodyA.
0068     qreal maxLengthA;
0069 
0070     /// The a reference length for the segment attached to bodyB.
0071     qreal lengthB;
0072 
0073     /// The maximum length of the segment attached to bodyB.
0074     qreal maxLengthB;
0075 
0076     /// The pulley ratio, used to simulate a block-and-tackle.
0077     qreal ratio;
0078 };
0079 
0080 /// The pulley joint is connected to two bodies and two fixed ground points.
0081 /// The pulley supports a ratio such that:
0082 /// length1 + ratio * length2 <= constant
0083 /// Yes, the force transmitted is scaled by the ratio.
0084 /// The pulley also enforces a maximum length limit on both sides. This is
0085 /// useful to prevent one side of the pulley hitting the top.
0086 class b2PulleyJoint : public b2Joint
0087 {
0088 public:
0089     b2Vec2 GetAnchorA() const override;
0090     b2Vec2 GetAnchorB() const override;
0091 
0092     b2Vec2 GetReactionForce(qreal inv_dt) const override;
0093     qreal GetReactionTorque(qreal inv_dt) const override;
0094 
0095     /// Get the first ground anchor.
0096     b2Vec2 GetGroundAnchorA() const;
0097 
0098     /// Get the second ground anchor.
0099     b2Vec2 GetGroundAnchorB() const;
0100 
0101     /// Get the current length of the segment attached to body1.
0102     qreal GetLength1() const;
0103 
0104     /// Get the current length of the segment attached to body2.
0105     qreal GetLength2() const;
0106 
0107     /// Get the pulley ratio.
0108     qreal GetRatio() const;
0109 
0110 protected:
0111 
0112     friend class b2Joint;
0113     b2PulleyJoint(const b2PulleyJointDef* data);
0114 
0115     void InitVelocityConstraints(const b2TimeStep& step) override;
0116     void SolveVelocityConstraints(const b2TimeStep& step) override;
0117     bool SolvePositionConstraints(qreal baumgarte) override;
0118 
0119     b2Vec2 m_groundAnchor1;
0120     b2Vec2 m_groundAnchor2;
0121     b2Vec2 m_localAnchor1;
0122     b2Vec2 m_localAnchor2;
0123 
0124     b2Vec2 m_u1;
0125     b2Vec2 m_u2;
0126     
0127     qreal m_constant;
0128     qreal m_ratio;
0129     
0130     qreal m_maxLength1;
0131     qreal m_maxLength2;
0132 
0133     // Effective masses
0134     qreal m_pulleyMass;
0135     qreal m_limitMass1;
0136     qreal m_limitMass2;
0137 
0138     // Impulses for accumulation/warm starting.
0139     qreal m_impulse;
0140     qreal m_limitImpulse1;
0141     qreal m_limitImpulse2;
0142 
0143     b2LimitState m_state;
0144     b2LimitState m_limitState1;
0145     b2LimitState m_limitState2;
0146 };
0147 
0148 #endif