File indexing completed on 2025-08-03 03:50:00
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_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 body1's origin. 0056 b2Vec2 localAnchorA; 0057 0058 /// The local anchor point relative to body2's origin. 0059 b2Vec2 localAnchorB; 0060 0061 /// The body2 angle minus body1 angle in the reference state (radians). 0062 qreal referenceAngle; 0063 0064 /// A flag to enable joint limits. 0065 bool enableLimit; 0066 0067 /// The lower angle for the joint limit (radians). 0068 qreal lowerAngle; 0069 0070 /// The upper angle for the joint limit (radians). 0071 qreal 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 qreal motorSpeed; 0078 0079 /// The maximum motor torque used to achieve the desired motor speed. 0080 /// Usually in N-m. 0081 qreal 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 override; 0094 b2Vec2 GetAnchorB() const override; 0095 0096 /// Get the current joint angle in radians. 0097 qreal GetJointAngle() const; 0098 0099 /// Get the current joint angle speed in radians per second. 0100 qreal GetJointSpeed() const; 0101 0102 /// Is the joint limit enabled? 0103 bool IsLimitEnabled() const; 0104 0105 /// Enable/disable the joint limit. 0106 void EnableLimit(bool flag); 0107 0108 /// Get the lower joint limit in radians. 0109 qreal GetLowerLimit() const; 0110 0111 /// Get the upper joint limit in radians. 0112 qreal GetUpperLimit() const; 0113 0114 /// Set the joint limits in radians. 0115 void SetLimits(qreal lower, qreal upper); 0116 0117 /// Is the joint motor enabled? 0118 bool IsMotorEnabled() const; 0119 0120 /// Enable/disable the joint motor. 0121 void EnableMotor(bool flag); 0122 0123 /// Set the motor speed in radians per second. 0124 void SetMotorSpeed(qreal speed); 0125 0126 /// Get the motor speed in radians per second. 0127 qreal GetMotorSpeed() const; 0128 0129 /// Set the maximum motor torque, usually in N-m. 0130 void SetMaxMotorTorque(qreal torque); 0131 0132 /// Get the reaction force given the inverse time step. 0133 /// Unit is N. 0134 b2Vec2 GetReactionForce(qreal inv_dt) const override; 0135 0136 /// Get the reaction torque due to the joint limit given the inverse time step. 0137 /// Unit is N*m. 0138 qreal GetReactionTorque(qreal inv_dt) const override; 0139 0140 /// Get the current motor torque given the inverse time step. 0141 /// Unit is N*m. 0142 qreal GetMotorTorque(qreal inv_dt) const; 0143 0144 protected: 0145 0146 friend class b2Joint; 0147 friend class b2GearJoint; 0148 0149 b2RevoluteJoint(const b2RevoluteJointDef* def); 0150 0151 void InitVelocityConstraints(const b2TimeStep& step) override; 0152 void SolveVelocityConstraints(const b2TimeStep& step) override; 0153 0154 bool SolvePositionConstraints(qreal baumgarte) override; 0155 0156 b2Vec2 m_localAnchor1; // relative 0157 b2Vec2 m_localAnchor2; 0158 b2Vec3 m_impulse; 0159 qreal m_motorImpulse; 0160 0161 b2Mat33 m_mass; // effective mass for point-to-point constraint. 0162 qreal m_motorMass; // effective mass for motor/limit angular constraint. 0163 0164 bool m_enableMotor; 0165 qreal m_maxMotorTorque; 0166 qreal m_motorSpeed; 0167 0168 bool m_enableLimit; 0169 qreal m_referenceAngle; 0170 qreal m_lowerAngle; 0171 qreal m_upperAngle; 0172 b2LimitState m_limitState; 0173 }; 0174 0175 inline qreal b2RevoluteJoint::GetMotorSpeed() const 0176 { 0177 return m_motorSpeed; 0178 } 0179 0180 #endif