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