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