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

0001 /*
0002 * Copyright (c) 2006-2007 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_DISTANCE_JOINT_H
0020 #define B2_DISTANCE_JOINT_H
0021 
0022 #include <Box2D/Dynamics/Joints/b2Joint.h>
0023 
0024 /// Distance joint definition. This requires defining an
0025 /// anchor point on both bodies and the non-zero length of the
0026 /// distance joint. The definition uses local anchor points
0027 /// so that the initial configuration can violate the constraint
0028 /// slightly. This helps when saving and loading a game.
0029 /// @warning Do not use a zero or short length.
0030 struct b2DistanceJointDef : public b2JointDef
0031 {
0032     b2DistanceJointDef()
0033     {
0034         type = e_distanceJoint;
0035         localAnchorA.Set(0.0f, 0.0f);
0036         localAnchorB.Set(0.0f, 0.0f);
0037         length = 1.0f;
0038         frequencyHz = 0.0f;
0039         dampingRatio = 0.0f;
0040     }
0041 
0042     /// Initialize the bodies, anchors, and length using the world
0043     /// anchors.
0044     void Initialize(b2Body* bodyA, b2Body* bodyB,
0045                     const b2Vec2& anchorA, const b2Vec2& anchorB);
0046 
0047     /// The local anchor point relative to bodyA's origin.
0048     b2Vec2 localAnchorA;
0049 
0050     /// The local anchor point relative to bodyB's origin.
0051     b2Vec2 localAnchorB;
0052 
0053     /// The natural length between the anchor points.
0054     float32 length;
0055 
0056     /// The mass-spring-damper frequency in Hertz. A value of 0
0057     /// disables softness.
0058     float32 frequencyHz;
0059 
0060     /// The damping ratio. 0 = no damping, 1 = critical damping.
0061     float32 dampingRatio;
0062 };
0063 
0064 /// A distance joint constrains two points on two bodies
0065 /// to remain at a fixed distance from each other. You can view
0066 /// this as a massless, rigid rod.
0067 class b2DistanceJoint : public b2Joint
0068 {
0069 public:
0070 
0071     b2Vec2 GetAnchorA() const;
0072     b2Vec2 GetAnchorB() const;
0073 
0074     /// Get the reaction force given the inverse time step.
0075     /// Unit is N.
0076     b2Vec2 GetReactionForce(float32 inv_dt) const;
0077 
0078     /// Get the reaction torque given the inverse time step.
0079     /// Unit is N*m. This is always zero for a distance joint.
0080     float32 GetReactionTorque(float32 inv_dt) const;
0081 
0082     /// The local anchor point relative to bodyA's origin.
0083     const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; }
0084 
0085     /// The local anchor point relative to bodyB's origin.
0086     const b2Vec2& GetLocalAnchorB() const  { return m_localAnchorB; }
0087 
0088     /// Set/get the natural length.
0089     /// Manipulating the length can lead to non-physical behavior when the frequency is zero.
0090     void SetLength(float32 length);
0091     float32 GetLength() const;
0092 
0093     /// Set/get frequency in Hz.
0094     void SetFrequency(float32 hz);
0095     float32 GetFrequency() const;
0096 
0097     /// Set/get damping ratio.
0098     void SetDampingRatio(float32 ratio);
0099     float32 GetDampingRatio() const;
0100 
0101     /// Dump joint to dmLog
0102     void Dump();
0103 
0104 protected:
0105 
0106     friend class b2Joint;
0107     b2DistanceJoint(const b2DistanceJointDef* data);
0108 
0109     void InitVelocityConstraints(const b2SolverData& data);
0110     void SolveVelocityConstraints(const b2SolverData& data);
0111     bool SolvePositionConstraints(const b2SolverData& data);
0112 
0113     float32 m_frequencyHz;
0114     float32 m_dampingRatio;
0115     float32 m_bias;
0116 
0117     // Solver shared
0118     b2Vec2 m_localAnchorA;
0119     b2Vec2 m_localAnchorB;
0120     float32 m_gamma;
0121     float32 m_impulse;
0122     float32 m_length;
0123 
0124     // Solver temp
0125     int32 m_indexA;
0126     int32 m_indexB;
0127     b2Vec2 m_u;
0128     b2Vec2 m_rA;
0129     b2Vec2 m_rB;
0130     b2Vec2 m_localCenterA;
0131     b2Vec2 m_localCenterB;
0132     float32 m_invMassA;
0133     float32 m_invMassB;
0134     float32 m_invIA;
0135     float32 m_invIB;
0136     float32 m_mass;
0137 };
0138 
0139 inline void b2DistanceJoint::SetLength(float32 length)
0140 {
0141     m_length = length;
0142 }
0143 
0144 inline float32 b2DistanceJoint::GetLength() const
0145 {
0146     return m_length;
0147 }
0148 
0149 inline void b2DistanceJoint::SetFrequency(float32 hz)
0150 {
0151     m_frequencyHz = hz;
0152 }
0153 
0154 inline float32 b2DistanceJoint::GetFrequency() const
0155 {
0156     return m_frequencyHz;
0157 }
0158 
0159 inline void b2DistanceJoint::SetDampingRatio(float32 ratio)
0160 {
0161     m_dampingRatio = ratio;
0162 }
0163 
0164 inline float32 b2DistanceJoint::GetDampingRatio() const
0165 {
0166     return m_dampingRatio;
0167 }
0168 
0169 #endif