rollmorad hinzugefügt

This commit is contained in:
2015-11-15 23:18:06 +00:00
commit 948a6775ab
850 changed files with 117333 additions and 0 deletions
@@ -0,0 +1,46 @@
/*
* 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 CIRCLE_CONTACT_H
#define CIRCLE_CONTACT_H
#include "../../Common/b2Math.h"
#include "../../Collision/b2Collision.h"
#include "b2Contact.h"
class b2BlockAllocator;
class b2CircleContact : public b2Contact
{
public:
static b2Contact* Create(b2Shape* shape1, b2Shape* shape2, b2BlockAllocator* allocator);
static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
b2CircleContact(b2Shape* shape1, b2Shape* shape2);
~b2CircleContact() {}
void Evaluate(b2ContactListener* listener);
b2Manifold* GetManifolds()
{
return &m_manifold;
}
b2Manifold m_manifold;
};
#endif
@@ -0,0 +1,183 @@
/*
* 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 CONTACT_H
#define CONTACT_H
#include "../../Common/b2Math.h"
#include "../../Collision/b2Collision.h"
#include "../../Collision/Shapes/b2Shape.h"
class b2Body;
class b2Contact;
class b2World;
class b2BlockAllocator;
class b2StackAllocator;
class b2ContactListener;
typedef b2Contact* b2ContactCreateFcn(b2Shape* shape1, b2Shape* shape2, b2BlockAllocator* allocator);
typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator);
struct b2ContactRegister
{
b2ContactCreateFcn* createFcn;
b2ContactDestroyFcn* destroyFcn;
bool primary;
};
/// A contact edge is used to connect bodies and contacts together
/// in a contact graph where each body is a node and each contact
/// is an edge. A contact edge belongs to a doubly linked list
/// maintained in each attached body. Each contact has two contact
/// nodes, one for each attached body.
struct b2ContactEdge
{
b2Body* other; ///< provides quick access to the other body attached.
b2Contact* contact; ///< the contact
b2ContactEdge* prev; ///< the previous contact edge in the body's contact list
b2ContactEdge* next; ///< the next contact edge in the body's contact list
};
/// This structure is used to report contact points.
struct b2ContactPoint
{
b2Shape* shape1; ///< the first shape
b2Shape* shape2; ///< the second shape
b2Vec2 position; ///< position in world coordinates
b2Vec2 velocity; ///< velocity of point on body2 relative to point on body1 (pre-solver)
b2Vec2 normal; ///< points from shape1 to shape2
float32 separation; ///< the separation is negative when shapes are touching
float32 friction; ///< the combined friction coefficient
float32 restitution; ///< the combined restitution coefficient
b2ContactID id; ///< the contact id identifies the features in contact
};
/// This structure is used to report contact point results.
struct b2ContactResult
{
b2Shape* shape1; ///< the first shape
b2Shape* shape2; ///< the second shape
b2Vec2 position; ///< position in world coordinates
b2Vec2 normal; ///< points from shape1 to shape2
float32 normalImpulse; ///< the normal impulse applied to body2
float32 tangentImpulse; ///< the tangent impulse applied to body2
b2ContactID id; ///< the contact id identifies the features in contact
};
/// The class manages contact between two shapes. A contact exists for each overlapping
/// AABB in the broad-phase (except if filtered). Therefore a contact object may exist
/// that has no contact points.
class b2Contact
{
public:
/// Get the manifold array.
virtual b2Manifold* GetManifolds() = 0;
/// Get the number of manifolds. This is 0 or 1 between convex shapes.
/// This may be greater than 1 for convex-vs-concave shapes. Each
/// manifold holds up to two contact points with a shared contact normal.
int32 GetManifoldCount() const;
/// Is this contact solid?
/// @return true if this contact should generate a response.
bool IsSolid() const;
/// Get the next contact in the world's contact list.
b2Contact* GetNext();
/// Get the first shape in this contact.
b2Shape* GetShape1();
/// Get the second shape in this contact.
b2Shape* GetShape2();
//--------------- Internals Below -------------------
public:
// m_flags
enum
{
e_nonSolidFlag = 0x0001,
e_slowFlag = 0x0002,
e_islandFlag = 0x0004,
e_toiFlag = 0x0008,
};
static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn,
b2ShapeType type1, b2ShapeType type2);
static void InitializeRegisters();
static b2Contact* Create(b2Shape* shape1, b2Shape* shape2, b2BlockAllocator* allocator);
static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
b2Contact() : m_shape1(NULL), m_shape2(NULL) {}
b2Contact(b2Shape* shape1, b2Shape* shape2);
virtual ~b2Contact() {}
void Update(b2ContactListener* listener);
virtual void Evaluate(b2ContactListener* listener) = 0;
static b2ContactRegister s_registers[e_shapeTypeCount][e_shapeTypeCount];
static bool s_initialized;
uint32 m_flags;
int32 m_manifoldCount;
// World pool and list pointers.
b2Contact* m_prev;
b2Contact* m_next;
// Nodes for connecting bodies.
b2ContactEdge m_node1;
b2ContactEdge m_node2;
b2Shape* m_shape1;
b2Shape* m_shape2;
// Combined friction
float32 m_friction;
float32 m_restitution;
float32 m_toi;
};
inline int32 b2Contact::GetManifoldCount() const
{
return m_manifoldCount;
}
inline bool b2Contact::IsSolid() const
{
return (m_flags & e_nonSolidFlag) == 0;
}
inline b2Contact* b2Contact::GetNext()
{
return m_next;
}
inline b2Shape* b2Contact::GetShape1()
{
return m_shape1;
}
inline b2Shape* b2Contact::GetShape2()
{
return m_shape2;
}
#endif
@@ -0,0 +1,77 @@
/*
* 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 CONTACT_SOLVER_H
#define CONTACT_SOLVER_H
#include "../../Common/b2Math.h"
#include "../../Collision/b2Collision.h"
#include "../b2World.h"
class b2Contact;
class b2Body;
class b2Island;
class b2StackAllocator;
struct b2ContactConstraintPoint
{
b2Vec2 localAnchor1;
b2Vec2 localAnchor2;
b2Vec2 r1;
b2Vec2 r2;
float32 normalImpulse;
float32 tangentImpulse;
float32 positionImpulse;
float32 normalMass;
float32 tangentMass;
float32 equalizedMass;
float32 separation;
float32 velocityBias;
};
struct b2ContactConstraint
{
b2ContactConstraintPoint points[b2_maxManifoldPoints];
b2Vec2 normal;
b2Manifold* manifold;
b2Body* body1;
b2Body* body2;
float32 friction;
float32 restitution;
int32 pointCount;
};
class b2ContactSolver
{
public:
b2ContactSolver(const b2TimeStep& step, b2Contact** contacts, int32 contactCount, b2StackAllocator* allocator);
~b2ContactSolver();
void InitVelocityConstraints(const b2TimeStep& step);
void SolveVelocityConstraints();
void FinalizeVelocityConstraints();
bool SolvePositionConstraints(float32 baumgarte);
b2TimeStep m_step;
b2StackAllocator* m_allocator;
b2ContactConstraint* m_constraints;
int m_constraintCount;
};
#endif
@@ -0,0 +1,33 @@
/*
* 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 B2_NULL_CONTACT_H
#define B2_NULL_CONTACT_H
#include "../../Common/b2Math.h"
#include "b2Contact.h"
class b2NullContact : public b2Contact
{
public:
b2NullContact() {}
void Evaluate(b2ContactListener*) {}
b2Manifold* GetManifolds() { return NULL; }
};
#endif
@@ -0,0 +1,44 @@
/*
* 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 POLY_AND_CIRCLE_CONTACT_H
#define POLY_AND_CIRCLE_CONTACT_H
#include "b2Contact.h"
class b2BlockAllocator;
class b2PolyAndCircleContact : public b2Contact
{
public:
static b2Contact* Create(b2Shape* shape1, b2Shape* shape2, b2BlockAllocator* allocator);
static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
b2PolyAndCircleContact(b2Shape* shape1, b2Shape* shape2);
~b2PolyAndCircleContact() {}
void Evaluate(b2ContactListener* listener);
b2Manifold* GetManifolds()
{
return &m_manifold;
}
b2Manifold m_manifold;
};
#endif
@@ -0,0 +1,44 @@
/*
* 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 POLYCONTACT_H
#define POLYCONTACT_H
#include "b2Contact.h"
class b2BlockAllocator;
class b2PolygonContact : public b2Contact
{
public:
static b2Contact* Create(b2Shape* shape1, b2Shape* shape2, b2BlockAllocator* allocator);
static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
b2PolygonContact(b2Shape* shape1, b2Shape* shape2);
~b2PolygonContact() {}
void Evaluate(b2ContactListener* listener);
b2Manifold* GetManifolds()
{
return &m_manifold;
}
b2Manifold m_manifold;
};
#endif
@@ -0,0 +1,96 @@
/*
* 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 B2_DISTANCE_JOINT_H
#define B2_DISTANCE_JOINT_H
#include "b2Joint.h"
/// Distance joint definition. This requires defining an
/// anchor point on both bodies and the non-zero length of the
/// distance joint. The definition uses local anchor points
/// so that the initial configuration can violate the constraint
/// slightly. This helps when saving and loading a game.
/// @warning Do not use a zero or short length.
struct b2DistanceJointDef : public b2JointDef
{
b2DistanceJointDef()
{
type = e_distanceJoint;
localAnchor1.Set(0.0f, 0.0f);
localAnchor2.Set(0.0f, 0.0f);
length = 1.0f;
frequencyHz = 0.0f;
dampingRatio = 0.0f;
}
/// Initialize the bodies, anchors, and length using the world
/// anchors.
void Initialize(b2Body* body1, b2Body* body2,
const b2Vec2& anchor1, const b2Vec2& anchor2);
/// The local anchor point relative to body1's origin.
b2Vec2 localAnchor1;
/// The local anchor point relative to body2's origin.
b2Vec2 localAnchor2;
/// The equilibrium length between the anchor points.
float32 length;
/// The response speed.
float32 frequencyHz;
/// The damping ratio. 0 = no damping, 1 = critical damping.
float32 dampingRatio;
};
/// A distance joint constrains two points on two bodies
/// to remain at a fixed distance from each other. You can view
/// this as a massless, rigid rod.
class b2DistanceJoint : public b2Joint
{
public:
b2Vec2 GetAnchor1() const;
b2Vec2 GetAnchor2() const;
b2Vec2 GetReactionForce() const;
float32 GetReactionTorque() const;
//--------------- Internals Below -------------------
b2DistanceJoint(const b2DistanceJointDef* data);
void InitVelocityConstraints(const b2TimeStep& step);
void SolveVelocityConstraints(const b2TimeStep& step);
bool SolvePositionConstraints();
b2Vec2 m_localAnchor1;
b2Vec2 m_localAnchor2;
b2Vec2 m_u;
float32 m_frequencyHz;
float32 m_dampingRatio;
float32 m_gamma;
float32 m_bias;
float32 m_impulse;
float32 m_mass; // effective mass for the constraint.
float32 m_length;
};
#endif
@@ -0,0 +1,109 @@
/*
* 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 B2_GEAR_JOINT_H
#define B2_GEAR_JOINT_H
#include "b2Joint.h"
class b2RevoluteJoint;
class b2PrismaticJoint;
/// Gear joint definition. This definition requires two existing
/// revolute or prismatic joints (any combination will work).
/// The provided joints must attach a dynamic body to a static body.
struct b2GearJointDef : public b2JointDef
{
b2GearJointDef()
{
type = e_gearJoint;
joint1 = NULL;
joint2 = NULL;
ratio = 1.0f;
}
/// The first revolute/prismatic joint attached to the gear joint.
b2Joint* joint1;
/// The second revolute/prismatic joint attached to the gear joint.
b2Joint* joint2;
/// The gear ratio.
/// @see b2GearJoint for explanation.
float32 ratio;
};
/// A gear joint is used to connect two joints together. Either joint
/// can be a revolute or prismatic joint. You specify a gear ratio
/// to bind the motions together:
/// coordinate1 + ratio * coordinate2 = constant
/// The ratio can be negative or positive. If one joint is a revolute joint
/// and the other joint is a prismatic joint, then the ratio will have units
/// of length or units of 1/length.
/// @warning The revolute and prismatic joints must be attached to
/// fixed bodies (which must be body1 on those joints).
class b2GearJoint : public b2Joint
{
public:
b2Vec2 GetAnchor1() const;
b2Vec2 GetAnchor2() const;
b2Vec2 GetReactionForce() const;
float32 GetReactionTorque() const;
/// Get the gear ratio.
float32 GetRatio() const;
//--------------- Internals Below -------------------
b2GearJoint(const b2GearJointDef* data);
void InitVelocityConstraints(const b2TimeStep& step);
void SolveVelocityConstraints(const b2TimeStep& step);
bool SolvePositionConstraints();
b2Body* m_ground1;
b2Body* m_ground2;
// One of these is NULL.
b2RevoluteJoint* m_revolute1;
b2PrismaticJoint* m_prismatic1;
// One of these is NULL.
b2RevoluteJoint* m_revolute2;
b2PrismaticJoint* m_prismatic2;
b2Vec2 m_groundAnchor1;
b2Vec2 m_groundAnchor2;
b2Vec2 m_localAnchor1;
b2Vec2 m_localAnchor2;
b2Jacobian m_J;
float32 m_constant;
float32 m_ratio;
// Effective mass
float32 m_mass;
// Impulse for accumulation/warm starting.
float32 m_force;
};
#endif
@@ -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
@@ -0,0 +1,102 @@
/*
* 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 B2_MOUSE_JOINT_H
#define B2_MOUSE_JOINT_H
#include "b2Joint.h"
/// Mouse joint definition. This requires a world target point,
/// tuning parameters, and the time step.
struct b2MouseJointDef : public b2JointDef
{
b2MouseJointDef()
{
type = e_mouseJoint;
target.Set(0.0f, 0.0f);
maxForce = 0.0f;
frequencyHz = 5.0f;
dampingRatio = 0.7f;
timeStep = 1.0f / 60.0f;
}
/// The initial world target point. This is assumed
/// to coincide with the body anchor initially.
b2Vec2 target;
/// The maximum constraint force that can be exerted
/// to move the candidate body. Usually you will express
/// as some multiple of the weight (multiplier * mass * gravity).
float32 maxForce;
/// The response speed.
float32 frequencyHz;
/// The damping ratio. 0 = no damping, 1 = critical damping.
float32 dampingRatio;
/// The time step used in the simulation.
float32 timeStep;
};
/// A mouse joint is used to make a point on a body track a
/// specified world point. This a soft constraint with a maximum
/// force. This allows the constraint to stretch and without
/// applying huge forces.
class b2MouseJoint : public b2Joint
{
public:
/// Implements b2Joint.
b2Vec2 GetAnchor1() const;
/// Implements b2Joint.
b2Vec2 GetAnchor2() const;
/// Implements b2Joint.
b2Vec2 GetReactionForce() const;
/// Implements b2Joint.
float32 GetReactionTorque() const;
/// Use this to update the target point.
void SetTarget(const b2Vec2& target);
//--------------- Internals Below -------------------
b2MouseJoint(const b2MouseJointDef* def);
void InitVelocityConstraints(const b2TimeStep& step);
void SolveVelocityConstraints(const b2TimeStep& step);
bool SolvePositionConstraints()
{
return true;
}
b2Vec2 m_localAnchor;
b2Vec2 m_target;
b2Vec2 m_impulse;
b2Mat22 m_mass; // effective mass for point-to-point constraint.
b2Vec2 m_C; // position error
float32 m_maxForce;
float32 m_beta; // bias factor
float32 m_gamma; // softness
};
#endif
@@ -0,0 +1,176 @@
/*
* 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 B2_PRISMATIC_JOINT_H
#define B2_PRISMATIC_JOINT_H
#include "b2Joint.h"
/// Prismatic joint definition. This requires defining a line of
/// motion using an axis and an anchor point. The definition uses local
/// anchor points and a local axis so that the initial configuration
/// can violate the constraint slightly. The joint translation is zero
/// when the local anchor points coincide in world space. Using local
/// anchors and a local axis helps when saving and loading a game.
struct b2PrismaticJointDef : public b2JointDef
{
b2PrismaticJointDef()
{
type = e_prismaticJoint;
localAnchor1.SetZero();
localAnchor2.SetZero();
localAxis1.Set(1.0f, 0.0f);
referenceAngle = 0.0f;
enableLimit = false;
lowerTranslation = 0.0f;
upperTranslation = 0.0f;
enableMotor = false;
maxMotorForce = 0.0f;
motorSpeed = 0.0f;
}
/// Initialize the bodies, anchors, axis, and reference angle using the world
/// anchor and world axis.
void Initialize(b2Body* body1, b2Body* body2, const b2Vec2& anchor, const b2Vec2& axis);
/// The local anchor point relative to body1's origin.
b2Vec2 localAnchor1;
/// The local anchor point relative to body2's origin.
b2Vec2 localAnchor2;
/// The local translation axis in body1.
b2Vec2 localAxis1;
/// The constrained angle between the bodies: body2_angle - body1_angle.
float32 referenceAngle;
/// Enable/disable the joint limit.
bool enableLimit;
/// The lower translation limit, usually in meters.
float32 lowerTranslation;
/// The upper translation limit, usually in meters.
float32 upperTranslation;
/// Enable/disable the joint motor.
bool enableMotor;
/// The maximum motor torque, usually in N-m.
float32 maxMotorForce;
/// The desired motor speed in radians per second.
float32 motorSpeed;
};
/// A prismatic joint. This joint provides one degree of freedom: translation
/// along an axis fixed in body1. Relative rotation is prevented. You can
/// use a joint limit to restrict the range of motion and a joint motor to
/// drive the motion or to model joint friction.
class b2PrismaticJoint : public b2Joint
{
public:
b2Vec2 GetAnchor1() const;
b2Vec2 GetAnchor2() const;
b2Vec2 GetReactionForce() const;
float32 GetReactionTorque() const;
/// Get the current joint translation, usually in meters.
float32 GetJointTranslation() const;
/// Get the current joint translation speed, usually in meters per second.
float32 GetJointSpeed() const;
/// Is the joint limit enabled?
bool IsLimitEnabled() const;
/// Enable/disable the joint limit.
void EnableLimit(bool flag);
/// Get the lower joint limit, usually in meters.
float32 GetLowerLimit() const;
/// Get the upper joint limit, usually in meters.
float32 GetUpperLimit() const;
/// Set the joint limits, usually in meters.
void SetLimits(float32 lower, float32 upper);
/// Is the joint motor enabled?
bool IsMotorEnabled() const;
/// Enable/disable the joint motor.
void EnableMotor(bool flag);
/// Set the motor speed, usually in meters per second.
void SetMotorSpeed(float32 speed);
/// Get the motor speed, usually in meters per second.
float32 GetMotorSpeed() const;
/// Set the maximum motor force, usually in N.
void SetMaxMotorForce(float32 force);
/// Get the current motor force, usually in N.
float32 GetMotorForce() const;
//--------------- Internals Below -------------------
b2PrismaticJoint(const b2PrismaticJointDef* def);
void InitVelocityConstraints(const b2TimeStep& step);
void SolveVelocityConstraints(const b2TimeStep& step);
bool SolvePositionConstraints();
b2Vec2 m_localAnchor1;
b2Vec2 m_localAnchor2;
b2Vec2 m_localXAxis1;
b2Vec2 m_localYAxis1;
float32 m_refAngle;
b2Jacobian m_linearJacobian;
float32 m_linearMass; // effective mass for point-to-line constraint.
float32 m_force;
float32 m_angularMass; // effective mass for angular constraint.
float32 m_torque;
b2Jacobian m_motorJacobian;
float32 m_motorMass; // effective mass for motor/limit translational constraint.
float32 m_motorForce;
float32 m_limitForce;
float32 m_limitPositionImpulse;
float32 m_lowerTranslation;
float32 m_upperTranslation;
float32 m_maxMotorForce;
float32 m_motorSpeed;
bool m_enableLimit;
bool m_enableMotor;
b2LimitState m_limitState;
};
inline float32 b2PrismaticJoint::GetMotorSpeed() const
{
return m_motorSpeed;
}
#endif
@@ -0,0 +1,153 @@
/*
* 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 B2_PULLEY_JOINT_H
#define B2_PULLEY_JOINT_H
#include "b2Joint.h"
const float32 b2_minPulleyLength = 2.0f;
/// Pulley joint definition. This requires two ground anchors,
/// two dynamic body anchor points, max lengths for each side,
/// and a pulley ratio.
struct b2PulleyJointDef : public b2JointDef
{
b2PulleyJointDef()
{
type = e_pulleyJoint;
groundAnchor1.Set(-1.0f, 1.0f);
groundAnchor2.Set(1.0f, 1.0f);
localAnchor1.Set(-1.0f, 0.0f);
localAnchor2.Set(1.0f, 0.0f);
length1 = 0.0f;
maxLength1 = 0.0f;
length2 = 0.0f;
maxLength2 = 0.0f;
ratio = 1.0f;
collideConnected = true;
}
/// Initialize the bodies, anchors, lengths, max lengths, and ratio using the world anchors.
void Initialize(b2Body* body1, b2Body* body2,
const b2Vec2& groundAnchor1, const b2Vec2& groundAnchor2,
const b2Vec2& anchor1, const b2Vec2& anchor2,
float32 ratio);
/// The first ground anchor in world coordinates. This point never moves.
b2Vec2 groundAnchor1;
/// The second ground anchor in world coordinates. This point never moves.
b2Vec2 groundAnchor2;
/// The local anchor point relative to body1's origin.
b2Vec2 localAnchor1;
/// The local anchor point relative to body2's origin.
b2Vec2 localAnchor2;
/// The a reference length for the segment attached to body1.
float32 length1;
/// The maximum length of the segment attached to body1.
float32 maxLength1;
/// The a reference length for the segment attached to body2.
float32 length2;
/// The maximum length of the segment attached to body2.
float32 maxLength2;
/// The pulley ratio, used to simulate a block-and-tackle.
float32 ratio;
};
/// The pulley joint is connected to two bodies and two fixed ground points.
/// The pulley supports a ratio such that:
/// length1 + ratio * length2 <= constant
/// Yes, the force transmitted is scaled by the ratio.
/// The pulley also enforces a maximum length limit on both sides. This is
/// useful to prevent one side of the pulley hitting the top.
class b2PulleyJoint : public b2Joint
{
public:
b2Vec2 GetAnchor1() const;
b2Vec2 GetAnchor2() const;
b2Vec2 GetReactionForce() const;
float32 GetReactionTorque() const;
/// Get the first ground anchor.
b2Vec2 GetGroundAnchor1() const;
/// Get the second ground anchor.
b2Vec2 GetGroundAnchor2() const;
/// Get the current length of the segment attached to body1.
float32 GetLength1() const;
/// Get the current length of the segment attached to body2.
float32 GetLength2() const;
/// Get the pulley ratio.
float32 GetRatio() const;
//--------------- Internals Below -------------------
b2PulleyJoint(const b2PulleyJointDef* data);
void InitVelocityConstraints(const b2TimeStep& step);
void SolveVelocityConstraints(const b2TimeStep& step);
bool SolvePositionConstraints();
b2Body* m_ground;
b2Vec2 m_groundAnchor1;
b2Vec2 m_groundAnchor2;
b2Vec2 m_localAnchor1;
b2Vec2 m_localAnchor2;
b2Vec2 m_u1;
b2Vec2 m_u2;
float32 m_constant;
float32 m_ratio;
float32 m_maxLength1;
float32 m_maxLength2;
// Effective masses
float32 m_pulleyMass;
float32 m_limitMass1;
float32 m_limitMass2;
// Impulses for accumulation/warm starting.
float32 m_force;
float32 m_limitForce1;
float32 m_limitForce2;
// Position impulses for accumulation.
float32 m_positionImpulse;
float32 m_limitPositionImpulse1;
float32 m_limitPositionImpulse2;
b2LimitState m_state;
b2LimitState m_limitState1;
b2LimitState m_limitState2;
};
#endif
@@ -0,0 +1,172 @@
/*
* 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 B2_REVOLUTE_JOINT_H
#define B2_REVOLUTE_JOINT_H
#include "b2Joint.h"
/// Revolute joint definition. This requires defining an
/// anchor point where the bodies are joined. The definition
/// uses local anchor points so that the initial configuration
/// can violate the constraint slightly. You also need to
/// specify the initial relative angle for joint limits. This
/// helps when saving and loading a game.
/// The local anchor points are measured from the body's origin
/// rather than the center of mass because:
/// 1. you might not know where the center of mass will be.
/// 2. if you add/remove shapes from a body and recompute the mass,
/// the joints will be broken.
struct b2RevoluteJointDef : public b2JointDef
{
b2RevoluteJointDef()
{
type = e_revoluteJoint;
localAnchor1.Set(0.0f, 0.0f);
localAnchor2.Set(0.0f, 0.0f);
referenceAngle = 0.0f;
lowerAngle = 0.0f;
upperAngle = 0.0f;
maxMotorTorque = 0.0f;
motorSpeed = 0.0f;
enableLimit = false;
enableMotor = false;
}
/// Initialize the bodies, anchors, and reference angle using the world
/// anchor.
void Initialize(b2Body* body1, b2Body* body2, const b2Vec2& anchor);
/// The local anchor point relative to body1's origin.
b2Vec2 localAnchor1;
/// The local anchor point relative to body2's origin.
b2Vec2 localAnchor2;
/// The body2 angle minus body1 angle in the reference state (radians).
float32 referenceAngle;
/// A flag to enable joint limits.
bool enableLimit;
/// The lower angle for the joint limit (radians).
float32 lowerAngle;
/// The upper angle for the joint limit (radians).
float32 upperAngle;
/// A flag to enable the joint motor.
bool enableMotor;
/// The desired motor speed. Usually in radians per second.
float32 motorSpeed;
/// The maximum motor torque used to achieve the desired motor speed.
/// Usually in N-m.
float32 maxMotorTorque;
};
/// A revolute joint constrains to bodies to share a common point while they
/// are free to rotate about the point. The relative rotation about the shared
/// point is the joint angle. You can limit the relative rotation with
/// a joint limit that specifies a lower and upper angle. You can use a motor
/// to drive the relative rotation about the shared point. A maximum motor torque
/// is provided so that infinite forces are not generated.
class b2RevoluteJoint : public b2Joint
{
public:
b2Vec2 GetAnchor1() const;
b2Vec2 GetAnchor2() const;
b2Vec2 GetReactionForce() const;
float32 GetReactionTorque() const;
/// Get the current joint angle in radians.
float32 GetJointAngle() const;
/// Get the current joint angle speed in radians per second.
float32 GetJointSpeed() const;
/// Is the joint limit enabled?
bool IsLimitEnabled() const;
/// Enable/disable the joint limit.
void EnableLimit(bool flag);
/// Get the lower joint limit in radians.
float32 GetLowerLimit() const;
/// Get the upper joint limit in radians.
float32 GetUpperLimit() const;
/// Set the joint limits in radians.
void SetLimits(float32 lower, float32 upper);
/// Is the joint motor enabled?
bool IsMotorEnabled() const;
/// Enable/disable the joint motor.
void EnableMotor(bool flag);
/// Set the motor speed in radians per second.
void SetMotorSpeed(float32 speed);
/// Get the motor speed in radians per second.
float32 GetMotorSpeed() const;
/// Set the maximum motor torque, usually in N-m.
void SetMaxMotorTorque(float32 torque);
/// Get the current motor torque, usually in N-m.
float32 GetMotorTorque() const;
//--------------- Internals Below -------------------
b2RevoluteJoint(const b2RevoluteJointDef* def);
void InitVelocityConstraints(const b2TimeStep& step);
void SolveVelocityConstraints(const b2TimeStep& step);
bool SolvePositionConstraints();
b2Vec2 m_localAnchor1; // relative
b2Vec2 m_localAnchor2;
b2Vec2 m_pivotForce;
float32 m_motorForce;
float32 m_limitForce;
float32 m_limitPositionImpulse;
b2Mat22 m_pivotMass; // effective mass for point-to-point constraint.
float32 m_motorMass; // effective mass for motor/limit angular constraint.
bool m_enableMotor;
float32 m_maxMotorTorque;
float32 m_motorSpeed;
bool m_enableLimit;
float32 m_referenceAngle;
float32 m_lowerAngle;
float32 m_upperAngle;
b2LimitState m_limitState;
};
inline float32 b2RevoluteJoint::GetMotorSpeed() const
{
return m_motorSpeed;
}
#endif
@@ -0,0 +1,587 @@
/*
* 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 B2_BODY_H
#define B2_BODY_H
#include "../Common/b2Math.h"
#include "../Collision/Shapes/b2Shape.h"
#include "Joints/b2Joint.h"
#include <memory>
class b2Joint;
class b2Contact;
class b2World;
struct b2JointEdge;
struct b2ContactEdge;
/// A body definition holds all the data needed to construct a rigid body.
/// You can safely re-use body definitions.
struct b2BodyDef
{
/// This constructor sets the body definition default values.
b2BodyDef()
{
massData.center.SetZero();
massData.mass = 0.0f;
massData.I = 0.0f;
userData = NULL;
position.Set(0.0f, 0.0f);
angle = 0.0f;
linearDamping = 0.0f;
angularDamping = 0.0f;
allowSleep = true;
isSleeping = false;
fixedRotation = false;
isBullet = false;
}
/// You can use this to initialized the mass properties of the body.
/// If you prefer, you can set the mass properties after the shapes
/// have been added using b2Body::SetMassFromShapes.
b2MassData massData;
/// Use this to store application specific body data.
void* userData;
/// The world position of the body. Avoid creating bodies at the origin
/// since this can lead to many overlapping shapes.
b2Vec2 position;
/// The world angle of the body in radians.
float32 angle;
/// Linear damping is use to reduce the linear velocity. The damping parameter
/// can be larger than 1.0f but the damping effect becomes sensitive to the
/// time step when the damping parameter is large.
float32 linearDamping;
/// Angular damping is use to reduce the angular velocity. The damping parameter
/// can be larger than 1.0f but the damping effect becomes sensitive to the
/// time step when the damping parameter is large.
float32 angularDamping;
/// Set this flag to false if this body should never fall asleep. Note that
/// this increases CPU usage.
bool allowSleep;
/// Is this body initially sleeping?
bool isSleeping;
/// Should this body be prevented from rotating? Useful for characters.
bool fixedRotation;
/// Is this a fast moving body that should be prevented from tunneling through
/// other moving bodies? Note that all bodies are prevented from tunneling through
/// static bodies.
/// @warning You should use this flag sparingly since it increases processing time.
bool isBullet;
};
/// A rigid body.
class b2Body
{
public:
/// Creates a shape and attach it to this body.
/// @param shapeDef the shape definition.
/// @warning This function is locked during callbacks.
b2Shape* CreateShape(b2ShapeDef* shapeDef);
/// Destroy a shape. This removes the shape from the broad-phase and
/// therefore destroys any contacts associated with this shape. All shapes
/// attached to a body are implicitly destroyed when the body is destroyed.
/// @param shape the shape to be removed.
/// @warning This function is locked during callbacks.
void DestroyShape(b2Shape* shape);
/// Set the mass properties. Note that this changes the center of mass position.
/// If you are not sure how to compute mass properties, use SetMassFromShapes.
/// The inertia tensor is assumed to be relative to the center of mass.
/// @param massData the mass properties.
void SetMass(const b2MassData* massData);
/// Compute the mass properties from the attached shapes. You typically call this
/// after adding all the shapes. If you add or remove shapes later, you may want
/// to call this again. Note that this changes the center of mass position.
void SetMassFromShapes();
/// Set the position of the body's origin and rotation (radians).
/// This breaks any contacts and wakes the other bodies.
/// @param position the new world position of the body's origin (not necessarily
/// the center of mass).
/// @param angle the new world rotation angle of the body in radians.
/// @return false if the movement put a shape outside the world. In this case the
/// body is automatically frozen.
bool SetXForm(const b2Vec2& position, float32 angle);
/// Get the body transform for the body's origin.
/// @return the world transform of the body's origin.
const b2XForm& GetXForm() const;
/// Get the world body origin position.
/// @return the world position of the body's origin.
const b2Vec2& GetPosition() const;
/// Get the angle in radians.
/// @return the current world rotation angle in radians.
float32 GetAngle() const;
/// Get the world position of the center of mass.
const b2Vec2& GetWorldCenter() const;
/// Get the local position of the center of mass.
const b2Vec2& GetLocalCenter() const;
/// Set the linear velocity of the center of mass.
/// @param v the new linear velocity of the center of mass.
void SetLinearVelocity(const b2Vec2& v);
/// Get the linear velocity of the center of mass.
/// @return the linear velocity of the center of mass.
b2Vec2 GetLinearVelocity() const;
/// Set the angular velocity.
/// @param omega the new angular velocity in radians/second.
void SetAngularVelocity(float32 omega);
/// Get the angular velocity.
/// @return the angular velocity in radians/second.
float32 GetAngularVelocity() const;
/// Apply a force at a world point. If the force is not
/// applied at the center of mass, it will generate a torque and
/// affect the angular velocity. This wakes up the body.
/// @param force the world force vector, usually in Newtons (N).
/// @param point the world position of the point of application.
void ApplyForce(const b2Vec2& force, const b2Vec2& point);
/// Apply a torque. This affects the angular velocity
/// without affecting the linear velocity of the center of mass.
/// This wakes up the body.
/// @param torque about the z-axis (out of the screen), usually in N-m.
void ApplyTorque(float32 torque);
/// Apply an impulse at a point. This immediately modifies the velocity.
/// It also modifies the angular velocity if the point of application
/// is not at the center of mass. This wakes up the body.
/// @param impulse the world impulse vector, usually in N-seconds or kg-m/s.
/// @param point the world position of the point of application.
void ApplyImpulse(const b2Vec2& impulse, const b2Vec2& point);
/// Get the total mass of the body.
/// @return the mass, usually in kilograms (kg).
float32 GetMass() const;
/// Get the central rotational inertia of the body.
/// @return the rotational inertia, usually in kg-m^2.
float32 GetInertia() const;
/// Get the world coordinates of a point given the local coordinates.
/// @param localPoint a point on the body measured relative the the body's origin.
/// @return the same point expressed in world coordinates.
b2Vec2 GetWorldPoint(const b2Vec2& localPoint) const;
/// Get the world coordinates of a vector given the local coordinates.
/// @param localVector a vector fixed in the body.
/// @return the same vector expressed in world coordinates.
b2Vec2 GetWorldVector(const b2Vec2& localVector) const;
/// Gets a local point relative to the body's origin given a world point.
/// @param a point in world coordinates.
/// @return the corresponding local point relative to the body's origin.
b2Vec2 GetLocalPoint(const b2Vec2& worldPoint) const;
/// Gets a local vector given a world vector.
/// @param a vector in world coordinates.
/// @return the corresponding local vector.
b2Vec2 GetLocalVector(const b2Vec2& worldVector) const;
/// Get the world linear velocity of a world point attached to this body.
/// @param a point in world coordinates.
/// @return the world velocity of a point.
b2Vec2 GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const;
/// Get the world velocity of a local point.
/// @param a point in local coordinates.
/// @return the world velocity of a point.
b2Vec2 GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const;
/// Is this body treated like a bullet for continuous collision detection?
bool IsBullet() const;
/// Should this body be treated like a bullet for continuous collision detection?
void SetBullet(bool flag);
/// Is this body static (immovable)?
bool IsStatic() const;
/// Is this body dynamic (movable)?
bool IsDynamic() const;
/// Is this body frozen?
bool IsFrozen() const;
/// Is this body sleeping (not simulating).
bool IsSleeping() const;
/// You can disable sleeping on this body.
void AllowSleeping(bool flag);
/// Wake up this body so it will begin simulating.
void WakeUp();
/// Put this body to sleep so it will stop simulating.
/// This also sets the velocity to zero.
void PutToSleep();
/// Get the list of all shapes attached to this body.
b2Shape* GetShapeList();
/// Get the list of all joints attached to this body.
b2JointEdge* GetJointList();
/// Get the next body in the world's body list.
b2Body* GetNext();
/// Get the user data pointer that was provided in the body definition.
void* GetUserData();
/// Set the user data. Use this to store your application specific data.
void SetUserData(void* data);
/// Get the parent world of this body.
b2World* GetWorld();
private:
friend class b2World;
friend class b2Island;
friend class b2ContactManager;
friend class b2ContactSolver;
friend class b2DistanceJoint;
friend class b2GearJoint;
friend class b2MouseJoint;
friend class b2PrismaticJoint;
friend class b2PulleyJoint;
friend class b2RevoluteJoint;
// m_flags
enum
{
e_frozenFlag = 0x0002,
e_islandFlag = 0x0004,
e_sleepFlag = 0x0008,
e_allowSleepFlag = 0x0010,
e_bulletFlag = 0x0020,
e_fixedRotationFlag = 0x0040,
};
// m_type
enum
{
e_staticType,
e_dynamicType,
e_maxTypes,
};
b2Body(const b2BodyDef* bd, b2World* world);
~b2Body();
bool SynchronizeShapes();
void SynchronizeTransform();
// This is used to prevent connected bodies from colliding.
// It may lie, depending on the collideConnected flag.
bool IsConnected(const b2Body* other) const;
void Advance(float32 t);
uint16 m_flags;
int16 m_type;
b2XForm m_xf; // the body origin transform
b2Sweep m_sweep; // the swept motion for CCD
b2Vec2 m_linearVelocity;
float32 m_angularVelocity;
b2Vec2 m_force;
float32 m_torque;
b2World* m_world;
b2Body* m_prev;
b2Body* m_next;
b2Shape* m_shapeList;
int32 m_shapeCount;
b2JointEdge* m_jointList;
b2ContactEdge* m_contactList;
float32 m_mass, m_invMass;
float32 m_I, m_invI;
float32 m_linearDamping;
float32 m_angularDamping;
float32 m_sleepTime;
void* m_userData;
};
inline const b2XForm& b2Body::GetXForm() const
{
return m_xf;
}
inline const b2Vec2& b2Body::GetPosition() const
{
return m_xf.position;
}
inline float32 b2Body::GetAngle() const
{
return m_sweep.a;
}
inline const b2Vec2& b2Body::GetWorldCenter() const
{
return m_sweep.c;
}
inline const b2Vec2& b2Body::GetLocalCenter() const
{
return m_sweep.localCenter;
}
inline void b2Body::SetLinearVelocity(const b2Vec2& v)
{
m_linearVelocity = v;
}
inline b2Vec2 b2Body::GetLinearVelocity() const
{
return m_linearVelocity;
}
inline void b2Body::SetAngularVelocity(float32 w)
{
m_angularVelocity = w;
}
inline float32 b2Body::GetAngularVelocity() const
{
return m_angularVelocity;
}
inline float32 b2Body::GetMass() const
{
return m_mass;
}
inline float32 b2Body::GetInertia() const
{
return m_I;
}
inline b2Vec2 b2Body::GetWorldPoint(const b2Vec2& localPoint) const
{
return b2Mul(m_xf, localPoint);
}
inline b2Vec2 b2Body::GetWorldVector(const b2Vec2& localVector) const
{
return b2Mul(m_xf.R, localVector);
}
inline b2Vec2 b2Body::GetLocalPoint(const b2Vec2& worldPoint) const
{
return b2MulT(m_xf, worldPoint);
}
inline b2Vec2 b2Body::GetLocalVector(const b2Vec2& worldVector) const
{
return b2MulT(m_xf.R, worldVector);
}
inline b2Vec2 b2Body::GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const
{
return m_linearVelocity + b2Cross(m_angularVelocity, worldPoint - m_sweep.c);
}
inline b2Vec2 b2Body::GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const
{
return GetLinearVelocityFromWorldPoint(GetWorldPoint(localPoint));
}
inline bool b2Body::IsBullet() const
{
return (m_flags & e_bulletFlag) == e_bulletFlag;
}
inline void b2Body::SetBullet(bool flag)
{
if (flag)
{
m_flags |= e_bulletFlag;
}
else
{
m_flags &= ~e_bulletFlag;
}
}
inline bool b2Body::IsStatic() const
{
return m_type == e_staticType;
}
inline bool b2Body::IsDynamic() const
{
return m_type == e_dynamicType;
}
inline bool b2Body::IsFrozen() const
{
return (m_flags & e_frozenFlag) == e_frozenFlag;
}
inline bool b2Body::IsSleeping() const
{
return (m_flags & e_sleepFlag) == e_sleepFlag;
}
inline void b2Body::AllowSleeping(bool flag)
{
if (flag)
{
m_flags |= e_allowSleepFlag;
}
else
{
m_flags &= ~e_allowSleepFlag;
WakeUp();
}
}
inline void b2Body::WakeUp()
{
m_flags &= ~e_sleepFlag;
m_sleepTime = 0.0f;
}
inline void b2Body::PutToSleep()
{
m_flags |= e_sleepFlag;
m_sleepTime = 0.0f;
m_linearVelocity.SetZero();
m_angularVelocity = 0.0f;
m_force.SetZero();
m_torque = 0.0f;
}
inline b2Shape* b2Body::GetShapeList()
{
return m_shapeList;
}
inline b2JointEdge* b2Body::GetJointList()
{
return m_jointList;
}
inline b2Body* b2Body::GetNext()
{
return m_next;
}
inline void* b2Body::GetUserData()
{
return m_userData;
}
inline void b2Body::SetUserData(void* data)
{
m_userData = data;
}
inline bool b2Body::IsConnected(const b2Body* other) const
{
for (b2JointEdge* jn = m_jointList; jn; jn = jn->next)
{
if (jn->other == other)
return jn->joint->m_collideConnected == false;
}
return false;
}
inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point)
{
if (IsSleeping())
{
WakeUp();
}
m_force += force;
m_torque += b2Cross(point - m_sweep.c, force);
}
inline void b2Body::ApplyTorque(float32 torque)
{
if (IsSleeping())
{
WakeUp();
}
m_torque += torque;
}
inline void b2Body::ApplyImpulse(const b2Vec2& impulse, const b2Vec2& point)
{
if (IsSleeping())
{
WakeUp();
}
m_linearVelocity += m_invMass * impulse;
m_angularVelocity += m_invI * b2Cross(point - m_sweep.c, impulse);
}
inline void b2Body::SynchronizeTransform()
{
m_xf.R.Set(m_sweep.a);
m_xf.position = m_sweep.c - b2Mul(m_xf.R, m_sweep.localCenter);
}
inline void b2Body::Advance(float32 t)
{
// Advance to the new safe time.
m_sweep.Advance(t);
m_sweep.c = m_sweep.c0;
m_sweep.a = m_sweep.a0;
SynchronizeTransform();
}
inline b2World* b2Body::GetWorld()
{
return m_world;
}
#endif
@@ -0,0 +1,54 @@
/*
* 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 B2_CONTACT_MANAGER_H
#define B2_CONTACT_MANAGER_H
#include "../Collision/b2BroadPhase.h"
#include "../Dynamics/Contacts/b2NullContact.h"
class b2World;
class b2Contact;
struct b2TimeStep;
// Delegate of b2World.
class b2ContactManager : public b2PairCallback
{
public:
b2ContactManager() : m_world(NULL), m_destroyImmediate(false) {}
// Implements PairCallback
void* PairAdded(void* proxyUserData1, void* proxyUserData2);
// Implements PairCallback
void PairRemoved(void* proxyUserData1, void* proxyUserData2, void* pairUserData);
void Destroy(b2Contact* c);
void Collide();
b2World* m_world;
// This lets us provide broadphase proxy pair user data for
// contacts that shouldn't exist.
b2NullContact m_nullContact;
bool m_destroyImmediate;
};
#endif
@@ -0,0 +1,88 @@
/*
* 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 B2_ISLAND_H
#define B2_ISLAND_H
#include "../Common/b2Math.h"
class b2Contact;
class b2Body;
class b2Joint;
class b2StackAllocator;
class b2ContactListener;
struct b2ContactConstraint;
struct b2TimeStep;
class b2Island
{
public:
b2Island(int32 bodyCapacity, int32 contactCapacity, int32 jointCapacity,
b2StackAllocator* allocator, b2ContactListener* listener);
~b2Island();
void Clear()
{
m_bodyCount = 0;
m_contactCount = 0;
m_jointCount = 0;
}
void Solve(const b2TimeStep& step, const b2Vec2& gravity, bool correctPositions, bool allowSleep);
void SolveTOI(const b2TimeStep& subStep);
void Add(b2Body* body)
{
b2Assert(m_bodyCount < m_bodyCapacity);
m_bodies[m_bodyCount++] = body;
}
void Add(b2Contact* contact)
{
b2Assert(m_contactCount < m_contactCapacity);
m_contacts[m_contactCount++] = contact;
}
void Add(b2Joint* joint)
{
b2Assert(m_jointCount < m_jointCapacity);
m_joints[m_jointCount++] = joint;
}
void Report(b2ContactConstraint* constraints);
b2StackAllocator* m_allocator;
b2ContactListener* m_listener;
b2Body** m_bodies;
b2Contact** m_contacts;
b2Joint** m_joints;
int32 m_bodyCount;
int32 m_jointCount;
int32 m_contactCount;
int32 m_bodyCapacity;
int32 m_contactCapacity;
int32 m_jointCapacity;
int32 m_positionIterationCount;
};
#endif
@@ -0,0 +1,256 @@
/*
* 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 B2_WORLD_H
#define B2_WORLD_H
#include "../Common/b2Math.h"
#include "../Common/b2BlockAllocator.h"
#include "../Common/b2StackAllocator.h"
#include "b2ContactManager.h"
#include "b2WorldCallbacks.h"
struct b2AABB;
struct b2ShapeDef;
struct b2BodyDef;
struct b2JointDef;
class b2Body;
class b2Joint;
class b2Shape;
class b2Contact;
class b2BroadPhase;
struct b2TimeStep
{
float32 dt; // time step
float32 inv_dt; // inverse time step (0 if dt == 0).
float32 dtRatio; // dt * inv_dt0
int32 maxIterations;
bool warmStarting;
bool positionCorrection;
};
/// The world class manages all physics entities, dynamic simulation,
/// and asynchronous queries. The world also contains efficient memory
/// management facilities.
class b2World
{
public:
/// Construct a world object.
/// @param worldAABB a bounding box that completely encompasses all your shapes.
/// @param gravity the world gravity vector.
/// @param doSleep improve performance by not simulating inactive bodies.
b2World(const b2AABB& worldAABB, const b2Vec2& gravity, bool doSleep);
/// Destruct the world. All physics entities are destroyed and all heap memory is released.
~b2World();
/// Register a destruction listener.
void SetDestructionListener(b2DestructionListener* listener);
/// Register a broad-phase boundary listener.
void SetBoundaryListener(b2BoundaryListener* listener);
/// Register a contact filter to provide specific control over collision.
/// Otherwise the default filter is used (b2_defaultFilter).
void SetContactFilter(b2ContactFilter* filter);
/// Register a contact event listener
void SetContactListener(b2ContactListener* listener);
/// Register a routine for debug drawing. The debug draw functions are called
/// inside the b2World::Step method, so make sure your renderer is ready to
/// consume draw commands when you call Step().
void SetDebugDraw(b2DebugDraw* debugDraw);
/// Create a rigid body given a definition. No reference to the definition
/// is retained.
/// @warning This function is locked during callbacks.
b2Body* CreateBody(const b2BodyDef* def);
/// Destroy a rigid body given a definition. No reference to the definition
/// is retained. This function is locked during callbacks.
/// @warning This automatically deletes all associated shapes and joints.
/// @warning This function is locked during callbacks.
void DestroyBody(b2Body* body);
/// Create a joint to constrain bodies together. No reference to the definition
/// is retained. This may cause the connected bodies to cease colliding.
/// @warning This function is locked during callbacks.
b2Joint* CreateJoint(const b2JointDef* def);
/// Destroy a joint. This may cause the connected bodies to begin colliding.
/// @warning This function is locked during callbacks.
void DestroyJoint(b2Joint* joint);
/// The world provides a single static ground body with no collision shapes.
/// You can use this to simplify the creation of joints and static shapes.
b2Body* GetGroundBody();
/// Take a time step. This performs collision detection, integration,
/// and constraint solution.
/// @param timeStep the amount of time to simulate, this should not vary.
/// @param iterations the number of iterations to be used by the constraint solver.
void Step(float32 timeStep, int32 iterations);
/// Query the world for all shapes that potentially overlap the
/// provided AABB. You provide a shape pointer buffer of specified
/// size. The number of shapes found is returned.
/// @param aabb the query box.
/// @param shapes a user allocated shape pointer array of size maxCount (or greater).
/// @param maxCount the capacity of the shapes array.
/// @return the number of shapes found in aabb.
int32 Query(const b2AABB& aabb, b2Shape** shapes, int32 maxCount);
/// Check if the AABB is within the broadphase limits.
bool InRange(const b2AABB& aabb) const;
/// Get the world body list. With the returned body, use b2Body::GetNext to get
/// the next body in the world list. A NULL body indicates the end of the list.
/// @return the head of the world body list.
b2Body* GetBodyList();
/// Get the world joint list. With the returned joint, use b2Joint::GetNext to get
/// the next joint in the world list. A NULL joint indicates the end of the list.
/// @return the head of the world joint list.
b2Joint* GetJointList();
/// Re-filter a shape. This re-runs contact filtering on a shape.
void Refilter(b2Shape* shape);
/// Enable/disable warm starting. For testing.
void SetWarmStarting(bool flag) { m_warmStarting = flag; }
/// Enable/disable position correction. For testing.
void SetPositionCorrection(bool flag) { m_positionCorrection = flag; }
/// Enable/disable continuous physics. For testing.
void SetContinuousPhysics(bool flag) { m_continuousPhysics = flag; }
/// Perform validation of internal data structures.
void Validate();
/// Get the number of broad-phase proxies.
int32 GetProxyCount() const;
/// Get the number of broad-phase pairs.
int32 GetPairCount() const;
/// Get the number of bodies.
int32 GetBodyCount() const;
/// Get the number joints.
int32 GetJointCount() const;
/// Get the number of contacts (each may have 0 or more contact points).
int32 GetContactCount() const;
/// Change the global gravity vector.
void SetGravity(const b2Vec2& gravity);
private:
friend class b2Body;
friend class b2ContactManager;
void Solve(const b2TimeStep& step);
void SolveTOI(const b2TimeStep& step);
void DrawJoint(b2Joint* joint);
void DrawShape(b2Shape* shape, const b2XForm& xf, const b2Color& color, bool core);
void DrawDebugData();
b2BlockAllocator m_blockAllocator;
b2StackAllocator m_stackAllocator;
bool m_lock;
b2BroadPhase* m_broadPhase;
b2ContactManager m_contactManager;
b2Body* m_bodyList;
b2Joint* m_jointList;
// Do not access
b2Contact* m_contactList;
int32 m_bodyCount;
int32 m_contactCount;
int32 m_jointCount;
b2Vec2 m_gravity;
bool m_allowSleep;
b2Body* m_groundBody;
b2DestructionListener* m_destructionListener;
b2BoundaryListener* m_boundaryListener;
b2ContactFilter* m_contactFilter;
b2ContactListener* m_contactListener;
b2DebugDraw* m_debugDraw;
float32 m_inv_dt0;
int32 m_positionIterationCount;
// This is for debugging the solver.
bool m_positionCorrection;
// This is for debugging the solver.
bool m_warmStarting;
// This is for debugging the solver.
bool m_continuousPhysics;
};
inline b2Body* b2World::GetGroundBody()
{
return m_groundBody;
}
inline b2Body* b2World::GetBodyList()
{
return m_bodyList;
}
inline b2Joint* b2World::GetJointList()
{
return m_jointList;
}
inline int32 b2World::GetBodyCount() const
{
return m_bodyCount;
}
inline int32 b2World::GetJointCount() const
{
return m_jointCount;
}
inline int32 b2World::GetContactCount() const
{
return m_contactCount;
}
inline void b2World::SetGravity(const b2Vec2& gravity)
{
m_gravity = gravity;
}
#endif
@@ -0,0 +1,172 @@
/*
* 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 B2_WORLD_CALLBACKS_H
#define B2_WORLD_CALLBACKS_H
#include "../Common/b2Settings.h"
struct b2Vec2;
struct b2XForm;
class b2Shape;
class b2Body;
class b2Joint;
class b2Contact;
struct b2ContactPoint;
struct b2ContactResult;
/// Joints and shapes are destroyed when their associated
/// body is destroyed. Implement this listener so that you
/// may nullify references to these joints and shapes.
class b2DestructionListener
{
public:
virtual ~b2DestructionListener() {}
/// Called when any joint is about to be destroyed due
/// to the destruction of one of its attached bodies.
virtual void SayGoodbye(b2Joint* joint) = 0;
/// Called when any shape is about to be destroyed due
/// to the destruction of its parent body.
virtual void SayGoodbye(b2Shape* shape) = 0;
};
/// This is called when a body's shape passes outside of the world boundary.
class b2BoundaryListener
{
public:
virtual ~b2BoundaryListener() {}
/// This is called for each body that leaves the world boundary.
/// @warning you can't modify the world inside this callback.
virtual void Violation(b2Body* body) = 0;
};
/// Implement this class to provide collision filtering. In other words, you can implement
/// this class if you want finer control over contact creation.
class b2ContactFilter
{
public:
virtual ~b2ContactFilter() {}
/// Return true if contact calculations should be performed between these two shapes.
/// @warning for performance reasons this is only called when the AABBs begin to overlap.
virtual bool ShouldCollide(b2Shape* shape1, b2Shape* shape2);
};
/// The default contact filter.
extern b2ContactFilter b2_defaultFilter;
/// Implement this class to get collision results. You can use these results for
/// things like sounds and game logic. You can also get contact results by
/// traversing the contact lists after the time step. However, you might miss
/// some contacts because continuous physics leads to sub-stepping.
/// Additionally you may receive multiple callbacks for the same contact in a
/// single time step.
/// You should strive to make your callbacks efficient because there may be
/// many callbacks per time step.
/// @warning The contact separation is the last computed value.
/// @warning You cannot create/destroy Box2D entities inside these callbacks.
class b2ContactListener
{
public:
virtual ~b2ContactListener() {}
/// Called when a contact point is added. This includes the geometry
/// and the forces.
virtual void Add(const b2ContactPoint* point) { B2_NOT_USED(point); }
/// Called when a contact point persists. This includes the geometry
/// and the forces.
virtual void Persist(const b2ContactPoint* point) { B2_NOT_USED(point); }
/// Called when a contact point is removed. This includes the last
/// computed geometry and forces.
virtual void Remove(const b2ContactPoint* point) { B2_NOT_USED(point); }
/// Called after a contact point is solved.
virtual void Result(const b2ContactResult* point) { B2_NOT_USED(point); }
};
/// Color for debug drawing. Each value has the range [0,1].
struct b2Color
{
b2Color() {}
b2Color(float32 r, float32 g, float32 b) : r(r), g(g), b(b) {}
float32 r, g, b;
};
/// Implement and register this class with a b2World to provide debug drawing of physics
/// entities in your game.
class b2DebugDraw
{
public:
b2DebugDraw();
virtual ~b2DebugDraw() {}
enum
{
e_shapeBit = 0x0001, ///< draw shapes
e_jointBit = 0x0002, ///< draw joint connections
e_coreShapeBit = 0x0004, ///< draw core (TOI) shapes
e_aabbBit = 0x0008, ///< draw axis aligned bounding boxes
e_obbBit = 0x0010, ///< draw oriented bounding boxes
e_pairBit = 0x0020, ///< draw broad-phase pairs
e_centerOfMassBit = 0x0040, ///< draw center of mass frame
};
/// Set the drawing flags.
void SetFlags(uint32 flags);
/// Get the drawing flags.
uint32 GetFlags() const;
/// Append flags to the current flags.
void AppendFlags(uint32 flags);
/// Clear flags from the current flags.
void ClearFlags(uint32 flags);
/// Draw a closed polygon provided in CCW order.
virtual void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) = 0;
/// Draw a solid closed polygon provided in CCW order.
virtual void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) = 0;
/// Draw a circle.
virtual void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) = 0;
/// Draw a solid circle.
virtual void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) = 0;
/// Draw a line segment.
virtual void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) = 0;
/// Draw a transform. Choose your own length scale.
/// @param xf a transform.
virtual void DrawXForm(const b2XForm& xf) = 0;
protected:
uint32 m_drawFlags;
};
#endif