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