| 1 | /* |
| 2 | * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org |
| 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_REVOLUTE_JOINT_H |
| 20 | #define B2_REVOLUTE_JOINT_H |
| 21 | |
| 22 | #include <Box2D/Dynamics/Joints/b2Joint.h> |
| 23 | |
| 24 | /// Revolute joint definition. This requires defining an |
| 25 | /// anchor point where the bodies are joined. The definition |
| 26 | /// uses local anchor points so that the initial configuration |
| 27 | /// can violate the constraint slightly. You also need to |
| 28 | /// specify the initial relative angle for joint limits. This |
| 29 | /// helps when saving and loading a game. |
| 30 | /// The local anchor points are measured from the body's origin |
| 31 | /// rather than the center of mass because: |
| 32 | /// 1. you might not know where the center of mass will be. |
| 33 | /// 2. if you add/remove shapes from a body and recompute the mass, |
| 34 | /// the joints will be broken. |
| 35 | struct b2RevoluteJointDef : public b2JointDef |
| 36 | { |
| 37 | b2RevoluteJointDef() |
| 38 | { |
| 39 | type = e_revoluteJoint; |
| 40 | localAnchorA.Set(0.0f, 0.0f); |
| 41 | localAnchorB.Set(0.0f, 0.0f); |
| 42 | referenceAngle = 0.0f; |
| 43 | lowerAngle = 0.0f; |
| 44 | upperAngle = 0.0f; |
| 45 | maxMotorTorque = 0.0f; |
| 46 | motorSpeed = 0.0f; |
| 47 | enableLimit = false; |
| 48 | enableMotor = false; |
| 49 | } |
| 50 | |
| 51 | /// Initialize the bodies, anchors, and reference angle using a world |
| 52 | /// anchor point. |
| 53 | void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor); |
| 54 | |
| 55 | /// The local anchor point relative to bodyA's origin. |
| 56 | b2Vec2 localAnchorA; |
| 57 | |
| 58 | /// The local anchor point relative to bodyB's origin. |
| 59 | b2Vec2 localAnchorB; |
| 60 | |
| 61 | /// The bodyB angle minus bodyA angle in the reference state (radians). |
| 62 | float32 referenceAngle; |
| 63 | |
| 64 | /// A flag to enable joint limits. |
| 65 | bool enableLimit; |
| 66 | |
| 67 | /// The lower angle for the joint limit (radians). |
| 68 | float32 lowerAngle; |
| 69 | |
| 70 | /// The upper angle for the joint limit (radians). |
| 71 | float32 upperAngle; |
| 72 | |
| 73 | /// A flag to enable the joint motor. |
| 74 | bool enableMotor; |
| 75 | |
| 76 | /// The desired motor speed. Usually in radians per second. |
| 77 | float32 motorSpeed; |
| 78 | |
| 79 | /// The maximum motor torque used to achieve the desired motor speed. |
| 80 | /// Usually in N-m. |
| 81 | float32 maxMotorTorque; |
| 82 | }; |
| 83 | |
| 84 | /// A revolute joint constrains two bodies to share a common point while they |
| 85 | /// are free to rotate about the point. The relative rotation about the shared |
| 86 | /// point is the joint angle. You can limit the relative rotation with |
| 87 | /// a joint limit that specifies a lower and upper angle. You can use a motor |
| 88 | /// to drive the relative rotation about the shared point. A maximum motor torque |
| 89 | /// is provided so that infinite forces are not generated. |
| 90 | class b2RevoluteJoint : public b2Joint |
| 91 | { |
| 92 | public: |
| 93 | b2Vec2 GetAnchorA() const; |
| 94 | b2Vec2 GetAnchorB() const; |
| 95 | |
| 96 | /// The local anchor point relative to bodyA's origin. |
| 97 | const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; } |
| 98 | |
| 99 | /// The local anchor point relative to bodyB's origin. |
| 100 | const b2Vec2& GetLocalAnchorB() const { return m_localAnchorB; } |
| 101 | |
| 102 | /// Get the reference angle. |
| 103 | float32 GetReferenceAngle() const { return m_referenceAngle; } |
| 104 | |
| 105 | /// Get the current joint angle in radians. |
| 106 | float32 GetJointAngle() const; |
| 107 | |
| 108 | /// Get the current joint angle speed in radians per second. |
| 109 | float32 GetJointSpeed() const; |
| 110 | |
| 111 | /// Is the joint limit enabled? |
| 112 | bool IsLimitEnabled() const; |
| 113 | |
| 114 | /// Enable/disable the joint limit. |
| 115 | void EnableLimit(bool flag); |
| 116 | |
| 117 | /// Get the lower joint limit in radians. |
| 118 | float32 GetLowerLimit() const; |
| 119 | |
| 120 | /// Get the upper joint limit in radians. |
| 121 | float32 GetUpperLimit() const; |
| 122 | |
| 123 | /// Set the joint limits in radians. |
| 124 | void SetLimits(float32 lower, float32 upper); |
| 125 | |
| 126 | /// Is the joint motor enabled? |
| 127 | bool IsMotorEnabled() const; |
| 128 | |
| 129 | /// Enable/disable the joint motor. |
| 130 | void EnableMotor(bool flag); |
| 131 | |
| 132 | /// Set the motor speed in radians per second. |
| 133 | void SetMotorSpeed(float32 speed); |
| 134 | |
| 135 | /// Get the motor speed in radians per second. |
| 136 | float32 GetMotorSpeed() const; |
| 137 | |
| 138 | /// Set the maximum motor torque, usually in N-m. |
| 139 | void SetMaxMotorTorque(float32 torque); |
| 140 | float32 GetMaxMotorTorque() const { return m_maxMotorTorque; } |
| 141 | |
| 142 | /// Get the reaction force given the inverse time step. |
| 143 | /// Unit is N. |
| 144 | b2Vec2 GetReactionForce(float32 inv_dt) const; |
| 145 | |
| 146 | /// Get the reaction torque due to the joint limit given the inverse time step. |
| 147 | /// Unit is N*m. |
| 148 | float32 GetReactionTorque(float32 inv_dt) const; |
| 149 | |
| 150 | /// Get the current motor torque given the inverse time step. |
| 151 | /// Unit is N*m. |
| 152 | float32 GetMotorTorque(float32 inv_dt) const; |
| 153 | |
| 154 | /// Dump to b2Log. |
| 155 | void Dump(); |
| 156 | |
| 157 | protected: |
| 158 | |
| 159 | friend class b2Joint; |
| 160 | friend class b2GearJoint; |
| 161 | |
| 162 | b2RevoluteJoint(const b2RevoluteJointDef* def); |
| 163 | |
| 164 | void InitVelocityConstraints(const b2SolverData& data); |
| 165 | void SolveVelocityConstraints(const b2SolverData& data); |
| 166 | bool SolvePositionConstraints(const b2SolverData& data); |
| 167 | |
| 168 | // Solver shared |
| 169 | b2Vec2 m_localAnchorA; |
| 170 | b2Vec2 m_localAnchorB; |
| 171 | b2Vec3 m_impulse; |
| 172 | float32 m_motorImpulse; |
| 173 | |
| 174 | bool m_enableMotor; |
| 175 | float32 m_maxMotorTorque; |
| 176 | float32 m_motorSpeed; |
| 177 | |
| 178 | bool m_enableLimit; |
| 179 | float32 m_referenceAngle; |
| 180 | float32 m_lowerAngle; |
| 181 | float32 m_upperAngle; |
| 182 | |
| 183 | // Solver temp |
| 184 | int32 m_indexA; |
| 185 | int32 m_indexB; |
| 186 | b2Vec2 m_rA; |
| 187 | b2Vec2 m_rB; |
| 188 | b2Vec2 m_localCenterA; |
| 189 | b2Vec2 m_localCenterB; |
| 190 | float32 m_invMassA; |
| 191 | float32 m_invMassB; |
| 192 | float32 m_invIA; |
| 193 | float32 m_invIB; |
| 194 | b2Mat33 m_mass; // effective mass for point-to-point constraint. |
| 195 | float32 m_motorMass; // effective mass for motor/limit angular constraint. |
| 196 | b2LimitState m_limitState; |
| 197 | }; |
| 198 | |
| 199 | inline float32 b2RevoluteJoint::GetMotorSpeed() const |
| 200 | { |
| 201 | return m_motorSpeed; |
| 202 | } |
| 203 | |
| 204 | #endif |
| 205 | |