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
24class b2Body;
25class b2Joint;
26struct b2SolverData;
27class b2BlockAllocator;
28
29enum 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
45enum b2LimitState
46{
47 e_inactiveLimit,
48 e_atLowerLimit,
49 e_atUpperLimit,
50 e_equalLimits
51};
52
53struct 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.
65struct 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.
74struct b2JointDef
75{
76 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.
103class b2Joint
104{
105public:
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.
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.
150 virtual void ShiftOrigin(const b2Vec2& newOrigin) { B2_NOT_USED(newOrigin); }
151
152protected:
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);
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
186inline b2JointType b2Joint::GetType() const
187{
188 return m_type;
189}
190
191inline b2Body* b2Joint::GetBodyA()
192{
193 return m_bodyA;
194}
195
196inline b2Body* b2Joint::GetBodyB()
197{
198 return m_bodyB;
199}
200
201inline b2Joint* b2Joint::GetNext()
202{
203 return m_next;
204}
205
206inline const b2Joint* b2Joint::GetNext() const
207{
208 return m_next;
209}
210
211inline void* b2Joint::GetUserData() const
212{
213 return m_userData;
214}
215
216inline void b2Joint::SetUserData(void* data)
217{
218 m_userData = data;
219}
220
221inline bool b2Joint::GetCollideConnected() const
222{
223 return m_collideConnected;
224}
225
226#endif
227