rollmorad hinzugefügt
This commit is contained in:
@@ -0,0 +1 @@
|
||||
link Versions/Current/Box2D
|
||||
@@ -0,0 +1 @@
|
||||
link Versions/Current/Headers
|
||||
@@ -0,0 +1 @@
|
||||
link Versions/Current/Resources
|
||||
Binary file not shown.
@@ -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>
|
||||
+92
@@ -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
|
||||
+163
@@ -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
|
||||
//---------------------------------------------------------------------------------
|
||||
+46
@@ -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
|
||||
+78
@@ -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
|
||||
+33
@@ -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
|
||||
+44
@@ -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
|
||||
+44
@@ -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
|
||||
+96
@@ -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
|
||||
+102
@@ -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
|
||||
+176
@@ -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
|
||||
+153
@@ -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
|
||||
+176
@@ -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
|
||||
Reference in New Issue
Block a user