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 @@
link Versions/Current/Box2D
@@ -0,0 +1 @@
link Versions/Current/Headers
@@ -0,0 +1 @@
link Versions/Current/Resources
@@ -0,0 +1,52 @@
/*
* 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 BOX2D_H
#define BOX2D_H
/**
\mainpage Box2D API Documentation
\section intro_sec Getting Started
For tutorials please see http://www.box2d.org/manual.html
For discussion please visit http://www.box2d.org/forum
*/
// These include files constitute the main Box2D API
#include "../Source/Common/b2Settings.h"
#include "../Source/Collision/Shapes/b2CircleShape.h"
#include "../Source/Collision/Shapes/b2PolygonShape.h"
#include "../Source/Collision/b2BroadPhase.h"
#include "../Source/Dynamics/b2WorldCallbacks.h"
#include "../Source/Dynamics/b2World.h"
#include "../Source/Dynamics/b2Body.h"
#include "../Source/Dynamics/Contacts/b2Contact.h"
#include "../Source/Dynamics/Joints/b2DistanceJoint.h"
#include "../Source/Dynamics/Joints/b2MouseJoint.h"
#include "../Source/Dynamics/Joints/b2PrismaticJoint.h"
#include "../Source/Dynamics/Joints/b2RevoluteJoint.h"
#include "../Source/Dynamics/Joints/b2PulleyJoint.h"
#include "../Source/Dynamics/Joints/b2GearJoint.h"
#endif
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>Box2D</string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.yourcocoaframework</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Box2D</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
</dict>
</plist>
@@ -0,0 +1,92 @@
/*
* 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_CIRCLE_SHAPE_H
#define B2_CIRCLE_SHAPE_H
#include "b2Shape.h"
/// This structure is used to build circle shapes.
struct b2CircleDef : public b2ShapeDef
{
b2CircleDef()
{
type = e_circleShape;
localPosition.SetZero();
radius = 1.0f;
}
b2Vec2 localPosition;
float32 radius;
};
/// A circle shape.
class b2CircleShape : public b2Shape
{
public:
/// @see b2Shape::TestPoint
bool TestPoint(const b2XForm& transform, const b2Vec2& p) const;
/// @see b2Shape::TestSegment
bool TestSegment( const b2XForm& transform,
float32* lambda,
b2Vec2* normal,
const b2Segment& segment,
float32 maxLambda) const;
/// @see b2Shape::ComputeAABB
void ComputeAABB(b2AABB* aabb, const b2XForm& transform) const;
/// @see b2Shape::ComputeSweptAABB
void ComputeSweptAABB( b2AABB* aabb,
const b2XForm& transform1,
const b2XForm& transform2) const;
/// @see b2Shape::ComputeMass
void ComputeMass(b2MassData* massData) const;
/// Get the local position of this circle in its parent body.
const b2Vec2& GetLocalPosition() const;
/// Get the radius of this circle.
float32 GetRadius() const;
private:
friend class b2Shape;
b2CircleShape(const b2ShapeDef* def);
void UpdateSweepRadius(const b2Vec2& center);
// Local position in parent body
b2Vec2 m_localPosition;
float32 m_radius;
};
inline const b2Vec2& b2CircleShape::GetLocalPosition() const
{
return m_localPosition;
}
inline float32 b2CircleShape::GetRadius() const
{
return m_radius;
}
#endif
@@ -0,0 +1,163 @@
/*
* 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_POLYGON_SHAPE_H
#define B2_POLYGON_SHAPE_H
#include "b2Shape.h"
/// Convex polygon. The vertices must be in CCW order for a right-handed
/// coordinate system with the z-axis coming out of the screen.
struct b2PolygonDef : public b2ShapeDef
{
b2PolygonDef()
{
type = e_polygonShape;
vertexCount = 0;
}
/// Build vertices to represent an axis-aligned box.
/// @param hx the half-width.
/// @param hy the half-height.
void SetAsBox(float32 hx, float32 hy);
/// Build vertices to represent an oriented box.
/// @param hx the half-width.
/// @param hy the half-height.
/// @param center the center of the box in local coordinates.
/// @param angle the rotation of the box in local coordinates.
void SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle);
/// The polygon vertices in local coordinates.
b2Vec2 vertices[b2_maxPolygonVertices];
/// The number of polygon vertices.
int32 vertexCount;
};
/// A convex polygon.
class b2PolygonShape : public b2Shape
{
public:
/// @see b2Shape::TestPoint
bool TestPoint(const b2XForm& transform, const b2Vec2& p) const;
/// @see b2Shape::TestSegment
bool TestSegment( const b2XForm& transform,
float32* lambda,
b2Vec2* normal,
const b2Segment& segment,
float32 maxLambda) const;
/// @see b2Shape::ComputeAABB
void ComputeAABB(b2AABB* aabb, const b2XForm& transform) const;
/// @see b2Shape::ComputeSweptAABB
void ComputeSweptAABB( b2AABB* aabb,
const b2XForm& transform1,
const b2XForm& transform2) const;
/// @see b2Shape::ComputeMass
void ComputeMass(b2MassData* massData) const;
/// Get the oriented bounding box relative to the parent body.
const b2OBB& GetOBB() const;
/// Get local centroid relative to the parent body.
const b2Vec2& GetCentroid() const;
/// Get the vertex count.
int32 GetVertexCount() const;
/// Get the vertices in local coordinates.
const b2Vec2* GetVertices() const;
/// Get the core vertices in local coordinates. These vertices
/// represent a smaller polygon that is used for time of impact
/// computations.
const b2Vec2* GetCoreVertices() const;
/// Get the edge normal vectors. There is one for each vertex.
const b2Vec2* GetNormals() const;
/// Get the first vertex and apply the supplied transform.
b2Vec2 GetFirstVertex(const b2XForm& xf) const;
/// Get the centroid and apply the supplied transform.
b2Vec2 Centroid(const b2XForm& xf) const;
/// Get the support point in the given world direction.
/// Use the supplied transform.
b2Vec2 Support(const b2XForm& xf, const b2Vec2& d) const;
private:
friend class b2Shape;
b2PolygonShape(const b2ShapeDef* def);
void UpdateSweepRadius(const b2Vec2& center);
// Local position of the polygon centroid.
b2Vec2 m_centroid;
b2OBB m_obb;
b2Vec2 m_vertices[b2_maxPolygonVertices];
b2Vec2 m_normals[b2_maxPolygonVertices];
b2Vec2 m_coreVertices[b2_maxPolygonVertices];
int32 m_vertexCount;
};
inline b2Vec2 b2PolygonShape::GetFirstVertex(const b2XForm& xf) const
{
return b2Mul(xf, m_coreVertices[0]);
}
inline const b2OBB& b2PolygonShape::GetOBB() const
{
return m_obb;
}
inline const b2Vec2& b2PolygonShape::GetCentroid() const
{
return m_centroid;
}
inline int32 b2PolygonShape::GetVertexCount() const
{
return m_vertexCount;
}
inline const b2Vec2* b2PolygonShape::GetVertices() const
{
return m_vertices;
}
inline const b2Vec2* b2PolygonShape::GetCoreVertices() const
{
return m_coreVertices;
}
inline const b2Vec2* b2PolygonShape::GetNormals() const
{
return m_normals;
}
#endif
@@ -0,0 +1,285 @@
/*
* 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_SHAPE_H
#define B2_SHAPE_H
#include "../../Common/b2Math.h"
#include "../b2Collision.h"
class b2BlockAllocator;
class b2Body;
class b2BroadPhase;
/// This holds the mass data computed for a shape.
struct b2MassData
{
/// The mass of the shape, usually in kilograms.
float32 mass;
/// The position of the shape's centroid relative to the shape's origin.
b2Vec2 center;
/// The rotational inertia of the shape.
float32 I;
};
/// This holds contact filtering data.
struct b2FilterData
{
/// The collision category bits. Normally you would just set one bit.
uint16 categoryBits;
/// The collision mask bits. This states the categories that this
/// shape would accept for collision.
uint16 maskBits;
/// Collision groups allow a certain group of objects to never collide (negative)
/// or always collide (positive). Zero means no collision group. Non-zero group
/// filtering always wins against the mask bits.
int16 groupIndex;
};
/// The various collision shape types supported by Box2D.
enum b2ShapeType
{
e_unknownShape = -1,
e_circleShape,
e_polygonShape,
e_shapeTypeCount,
};
/// A shape definition is used to construct a shape. This class defines an
/// abstract shape definition. You can reuse shape definitions safely.
struct b2ShapeDef
{
/// The constructor sets the default shape definition values.
b2ShapeDef()
{
type = e_unknownShape;
userData = NULL;
friction = 0.2f;
restitution = 0.0f;
density = 0.0f;
filter.categoryBits = 0x0001;
filter.maskBits = 0xFFFF;
filter.groupIndex = 0;
isSensor = false;
}
virtual ~b2ShapeDef() {}
/// Holds the shape type for down-casting.
b2ShapeType type;
/// Use this to store application specify shape data.
void* userData;
/// The shape's friction coefficient, usually in the range [0,1].
float32 friction;
/// The shape's restitution (elasticity) usually in the range [0,1].
float32 restitution;
/// The shape's density, usually in kg/m^2.
float32 density;
/// A sensor shape collects contact information but never generates a collision
/// response.
bool isSensor;
/// Contact filtering data.
b2FilterData filter;
};
/// A shape is used for collision detection. Shapes are created in b2World.
/// You can use shape for collision detection before they are attached to the world.
/// @warning you cannot reuse shapes.
class b2Shape
{
public:
/// Get the type of this shape. You can use this to down cast to the concrete shape.
/// @return the shape type.
b2ShapeType GetType() const;
/// Is this shape a sensor (non-solid)?
/// @return the true if the shape is a sensor.
bool IsSensor() const;
/// Set the contact filtering data. You must call b2World::Refilter to correct
/// existing contacts/non-contacts.
void SetFilterData(const b2FilterData& filter);
/// Get the contact filtering data.
const b2FilterData& GetFilterData() const;
/// Get the parent body of this shape. This is NULL if the shape is not attached.
/// @return the parent body.
b2Body* GetBody();
/// Get the next shape in the parent body's shape list.
/// @return the next shape.
b2Shape* GetNext();
/// Get the user data that was assigned in the shape definition. Use this to
/// store your application specific data.
void* GetUserData();
/// Set the user data. Use this to store your application specific data.
void SetUserData(void* data);
/// Test a point for containment in this shape. This only works for convex shapes.
/// @param xf the shape world transform.
/// @param p a point in world coordinates.
virtual bool TestPoint(const b2XForm& xf, const b2Vec2& p) const = 0;
/// Perform a ray cast against this shape.
/// @param xf the shape world transform.
/// @param lambda returns the hit fraction. You can use this to compute the contact point
/// p = (1 - lambda) * segment.p1 + lambda * segment.p2.
/// @param normal returns the normal at the contact point. If there is no intersection, the normal
/// is not set.
/// @param segment defines the begin and end point of the ray cast.
/// @param maxLambda a number typically in the range [0,1].
/// @return true if there was an intersection.
virtual bool TestSegment( const b2XForm& xf,
float32* lambda,
b2Vec2* normal,
const b2Segment& segment,
float32 maxLambda) const = 0;
/// Given a transform, compute the associated axis aligned bounding box for this shape.
/// @param aabb returns the axis aligned box.
/// @param xf the world transform of the shape.
virtual void ComputeAABB(b2AABB* aabb, const b2XForm& xf) const = 0;
/// Given two transforms, compute the associated swept axis aligned bounding box for this shape.
/// @param aabb returns the axis aligned box.
/// @param xf1 the starting shape world transform.
/// @param xf2 the ending shape world transform.
virtual void ComputeSweptAABB( b2AABB* aabb,
const b2XForm& xf1,
const b2XForm& xf2) const = 0;
/// Compute the mass properties of this shape using its dimensions and density.
/// The inertia tensor is computed about the local origin, not the centroid.
/// @param massData returns the mass data for this shape.
virtual void ComputeMass(b2MassData* massData) const = 0;
/// Get the maximum radius about the parent body's center of mass.
float32 GetSweepRadius() const;
/// Get the coefficient of friction.
float32 GetFriction() const;
/// Get the coefficient of restitution.
float32 GetRestitution() const;
protected:
friend class b2Body;
friend class b2World;
static b2Shape* Create(const b2ShapeDef* def, b2BlockAllocator* allocator);
static void Destroy(b2Shape* shape, b2BlockAllocator* allocator);
b2Shape(const b2ShapeDef* def);
virtual ~b2Shape();
void CreateProxy(b2BroadPhase* broadPhase, const b2XForm& xf);
void DestroyProxy(b2BroadPhase* broadPhase);
bool Synchronize(b2BroadPhase* broadPhase, const b2XForm& xf1, const b2XForm& xf2);
void RefilterProxy(b2BroadPhase* broadPhase, const b2XForm& xf);
virtual void UpdateSweepRadius(const b2Vec2& center) = 0;
b2ShapeType m_type;
b2Shape* m_next;
b2Body* m_body;
// Sweep radius relative to the parent body's center of mass.
float32 m_sweepRadius;
float32 m_density;
float32 m_friction;
float32 m_restitution;
uint16 m_proxyId;
b2FilterData m_filter;
bool m_isSensor;
void* m_userData;
};
inline b2ShapeType b2Shape::GetType() const
{
return m_type;
}
inline bool b2Shape::IsSensor() const
{
return m_isSensor;
}
inline void b2Shape::SetFilterData(const b2FilterData& filter)
{
m_filter = filter;
}
inline const b2FilterData& b2Shape::GetFilterData() const
{
return m_filter;
}
inline void* b2Shape::GetUserData()
{
return m_userData;
}
inline void b2Shape::SetUserData(void* data)
{
m_userData = data;
}
inline b2Body* b2Shape::GetBody()
{
return m_body;
}
inline b2Shape* b2Shape::GetNext()
{
return m_next;
}
inline float32 b2Shape::GetSweepRadius() const
{
return m_sweepRadius;
}
inline float32 b2Shape::GetFriction() const
{
return m_friction;
}
inline float32 b2Shape::GetRestitution() const
{
return m_restitution;
}
#endif
@@ -0,0 +1,146 @@
/*
* 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_BROAD_PHASE_H
#define B2_BROAD_PHASE_H
/*
This broad phase uses the Sweep and Prune algorithm as described in:
Collision Detection in Interactive 3D Environments by Gino van den Bergen
Also, some ideas, such as using integral values for fast compares comes from
Bullet (http:/www.bulletphysics.com).
*/
#include "../Common/b2Settings.h"
#include "b2Collision.h"
#include "b2PairManager.h"
#include <climits>
#ifdef TARGET_FLOAT32_IS_FIXED
#define B2BROADPHASE_MAX (USHRT_MAX/2)
#else
#define B2BROADPHASE_MAX USHRT_MAX
#endif
const uint16 b2_invalid = B2BROADPHASE_MAX;
const uint16 b2_nullEdge = B2BROADPHASE_MAX;
struct b2BoundValues;
struct b2Bound
{
bool IsLower() const { return (value & 1) == 0; }
bool IsUpper() const { return (value & 1) == 1; }
uint16 value;
uint16 proxyId;
uint16 stabbingCount;
};
struct b2Proxy
{
uint16 GetNext() const { return lowerBounds[0]; }
void SetNext(uint16 next) { lowerBounds[0] = next; }
bool IsValid() const { return overlapCount != b2_invalid; }
uint16 lowerBounds[2], upperBounds[2];
uint16 overlapCount;
uint16 timeStamp;
void* userData;
};
class b2BroadPhase
{
public:
b2BroadPhase(const b2AABB& worldAABB, b2PairCallback* callback);
~b2BroadPhase();
// Use this to see if your proxy is in range. If it is not in range,
// it should be destroyed. Otherwise you may get O(m^2) pairs, where m
// is the number of proxies that are out of range.
bool InRange(const b2AABB& aabb) const;
// Create and destroy proxies. These call Flush first.
uint16 CreateProxy(const b2AABB& aabb, void* userData);
void DestroyProxy(int32 proxyId);
// Call MoveProxy as many times as you like, then when you are done
// call Commit to finalized the proxy pairs (for your time step).
void MoveProxy(int32 proxyId, const b2AABB& aabb);
void Commit();
// Get a single proxy. Returns NULL if the id is invalid.
b2Proxy* GetProxy(int32 proxyId);
// Query an AABB for overlapping proxies, returns the user data and
// the count, up to the supplied maximum count.
int32 Query(const b2AABB& aabb, void** userData, int32 maxCount);
void Validate();
void ValidatePairs();
private:
void ComputeBounds(uint16* lowerValues, uint16* upperValues, const b2AABB& aabb);
bool TestOverlap(b2Proxy* p1, b2Proxy* p2);
bool TestOverlap(const b2BoundValues& b, b2Proxy* p);
void Query(int32* lowerIndex, int32* upperIndex, uint16 lowerValue, uint16 upperValue,
b2Bound* bounds, int32 boundCount, int32 axis);
void IncrementOverlapCount(int32 proxyId);
void IncrementTimeStamp();
public:
friend class b2PairManager;
b2PairManager m_pairManager;
b2Proxy m_proxyPool[b2_maxProxies];
uint16 m_freeProxy;
b2Bound m_bounds[2][2*b2_maxProxies];
uint16 m_queryResults[b2_maxProxies];
int32 m_queryResultCount;
b2AABB m_worldAABB;
b2Vec2 m_quantizationFactor;
int32 m_proxyCount;
uint16 m_timeStamp;
static bool s_validate;
};
inline bool b2BroadPhase::InRange(const b2AABB& aabb) const
{
b2Vec2 d = b2Max(aabb.lowerBound - m_worldAABB.upperBound, m_worldAABB.lowerBound - aabb.upperBound);
return b2Max(d.x, d.y) < 0.0f;
}
inline b2Proxy* b2BroadPhase::GetProxy(int32 proxyId)
{
if (proxyId == b2_nullProxy || m_proxyPool[proxyId].IsValid() == false)
{
return NULL;
}
return m_proxyPool + proxyId;
}
#endif
@@ -0,0 +1,154 @@
/*
* 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_COLLISION_H
#define B2_COLLISION_H
#include "../Common/b2Math.h"
#include <climits>
/// @file
/// Structures and functions used for computing contact points, distance
/// queries, and TOI queries.
class b2Shape;
class b2CircleShape;
class b2PolygonShape;
const uint8 b2_nullFeature = UCHAR_MAX;
/// Contact ids to facilitate warm starting.
union b2ContactID
{
/// The features that intersect to form the contact point
struct Features
{
uint8 referenceEdge; ///< The edge that defines the outward contact normal.
uint8 incidentEdge; ///< The edge most anti-parallel to the reference edge.
uint8 incidentVertex; ///< The vertex (0 or 1) on the incident edge that was clipped.
uint8 flip; ///< A value of 1 indicates that the reference edge is on shape2.
} features;
uint32 key; ///< Used to quickly compare contact ids.
};
/// A manifold point is a contact point belonging to a contact
/// manifold. It holds details related to the geometry and dynamics
/// of the contact points.
/// The point is stored in local coordinates because CCD
/// requires sub-stepping in which the separation is stale.
struct b2ManifoldPoint
{
b2Vec2 localPoint1; ///< local position of the contact point in body1
b2Vec2 localPoint2; ///< local position of the contact point in body2
float32 separation; ///< the separation of the shapes along the normal vector
float32 normalImpulse; ///< the non-penetration impulse
float32 tangentImpulse; ///< the friction impulse
b2ContactID id; ///< uniquely identifies a contact point between two shapes
};
/// A manifold for two touching convex shapes.
struct b2Manifold
{
b2ManifoldPoint points[b2_maxManifoldPoints]; ///< the points of contact
b2Vec2 normal; ///< the shared unit normal vector
int32 pointCount; ///< the number of manifold points
};
/// A line segment.
struct b2Segment
{
/// Ray cast against this segment with another segment.
bool TestSegment(float32* lambda, b2Vec2* normal, const b2Segment& segment, float32 maxLambda) const;
b2Vec2 p1; ///< the starting point
b2Vec2 p2; ///< the ending point
};
/// An axis aligned bounding box.
struct b2AABB
{
/// Verify that the bounds are sorted.
bool IsValid() const;
b2Vec2 lowerBound; ///< the lower vertex
b2Vec2 upperBound; ///< the upper vertex
};
/// An oriented bounding box.
struct b2OBB
{
b2Mat22 R; ///< the rotation matrix
b2Vec2 center; ///< the local centroid
b2Vec2 extents; ///< the half-widths
};
/// Compute the collision manifold between two circles.
void b2CollideCircles(b2Manifold* manifold,
const b2CircleShape* circle1, const b2XForm& xf1,
const b2CircleShape* circle2, const b2XForm& xf2);
/// Compute the collision manifold between a polygon and a circle.
void b2CollidePolygonAndCircle(b2Manifold* manifold,
const b2PolygonShape* polygon, const b2XForm& xf1,
const b2CircleShape* circle, const b2XForm& xf2);
/// Compute the collision manifold between two circles.
void b2CollidePolygons(b2Manifold* manifold,
const b2PolygonShape* polygon1, const b2XForm& xf1,
const b2PolygonShape* polygon2, const b2XForm& xf2);
/// Compute the distance between two shapes and the closest points.
/// @return the distance between the shapes or zero if they are overlapped/touching.
float32 b2Distance(b2Vec2* x1, b2Vec2* x2,
const b2Shape* shape1, const b2XForm& xf1,
const b2Shape* shape2, const b2XForm& xf2);
/// Compute the time when two shapes begin to touch or touch at a closer distance.
/// @warning the sweeps must have the same time interval.
/// @return the fraction between [0,1] in which the shapes first touch.
/// fraction=0 means the shapes begin touching/overlapped, and fraction=1 means the shapes don't touch.
float32 b2TimeOfImpact(const b2Shape* shape1, const b2Sweep& sweep1,
const b2Shape* shape2, const b2Sweep& sweep2);
// ---------------- Inline Functions ------------------------------------------
inline bool b2AABB::IsValid() const
{
b2Vec2 d = upperBound - lowerBound;
bool valid = d.x >= 0.0f && d.y >= 0.0f;
valid = valid && lowerBound.IsValid() && upperBound.IsValid();
return valid;
}
inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b)
{
b2Vec2 d1, d2;
d1 = b.lowerBound - a.upperBound;
d2 = a.lowerBound - b.upperBound;
if (d1.x > 0.0f || d1.y > 0.0f)
return false;
if (d2.x > 0.0f || d2.y > 0.0f)
return false;
return true;
}
#endif
@@ -0,0 +1,121 @@
/*
* 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.
*/
// The pair manager is used by the broad-phase to quickly add/remove/find pairs
// of overlapping proxies. It is based closely on code provided by Pierre Terdiman.
// http://www.codercorner.com/IncrementalSAP.txt
#ifndef B2_PAIR_MANAGER_H
#define B2_PAIR_MANAGER_H
#include "../Common/b2Settings.h"
#include "../Common/b2Math.h"
#include <climits>
class b2BroadPhase;
struct b2Proxy;
const uint16 b2_nullPair = USHRT_MAX;
const uint16 b2_nullProxy = USHRT_MAX;
const int32 b2_tableCapacity = b2_maxPairs; // must be a power of two
const int32 b2_tableMask = b2_tableCapacity - 1;
struct b2Pair
{
enum
{
e_pairBuffered = 0x0001,
e_pairRemoved = 0x0002,
e_pairFinal = 0x0004,
};
void SetBuffered() { status |= e_pairBuffered; }
void ClearBuffered() { status &= ~e_pairBuffered; }
bool IsBuffered() { return (status & e_pairBuffered) == e_pairBuffered; }
void SetRemoved() { status |= e_pairRemoved; }
void ClearRemoved() { status &= ~e_pairRemoved; }
bool IsRemoved() { return (status & e_pairRemoved) == e_pairRemoved; }
void SetFinal() { status |= e_pairFinal; }
bool IsFinal() { return (status & e_pairFinal) == e_pairFinal; }
void* userData;
uint16 proxyId1;
uint16 proxyId2;
uint16 next;
uint16 status;
};
struct b2BufferedPair
{
uint16 proxyId1;
uint16 proxyId2;
};
class b2PairCallback
{
public:
virtual ~b2PairCallback() {}
// This should return the new pair user data. It is ok if the
// user data is null.
virtual void* PairAdded(void* proxyUserData1, void* proxyUserData2) = 0;
// This should free the pair's user data. In extreme circumstances, it is possible
// this will be called with null pairUserData because the pair never existed.
virtual void PairRemoved(void* proxyUserData1, void* proxyUserData2, void* pairUserData) = 0;
};
class b2PairManager
{
public:
b2PairManager();
void Initialize(b2BroadPhase* broadPhase, b2PairCallback* callback);
void AddBufferedPair(int32 proxyId1, int32 proxyId2);
void RemoveBufferedPair(int32 proxyId1, int32 proxyId2);
void Commit();
private:
b2Pair* Find(int32 proxyId1, int32 proxyId2);
b2Pair* Find(int32 proxyId1, int32 proxyId2, uint32 hashValue);
b2Pair* AddPair(int32 proxyId1, int32 proxyId2);
void* RemovePair(int32 proxyId1, int32 proxyId2);
void ValidateBuffer();
void ValidateTable();
public:
b2BroadPhase *m_broadPhase;
b2PairCallback *m_callback;
b2Pair m_pairs[b2_maxPairs];
uint16 m_freePair;
int32 m_pairCount;
b2BufferedPair m_pairBuffer[b2_maxPairs];
int32 m_pairBufferCount;
uint16 m_hashTable[b2_tableCapacity];
};
#endif
@@ -0,0 +1,477 @@
/*
Copyright (c) 2006 Henry Strickland & Ryan Seto
2007-2008 Tobias Weyand (modifications and extensions)
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
(* http://www.opensource.org/licenses/mit-license.php *)
*/
#ifndef _FIXED_H_
#define _FIXED_H_
#include <stdio.h>
#ifdef TARGET_IS_NDS
#include "nds.h"
#endif
#define FIXED_BP 16
#define FIXED_MAX ((1<<(32-FIXED_BP-1))-1)
#define FIXED_MIN (-(1<<(32-FIXED_BP-1)))
#define FIXED_EPSILON (Fixed(0.00007f))
#define G_1_DIV_PI 20861
class Fixed {
private:
int g; // the guts
const static int BP= FIXED_BP; // how many low bits are right of Binary Point
const static int BP2= BP*2; // how many low bits are right of Binary Point
const static int BPhalf= BP/2; // how many low bits are right of Binary Point
double STEP(); // smallest step we can represent
// for private construction via guts
enum FixedRaw { RAW };
Fixed(FixedRaw, int guts);
public:
Fixed();
Fixed(const Fixed &a);
Fixed(float a);
Fixed(double a);
Fixed(int a);
Fixed(long a);
Fixed& operator =(const Fixed a);
Fixed& operator =(float a);
Fixed& operator =(double a);
Fixed& operator =(int a);
Fixed& operator =(long a);
operator float();
operator double();
operator int();
operator long();
operator unsigned short();
operator float() const;
Fixed operator +() const;
Fixed operator -() const;
Fixed operator +(const Fixed a) const;
Fixed operator -(const Fixed a) const;
#if 1
// more acurate, using long long
Fixed operator *(const Fixed a) const;
#else
// faster, but with only half as many bits right of binary point
Fixed operator *(const Fixed a) const;
#endif
Fixed operator /(const Fixed a) const;
Fixed operator *(unsigned short a) const;
Fixed operator *(int a) const;
Fixed operator +(float a) const;
Fixed operator -(float a) const;
Fixed operator *(float a) const;
Fixed operator /(float a) const;
Fixed operator +(double a) const;
Fixed operator -(double a) const;
Fixed operator *(double a) const;
Fixed operator /(double a) const;
Fixed operator >>(int a) const;
Fixed operator <<(int a) const;
Fixed& operator +=(Fixed a);
Fixed& operator -=(Fixed a);
Fixed& operator *=(Fixed a);
Fixed& operator /=(Fixed a);
Fixed& operator +=(int a);
Fixed& operator -=(int a);
Fixed& operator *=(int a);
Fixed& operator /=(int a);
Fixed& operator +=(long a);
Fixed& operator -=(long a);
Fixed& operator *=(long a);
Fixed& operator /=(long a);
Fixed& operator +=(float a);
Fixed& operator -=(float a);
Fixed& operator *=(float a);
Fixed& operator /=(float a);
Fixed& operator +=(double a);
Fixed& operator -=(double a);
Fixed& operator *=(double a);
Fixed& operator /=(double a);
bool operator ==(const Fixed a) const;
bool operator !=(const Fixed a) const;
bool operator <=(const Fixed a) const;
bool operator >=(const Fixed a) const;
bool operator <(const Fixed a) const;
bool operator >(const Fixed a) const;
bool operator ==(float a) const;
bool operator !=(float a) const;
bool operator <=(float a) const;
bool operator >=(float a) const;
bool operator <(float a) const;
bool operator >(float a) const;
bool operator ==(double a) const;
bool operator !=(double a) const;
bool operator <=(double a) const;
bool operator >=(double a) const;
bool operator <(double a) const;
bool operator >(double a) const;
bool operator >(int a) const;
bool operator <(int a) const;
bool operator >=(int a) const;
bool operator <=(int a) const;
Fixed abs();
Fixed sqrt();
#ifdef TARGET_IS_NDS
Fixed cosf();
Fixed sinf();
Fixed tanf();
#endif
};
//
// Implementation
//
inline double Fixed::STEP() { return 1.0 / (1<<BP); } // smallest step we can represent
// for private construction via guts
inline Fixed::Fixed(FixedRaw, int guts) : g(guts) {}
inline Fixed::Fixed() : g(0) {}
inline Fixed::Fixed(const Fixed &a) : g( a.g ) {}
inline Fixed::Fixed(float a) : g( int(a * (float)(1<<BP)) ) {}
inline Fixed::Fixed(double a) : g( int(a * (double)(1<<BP) ) ) {}
inline Fixed::Fixed(int a) : g( a << BP ) {}
inline Fixed::Fixed(long a) : g( a << BP ) {}
inline Fixed& Fixed::operator =(const Fixed a) { g= a.g; return *this; }
inline Fixed& Fixed::operator =(float a) { g= Fixed(a).g; return *this; }
inline Fixed& Fixed::operator =(double a) { g= Fixed(a).g; return *this; }
inline Fixed& Fixed::operator =(int a) { g= Fixed(a).g; return *this; }
inline Fixed& Fixed::operator =(long a) { g= Fixed(a).g; return *this; }
inline Fixed::operator float() { return g * (float)STEP(); }
inline Fixed::operator double() { return g * (double)STEP(); }
inline Fixed::operator int() { return g>>BP; }
inline Fixed::operator long() { return g>>BP; }
//#pragma warning(disable: 4244) //HARDWIRE added pragma to prevent VS2005 compilation error
inline Fixed::operator unsigned short() { return g>>BP; }
inline Fixed::operator float() const { return g / (float)(1<<BP); }
inline Fixed Fixed::operator +() const { return Fixed(RAW,g); }
inline Fixed Fixed::operator -() const { return Fixed(RAW,-g); }
inline Fixed Fixed::operator +(const Fixed a) const { return Fixed(RAW, g + a.g); }
inline Fixed Fixed::operator -(const Fixed a) const { return Fixed(RAW, g - a.g); }
#if 1
// more acurate, using long long
inline Fixed Fixed::operator *(const Fixed a) const { return Fixed(RAW, (int)( ((long long)g * (long long)a.g ) >> BP)); }
#elif 0
// check for overflow and figure out where. Must specify -rdynamic in linker
#include <execinfo.h>
#include <signal.h>
#include <exception>
inline Fixed Fixed::operator *(const Fixed a) const {
long long x = ((long long)g * (long long)a.g );
if(x > 0x7fffffffffffLL || x < -0x7fffffffffffLL) {
printf("overflow");
void *array[2];
int nSize = backtrace(array, 2);
char **symbols = backtrace_symbols(array, nSize);
for(int i=0; i<nSize; i++) {
printf(" %s", symbols[i]);
}
printf("\n");
}
return Fixed(RAW, (int)(x>>BP));
}
#else
// faster, but with only half as many bits right of binary point
inline Fixed Fixed::operator *(const Fixed a) const { return Fixed(RAW, (g>>BPhalf) * (a.g>>BPhalf) ); }
#endif
#ifdef TARGET_IS_NDS
// Division using the DS's maths coprocessor
inline Fixed Fixed::operator /(const Fixed a) const
{
//printf("%d %d\n", (long long)g << BP, a.g);
return Fixed(RAW, int( div64((long long)g << BP, a.g) ) );
}
#else
inline Fixed Fixed::operator /(const Fixed a) const
{
return Fixed(RAW, int( (((long long)g << BP2) / (long long)(a.g)) >> BP) );
//return Fixed(RAW, int( (((long long)g << BP) / (long long)(a.g)) ) );
}
#endif
inline Fixed Fixed::operator *(unsigned short a) const { return operator*(Fixed(a)); }
inline Fixed Fixed::operator *(int a) const { return operator*(Fixed(a)); }
inline Fixed Fixed::operator +(float a) const { return Fixed(RAW, g + Fixed(a).g); }
inline Fixed Fixed::operator -(float a) const { return Fixed(RAW, g - Fixed(a).g); }
inline Fixed Fixed::operator *(float a) const { return Fixed(RAW, (g>>BPhalf) * (Fixed(a).g>>BPhalf) ); }
//inline Fixed Fixed::operator /(float a) const { return Fixed(RAW, int( (((long long)g << BP2) / (long long)(Fixed(a).g)) >> BP) ); }
inline Fixed Fixed::operator /(float a) const { return operator/(Fixed(a)); }
inline Fixed Fixed::operator +(double a) const { return Fixed(RAW, g + Fixed(a).g); }
inline Fixed Fixed::operator -(double a) const { return Fixed(RAW, g - Fixed(a).g); }
inline Fixed Fixed::operator *(double a) const { return Fixed(RAW, (g>>BPhalf) * (Fixed(a).g>>BPhalf) ); }
//inline Fixed Fixed::operator /(double a) const { return Fixed(RAW, int( (((long long)g << BP2) / (long long)(Fixed(a).g)) >> BP) ); }
inline Fixed Fixed::operator /(double a) const { return operator/(Fixed(a)); }
inline Fixed Fixed::operator >>(int a) const { return Fixed(RAW, g >> a); }
inline Fixed Fixed::operator <<(int a) const { return Fixed(RAW, g << a); }
inline Fixed& Fixed::operator +=(Fixed a) { return *this = *this + a; }
inline Fixed& Fixed::operator -=(Fixed a) { return *this = *this - a; }
inline Fixed& Fixed::operator *=(Fixed a) { return *this = *this * a; }
//inline Fixed& Fixed::operator /=(Fixed a) { return *this = *this / a; }
inline Fixed& Fixed::operator /=(Fixed a) { return *this = operator/(a); }
inline Fixed& Fixed::operator +=(int a) { return *this = *this + (Fixed)a; }
inline Fixed& Fixed::operator -=(int a) { return *this = *this - (Fixed)a; }
inline Fixed& Fixed::operator *=(int a) { return *this = *this * (Fixed)a; }
//inline Fixed& Fixed::operator /=(int a) { return *this = *this / (Fixed)a; }
inline Fixed& Fixed::operator /=(int a) { return *this = operator/((Fixed)a); }
inline Fixed& Fixed::operator +=(long a) { return *this = *this + (Fixed)a; }
inline Fixed& Fixed::operator -=(long a) { return *this = *this - (Fixed)a; }
inline Fixed& Fixed::operator *=(long a) { return *this = *this * (Fixed)a; }
//inline Fixed& Fixed::operator /=(long a) { return *this = *this / (Fixed)a; }
inline Fixed& Fixed::operator /=(long a) { return *this = operator/((Fixed)a); }
inline Fixed& Fixed::operator +=(float a) { return *this = *this + a; }
inline Fixed& Fixed::operator -=(float a) { return *this = *this - a; }
inline Fixed& Fixed::operator *=(float a) { return *this = *this * a; }
//inline Fixed& Fixed::operator /=(float a) { return *this = *this / a; }
inline Fixed& Fixed::operator /=(float a) { return *this = operator/(a); }
inline Fixed& Fixed::operator +=(double a) { return *this = *this + a; }
inline Fixed& Fixed::operator -=(double a) { return *this = *this - a; }
inline Fixed& Fixed::operator *=(double a) { return *this = *this * a; }
//inline Fixed& Fixed::operator /=(double a) { return *this = *this / a; }
inline Fixed& Fixed::operator /=(double a) { return *this = operator/(a); }
inline Fixed operator +(int a, const Fixed b) { return Fixed(a)+b; }
inline Fixed operator -(int a, const Fixed b) { return Fixed(a)-b; }
inline Fixed operator *(int a, const Fixed b) { return Fixed(a)*b; }
inline Fixed operator /(int a, const Fixed b) { return Fixed(a)/b; };
inline Fixed operator +(float a, const Fixed b) { return Fixed(a)+b; }
inline Fixed operator -(float a, const Fixed b) { return Fixed(a)-b; }
inline Fixed operator *(float a, const Fixed b) { return Fixed(a)*b; }
inline Fixed operator /(float a, const Fixed b) { return Fixed(a)/b; }
inline bool Fixed::operator ==(const Fixed a) const { return g == a.g; }
inline bool Fixed::operator !=(const Fixed a) const { return g != a.g; }
inline bool Fixed::operator <=(const Fixed a) const { return g <= a.g; }
inline bool Fixed::operator >=(const Fixed a) const { return g >= a.g; }
inline bool Fixed::operator <(const Fixed a) const { return g < a.g; }
inline bool Fixed::operator >(const Fixed a) const { return g > a.g; }
inline bool Fixed::operator ==(float a) const { return g == Fixed(a).g; }
inline bool Fixed::operator !=(float a) const { return g != Fixed(a).g; }
inline bool Fixed::operator <=(float a) const { return g <= Fixed(a).g; }
inline bool Fixed::operator >=(float a) const { return g >= Fixed(a).g; }
inline bool Fixed::operator <(float a) const { return g < Fixed(a).g; }
inline bool Fixed::operator >(float a) const { return g > Fixed(a).g; }
inline bool Fixed::operator ==(double a) const { return g == Fixed(a).g; }
inline bool Fixed::operator !=(double a) const { return g != Fixed(a).g; }
inline bool Fixed::operator <=(double a) const { return g <= Fixed(a).g; }
inline bool Fixed::operator >=(double a) const { return g >= Fixed(a).g; }
inline bool Fixed::operator <(double a) const { return g < Fixed(a).g; }
inline bool Fixed::operator >(double a) const { return g > Fixed(a).g; }
inline bool Fixed::operator >(int a) const { return g > Fixed(a).g; }
inline bool Fixed::operator <(int a) const { return g < Fixed(a).g; }
inline bool Fixed::operator >=(int a) const{ return g >= Fixed(a).g; };
inline bool Fixed::operator <=(int a) const{ return g <= Fixed(a).g; };
inline bool operator ==(float a, const Fixed b) { return Fixed(a) == b; }
inline bool operator !=(float a, const Fixed b) { return Fixed(a) != b; }
inline bool operator <=(float a, const Fixed b) { return Fixed(a) <= b; }
inline bool operator >=(float a, const Fixed b) { return Fixed(a) >= b; }
inline bool operator <(float a, const Fixed b) { return Fixed(a) < b; }
inline bool operator >(float a, const Fixed b) { return Fixed(a) > b; }
inline Fixed operator +(double a, const Fixed b) { return Fixed(a)+b; }
inline Fixed operator -(double a, const Fixed b) { return Fixed(a)-b; }
inline Fixed operator *(double a, const Fixed b) { return Fixed(a)*b; }
inline Fixed operator /(double a, const Fixed b) { return Fixed(a)/b; }
inline bool operator ==(double a, const Fixed b) { return Fixed(a) == b; }
inline bool operator !=(double a, const Fixed b) { return Fixed(a) != b; }
inline bool operator <=(double a, const Fixed b) { return Fixed(a) <= b; }
inline bool operator >=(double a, const Fixed b) { return Fixed(a) >= b; }
inline bool operator <(double a, const Fixed b) { return Fixed(a) < b; }
inline bool operator >(double a, const Fixed b) { return Fixed(a) > b; }
inline bool operator ==(int a, const Fixed b) { return Fixed(a) == b; }
inline bool operator !=(int a, const Fixed b) { return Fixed(a) != b; }
inline bool operator <=(int a, const Fixed b) { return Fixed(a) <= b; }
inline bool operator >=(int a, const Fixed b) { return Fixed(a) >= b; }
inline bool operator <(int a, const Fixed b) { return Fixed(a) < b; }
inline bool operator >(int a, const Fixed b) { return Fixed(a) > b; }
inline int& operator +=(int& a, const Fixed b) { a = (Fixed)a + b; return a; }
inline int& operator -=(int& a, const Fixed b) { a = (Fixed)a - b; return a; }
inline int& operator *=(int& a, const Fixed b) { a = (Fixed)a * b; return a; }
inline int& operator /=(int& a, const Fixed b) { a = (Fixed)a / b; return a; }
inline long& operator +=(long& a, const Fixed b) { a = (Fixed)a + b; return a; }
inline long& operator -=(long& a, const Fixed b) { a = (Fixed)a - b; return a; }
inline long& operator *=(long& a, const Fixed b) { a = (Fixed)a * b; return a; }
inline long& operator /=(long& a, const Fixed b) { a = (Fixed)a / b; return a; }
inline float& operator +=(float& a, const Fixed b) { a = a + b; return a; }
inline float& operator -=(float& a, const Fixed b) { a = a - b; return a; }
inline float& operator *=(float& a, const Fixed b) { a = a * b; return a; }
inline float& operator /=(float& a, const Fixed b) { a = a / b; return a; }
inline double& operator +=(double& a, const Fixed b) { a = a + b; return a; }
inline double& operator -=(double& a, const Fixed b) { a = a - b; return a; }
inline double& operator *=(double& a, const Fixed b) { a = a * b; return a; }
inline double& operator /=(double& a, const Fixed b) { a = a / b; return a; }
inline Fixed Fixed::abs() { return (g>0) ? Fixed(RAW, g) : Fixed(RAW, -g); }
inline Fixed abs(Fixed f) { return f.abs(); }
//inline Fixed atan2(Fixed a, Fixed b) { return atan2f((float) a, (float) b); }
inline Fixed atan2(Fixed y, Fixed x)
{
Fixed abs_y = y.abs() + FIXED_EPSILON; // avoid 0/0
Fixed r, angle;
if(x >= 0.0f) {
r = (x - abs_y) / (x + abs_y);
angle = 3.1415926/4.0;
} else {
r = (x + abs_y) / (abs_y - x);
angle = 3.0*3.1415926/4.0;
}
angle += Fixed(0.1963) * (r * r * r) - Fixed(0.9817) * r;
return (y < 0) ? -angle : angle;
}
#if TARGET_IS_NDS
static inline long nds_sqrt64(long long a)
{
SQRT_CR = SQRT_64;
while(SQRT_CR & SQRT_BUSY);
SQRT_PARAM64 = a;
while(SQRT_CR & SQRT_BUSY);
return SQRT_RESULT32;
}
static inline int32 div6464(int64 num, int64 den)
{
DIV_CR = DIV_64_64;
while(DIV_CR & DIV_BUSY);
DIV_NUMERATOR64 = num;
DIV_DENOMINATOR64 = den;
while(DIV_CR & DIV_BUSY);
return (DIV_RESULT32);
}
inline Fixed Fixed::sqrt()
{
return Fixed(RAW, nds_sqrt64(((long long)(g))<<BP));
}
#else
inline Fixed Fixed::sqrt()
{
long long m, root = 0, left = (long long)g<<FIXED_BP;
for ( m = (long long)1<<( (sizeof(long long)<<3) - 2); m; m >>= 2 )
{
if ( ( left & -m ) > root )
left -= ( root += m ), root += m;
root >>= 1;
}
return Fixed(RAW, root);
}
#endif
inline Fixed sqrt(Fixed a) { return a.sqrt(); }
inline Fixed sqrtf(Fixed a) { return a.sqrt(); }
#endif
#ifdef TARGET_IS_NDS
// Use the libnds lookup tables for trigonometry functions
inline Fixed Fixed::cosf() {
int idx = (((long long)g*(long long)G_1_DIV_PI)>>24)%512;
if(idx < 0)
idx += 512;
return Fixed(RAW, COS_bin[idx] << 4);
}
inline Fixed cosf(Fixed x) { return x.cosf(); }
inline Fixed Fixed::sinf() {
int idx = (((long long)g*(long long)G_1_DIV_PI)>>24)%512;
if(idx < 0)
idx += 512;
return Fixed(RAW, SIN_bin[idx] << 4);
}
inline Fixed sinf(Fixed x) { return x.sinf(); }
inline Fixed Fixed::tanf() {
int idx = (((long long)g*(long long)G_1_DIV_PI)>>24)%512;
if(idx < 0)
idx += 512;
return Fixed(RAW, TAN_bin[idx] << 4);
}
inline Fixed tanf(Fixed x) { return x.tanf(); }
#endif
@@ -0,0 +1,59 @@
/*
* 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_BLOCK_ALLOCATOR_H
#define B2_BLOCK_ALLOCATOR_H
#include "b2Settings.h"
const int32 b2_chunkSize = 4096;
const int32 b2_maxBlockSize = 640;
const int32 b2_blockSizes = 14;
const int32 b2_chunkArrayIncrement = 128;
struct b2Block;
struct b2Chunk;
// This is a small object allocator used for allocating small
// objects that persist for more than one time step.
// See: http://www.codeproject.com/useritems/Small_Block_Allocator.asp
class b2BlockAllocator
{
public:
b2BlockAllocator();
~b2BlockAllocator();
void* Allocate(int32 size);
void Free(void* p, int32 size);
void Clear();
private:
b2Chunk* m_chunks;
int32 m_chunkCount;
int32 m_chunkSpace;
b2Block* m_freeLists[b2_blockSizes];
static int32 s_blockSizes[b2_blockSizes];
static uint8 s_blockSizeLookup[b2_maxBlockSize + 1];
static bool s_blockSizeLookupInitialized;
};
#endif
@@ -0,0 +1,636 @@
/*
* 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_MATH_H
#define B2_MATH_H
#include "b2Settings.h"
#include <cmath>
#include <cfloat>
#include <cstdlib>
#include <stdio.h>
#ifdef TARGET_FLOAT32_IS_FIXED
inline Fixed b2Min(const Fixed& a, const Fixed& b)
{
return a < b ? a : b;
}
inline Fixed b2Max(const Fixed& a, const Fixed& b)
{
return a > b ? a : b;
}
inline Fixed b2Clamp(Fixed a, Fixed low, Fixed high)
{
return b2Max(low, b2Min(a, high));
}
inline bool b2IsValid(Fixed x)
{
return true;
}
#define b2Sqrt(x) sqrt(x)
#define b2Atan2(y, x) atan2(y, x)
#else
/// This function is used to ensure that a floating point number is
/// not a NaN or infinity.
inline bool b2IsValid(float32 x)
{
#ifdef _MSC_VER
return _finite(x) != 0;
#else
return finite(x) != 0;
#endif
}
/// This is a approximate yet fast inverse square-root.
inline float32 b2InvSqrt(float32 x)
{
union
{
float32 x;
int32 i;
} convert;
convert.x = x;
float32 xhalf = 0.5f * x;
convert.i = 0x5f3759df - (convert.i >> 1);
x = convert.x;
x = x * (1.5f - xhalf * x * x);
return x;
}
#define b2Sqrt(x) sqrtf(x)
#define b2Atan2(y, x) atan2f(y, x)
#endif
inline float32 b2Abs(float32 a)
{
return a > 0.0f ? a : -a;
}
/// A 2D column vector.
struct b2Vec2
{
/// Default constructor does nothing (for performance).
b2Vec2() {}
/// Construct using coordinates.
b2Vec2(float32 x, float32 y) : x(x), y(y) {}
/// Set this vector to all zeros.
void SetZero() { x = 0.0f; y = 0.0f; }
/// Set this vector to some specified coordinates.
void Set(float32 x_, float32 y_) { x = x_; y = y_; }
/// Negate this vector.
b2Vec2 operator -() const { b2Vec2 v; v.Set(-x, -y); return v; }
/// Add a vector to this vector.
void operator += (const b2Vec2& v)
{
x += v.x; y += v.y;
}
/// Subtract a vector from this vector.
void operator -= (const b2Vec2& v)
{
x -= v.x; y -= v.y;
}
/// Multiply this vector by a scalar.
void operator *= (float32 a)
{
x *= a; y *= a;
}
/// Get the length of this vector (the norm).
float32 Length() const
{
#ifdef TARGET_FLOAT32_IS_FIXED
float est = b2Abs(x) + b2Abs(y);
if(est == 0.0f) {
return 0.0;
} else if(est < 0.1) {
return (1.0/256.0) * b2Vec2(x<<8, y<<8).Length();
} else if(est < 180.0f) {
return b2Sqrt(x * x + y * y);
} else {
return 256.0 * (b2Vec2(x>>8, y>>8).Length());
}
#else
return b2Sqrt(x * x + y * y);
#endif
}
/// Get the length squared. For performance, use this instead of
/// b2Vec2::Length (if possible).
float32 LengthSquared() const
{
return x * x + y * y;
}
/// Convert this vector into a unit vector. Returns the length.
#ifdef TARGET_FLOAT32_IS_FIXED
float32 Normalize()
{
float32 length = Length();
if (length < B2_FLT_EPSILON)
{
return 0.0f;
}
#ifdef NORMALIZE_BY_INVERT_MULTIPLY
if (length < (1.0/16.0)) {
x = x << 4;
y = y << 4;
return (1.0/16.0)*Normalize();
} else if(length > 16.0) {
x = x >> 4;
y = y >> 4;
return 16.0*Normalize();
}
float32 invLength = 1.0f / length;
x *= invLength;
y *= invLength;
#else
x /= length;
y /= length;
#endif
return length;
}
#else
float32 Normalize()
{
float32 length = Length();
if (length < B2_FLT_EPSILON)
{
return 0.0f;
}
float32 invLength = 1.0f / length;
x *= invLength;
y *= invLength;
return length;
}
#endif
/// Does this vector contain finite coordinates?
bool IsValid() const
{
return b2IsValid(x) && b2IsValid(y);
}
float32 x, y;
};
/// A 2-by-2 matrix. Stored in column-major order.
struct b2Mat22
{
/// The default constructor does nothing (for performance).
b2Mat22() {}
/// Construct this matrix using columns.
b2Mat22(const b2Vec2& c1, const b2Vec2& c2)
{
col1 = c1;
col2 = c2;
}
/// Construct this matrix using scalars.
b2Mat22(float32 a11, float32 a12, float32 a21, float32 a22)
{
col1.x = a11; col1.y = a21;
col2.x = a12; col2.y = a22;
}
/// Construct this matrix using an angle. This matrix becomes
/// an orthonormal rotation matrix.
explicit b2Mat22(float32 angle)
{
float32 c = cosf(angle), s = sinf(angle);
col1.x = c; col2.x = -s;
col1.y = s; col2.y = c;
}
/// Initialize this matrix using columns.
void Set(const b2Vec2& c1, const b2Vec2& c2)
{
col1 = c1;
col2 = c2;
}
/// Initialize this matrix using an angle. This matrix becomes
/// an orthonormal rotation matrix.
void Set(float32 angle)
{
float32 c = cosf(angle), s = sinf(angle);
col1.x = c; col2.x = -s;
col1.y = s; col2.y = c;
}
/// Set this to the identity matrix.
void SetIdentity()
{
col1.x = 1.0f; col2.x = 0.0f;
col1.y = 0.0f; col2.y = 1.0f;
}
/// Set this matrix to all zeros.
void SetZero()
{
col1.x = 0.0f; col2.x = 0.0f;
col1.y = 0.0f; col2.y = 0.0f;
}
/// Extract the angle from this matrix (assumed to be
/// a rotation matrix).
float32 GetAngle() const
{
return b2Atan2(col1.y, col1.x);
}
#ifdef TARGET_FLOAT32_IS_FIXED
/// Compute the inverse of this matrix, such that inv(A) * A = identity.
b2Mat22 Invert() const
{
float32 a = col1.x, b = col2.x, c = col1.y, d = col2.y;
float32 det = a * d - b * c;
b2Mat22 B;
int n = 0;
if(b2Abs(det) <= (B2_FLT_EPSILON<<8))
{
n = 3;
a = a<<n; b = b<<n;
c = c<<n; d = d<<n;
det = a * d - b * c;
b2Assert(det != 0.0f);
det = float32(1) / det;
B.col1.x = ( det * d) << n; B.col2.x = (-det * b) << n;
B.col1.y = (-det * c) << n; B.col2.y = ( det * a) << n;
}
else
{
n = (b2Abs(det) >= 16.0)? 4 : 0;
b2Assert(det != 0.0f);
det = float32(1<<n) / det;
B.col1.x = ( det * d) >> n; B.col2.x = (-det * b) >> n;
B.col1.y = (-det * c) >> n; B.col2.y = ( det * a) >> n;
}
return B;
}
// Solve A * x = b
b2Vec2 Solve(const b2Vec2& b) const
{
float32 a11 = col1.x, a12 = col2.x, a21 = col1.y, a22 = col2.y;
float32 det = a11 * a22 - a12 * a21;
int n = 0;
b2Vec2 x;
if(b2Abs(det) <= (B2_FLT_EPSILON<<8))
{
n = 3;
a11 = col1.x<<n; a12 = col2.x<<n;
a21 = col1.y<<n; a22 = col2.y<<n;
det = a11 * a22 - a12 * a21;
b2Assert(det != 0.0f);
det = float32(1) / det;
x.x = (det * (a22 * b.x - a12 * b.y)) << n;
x.y = (det * (a11 * b.y - a21 * b.x)) << n;
}
else
{
n = (b2Abs(det) >= 16.0) ? 4 : 0;
b2Assert(det != 0.0f);
det = float32(1<<n) / det;
x.x = (det * (a22 * b.x - a12 * b.y)) >> n;
x.y = (det * (a11 * b.y - a21 * b.x)) >> n;
}
return x;
}
#else
b2Mat22 Invert() const
{
float32 a = col1.x, b = col2.x, c = col1.y, d = col2.y;
b2Mat22 B;
float32 det = a * d - b * c;
b2Assert(det != 0.0f);
det = float32(1.0f) / det;
B.col1.x = det * d; B.col2.x = -det * b;
B.col1.y = -det * c; B.col2.y = det * a;
return B;
}
/// Solve A * x = b, where b is a column vector. This is more efficient
/// than computing the inverse in one-shot cases.
b2Vec2 Solve(const b2Vec2& b) const
{
float32 a11 = col1.x, a12 = col2.x, a21 = col1.y, a22 = col2.y;
float32 det = a11 * a22 - a12 * a21;
b2Assert(det != 0.0f);
det = 1.0f / det;
b2Vec2 x;
x.x = det * (a22 * b.x - a12 * b.y);
x.y = det * (a11 * b.y - a21 * b.x);
return x;
}
#endif
b2Vec2 col1, col2;
};
/// A transform contains translation and rotation. It is used to represent
/// the position and orientation of rigid frames.
struct b2XForm
{
/// The default constructor does nothing (for performance).
b2XForm() {}
/// Initialize using a position vector and a rotation matrix.
b2XForm(const b2Vec2& position, const b2Mat22& R) : position(position), R(R) {}
/// Set this to the identity transform.
void SetIdentity()
{
position.SetZero();
R.SetIdentity();
}
b2Vec2 position;
b2Mat22 R;
};
/// This describes the motion of a body/shape for TOI computation.
/// Shapes are defined with respect to the body origin, which may
/// no coincide with the center of mass. However, to support dynamics
/// we must interpolate the center of mass position.
struct b2Sweep
{
/// Get the interpolated transform at a specific time.
/// @param t the normalized time in [0,1].
void GetXForm(b2XForm* xf, float32 t) const;
/// Advance the sweep forward, yielding a new initial state.
/// @param t the new initial time.
void Advance(float32 t);
b2Vec2 localCenter; ///< local center of mass position
b2Vec2 c0, c; ///< center world positions
float32 a0, a; ///< world angles
float32 t0; ///< time interval = [t0,1], where t0 is in [0,1]
};
extern const b2Vec2 b2Vec2_zero;
extern const b2Mat22 b2Mat22_identity;
extern const b2XForm b2XForm_identity;
/// Peform the dot product on two vectors.
inline float32 b2Dot(const b2Vec2& a, const b2Vec2& b)
{
return a.x * b.x + a.y * b.y;
}
/// Perform the cross product on two vectors. In 2D this produces a scalar.
inline float32 b2Cross(const b2Vec2& a, const b2Vec2& b)
{
return a.x * b.y - a.y * b.x;
}
/// Perform the cross product on a vector and a scalar. In 2D this produces
/// a vector.
inline b2Vec2 b2Cross(const b2Vec2& a, float32 s)
{
b2Vec2 v; v.Set(s * a.y, -s * a.x);
return v;
}
/// Perform the cross product on a scalar and a vector. In 2D this produces
/// a vector.
inline b2Vec2 b2Cross(float32 s, const b2Vec2& a)
{
b2Vec2 v; v.Set(-s * a.y, s * a.x);
return v;
}
/// Multiply a matrix times a vector. If a rotation matrix is provided,
/// then this transforms the vector from one frame to another.
inline b2Vec2 b2Mul(const b2Mat22& A, const b2Vec2& v)
{
b2Vec2 u;
u.Set(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y);
return u;
}
/// Multiply a matrix transpose times a vector. If a rotation matrix is provided,
/// then this transforms the vector from one frame to another (inverse transform).
inline b2Vec2 b2MulT(const b2Mat22& A, const b2Vec2& v)
{
b2Vec2 u;
u.Set(b2Dot(v, A.col1), b2Dot(v, A.col2));
return u;
}
/// Add two vectors component-wise.
inline b2Vec2 operator + (const b2Vec2& a, const b2Vec2& b)
{
b2Vec2 v; v.Set(a.x + b.x, a.y + b.y);
return v;
}
/// Subtract two vectors component-wise.
inline b2Vec2 operator - (const b2Vec2& a, const b2Vec2& b)
{
b2Vec2 v; v.Set(a.x - b.x, a.y - b.y);
return v;
}
inline b2Vec2 operator * (float32 s, const b2Vec2& a)
{
b2Vec2 v; v.Set(s * a.x, s * a.y);
return v;
}
inline bool operator == (const b2Vec2& a, const b2Vec2& b)
{
return a.x == b.x && a.y == b.y;
}
inline float32 b2Distance(const b2Vec2& a, const b2Vec2& b)
{
b2Vec2 c = a - b;
return c.Length();
}
inline float32 b2DistanceSquared(const b2Vec2& a, const b2Vec2& b)
{
b2Vec2 c = a - b;
return b2Dot(c, c);
}
inline b2Mat22 operator + (const b2Mat22& A, const b2Mat22& B)
{
b2Mat22 C;
C.Set(A.col1 + B.col1, A.col2 + B.col2);
return C;
}
// A * B
inline b2Mat22 b2Mul(const b2Mat22& A, const b2Mat22& B)
{
b2Mat22 C;
C.Set(b2Mul(A, B.col1), b2Mul(A, B.col2));
return C;
}
// A^T * B
inline b2Mat22 b2MulT(const b2Mat22& A, const b2Mat22& B)
{
b2Vec2 c1; c1.Set(b2Dot(A.col1, B.col1), b2Dot(A.col2, B.col1));
b2Vec2 c2; c2.Set(b2Dot(A.col1, B.col2), b2Dot(A.col2, B.col2));
b2Mat22 C;
C.Set(c1, c2);
return C;
}
inline b2Vec2 b2Mul(const b2XForm& T, const b2Vec2& v)
{
return T.position + b2Mul(T.R, v);
}
inline b2Vec2 b2MulT(const b2XForm& T, const b2Vec2& v)
{
return b2MulT(T.R, v - T.position);
}
inline b2Vec2 b2Abs(const b2Vec2& a)
{
b2Vec2 b; b.Set(b2Abs(a.x), b2Abs(a.y));
return b;
}
inline b2Mat22 b2Abs(const b2Mat22& A)
{
b2Mat22 B;
B.Set(b2Abs(A.col1), b2Abs(A.col2));
return B;
}
template <typename T>
inline T b2Min(T a, T b)
{
return a < b ? a : b;
}
inline b2Vec2 b2Min(const b2Vec2& a, const b2Vec2& b)
{
b2Vec2 c;
c.x = b2Min(a.x, b.x);
c.y = b2Min(a.y, b.y);
return c;
}
template <typename T>
inline T b2Max(T a, T b)
{
return a > b ? a : b;
}
inline b2Vec2 b2Max(const b2Vec2& a, const b2Vec2& b)
{
b2Vec2 c;
c.x = b2Max(a.x, b.x);
c.y = b2Max(a.y, b.y);
return c;
}
template <typename T>
inline T b2Clamp(T a, T low, T high)
{
return b2Max(low, b2Min(a, high));
}
inline b2Vec2 b2Clamp(const b2Vec2& a, const b2Vec2& low, const b2Vec2& high)
{
return b2Max(low, b2Min(a, high));
}
template<typename T> inline void b2Swap(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp;
}
#define RAND_LIMIT 32767
// Random number in range [-1,1]
inline float32 b2Random()
{
float32 r = (float32)(rand() & (RAND_LIMIT));
r /= RAND_LIMIT;
r = 2.0f * r - 1.0f;
return r;
}
/// Random floating point number in range [lo, hi]
inline float32 b2Random(float32 lo, float32 hi)
{
float32 r = (float32)(rand() & (RAND_LIMIT));
r /= RAND_LIMIT;
r = (hi - lo) * r + lo;
return r;
}
/// "Next Largest Power of 2
/// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
/// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
/// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
/// largest power of 2. For a 32-bit value:"
inline uint32 b2NextPowerOfTwo(uint32 x)
{
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return x + 1;
}
inline bool b2IsPowerOfTwo(uint32 x)
{
bool result = x > 0 && (x & (x - 1)) == 0;
return result;
}
#endif
@@ -0,0 +1,181 @@
/*
* 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_SETTINGS_H
#define B2_SETTINGS_H
#include <assert.h>
#include <math.h>
#define B2_NOT_USED(x) x
#define b2Assert(A) assert(A)
// TODO_ERIN this is not working yet (Theo Jansen Walker is unstable).
//#define B2_TOI_JOINTS
// need to include NDS jtypes.h instead of
// usual typedefs because NDS jtypes defines
// them slightly differently, oh well.
#ifdef TARGET_IS_NDS
#include "jtypes.h"
#else
typedef signed char int8;
typedef signed short int16;
typedef signed int int32;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
#endif
#ifdef TARGET_FLOAT32_IS_FIXED
#include "Fixed.h"
typedef Fixed float32;
#define B2_FLT_MAX FIXED_MAX
#define B2_FLT_EPSILON FIXED_EPSILON
#define B2FORCE_SCALE(x) ((x)<<7)
#define B2FORCE_INV_SCALE(x) ((x)>>7)
#else
typedef float float32;
#define B2_FLT_MAX FLT_MAX
#define B2_FLT_EPSILON FLT_EPSILON
#define B2FORCE_SCALE(x) (x)
#define B2FORCE_INV_SCALE(x) (x)
#endif
const float32 b2_pi = 3.14159265359f;
/// @file
/// Global tuning constants based on meters-kilograms-seconds (MKS) units.
///
// Collision
const int32 b2_maxManifoldPoints = 2;
const int32 b2_maxPolygonVertices = 8;
const int32 b2_maxProxies = 16384; // this must be a power of two
const int32 b2_maxPairs = 8 * b2_maxProxies; // this must be a power of two
// Dynamics
/// A small length used as a collision and constraint tolerance. Usually it is
/// chosen to be numerically significant, but visually insignificant.
const float32 b2_linearSlop = 0.005f; // 0.5 cm
/// A small angle used as a collision and constraint tolerance. Usually it is
/// chosen to be numerically significant, but visually insignificant.
const float32 b2_angularSlop = 2.0f / 180.0f * b2_pi; // 2 degrees
/// Continuous collision detection (CCD) works with core, shrunken shapes. This is the
/// amount by which shapes are automatically shrunk to work with CCD. This must be
/// larger than b2_linearSlop.
const float32 b2_toiSlop = 8.0f * b2_linearSlop;
/// Maximum number of contacts to be handled to solve a TOI island.
const int32 b2_maxTOIContactsPerIsland = 32;
/// Maximum number of joints to be handled to solve a TOI island.
const int32 b2_maxTOIJointsPerIsland = 32;
/// A velocity threshold for elastic collisions. Any collision with a relative linear
/// velocity below this threshold will be treated as inelastic.
const float32 b2_velocityThreshold = 1.0f; // 1 m/s
/// The maximum linear position correction used when solving constraints. This helps to
/// prevent overshoot.
const float32 b2_maxLinearCorrection = 0.2f; // 20 cm
/// The maximum angular position correction used when solving constraints. This helps to
/// prevent overshoot.
const float32 b2_maxAngularCorrection = 8.0f / 180.0f * b2_pi; // 8 degrees
/// The maximum linear velocity of a body. This limit is very large and is used
/// to prevent numerical problems. You shouldn't need to adjust this.
#ifdef TARGET_FLOAT32_IS_FIXED
const float32 b2_maxLinearVelocity = 100.0f;
#else
const float32 b2_maxLinearVelocity = 200.0f;
const float32 b2_maxLinearVelocitySquared = b2_maxLinearVelocity * b2_maxLinearVelocity;
#endif
/// The maximum angular velocity of a body. This limit is very large and is used
/// to prevent numerical problems. You shouldn't need to adjust this.
const float32 b2_maxAngularVelocity = 250.0f;
#ifndef TARGET_FLOAT32_IS_FIXED
const float32 b2_maxAngularVelocitySquared = b2_maxAngularVelocity * b2_maxAngularVelocity;
#endif
/// This scale factor controls how fast overlap is resolved. Ideally this would be 1 so
/// that overlap is removed in one time step. However using values close to 1 often lead
/// to overshoot.
const float32 b2_contactBaumgarte = 0.2f;
// Sleep
/// The time that a body must be still before it will go to sleep.
const float32 b2_timeToSleep = 0.5f; // half a second
/// A body cannot sleep if its linear velocity is above this tolerance.
const float32 b2_linearSleepTolerance = 0.01f; // 1 cm/s
/// A body cannot sleep if its angular velocity is above this tolerance.
const float32 b2_angularSleepTolerance = 2.0f / 180.0f; // 2 degrees/s
// Memory Allocation
/// The current number of bytes allocated through b2Alloc.
extern int32 b2_byteCount;
/// Implement this function to use your own memory allocator.
void* b2Alloc(int32 size);
/// If you implement b2Alloc, you should also implement this function.
void b2Free(void* mem);
/// Version numbering scheme.
/// See http://en.wikipedia.org/wiki/Software_versioning
struct b2Version
{
int32 major; ///< significant changes
int32 minor; ///< incremental changes
int32 revision; ///< bug fixes
};
/// Current version.
extern b2Version b2_version;
/// Friction mixing law. Feel free to customize this.
inline float32 b2MixFriction(float32 friction1, float32 friction2)
{
return sqrtf(friction1 * friction2);
}
/// Restitution mixing law. Feel free to customize this.
inline float32 b2MixRestitution(float32 restitution1, float32 restitution2)
{
return restitution1 > restitution2 ? restitution1 : restitution2;
}
#endif
@@ -0,0 +1,60 @@
/*
* 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_STACK_ALLOCATOR_H
#define B2_STACK_ALLOCATOR_H
#include "b2Settings.h"
const int32 b2_stackSize = 100 * 1024; // 100k
const int32 b2_maxStackEntries = 32;
struct b2StackEntry
{
char* data;
int32 size;
bool usedMalloc;
};
// This is a stack allocator used for fast per step allocations.
// You must nest allocate/free pairs. The code will assert
// if you try to interleave multiple allocate/free pairs.
class b2StackAllocator
{
public:
b2StackAllocator();
~b2StackAllocator();
void* Allocate(int32 size);
void Free(void* p);
int32 GetMaxAllocation() const;
private:
char m_data[b2_stackSize];
int32 m_index;
int32 m_allocation;
int32 m_maxAllocation;
b2StackEntry m_entries[b2_maxStackEntries];
int32 m_entryCount;
};
#endif
@@ -0,0 +1,139 @@
/*---------------------------------------------------------------------------------
$Id: jtypes.h,v 1.17 2007/07/18 05:20:45 wntrmute Exp $
jtypes.h -- Common types (and a few useful macros)
Copyright (C) 2005
Michael Noland (joat)
Jason Rogers (dovoto)
Dave Murphy (WinterMute)
Chris Double (doublec)
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 NDS_JTYPES_INCLUDE
#define NDS_JTYPES_INCLUDE
//---------------------------------------------------------------------------------
#define PACKED __attribute__ ((packed))
#define packed_struct struct PACKED
//---------------------------------------------------------------------------------
// libgba compatible section macros
//---------------------------------------------------------------------------------
#define ITCM_CODE __attribute__((section(".itcm"), long_call))
#define DTCM_DATA __attribute__((section(".dtcm")))
#define DTCM_BSS __attribute__((section(".sbss")))
#define ALIGN(m) __attribute__((aligned (m)))
#define PACKED __attribute__ ((packed))
#define packed_struct struct PACKED
//---------------------------------------------------------------------------------
// These are linked to the bin2o macro in the Makefile
//---------------------------------------------------------------------------------
#define GETRAW(name) (name)
#define GETRAWSIZE(name) ((int)name##_size)
#define GETRAWEND(name) ((int)name##_end)
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define BIT(n) (1 << (n))
// define libnds types in terms of stdint
#include <stdint.h>
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
//typedef float float32;
typedef double float64;
typedef volatile uint8_t vuint8;
typedef volatile uint16_t vuint16;
typedef volatile uint32_t vuint32;
typedef volatile uint64_t vuint64;
typedef volatile int8_t vint8;
typedef volatile int16_t vint16;
typedef volatile int32_t vint32;
typedef volatile int64_t vint64;
typedef volatile float vfloat32;
typedef volatile float64 vfloat64;
typedef uint8_t byte;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef volatile u8 vu8;
typedef volatile u16 vu16;
typedef volatile u32 vu32;
typedef volatile u64 vu64;
typedef volatile s8 vs8;
typedef volatile s16 vs16;
typedef volatile s32 vs32;
typedef volatile s64 vs64;
typedef struct touchPosition {
int16 x;
int16 y;
int16 px;
int16 py;
int16 z1;
int16 z2;
} touchPosition;
#ifndef __cplusplus
/** C++ compatible bool for C
*/
typedef enum { false, true } bool;
#endif
// Handy function pointer typedefs
typedef void ( * IntFn)(void);
typedef void (* VoidFunctionPointer)(void);
typedef void (* fp)(void);
//---------------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------------
@@ -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,78 @@
/*
* 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 normalMass;
float32 tangentMass;
float32 equalizedMass;
float32 separation;
float32 velocityBias;
};
struct b2ContactConstraint
{
b2ContactConstraintPoint points[b2_maxManifoldPoints];
b2Vec2 normal;
b2Mat22 normalMass;
b2Mat22 K;
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,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_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;
#ifdef B2_TOI_JOINTS
b2Vec2 m_lastWarmStartingPivotForce;
#endif
};
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(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,264 @@
/*
* 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);
/// Get the global gravity vector.
b2Vec2 GetGravity() const;
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;
}
inline b2Vec2 b2World::GetGravity() const
{
return m_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
@@ -0,0 +1 @@
link A