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_JOINT_H
20 #define B2_JOINT_H
21
22 #include <Box2D/Common/b2Math.h>
23
24 class b2Body;
25 class b2Joint;
26 struct b2SolverData;
27 class b2BlockAllocator;
28
29 enum b2JointType
30 {
31 e_unknownJoint,
32 e_revoluteJoint,
33 e_prismaticJoint,
34 e_distanceJoint,
35 e_pulleyJoint,
36 e_mouseJoint,
37 e_gearJoint,
38 e_wheelJoint,
39 e_weldJoint,
40 e_frictionJoint,
41 e_ropeJoint,
42 e_motorJoint
43 };
44
45 enum b2LimitState
46 {
47 e_inactiveLimit,
48 e_atLowerLimit,
49 e_atUpperLimit,
50 e_equalLimits
51 };
52
53 struct b2Jacobian
54 {
55 b2Vec2 linear;
56 float32 angularA;
57 float32 angularB;
58 };
59
60 /// A joint edge is used to connect bodies and joints together
61 /// in a joint graph where each body is a node and each joint
62 /// is an edge. A joint edge belongs to a doubly linked list
63 /// maintained in each attached body. Each joint has two joint
64 /// nodes, one for each attached body.
65 struct b2JointEdge
66 {
67 b2Body* other; ///< provides quick access to the other body attached.
68 b2Joint* joint; ///< the joint
69 b2JointEdge* prev; ///< the previous joint edge in the body's joint list
70 b2JointEdge* next; ///< the next joint edge in the body's joint list
71 };
72
73 /// Joint definitions are used to construct joints.
74 struct b2JointDef
75 {
b2JointDefb2JointDef76 b2JointDef()
77 {
78 type = e_unknownJoint;
79 userData = NULL;
80 bodyA = NULL;
81 bodyB = NULL;
82 collideConnected = false;
83 }
84
85 /// The joint type is set automatically for concrete joint types.
86 b2JointType type;
87
88 /// Use this to attach application specific data to your joints.
89 void* userData;
90
91 /// The first attached body.
92 b2Body* bodyA;
93
94 /// The second attached body.
95 b2Body* bodyB;
96
97 /// Set this flag to true if the attached bodies should collide.
98 bool collideConnected;
99 };
100
101 /// The base joint class. Joints are used to constraint two bodies together in
102 /// various fashions. Some joints also feature limits and motors.
103 class b2Joint
104 {
105 public:
106
107 /// Get the type of the concrete joint.
108 b2JointType GetType() const;
109
110 /// Get the first body attached to this joint.
111 b2Body* GetBodyA();
112
113 /// Get the second body attached to this joint.
114 b2Body* GetBodyB();
115
116 /// Get the anchor point on bodyA in world coordinates.
117 virtual b2Vec2 GetAnchorA() const = 0;
118
119 /// Get the anchor point on bodyB in world coordinates.
120 virtual b2Vec2 GetAnchorB() const = 0;
121
122 /// Get the reaction force on bodyB at the joint anchor in Newtons.
123 virtual b2Vec2 GetReactionForce(float32 inv_dt) const = 0;
124
125 /// Get the reaction torque on bodyB in N*m.
126 virtual float32 GetReactionTorque(float32 inv_dt) const = 0;
127
128 /// Get the next joint the world joint list.
129 b2Joint* GetNext();
130 const b2Joint* GetNext() const;
131
132 /// Get the user data pointer.
133 void* GetUserData() const;
134
135 /// Set the user data pointer.
136 void SetUserData(void* data);
137
138 /// Short-cut function to determine if either body is inactive.
139 bool IsActive() const;
140
141 /// Get collide connected.
142 /// Note: modifying the collide connect flag won't work correctly because
143 /// the flag is only checked when fixture AABBs begin to overlap.
144 bool GetCollideConnected() const;
145
146 /// Dump this joint to the log file.
Dump()147 virtual void Dump() { b2Log("// Dump is not supported for this joint type.\n"); }
148
149 /// Shift the origin for any points stored in world coordinates.
ShiftOrigin(const b2Vec2 & newOrigin)150 virtual void ShiftOrigin(const b2Vec2& newOrigin) { B2_NOT_USED(newOrigin); }
151
152 protected:
153 friend class b2World;
154 friend class b2Body;
155 friend class b2Island;
156 friend class b2GearJoint;
157
158 static b2Joint* Create(const b2JointDef* def, b2BlockAllocator* allocator);
159 static void Destroy(b2Joint* joint, b2BlockAllocator* allocator);
160
161 b2Joint(const b2JointDef* def);
~b2Joint()162 virtual ~b2Joint() {}
163
164 virtual void InitVelocityConstraints(const b2SolverData& data) = 0;
165 virtual void SolveVelocityConstraints(const b2SolverData& data) = 0;
166
167 // This returns true if the position errors are within tolerance.
168 virtual bool SolvePositionConstraints(const b2SolverData& data) = 0;
169
170 b2JointType m_type;
171 b2Joint* m_prev;
172 b2Joint* m_next;
173 b2JointEdge m_edgeA;
174 b2JointEdge m_edgeB;
175 b2Body* m_bodyA;
176 b2Body* m_bodyB;
177
178 int32 m_index;
179
180 bool m_islandFlag;
181 bool m_collideConnected;
182
183 void* m_userData;
184 };
185
GetType()186 inline b2JointType b2Joint::GetType() const
187 {
188 return m_type;
189 }
190
GetBodyA()191 inline b2Body* b2Joint::GetBodyA()
192 {
193 return m_bodyA;
194 }
195
GetBodyB()196 inline b2Body* b2Joint::GetBodyB()
197 {
198 return m_bodyB;
199 }
200
GetNext()201 inline b2Joint* b2Joint::GetNext()
202 {
203 return m_next;
204 }
205
GetNext()206 inline const b2Joint* b2Joint::GetNext() const
207 {
208 return m_next;
209 }
210
GetUserData()211 inline void* b2Joint::GetUserData() const
212 {
213 return m_userData;
214 }
215
SetUserData(void * data)216 inline void b2Joint::SetUserData(void* data)
217 {
218 m_userData = data;
219 }
220
GetCollideConnected()221 inline bool b2Joint::GetCollideConnected() const
222 {
223 return m_collideConnected;
224 }
225
226 #endif
227