File indexing completed on 2025-08-03 03:49:58
0001 /* 0002 * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 0003 * 0004 * This software is provided 'as-is', without any express or implied 0005 * warranty. In no event will the authors be held liable for any damages 0006 * arising from the use of this software. 0007 * Permission is granted to anyone to use this software for any purpose, 0008 * including commercial applications, and to alter it and redistribute it 0009 * freely, subject to the following restrictions: 0010 * 1. The origin of this software must not be misrepresented; you must not 0011 * claim that you wrote the original software. If you use this software 0012 * in a product, an acknowledgment in the product documentation would be 0013 * appreciated but is not required. 0014 * 2. Altered source versions must be plainly marked as such, and must not be 0015 * misrepresented as being the original software. 0016 * 3. This notice may not be removed or altered from any source distribution. 0017 */ 0018 0019 #ifndef B2_JOINT_H 0020 #define B2_JOINT_H 0021 0022 #include <Box2D/Common/b2Math.h> 0023 0024 class b2Body; 0025 class b2Joint; 0026 struct b2TimeStep; 0027 class b2BlockAllocator; 0028 0029 enum b2JointType 0030 { 0031 e_unknownJoint, 0032 e_revoluteJoint, 0033 e_prismaticJoint, 0034 e_distanceJoint, 0035 e_pulleyJoint, 0036 e_mouseJoint, 0037 e_gearJoint, 0038 e_lineJoint, 0039 e_weldJoint, 0040 e_frictionJoint, 0041 e_ropeJoint 0042 }; 0043 0044 enum b2LimitState 0045 { 0046 e_inactiveLimit, 0047 e_atLowerLimit, 0048 e_atUpperLimit, 0049 e_equalLimits 0050 }; 0051 0052 struct b2Jacobian 0053 { 0054 b2Vec2 linearA; 0055 qreal angularA; 0056 b2Vec2 linearB; 0057 qreal angularB; 0058 0059 void SetZero(); 0060 void Set(const b2Vec2& x1, qreal a1, const b2Vec2& x2, qreal a2); 0061 qreal Compute(const b2Vec2& x1, qreal a1, const b2Vec2& x2, qreal a2); 0062 }; 0063 0064 /// A joint edge is used to connect bodies and joints together 0065 /// in a joint graph where each body is a node and each joint 0066 /// is an edge. A joint edge belongs to a doubly linked list 0067 /// maintained in each attached body. Each joint has two joint 0068 /// nodes, one for each attached body. 0069 struct b2JointEdge 0070 { 0071 b2Body* other; ///< provides quick access to the other body attached. 0072 b2Joint* joint; ///< the joint 0073 b2JointEdge* prev; ///< the previous joint edge in the body's joint list 0074 b2JointEdge* next; ///< the next joint edge in the body's joint list 0075 }; 0076 0077 /// Joint definitions are used to construct joints. 0078 struct b2JointDef 0079 { 0080 b2JointDef() 0081 { 0082 type = e_unknownJoint; 0083 userData = NULL; 0084 bodyA = NULL; 0085 bodyB = NULL; 0086 collideConnected = false; 0087 } 0088 0089 /// The joint type is set automatically for concrete joint types. 0090 b2JointType type; 0091 0092 /// Use this to attach application specific data to your joints. 0093 void* userData; 0094 0095 /// The first attached body. 0096 b2Body* bodyA; 0097 0098 /// The second attached body. 0099 b2Body* bodyB; 0100 0101 /// Set this flag to true if the attached bodies should collide. 0102 bool collideConnected; 0103 }; 0104 0105 /// The base joint class. Joints are used to constraint two bodies together in 0106 /// various fashions. Some joints also feature limits and motors. 0107 class b2Joint 0108 { 0109 public: 0110 0111 /// Get the type of the concrete joint. 0112 b2JointType GetType() const; 0113 0114 /// Get the first body attached to this joint. 0115 b2Body* GetBodyA(); 0116 0117 /// Get the second body attached to this joint. 0118 b2Body* GetBodyB(); 0119 0120 /// Get the anchor point on bodyA in world coordinates. 0121 virtual b2Vec2 GetAnchorA() const = 0; 0122 0123 /// Get the anchor point on bodyB in world coordinates. 0124 virtual b2Vec2 GetAnchorB() const = 0; 0125 0126 /// Get the reaction force on body2 at the joint anchor in Newtons. 0127 virtual b2Vec2 GetReactionForce(qreal inv_dt) const = 0; 0128 0129 /// Get the reaction torque on body2 in N*m. 0130 virtual qreal GetReactionTorque(qreal inv_dt) const = 0; 0131 0132 /// Get the next joint the world joint list. 0133 b2Joint* GetNext(); 0134 const b2Joint* GetNext() const; 0135 0136 /// Get the user data pointer. 0137 void* GetUserData() const; 0138 0139 /// Set the user data pointer. 0140 void SetUserData(void* data); 0141 0142 /// Short-cut function to determine if either body is inactive. 0143 bool IsActive() const; 0144 0145 protected: 0146 friend class b2World; 0147 friend class b2Body; 0148 friend class b2Island; 0149 0150 static b2Joint* Create(const b2JointDef* def, b2BlockAllocator* allocator); 0151 static void Destroy(b2Joint* joint, b2BlockAllocator* allocator); 0152 0153 b2Joint(const b2JointDef* def); 0154 virtual ~b2Joint() {} 0155 0156 virtual void InitVelocityConstraints(const b2TimeStep& step) = 0; 0157 virtual void SolveVelocityConstraints(const b2TimeStep& step) = 0; 0158 0159 // This returns true if the position errors are within tolerance. 0160 virtual bool SolvePositionConstraints(qreal baumgarte) = 0; 0161 0162 b2JointType m_type; 0163 b2Joint* m_prev; 0164 b2Joint* m_next; 0165 b2JointEdge m_edgeA; 0166 b2JointEdge m_edgeB; 0167 b2Body* m_bodyA; 0168 b2Body* m_bodyB; 0169 0170 bool m_islandFlag; 0171 bool m_collideConnected; 0172 0173 void* m_userData; 0174 0175 // Cache here per time step to reduce cache misses. 0176 // TODO_ERIN will be wrong if the mass changes. 0177 b2Vec2 m_localCenterA, m_localCenterB; 0178 qreal m_invMassA, m_invIA; 0179 qreal m_invMassB, m_invIB; 0180 }; 0181 0182 inline void b2Jacobian::SetZero() 0183 { 0184 linearA.SetZero(); angularA = 0.0f; 0185 linearB.SetZero(); angularB = 0.0f; 0186 } 0187 0188 inline void b2Jacobian::Set(const b2Vec2& x1, qreal a1, const b2Vec2& x2, qreal a2) 0189 { 0190 linearA = x1; angularA = a1; 0191 linearB = x2; angularB = a2; 0192 } 0193 0194 inline qreal b2Jacobian::Compute(const b2Vec2& x1, qreal a1, const b2Vec2& x2, qreal a2) 0195 { 0196 return b2Dot(linearA, x1) + angularA * a1 + b2Dot(linearB, x2) + angularB * a2; 0197 } 0198 0199 inline b2JointType b2Joint::GetType() const 0200 { 0201 return m_type; 0202 } 0203 0204 inline b2Body* b2Joint::GetBodyA() 0205 { 0206 return m_bodyA; 0207 } 0208 0209 inline b2Body* b2Joint::GetBodyB() 0210 { 0211 return m_bodyB; 0212 } 0213 0214 inline b2Joint* b2Joint::GetNext() 0215 { 0216 return m_next; 0217 } 0218 0219 inline const b2Joint* b2Joint::GetNext() const 0220 { 0221 return m_next; 0222 } 0223 0224 inline void* b2Joint::GetUserData() const 0225 { 0226 return m_userData; 0227 } 0228 0229 inline void b2Joint::SetUserData(void* data) 0230 { 0231 m_userData = data; 0232 } 0233 0234 #endif