first commit
[blok] / Box2D / Source / Dynamics / Joints / b2Joint.h
diff --git a/Box2D/Source/Dynamics/Joints/b2Joint.h b/Box2D/Source/Dynamics/Joints/b2Joint.h
new file mode 100644 (file)
index 0000000..11744e7
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef JOINT_H
+#define JOINT_H
+
+#include "../../Common/b2Math.h"
+
+class b2Body;
+class b2Joint;
+struct b2TimeStep;
+class b2BlockAllocator;
+
+enum b2JointType
+{
+       e_unknownJoint,
+       e_revoluteJoint,
+       e_prismaticJoint,
+       e_distanceJoint,
+       e_pulleyJoint,
+       e_mouseJoint,
+       e_gearJoint
+};
+
+enum b2LimitState
+{
+       e_inactiveLimit,
+       e_atLowerLimit,
+       e_atUpperLimit,
+       e_equalLimits
+};
+
+struct b2Jacobian
+{
+       b2Vec2 linear1;
+       float32 angular1;
+       b2Vec2 linear2;
+       float32 angular2;
+
+       void SetZero();
+       void Set(const b2Vec2& x1, float32 a1, const b2Vec2& x2, float32 a2);
+       float32 Compute(const b2Vec2& x1, float32 a1, const b2Vec2& x2, float32 a2);
+};
+
+/// A joint edge is used to connect bodies and joints together
+/// in a joint graph where each body is a node and each joint
+/// is an edge. A joint edge belongs to a doubly linked list
+/// maintained in each attached body. Each joint has two joint
+/// nodes, one for each attached body.
+struct b2JointEdge
+{
+       b2Body* other;                  ///< provides quick access to the other body attached.
+       b2Joint* joint;                 ///< the joint
+       b2JointEdge* prev;              ///< the previous joint edge in the body's joint list
+       b2JointEdge* next;              ///< the next joint edge in the body's joint list
+};
+
+/// Joint definitions are used to construct joints.
+struct b2JointDef
+{
+       b2JointDef()
+       {
+               type = e_unknownJoint;
+               userData = NULL;
+               body1 = NULL;
+               body2 = NULL;
+               collideConnected = false;
+       }
+
+       /// The joint type is set automatically for concrete joint types.
+       b2JointType type;
+
+       /// Use this to attach application specific data to your joints.
+       void* userData;
+
+       /// The first attached body.
+       b2Body* body1;
+
+       /// The second attached body.
+       b2Body* body2;
+
+       /// Set this flag to true if the attached bodies should collide.
+       bool collideConnected;
+};
+
+/// The base joint class. Joints are used to constraint two bodies together in
+/// various fashions. Some joints also feature limits and motors.
+class b2Joint
+{
+public:
+
+       /// Get the type of the concrete joint.
+       b2JointType GetType() const;
+
+       /// Get the first body attached to this joint.
+       b2Body* GetBody1();
+
+       /// Get the second body attached to this joint.
+       b2Body* GetBody2();
+
+       /// Get the anchor point on body1 in world coordinates.
+       virtual b2Vec2 GetAnchor1() const = 0;
+
+       /// Get the anchor point on body2 in world coordinates.
+       virtual b2Vec2 GetAnchor2() const = 0;
+
+       /// Get the reaction force on body2 at the joint anchor.
+       virtual b2Vec2 GetReactionForce() const = 0;
+
+       /// Get the reaction torque on body2.
+       virtual float32 GetReactionTorque() const = 0;
+
+       /// Get the next joint the world joint list.
+       b2Joint* GetNext();
+
+       /// Get the user data pointer.
+       void* GetUserData();
+
+       /// Set the user data pointer.
+       void SetUserData(void* data);
+
+       //--------------- Internals Below -------------------
+protected:
+       friend class b2World;
+       friend class b2Body;
+       friend class b2Island;
+
+       static b2Joint* Create(const b2JointDef* def, b2BlockAllocator* allocator);
+       static void Destroy(b2Joint* joint, b2BlockAllocator* allocator);
+
+       b2Joint(const b2JointDef* def);
+       virtual ~b2Joint() {}
+
+       virtual void InitVelocityConstraints(const b2TimeStep& step) = 0;
+       virtual void SolveVelocityConstraints(const b2TimeStep& step) = 0;
+
+       // This returns true if the position errors are within tolerance.
+       virtual void InitPositionConstraints() {}
+       virtual bool SolvePositionConstraints() = 0;
+
+       b2JointType m_type;
+       b2Joint* m_prev;
+       b2Joint* m_next;
+       b2JointEdge m_node1;
+       b2JointEdge m_node2;
+       b2Body* m_body1;
+       b2Body* m_body2;
+
+       float32 m_inv_dt;
+
+       bool m_islandFlag;
+       bool m_collideConnected;
+
+       void* m_userData;
+};
+
+inline void b2Jacobian::SetZero()
+{
+       linear1.SetZero(); angular1 = 0.0f;
+       linear2.SetZero(); angular2 = 0.0f;
+}
+
+inline void b2Jacobian::Set(const b2Vec2& x1, float32 a1, const b2Vec2& x2, float32 a2)
+{
+       linear1 = x1; angular1 = a1;
+       linear2 = x2; angular2 = a2;
+}
+
+inline float32 b2Jacobian::Compute(const b2Vec2& x1, float32 a1, const b2Vec2& x2, float32 a2)
+{
+       return b2Dot(linear1, x1) + angular1 * a1 + b2Dot(linear2, x2) + angular2 * a2;
+}
+
+inline b2JointType b2Joint::GetType() const
+{
+       return m_type;
+}
+
+inline b2Body* b2Joint::GetBody1()
+{
+       return m_body1;
+}
+
+inline b2Body* b2Joint::GetBody2()
+{
+       return m_body2;
+}
+
+inline b2Joint* b2Joint::GetNext()
+{
+       return m_next;
+}
+
+inline void* b2Joint::GetUserData()
+{
+       return m_userData;
+}
+
+inline void b2Joint::SetUserData(void* data)
+{
+       m_userData = data;
+}
+
+#endif