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