File indexing completed on 2024-12-29 03:29:28
0001 /* 0002 * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org 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_REVOLUTE_JOINT_H 0020 #define B2_REVOLUTE_JOINT_H 0021 0022 #include <Box2D/Dynamics/Joints/b2Joint.h> 0023 0024 /// Revolute joint definition. This requires defining an 0025 /// anchor point where the bodies are joined. The definition 0026 /// uses local anchor points so that the initial configuration 0027 /// can violate the constraint slightly. You also need to 0028 /// specify the initial relative angle for joint limits. This 0029 /// helps when saving and loading a game. 0030 /// The local anchor points are measured from the body's origin 0031 /// rather than the center of mass because: 0032 /// 1. you might not know where the center of mass will be. 0033 /// 2. if you add/remove shapes from a body and recompute the mass, 0034 /// the joints will be broken. 0035 struct b2RevoluteJointDef : public b2JointDef 0036 { 0037 b2RevoluteJointDef() 0038 { 0039 type = e_revoluteJoint; 0040 localAnchorA.Set(0.0f, 0.0f); 0041 localAnchorB.Set(0.0f, 0.0f); 0042 referenceAngle = 0.0f; 0043 lowerAngle = 0.0f; 0044 upperAngle = 0.0f; 0045 maxMotorTorque = 0.0f; 0046 motorSpeed = 0.0f; 0047 enableLimit = false; 0048 enableMotor = false; 0049 } 0050 0051 /// Initialize the bodies, anchors, and reference angle using a world 0052 /// anchor point. 0053 void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor); 0054 0055 /// The local anchor point relative to bodyA's origin. 0056 b2Vec2 localAnchorA; 0057 0058 /// The local anchor point relative to bodyB's origin. 0059 b2Vec2 localAnchorB; 0060 0061 /// The bodyB angle minus bodyA angle in the reference state (radians). 0062 float32 referenceAngle; 0063 0064 /// A flag to enable joint limits. 0065 bool enableLimit; 0066 0067 /// The lower angle for the joint limit (radians). 0068 float32 lowerAngle; 0069 0070 /// The upper angle for the joint limit (radians). 0071 float32 upperAngle; 0072 0073 /// A flag to enable the joint motor. 0074 bool enableMotor; 0075 0076 /// The desired motor speed. Usually in radians per second. 0077 float32 motorSpeed; 0078 0079 /// The maximum motor torque used to achieve the desired motor speed. 0080 /// Usually in N-m. 0081 float32 maxMotorTorque; 0082 }; 0083 0084 /// A revolute joint constrains two bodies to share a common point while they 0085 /// are free to rotate about the point. The relative rotation about the shared 0086 /// point is the joint angle. You can limit the relative rotation with 0087 /// a joint limit that specifies a lower and upper angle. You can use a motor 0088 /// to drive the relative rotation about the shared point. A maximum motor torque 0089 /// is provided so that infinite forces are not generated. 0090 class b2RevoluteJoint : public b2Joint 0091 { 0092 public: 0093 b2Vec2 GetAnchorA() const; 0094 b2Vec2 GetAnchorB() const; 0095 0096 /// The local anchor point relative to bodyA's origin. 0097 const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; } 0098 0099 /// The local anchor point relative to bodyB's origin. 0100 const b2Vec2& GetLocalAnchorB() const { return m_localAnchorB; } 0101 0102 /// Get the reference angle. 0103 float32 GetReferenceAngle() const { return m_referenceAngle; } 0104 0105 /// Get the current joint angle in radians. 0106 float32 GetJointAngle() const; 0107 0108 /// Get the current joint angle speed in radians per second. 0109 float32 GetJointSpeed() const; 0110 0111 /// Is the joint limit enabled? 0112 bool IsLimitEnabled() const; 0113 0114 /// Enable/disable the joint limit. 0115 void EnableLimit(bool flag); 0116 0117 /// Get the lower joint limit in radians. 0118 float32 GetLowerLimit() const; 0119 0120 /// Get the upper joint limit in radians. 0121 float32 GetUpperLimit() const; 0122 0123 /// Set the joint limits in radians. 0124 void SetLimits(float32 lower, float32 upper); 0125 0126 /// Is the joint motor enabled? 0127 bool IsMotorEnabled() const; 0128 0129 /// Enable/disable the joint motor. 0130 void EnableMotor(bool flag); 0131 0132 /// Set the motor speed in radians per second. 0133 void SetMotorSpeed(float32 speed); 0134 0135 /// Get the motor speed in radians per second. 0136 float32 GetMotorSpeed() const; 0137 0138 /// Set the maximum motor torque, usually in N-m. 0139 void SetMaxMotorTorque(float32 torque); 0140 float32 GetMaxMotorTorque() const { return m_maxMotorTorque; } 0141 0142 /// Get the reaction force given the inverse time step. 0143 /// Unit is N. 0144 b2Vec2 GetReactionForce(float32 inv_dt) const; 0145 0146 /// Get the reaction torque due to the joint limit given the inverse time step. 0147 /// Unit is N*m. 0148 float32 GetReactionTorque(float32 inv_dt) const; 0149 0150 /// Get the current motor torque given the inverse time step. 0151 /// Unit is N*m. 0152 float32 GetMotorTorque(float32 inv_dt) const; 0153 0154 /// Dump to b2Log. 0155 void Dump(); 0156 0157 protected: 0158 0159 friend class b2Joint; 0160 friend class b2GearJoint; 0161 0162 b2RevoluteJoint(const b2RevoluteJointDef* def); 0163 0164 void InitVelocityConstraints(const b2SolverData& data); 0165 void SolveVelocityConstraints(const b2SolverData& data); 0166 bool SolvePositionConstraints(const b2SolverData& data); 0167 0168 // Solver shared 0169 b2Vec2 m_localAnchorA; 0170 b2Vec2 m_localAnchorB; 0171 b2Vec3 m_impulse; 0172 float32 m_motorImpulse; 0173 0174 bool m_enableMotor; 0175 float32 m_maxMotorTorque; 0176 float32 m_motorSpeed; 0177 0178 bool m_enableLimit; 0179 float32 m_referenceAngle; 0180 float32 m_lowerAngle; 0181 float32 m_upperAngle; 0182 0183 // Solver temp 0184 int32 m_indexA; 0185 int32 m_indexB; 0186 b2Vec2 m_rA; 0187 b2Vec2 m_rB; 0188 b2Vec2 m_localCenterA; 0189 b2Vec2 m_localCenterB; 0190 float32 m_invMassA; 0191 float32 m_invMassB; 0192 float32 m_invIA; 0193 float32 m_invIB; 0194 b2Mat33 m_mass; // effective mass for point-to-point constraint. 0195 float32 m_motorMass; // effective mass for motor/limit angular constraint. 0196 b2LimitState m_limitState; 0197 }; 0198 0199 inline float32 b2RevoluteJoint::GetMotorSpeed() const 0200 { 0201 return m_motorSpeed; 0202 } 0203 0204 #endif