Home | History | Annotate | Download | only in Joints
      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 {
     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.
    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.
    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 
    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);
    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 
    186 inline b2JointType b2Joint::GetType() const
    187 {
    188 	return m_type;
    189 }
    190 
    191 inline b2Body* b2Joint::GetBodyA()
    192 {
    193 	return m_bodyA;
    194 }
    195 
    196 inline b2Body* b2Joint::GetBodyB()
    197 {
    198 	return m_bodyB;
    199 }
    200 
    201 inline b2Joint* b2Joint::GetNext()
    202 {
    203 	return m_next;
    204 }
    205 
    206 inline const b2Joint* b2Joint::GetNext() const
    207 {
    208 	return m_next;
    209 }
    210 
    211 inline void* b2Joint::GetUserData() const
    212 {
    213 	return m_userData;
    214 }
    215 
    216 inline void b2Joint::SetUserData(void* data)
    217 {
    218 	m_userData = data;
    219 }
    220 
    221 inline bool b2Joint::GetCollideConnected() const
    222 {
    223 	return m_collideConnected;
    224 }
    225 
    226 #endif
    227