1 | /* |
2 | * Copyright (c) 2006-2007 Erin Catto http://www.box2d.org |
3 | * |
4 | * This software is provided 'as-is', without any express or implied |
5 | * warranty. In no event will the authors be held liable for any damages |
6 | * arising from the use of this software. |
7 | * Permission is granted to anyone to use this software for any purpose, |
8 | * including commercial applications, and to alter it and redistribute it |
9 | * freely, subject to the following restrictions: |
10 | * 1. The origin of this software must not be misrepresented; you must not |
11 | * claim that you wrote the original software. If you use this software |
12 | * in a product, an acknowledgment in the product documentation would be |
13 | * appreciated but is not required. |
14 | * 2. Altered source versions must be plainly marked as such, and must not be |
15 | * misrepresented as being the original software. |
16 | * 3. This notice may not be removed or altered from any source distribution. |
17 | */ |
18 | |
19 | #ifndef B2_DISTANCE_JOINT_H |
20 | #define B2_DISTANCE_JOINT_H |
21 | |
22 | #include <Box2D/Dynamics/Joints/b2Joint.h> |
23 | |
24 | /// Distance joint definition. This requires defining an |
25 | /// anchor point on both bodies and the non-zero length of the |
26 | /// distance joint. The definition uses local anchor points |
27 | /// so that the initial configuration can violate the constraint |
28 | /// slightly. This helps when saving and loading a game. |
29 | /// @warning Do not use a zero or short length. |
30 | struct b2DistanceJointDef : public b2JointDef |
31 | { |
32 | b2DistanceJointDef() |
33 | { |
34 | type = e_distanceJoint; |
35 | localAnchorA.Set(0.0f, 0.0f); |
36 | localAnchorB.Set(0.0f, 0.0f); |
37 | length = 1.0f; |
38 | frequencyHz = 0.0f; |
39 | dampingRatio = 0.0f; |
40 | } |
41 | |
42 | /// Initialize the bodies, anchors, and length using the world |
43 | /// anchors. |
44 | void Initialize(b2Body* bodyA, b2Body* bodyB, |
45 | const b2Vec2& anchorA, const b2Vec2& anchorB); |
46 | |
47 | /// The local anchor point relative to bodyA's origin. |
48 | b2Vec2 localAnchorA; |
49 | |
50 | /// The local anchor point relative to bodyB's origin. |
51 | b2Vec2 localAnchorB; |
52 | |
53 | /// The natural length between the anchor points. |
54 | float32 length; |
55 | |
56 | /// The mass-spring-damper frequency in Hertz. A value of 0 |
57 | /// disables softness. |
58 | float32 frequencyHz; |
59 | |
60 | /// The damping ratio. 0 = no damping, 1 = critical damping. |
61 | float32 dampingRatio; |
62 | }; |
63 | |
64 | /// A distance joint constrains two points on two bodies |
65 | /// to remain at a fixed distance from each other. You can view |
66 | /// this as a massless, rigid rod. |
67 | class b2DistanceJoint : public b2Joint |
68 | { |
69 | public: |
70 | |
71 | b2Vec2 GetAnchorA() const; |
72 | b2Vec2 GetAnchorB() const; |
73 | |
74 | /// Get the reaction force given the inverse time step. |
75 | /// Unit is N. |
76 | b2Vec2 GetReactionForce(float32 inv_dt) const; |
77 | |
78 | /// Get the reaction torque given the inverse time step. |
79 | /// Unit is N*m. This is always zero for a distance joint. |
80 | float32 GetReactionTorque(float32 inv_dt) const; |
81 | |
82 | /// The local anchor point relative to bodyA's origin. |
83 | const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; } |
84 | |
85 | /// The local anchor point relative to bodyB's origin. |
86 | const b2Vec2& GetLocalAnchorB() const { return m_localAnchorB; } |
87 | |
88 | /// Set/get the natural length. |
89 | /// Manipulating the length can lead to non-physical behavior when the frequency is zero. |
90 | void SetLength(float32 length); |
91 | float32 GetLength() const; |
92 | |
93 | /// Set/get frequency in Hz. |
94 | void SetFrequency(float32 hz); |
95 | float32 GetFrequency() const; |
96 | |
97 | /// Set/get damping ratio. |
98 | void SetDampingRatio(float32 ratio); |
99 | float32 GetDampingRatio() const; |
100 | |
101 | /// Dump joint to dmLog |
102 | void Dump(); |
103 | |
104 | protected: |
105 | |
106 | friend class b2Joint; |
107 | b2DistanceJoint(const b2DistanceJointDef* data); |
108 | |
109 | void InitVelocityConstraints(const b2SolverData& data); |
110 | void SolveVelocityConstraints(const b2SolverData& data); |
111 | bool SolvePositionConstraints(const b2SolverData& data); |
112 | |
113 | float32 m_frequencyHz; |
114 | float32 m_dampingRatio; |
115 | float32 m_bias; |
116 | |
117 | // Solver shared |
118 | b2Vec2 m_localAnchorA; |
119 | b2Vec2 m_localAnchorB; |
120 | float32 m_gamma; |
121 | float32 m_impulse; |
122 | float32 m_length; |
123 | |
124 | // Solver temp |
125 | int32 m_indexA; |
126 | int32 m_indexB; |
127 | b2Vec2 m_u; |
128 | b2Vec2 m_rA; |
129 | b2Vec2 m_rB; |
130 | b2Vec2 m_localCenterA; |
131 | b2Vec2 m_localCenterB; |
132 | float32 m_invMassA; |
133 | float32 m_invMassB; |
134 | float32 m_invIA; |
135 | float32 m_invIB; |
136 | float32 m_mass; |
137 | }; |
138 | |
139 | inline void b2DistanceJoint::SetLength(float32 length) |
140 | { |
141 | m_length = length; |
142 | } |
143 | |
144 | inline float32 b2DistanceJoint::GetLength() const |
145 | { |
146 | return m_length; |
147 | } |
148 | |
149 | inline void b2DistanceJoint::SetFrequency(float32 hz) |
150 | { |
151 | m_frequencyHz = hz; |
152 | } |
153 | |
154 | inline float32 b2DistanceJoint::GetFrequency() const |
155 | { |
156 | return m_frequencyHz; |
157 | } |
158 | |
159 | inline void b2DistanceJoint::SetDampingRatio(float32 ratio) |
160 | { |
161 | m_dampingRatio = ratio; |
162 | } |
163 | |
164 | inline float32 b2DistanceJoint::GetDampingRatio() const |
165 | { |
166 | return m_dampingRatio; |
167 | } |
168 | |
169 | #endif |
170 | |