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. 35struct 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. 90class b2RevoluteJoint : public b2Joint 91{ 92public: 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 157protected: 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 199inline float32 b2RevoluteJoint::GetMotorSpeed() const 200{ 201 return m_motorSpeed; 202} 203 204#endif 205