1 | /* |
2 | * Copyright (c) 2006-2011 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_REVOLUTE_JOINT_H |
20 | #define B2_REVOLUTE_JOINT_H |
21 | |
22 | #include <Box2D/Dynamics/Joints/b2Joint.h> |
23 | |
24 | /// Revolute joint definition. This requires defining an |
25 | /// anchor point where the bodies are joined. The definition |
26 | /// uses local anchor points so that the initial configuration |
27 | /// can violate the constraint slightly. You also need to |
28 | /// specify the initial relative angle for joint limits. This |
29 | /// helps when saving and loading a game. |
30 | /// The local anchor points are measured from the body's origin |
31 | /// rather than the center of mass because: |
32 | /// 1. you might not know where the center of mass will be. |
33 | /// 2. if you add/remove shapes from a body and recompute the mass, |
34 | /// the joints will be broken. |
35 | struct b2RevoluteJointDef : public b2JointDef |
36 | { |
37 | b2RevoluteJointDef() |
38 | { |
39 | type = e_revoluteJoint; |
40 | localAnchorA.Set(0.0f, 0.0f); |
41 | localAnchorB.Set(0.0f, 0.0f); |
42 | referenceAngle = 0.0f; |
43 | lowerAngle = 0.0f; |
44 | upperAngle = 0.0f; |
45 | maxMotorTorque = 0.0f; |
46 | motorSpeed = 0.0f; |
47 | enableLimit = false; |
48 | enableMotor = false; |
49 | } |
50 | |
51 | /// Initialize the bodies, anchors, and reference angle using a world |
52 | /// anchor point. |
53 | void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor); |
54 | |
55 | /// The local anchor point relative to bodyA's origin. |
56 | b2Vec2 localAnchorA; |
57 | |
58 | /// The local anchor point relative to bodyB's origin. |
59 | b2Vec2 localAnchorB; |
60 | |
61 | /// The bodyB angle minus bodyA angle in the reference state (radians). |
62 | float32 referenceAngle; |
63 | |
64 | /// A flag to enable joint limits. |
65 | bool enableLimit; |
66 | |
67 | /// The lower angle for the joint limit (radians). |
68 | float32 lowerAngle; |
69 | |
70 | /// The upper angle for the joint limit (radians). |
71 | float32 upperAngle; |
72 | |
73 | /// A flag to enable the joint motor. |
74 | bool enableMotor; |
75 | |
76 | /// The desired motor speed. Usually in radians per second. |
77 | float32 motorSpeed; |
78 | |
79 | /// The maximum motor torque used to achieve the desired motor speed. |
80 | /// Usually in N-m. |
81 | float32 maxMotorTorque; |
82 | }; |
83 | |
84 | /// A revolute joint constrains two bodies to share a common point while they |
85 | /// are free to rotate about the point. The relative rotation about the shared |
86 | /// point is the joint angle. You can limit the relative rotation with |
87 | /// a joint limit that specifies a lower and upper angle. You can use a motor |
88 | /// to drive the relative rotation about the shared point. A maximum motor torque |
89 | /// is provided so that infinite forces are not generated. |
90 | class b2RevoluteJoint : public b2Joint |
91 | { |
92 | public: |
93 | b2Vec2 GetAnchorA() const; |
94 | b2Vec2 GetAnchorB() const; |
95 | |
96 | /// The local anchor point relative to bodyA's origin. |
97 | const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; } |
98 | |
99 | /// The local anchor point relative to bodyB's origin. |
100 | const b2Vec2& GetLocalAnchorB() const { return m_localAnchorB; } |
101 | |
102 | /// Get the reference angle. |
103 | float32 GetReferenceAngle() const { return m_referenceAngle; } |
104 | |
105 | /// Get the current joint angle in radians. |
106 | float32 GetJointAngle() const; |
107 | |
108 | /// Get the current joint angle speed in radians per second. |
109 | float32 GetJointSpeed() const; |
110 | |
111 | /// Is the joint limit enabled? |
112 | bool IsLimitEnabled() const; |
113 | |
114 | /// Enable/disable the joint limit. |
115 | void EnableLimit(bool flag); |
116 | |
117 | /// Get the lower joint limit in radians. |
118 | float32 GetLowerLimit() const; |
119 | |
120 | /// Get the upper joint limit in radians. |
121 | float32 GetUpperLimit() const; |
122 | |
123 | /// Set the joint limits in radians. |
124 | void SetLimits(float32 lower, float32 upper); |
125 | |
126 | /// Is the joint motor enabled? |
127 | bool IsMotorEnabled() const; |
128 | |
129 | /// Enable/disable the joint motor. |
130 | void EnableMotor(bool flag); |
131 | |
132 | /// Set the motor speed in radians per second. |
133 | void SetMotorSpeed(float32 speed); |
134 | |
135 | /// Get the motor speed in radians per second. |
136 | float32 GetMotorSpeed() const; |
137 | |
138 | /// Set the maximum motor torque, usually in N-m. |
139 | void SetMaxMotorTorque(float32 torque); |
140 | float32 GetMaxMotorTorque() const { return m_maxMotorTorque; } |
141 | |
142 | /// Get the reaction force given the inverse time step. |
143 | /// Unit is N. |
144 | b2Vec2 GetReactionForce(float32 inv_dt) const; |
145 | |
146 | /// Get the reaction torque due to the joint limit given the inverse time step. |
147 | /// Unit is N*m. |
148 | float32 GetReactionTorque(float32 inv_dt) const; |
149 | |
150 | /// Get the current motor torque given the inverse time step. |
151 | /// Unit is N*m. |
152 | float32 GetMotorTorque(float32 inv_dt) const; |
153 | |
154 | /// Dump to b2Log. |
155 | void Dump(); |
156 | |
157 | protected: |
158 | |
159 | friend class b2Joint; |
160 | friend class b2GearJoint; |
161 | |
162 | b2RevoluteJoint(const b2RevoluteJointDef* def); |
163 | |
164 | void InitVelocityConstraints(const b2SolverData& data); |
165 | void SolveVelocityConstraints(const b2SolverData& data); |
166 | bool SolvePositionConstraints(const b2SolverData& data); |
167 | |
168 | // Solver shared |
169 | b2Vec2 m_localAnchorA; |
170 | b2Vec2 m_localAnchorB; |
171 | b2Vec3 m_impulse; |
172 | float32 m_motorImpulse; |
173 | |
174 | bool m_enableMotor; |
175 | float32 m_maxMotorTorque; |
176 | float32 m_motorSpeed; |
177 | |
178 | bool m_enableLimit; |
179 | float32 m_referenceAngle; |
180 | float32 m_lowerAngle; |
181 | float32 m_upperAngle; |
182 | |
183 | // Solver temp |
184 | int32 m_indexA; |
185 | int32 m_indexB; |
186 | b2Vec2 m_rA; |
187 | b2Vec2 m_rB; |
188 | b2Vec2 m_localCenterA; |
189 | b2Vec2 m_localCenterB; |
190 | float32 m_invMassA; |
191 | float32 m_invMassB; |
192 | float32 m_invIA; |
193 | float32 m_invIB; |
194 | b2Mat33 m_mass; // effective mass for point-to-point constraint. |
195 | float32 m_motorMass; // effective mass for motor/limit angular constraint. |
196 | b2LimitState m_limitState; |
197 | }; |
198 | |
199 | inline float32 b2RevoluteJoint::GetMotorSpeed() const |
200 | { |
201 | return m_motorSpeed; |
202 | } |
203 | |
204 | #endif |
205 | |