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