1 /* 2 * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 3 * 4 * This software is provided 'as-is', without any express or implied 5 * warranty. In no event will the authors be held liable for any damages 6 * arising from the use of this software. 7 * Permission is granted to anyone to use this software for any purpose, 8 * including commercial applications, and to alter it and redistribute it 9 * freely, subject to the following restrictions: 10 * 1. The origin of this software must not be misrepresented; you must not 11 * claim that you wrote the original software. If you use this software 12 * in a product, an acknowledgment in the product documentation would be 13 * appreciated but is not required. 14 * 2. Altered source versions must be plainly marked as such, and must not be 15 * misrepresented as being the original software. 16 * 3. This notice may not be removed or altered from any source distribution. 17 */ 18 19 #ifndef B2_PULLEY_JOINT_H 20 #define B2_PULLEY_JOINT_H 21 22 #include "b2Joint.h" 23 24 const float32 b2_minPulleyLength = 2.0f; 25 26 /// Pulley joint definition. This requires two ground anchors, 27 /// two dynamic body anchor points, max lengths for each side, 28 /// and a pulley ratio. 29 struct b2PulleyJointDef : public b2JointDef 30 { b2PulleyJointDefb2PulleyJointDef31 b2PulleyJointDef() 32 { 33 type = e_pulleyJoint; 34 groundAnchor1.Set(-1.0f, 1.0f); 35 groundAnchor2.Set(1.0f, 1.0f); 36 localAnchor1.Set(-1.0f, 0.0f); 37 localAnchor2.Set(1.0f, 0.0f); 38 length1 = 0.0f; 39 maxLength1 = 0.0f; 40 length2 = 0.0f; 41 maxLength2 = 0.0f; 42 ratio = 1.0f; 43 collideConnected = true; 44 } 45 46 /// Initialize the bodies, anchors, lengths, max lengths, and ratio using the world anchors. 47 void Initialize(b2Body* body1, b2Body* body2, 48 const b2Vec2& groundAnchor1, const b2Vec2& groundAnchor2, 49 const b2Vec2& anchor1, const b2Vec2& anchor2, 50 float32 ratio); 51 52 /// The first ground anchor in world coordinates. This point never moves. 53 b2Vec2 groundAnchor1; 54 55 /// The second ground anchor in world coordinates. This point never moves. 56 b2Vec2 groundAnchor2; 57 58 /// The local anchor point relative to body1's origin. 59 b2Vec2 localAnchor1; 60 61 /// The local anchor point relative to body2's origin. 62 b2Vec2 localAnchor2; 63 64 /// The a reference length for the segment attached to body1. 65 float32 length1; 66 67 /// The maximum length of the segment attached to body1. 68 float32 maxLength1; 69 70 /// The a reference length for the segment attached to body2. 71 float32 length2; 72 73 /// The maximum length of the segment attached to body2. 74 float32 maxLength2; 75 76 /// The pulley ratio, used to simulate a block-and-tackle. 77 float32 ratio; 78 }; 79 80 /// The pulley joint is connected to two bodies and two fixed ground points. 81 /// The pulley supports a ratio such that: 82 /// length1 + ratio * length2 <= constant 83 /// Yes, the force transmitted is scaled by the ratio. 84 /// The pulley also enforces a maximum length limit on both sides. This is 85 /// useful to prevent one side of the pulley hitting the top. 86 class b2PulleyJoint : public b2Joint 87 { 88 public: 89 b2Vec2 GetAnchor1() const; 90 b2Vec2 GetAnchor2() const; 91 92 b2Vec2 GetReactionForce() const; 93 float32 GetReactionTorque() const; 94 95 /// Get the first ground anchor. 96 b2Vec2 GetGroundAnchor1() const; 97 98 /// Get the second ground anchor. 99 b2Vec2 GetGroundAnchor2() const; 100 101 /// Get the current length of the segment attached to body1. 102 float32 GetLength1() const; 103 104 /// Get the current length of the segment attached to body2. 105 float32 GetLength2() const; 106 107 /// Get the pulley ratio. 108 float32 GetRatio() const; 109 110 //--------------- Internals Below ------------------- 111 112 b2PulleyJoint(const b2PulleyJointDef* data); 113 114 void InitVelocityConstraints(const b2TimeStep& step); 115 void SolveVelocityConstraints(const b2TimeStep& step); 116 bool SolvePositionConstraints(); 117 118 b2Body* m_ground; 119 b2Vec2 m_groundAnchor1; 120 b2Vec2 m_groundAnchor2; 121 b2Vec2 m_localAnchor1; 122 b2Vec2 m_localAnchor2; 123 124 b2Vec2 m_u1; 125 b2Vec2 m_u2; 126 127 float32 m_constant; 128 float32 m_ratio; 129 130 float32 m_maxLength1; 131 float32 m_maxLength2; 132 133 // Effective masses 134 float32 m_pulleyMass; 135 float32 m_limitMass1; 136 float32 m_limitMass2; 137 138 // Impulses for accumulation/warm starting. 139 float32 m_force; 140 float32 m_limitForce1; 141 float32 m_limitForce2; 142 143 // Position impulses for accumulation. 144 float32 m_positionImpulse; 145 float32 m_limitPositionImpulse1; 146 float32 m_limitPositionImpulse2; 147 148 b2LimitState m_state; 149 b2LimitState m_limitState1; 150 b2LimitState m_limitState2; 151 }; 152 153 #endif 154