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