File indexing completed on 2024-12-29 03:29:29

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_WHEEL_JOINT_H
0020 #define B2_WHEEL_JOINT_H
0021 
0022 #include <Box2D/Dynamics/Joints/b2Joint.h>
0023 
0024 /// Wheel joint definition. This requires defining a line of
0025 /// motion using an axis and an anchor point. The definition uses local
0026 /// anchor points and a local axis so that the initial configuration
0027 /// can violate the constraint slightly. The joint translation is zero
0028 /// when the local anchor points coincide in world space. Using local
0029 /// anchors and a local axis helps when saving and loading a game.
0030 struct b2WheelJointDef : public b2JointDef
0031 {
0032     b2WheelJointDef()
0033     {
0034         type = e_wheelJoint;
0035         localAnchorA.SetZero();
0036         localAnchorB.SetZero();
0037         localAxisA.Set(1.0f, 0.0f);
0038         enableMotor = false;
0039         maxMotorTorque = 0.0f;
0040         motorSpeed = 0.0f;
0041         frequencyHz = 2.0f;
0042         dampingRatio = 0.7f;
0043     }
0044 
0045     /// Initialize the bodies, anchors, axis, and reference angle using the world
0046     /// anchor and world axis.
0047     void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor, const b2Vec2& axis);
0048 
0049     /// The local anchor point relative to bodyA's origin.
0050     b2Vec2 localAnchorA;
0051 
0052     /// The local anchor point relative to bodyB's origin.
0053     b2Vec2 localAnchorB;
0054 
0055     /// The local translation axis in bodyA.
0056     b2Vec2 localAxisA;
0057 
0058     /// Enable/disable the joint motor.
0059     bool enableMotor;
0060 
0061     /// The maximum motor torque, usually in N-m.
0062     float32 maxMotorTorque;
0063 
0064     /// The desired motor speed in radians per second.
0065     float32 motorSpeed;
0066 
0067     /// Suspension frequency, zero indicates no suspension
0068     float32 frequencyHz;
0069 
0070     /// Suspension damping ratio, one indicates critical damping
0071     float32 dampingRatio;
0072 };
0073 
0074 /// A wheel joint. This joint provides two degrees of freedom: translation
0075 /// along an axis fixed in bodyA and rotation in the plane. In other words, it is a point to
0076 /// line constraint with a rotational motor and a linear spring/damper.
0077 /// This joint is designed for vehicle suspensions.
0078 class b2WheelJoint : public b2Joint
0079 {
0080 public:
0081     b2Vec2 GetAnchorA() const;
0082     b2Vec2 GetAnchorB() const;
0083 
0084     b2Vec2 GetReactionForce(float32 inv_dt) const;
0085     float32 GetReactionTorque(float32 inv_dt) const;
0086 
0087     /// The local anchor point relative to bodyA's origin.
0088     const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; }
0089 
0090     /// The local anchor point relative to bodyB's origin.
0091     const b2Vec2& GetLocalAnchorB() const  { return m_localAnchorB; }
0092 
0093     /// The local joint axis relative to bodyA.
0094     const b2Vec2& GetLocalAxisA() const { return m_localXAxisA; }
0095 
0096     /// Get the current joint translation, usually in meters.
0097     float32 GetJointTranslation() const;
0098 
0099     /// Get the current joint translation speed, usually in meters per second.
0100     float32 GetJointSpeed() const;
0101 
0102     /// Is the joint motor enabled?
0103     bool IsMotorEnabled() const;
0104 
0105     /// Enable/disable the joint motor.
0106     void EnableMotor(bool flag);
0107 
0108     /// Set the motor speed, usually in radians per second.
0109     void SetMotorSpeed(float32 speed);
0110 
0111     /// Get the motor speed, usually in radians per second.
0112     float32 GetMotorSpeed() const;
0113 
0114     /// Set/Get the maximum motor force, usually in N-m.
0115     void SetMaxMotorTorque(float32 torque);
0116     float32 GetMaxMotorTorque() const;
0117 
0118     /// Get the current motor torque given the inverse time step, usually in N-m.
0119     float32 GetMotorTorque(float32 inv_dt) const;
0120 
0121     /// Set/Get the spring frequency in hertz. Setting the frequency to zero disables the spring.
0122     void SetSpringFrequencyHz(float32 hz);
0123     float32 GetSpringFrequencyHz() const;
0124 
0125     /// Set/Get the spring damping ratio
0126     void SetSpringDampingRatio(float32 ratio);
0127     float32 GetSpringDampingRatio() const;
0128 
0129     /// Dump to b2Log
0130     void Dump();
0131 
0132 protected:
0133 
0134     friend class b2Joint;
0135     b2WheelJoint(const b2WheelJointDef* def);
0136 
0137     void InitVelocityConstraints(const b2SolverData& data);
0138     void SolveVelocityConstraints(const b2SolverData& data);
0139     bool SolvePositionConstraints(const b2SolverData& data);
0140 
0141     float32 m_frequencyHz;
0142     float32 m_dampingRatio;
0143 
0144     // Solver shared
0145     b2Vec2 m_localAnchorA;
0146     b2Vec2 m_localAnchorB;
0147     b2Vec2 m_localXAxisA;
0148     b2Vec2 m_localYAxisA;
0149 
0150     float32 m_impulse;
0151     float32 m_motorImpulse;
0152     float32 m_springImpulse;
0153 
0154     float32 m_maxMotorTorque;
0155     float32 m_motorSpeed;
0156     bool m_enableMotor;
0157 
0158     // Solver temp
0159     int32 m_indexA;
0160     int32 m_indexB;
0161     b2Vec2 m_localCenterA;
0162     b2Vec2 m_localCenterB;
0163     float32 m_invMassA;
0164     float32 m_invMassB;
0165     float32 m_invIA;
0166     float32 m_invIB;
0167 
0168     b2Vec2 m_ax, m_ay;
0169     float32 m_sAx, m_sBx;
0170     float32 m_sAy, m_sBy;
0171 
0172     float32 m_mass;
0173     float32 m_motorMass;
0174     float32 m_springMass;
0175 
0176     float32 m_bias;
0177     float32 m_gamma;
0178 };
0179 
0180 inline float32 b2WheelJoint::GetMotorSpeed() const
0181 {
0182     return m_motorSpeed;
0183 }
0184 
0185 inline float32 b2WheelJoint::GetMaxMotorTorque() const
0186 {
0187     return m_maxMotorTorque;
0188 }
0189 
0190 inline void b2WheelJoint::SetSpringFrequencyHz(float32 hz)
0191 {
0192     m_frequencyHz = hz;
0193 }
0194 
0195 inline float32 b2WheelJoint::GetSpringFrequencyHz() const
0196 {
0197     return m_frequencyHz;
0198 }
0199 
0200 inline void b2WheelJoint::SetSpringDampingRatio(float32 ratio)
0201 {
0202     m_dampingRatio = ratio;
0203 }
0204 
0205 inline float32 b2WheelJoint::GetSpringDampingRatio() const
0206 {
0207     return m_dampingRatio;
0208 }
0209 
0210 #endif