Initial commit
This commit is contained in:
105
inc/Box2D/Collision/Shapes/b2ChainShape.h
Normal file
105
inc/Box2D/Collision/Shapes/b2ChainShape.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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_CHAIN_SHAPE_H
|
||||
#define B2_CHAIN_SHAPE_H
|
||||
|
||||
#include <Box2D/Collision/Shapes/b2Shape.h>
|
||||
|
||||
class b2EdgeShape;
|
||||
|
||||
/// A chain shape is a free form sequence of line segments.
|
||||
/// The chain has two-sided collision, so you can use inside and outside collision.
|
||||
/// Therefore, you may use any winding order.
|
||||
/// Since there may be many vertices, they are allocated using b2Alloc.
|
||||
/// Connectivity information is used to create smooth collisions.
|
||||
/// WARNING: The chain will not collide properly if there are self-intersections.
|
||||
class b2ChainShape : public b2Shape
|
||||
{
|
||||
public:
|
||||
b2ChainShape();
|
||||
|
||||
/// The destructor frees the vertices using b2Free.
|
||||
~b2ChainShape();
|
||||
|
||||
/// Clear all data.
|
||||
void Clear();
|
||||
|
||||
/// Create a loop. This automatically adjusts connectivity.
|
||||
/// @param vertices an array of vertices, these are copied
|
||||
/// @param count the vertex count
|
||||
void CreateLoop(const b2Vec2* vertices, int32 count);
|
||||
|
||||
/// Create a chain with isolated end vertices.
|
||||
/// @param vertices an array of vertices, these are copied
|
||||
/// @param count the vertex count
|
||||
void CreateChain(const b2Vec2* vertices, int32 count);
|
||||
|
||||
/// Establish connectivity to a vertex that precedes the first vertex.
|
||||
/// Don't call this for loops.
|
||||
void SetPrevVertex(const b2Vec2& prevVertex);
|
||||
|
||||
/// Establish connectivity to a vertex that follows the last vertex.
|
||||
/// Don't call this for loops.
|
||||
void SetNextVertex(const b2Vec2& nextVertex);
|
||||
|
||||
/// Implement b2Shape. Vertices are cloned using b2Alloc.
|
||||
b2Shape* Clone(b2BlockAllocator* allocator) const;
|
||||
|
||||
/// @see b2Shape::GetChildCount
|
||||
int32 GetChildCount() const;
|
||||
|
||||
/// Get a child edge.
|
||||
void GetChildEdge(b2EdgeShape* edge, int32 index) const;
|
||||
|
||||
/// This always return false.
|
||||
/// @see b2Shape::TestPoint
|
||||
bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
|
||||
|
||||
/// Implement b2Shape.
|
||||
bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
|
||||
const b2Transform& transform, int32 childIndex) const;
|
||||
|
||||
/// @see b2Shape::ComputeAABB
|
||||
void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
|
||||
|
||||
/// Chains have zero mass.
|
||||
/// @see b2Shape::ComputeMass
|
||||
void ComputeMass(b2MassData* massData, float32 density) const;
|
||||
|
||||
/// The vertices. Owned by this class.
|
||||
b2Vec2* m_vertices;
|
||||
|
||||
/// The vertex count.
|
||||
int32 m_count;
|
||||
|
||||
b2Vec2 m_prevVertex, m_nextVertex;
|
||||
bool m_hasPrevVertex, m_hasNextVertex;
|
||||
};
|
||||
|
||||
inline b2ChainShape::b2ChainShape()
|
||||
{
|
||||
m_type = e_chain;
|
||||
m_radius = b2_polygonRadius;
|
||||
m_vertices = NULL;
|
||||
m_count = 0;
|
||||
m_hasPrevVertex = false;
|
||||
m_hasNextVertex = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
91
inc/Box2D/Collision/Shapes/b2CircleShape.h
Normal file
91
inc/Box2D/Collision/Shapes/b2CircleShape.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 <Box2D/Collision/Shapes/b2Shape.h>
|
||||
|
||||
/// A circle shape.
|
||||
class b2CircleShape : public b2Shape
|
||||
{
|
||||
public:
|
||||
b2CircleShape();
|
||||
|
||||
/// Implement b2Shape.
|
||||
b2Shape* Clone(b2BlockAllocator* allocator) const;
|
||||
|
||||
/// @see b2Shape::GetChildCount
|
||||
int32 GetChildCount() const;
|
||||
|
||||
/// Implement b2Shape.
|
||||
bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
|
||||
|
||||
/// Implement b2Shape.
|
||||
bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
|
||||
const b2Transform& transform, int32 childIndex) const;
|
||||
|
||||
/// @see b2Shape::ComputeAABB
|
||||
void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
|
||||
|
||||
/// @see b2Shape::ComputeMass
|
||||
void ComputeMass(b2MassData* massData, float32 density) const;
|
||||
|
||||
/// Get the supporting vertex index in the given direction.
|
||||
int32 GetSupport(const b2Vec2& d) const;
|
||||
|
||||
/// Get the supporting vertex in the given direction.
|
||||
const b2Vec2& GetSupportVertex(const b2Vec2& d) const;
|
||||
|
||||
/// Get the vertex count.
|
||||
int32 GetVertexCount() const { return 1; }
|
||||
|
||||
/// Get a vertex by index. Used by b2Distance.
|
||||
const b2Vec2& GetVertex(int32 index) const;
|
||||
|
||||
/// Position
|
||||
b2Vec2 m_p;
|
||||
};
|
||||
|
||||
inline b2CircleShape::b2CircleShape()
|
||||
{
|
||||
m_type = e_circle;
|
||||
m_radius = 0.0f;
|
||||
m_p.SetZero();
|
||||
}
|
||||
|
||||
inline int32 b2CircleShape::GetSupport(const b2Vec2 &d) const
|
||||
{
|
||||
B2_NOT_USED(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline const b2Vec2& b2CircleShape::GetSupportVertex(const b2Vec2 &d) const
|
||||
{
|
||||
B2_NOT_USED(d);
|
||||
return m_p;
|
||||
}
|
||||
|
||||
inline const b2Vec2& b2CircleShape::GetVertex(int32 index) const
|
||||
{
|
||||
B2_NOT_USED(index);
|
||||
b2Assert(index == 0);
|
||||
return m_p;
|
||||
}
|
||||
|
||||
#endif
|
||||
74
inc/Box2D/Collision/Shapes/b2EdgeShape.h
Normal file
74
inc/Box2D/Collision/Shapes/b2EdgeShape.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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_EDGE_SHAPE_H
|
||||
#define B2_EDGE_SHAPE_H
|
||||
|
||||
#include <Box2D/Collision/Shapes/b2Shape.h>
|
||||
|
||||
/// A line segment (edge) shape. These can be connected in chains or loops
|
||||
/// to other edge shapes. The connectivity information is used to ensure
|
||||
/// correct contact normals.
|
||||
class b2EdgeShape : public b2Shape
|
||||
{
|
||||
public:
|
||||
b2EdgeShape();
|
||||
|
||||
/// Set this as an isolated edge.
|
||||
void Set(const b2Vec2& v1, const b2Vec2& v2);
|
||||
|
||||
/// Implement b2Shape.
|
||||
b2Shape* Clone(b2BlockAllocator* allocator) const;
|
||||
|
||||
/// @see b2Shape::GetChildCount
|
||||
int32 GetChildCount() const;
|
||||
|
||||
/// @see b2Shape::TestPoint
|
||||
bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
|
||||
|
||||
/// Implement b2Shape.
|
||||
bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
|
||||
const b2Transform& transform, int32 childIndex) const;
|
||||
|
||||
/// @see b2Shape::ComputeAABB
|
||||
void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
|
||||
|
||||
/// @see b2Shape::ComputeMass
|
||||
void ComputeMass(b2MassData* massData, float32 density) const;
|
||||
|
||||
/// These are the edge vertices
|
||||
b2Vec2 m_vertex1, m_vertex2;
|
||||
|
||||
/// Optional adjacent vertices. These are used for smooth collision.
|
||||
b2Vec2 m_vertex0, m_vertex3;
|
||||
bool m_hasVertex0, m_hasVertex3;
|
||||
};
|
||||
|
||||
inline b2EdgeShape::b2EdgeShape()
|
||||
{
|
||||
m_type = e_edge;
|
||||
m_radius = b2_polygonRadius;
|
||||
m_vertex0.x = 0.0f;
|
||||
m_vertex0.y = 0.0f;
|
||||
m_vertex3.x = 0.0f;
|
||||
m_vertex3.y = 0.0f;
|
||||
m_hasVertex0 = false;
|
||||
m_hasVertex3 = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
101
inc/Box2D/Collision/Shapes/b2PolygonShape.h
Normal file
101
inc/Box2D/Collision/Shapes/b2PolygonShape.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 <Box2D/Collision/Shapes/b2Shape.h>
|
||||
|
||||
/// A convex polygon. It is assumed that the interior of the polygon is to
|
||||
/// the left of each edge.
|
||||
/// Polygons have a maximum number of vertices equal to b2_maxPolygonVertices.
|
||||
/// In most cases you should not need many vertices for a convex polygon.
|
||||
class b2PolygonShape : public b2Shape
|
||||
{
|
||||
public:
|
||||
b2PolygonShape();
|
||||
|
||||
/// Implement b2Shape.
|
||||
b2Shape* Clone(b2BlockAllocator* allocator) const;
|
||||
|
||||
/// @see b2Shape::GetChildCount
|
||||
int32 GetChildCount() const;
|
||||
|
||||
/// Create a convex hull from the given array of local points.
|
||||
/// The count must be in the range [3, b2_maxPolygonVertices].
|
||||
/// @warning the points may be re-ordered, even if they form a convex polygon
|
||||
/// @warning collinear points are handled but not removed. Collinear points
|
||||
/// may lead to poor stacking behavior.
|
||||
void Set(const b2Vec2* points, int32 count);
|
||||
|
||||
/// Build vertices to represent an axis-aligned box centered on the local origin.
|
||||
/// @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);
|
||||
|
||||
/// @see b2Shape::TestPoint
|
||||
bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
|
||||
|
||||
/// Implement b2Shape.
|
||||
bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
|
||||
const b2Transform& transform, int32 childIndex) const;
|
||||
|
||||
/// @see b2Shape::ComputeAABB
|
||||
void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
|
||||
|
||||
/// @see b2Shape::ComputeMass
|
||||
void ComputeMass(b2MassData* massData, float32 density) const;
|
||||
|
||||
/// Get the vertex count.
|
||||
int32 GetVertexCount() const { return m_count; }
|
||||
|
||||
/// Get a vertex by index.
|
||||
const b2Vec2& GetVertex(int32 index) const;
|
||||
|
||||
/// Validate convexity. This is a very time consuming operation.
|
||||
/// @returns true if valid
|
||||
bool Validate() const;
|
||||
|
||||
b2Vec2 m_centroid;
|
||||
b2Vec2 m_vertices[b2_maxPolygonVertices];
|
||||
b2Vec2 m_normals[b2_maxPolygonVertices];
|
||||
int32 m_count;
|
||||
};
|
||||
|
||||
inline b2PolygonShape::b2PolygonShape()
|
||||
{
|
||||
m_type = e_polygon;
|
||||
m_radius = b2_polygonRadius;
|
||||
m_count = 0;
|
||||
m_centroid.SetZero();
|
||||
}
|
||||
|
||||
inline const b2Vec2& b2PolygonShape::GetVertex(int32 index) const
|
||||
{
|
||||
b2Assert(0 <= index && index < m_count);
|
||||
return m_vertices[index];
|
||||
}
|
||||
|
||||
#endif
|
||||
101
inc/Box2D/Collision/Shapes/b2Shape.h
Normal file
101
inc/Box2D/Collision/Shapes/b2Shape.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 <Box2D/Common/b2BlockAllocator.h>
|
||||
#include <Box2D/Common/b2Math.h>
|
||||
#include <Box2D/Collision/b2Collision.h>
|
||||
|
||||
/// 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 about the local origin.
|
||||
float32 I;
|
||||
};
|
||||
|
||||
/// A shape is used for collision detection. You can create a shape however you like.
|
||||
/// Shapes used for simulation in b2World are created automatically when a b2Fixture
|
||||
/// is created. Shapes may encapsulate a one or more child shapes.
|
||||
class b2Shape
|
||||
{
|
||||
public:
|
||||
|
||||
enum Type
|
||||
{
|
||||
e_circle = 0,
|
||||
e_edge = 1,
|
||||
e_polygon = 2,
|
||||
e_chain = 3,
|
||||
e_typeCount = 4
|
||||
};
|
||||
|
||||
virtual ~b2Shape() {}
|
||||
|
||||
/// Clone the concrete shape using the provided allocator.
|
||||
virtual b2Shape* Clone(b2BlockAllocator* allocator) const = 0;
|
||||
|
||||
/// Get the type of this shape. You can use this to down cast to the concrete shape.
|
||||
/// @return the shape type.
|
||||
Type GetType() const;
|
||||
|
||||
/// Get the number of child primitives.
|
||||
virtual int32 GetChildCount() const = 0;
|
||||
|
||||
/// 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 b2Transform& xf, const b2Vec2& p) const = 0;
|
||||
|
||||
/// Cast a ray against a child shape.
|
||||
/// @param output the ray-cast results.
|
||||
/// @param input the ray-cast input parameters.
|
||||
/// @param transform the transform to be applied to the shape.
|
||||
/// @param childIndex the child shape index
|
||||
virtual bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
|
||||
const b2Transform& transform, int32 childIndex) const = 0;
|
||||
|
||||
/// Given a transform, compute the associated axis aligned bounding box for a child shape.
|
||||
/// @param aabb returns the axis aligned box.
|
||||
/// @param xf the world transform of the shape.
|
||||
/// @param childIndex the child shape
|
||||
virtual void ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const = 0;
|
||||
|
||||
/// Compute the mass properties of this shape using its dimensions and density.
|
||||
/// The inertia tensor is computed about the local origin.
|
||||
/// @param massData returns the mass data for this shape.
|
||||
/// @param density the density in kilograms per meter squared.
|
||||
virtual void ComputeMass(b2MassData* massData, float32 density) const = 0;
|
||||
|
||||
Type m_type;
|
||||
float32 m_radius;
|
||||
};
|
||||
|
||||
inline b2Shape::Type b2Shape::GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
#endif
|
||||
257
inc/Box2D/Collision/b2BroadPhase.h
Normal file
257
inc/Box2D/Collision/b2BroadPhase.h
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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
|
||||
|
||||
#include <Box2D/Common/b2Settings.h>
|
||||
#include <Box2D/Collision/b2Collision.h>
|
||||
#include <Box2D/Collision/b2DynamicTree.h>
|
||||
#include <algorithm>
|
||||
|
||||
struct b2Pair
|
||||
{
|
||||
int32 proxyIdA;
|
||||
int32 proxyIdB;
|
||||
};
|
||||
|
||||
/// The broad-phase is used for computing pairs and performing volume queries and ray casts.
|
||||
/// This broad-phase does not persist pairs. Instead, this reports potentially new pairs.
|
||||
/// It is up to the client to consume the new pairs and to track subsequent overlap.
|
||||
class b2BroadPhase
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_nullProxy = -1
|
||||
};
|
||||
|
||||
b2BroadPhase();
|
||||
~b2BroadPhase();
|
||||
|
||||
/// Create a proxy with an initial AABB. Pairs are not reported until
|
||||
/// UpdatePairs is called.
|
||||
int32 CreateProxy(const b2AABB& aabb, void* userData);
|
||||
|
||||
/// Destroy a proxy. It is up to the client to remove any pairs.
|
||||
void DestroyProxy(int32 proxyId);
|
||||
|
||||
/// Call MoveProxy as many times as you like, then when you are done
|
||||
/// call UpdatePairs to finalized the proxy pairs (for your time step).
|
||||
void MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement);
|
||||
|
||||
/// Call to trigger a re-processing of it's pairs on the next call to UpdatePairs.
|
||||
void TouchProxy(int32 proxyId);
|
||||
|
||||
/// Get the fat AABB for a proxy.
|
||||
const b2AABB& GetFatAABB(int32 proxyId) const;
|
||||
|
||||
/// Get user data from a proxy. Returns NULL if the id is invalid.
|
||||
void* GetUserData(int32 proxyId) const;
|
||||
|
||||
/// Test overlap of fat AABBs.
|
||||
bool TestOverlap(int32 proxyIdA, int32 proxyIdB) const;
|
||||
|
||||
/// Get the number of proxies.
|
||||
int32 GetProxyCount() const;
|
||||
|
||||
/// Update the pairs. This results in pair callbacks. This can only add pairs.
|
||||
template <typename T>
|
||||
void UpdatePairs(T* callback);
|
||||
|
||||
/// Query an AABB for overlapping proxies. The callback class
|
||||
/// is called for each proxy that overlaps the supplied AABB.
|
||||
template <typename T>
|
||||
void Query(T* callback, const b2AABB& aabb) const;
|
||||
|
||||
/// Ray-cast against the proxies in the tree. This relies on the callback
|
||||
/// to perform a exact ray-cast in the case were the proxy contains a shape.
|
||||
/// The callback also performs the any collision filtering. This has performance
|
||||
/// roughly equal to k * log(n), where k is the number of collisions and n is the
|
||||
/// number of proxies in the tree.
|
||||
/// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
|
||||
/// @param callback a callback class that is called for each proxy that is hit by the ray.
|
||||
template <typename T>
|
||||
void RayCast(T* callback, const b2RayCastInput& input) const;
|
||||
|
||||
/// Get the height of the embedded tree.
|
||||
int32 GetTreeHeight() const;
|
||||
|
||||
/// Get the balance of the embedded tree.
|
||||
int32 GetTreeBalance() const;
|
||||
|
||||
/// Get the quality metric of the embedded tree.
|
||||
float32 GetTreeQuality() const;
|
||||
|
||||
/// Shift the world origin. Useful for large worlds.
|
||||
/// The shift formula is: position -= newOrigin
|
||||
/// @param newOrigin the new origin with respect to the old origin
|
||||
void ShiftOrigin(const b2Vec2& newOrigin);
|
||||
|
||||
private:
|
||||
|
||||
friend class b2DynamicTree;
|
||||
|
||||
void BufferMove(int32 proxyId);
|
||||
void UnBufferMove(int32 proxyId);
|
||||
|
||||
bool QueryCallback(int32 proxyId);
|
||||
|
||||
b2DynamicTree m_tree;
|
||||
|
||||
int32 m_proxyCount;
|
||||
|
||||
int32* m_moveBuffer;
|
||||
int32 m_moveCapacity;
|
||||
int32 m_moveCount;
|
||||
|
||||
b2Pair* m_pairBuffer;
|
||||
int32 m_pairCapacity;
|
||||
int32 m_pairCount;
|
||||
|
||||
int32 m_queryProxyId;
|
||||
};
|
||||
|
||||
/// This is used to sort pairs.
|
||||
inline bool b2PairLessThan(const b2Pair& pair1, const b2Pair& pair2)
|
||||
{
|
||||
if (pair1.proxyIdA < pair2.proxyIdA)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pair1.proxyIdA == pair2.proxyIdA)
|
||||
{
|
||||
return pair1.proxyIdB < pair2.proxyIdB;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void* b2BroadPhase::GetUserData(int32 proxyId) const
|
||||
{
|
||||
return m_tree.GetUserData(proxyId);
|
||||
}
|
||||
|
||||
inline bool b2BroadPhase::TestOverlap(int32 proxyIdA, int32 proxyIdB) const
|
||||
{
|
||||
const b2AABB& aabbA = m_tree.GetFatAABB(proxyIdA);
|
||||
const b2AABB& aabbB = m_tree.GetFatAABB(proxyIdB);
|
||||
return b2TestOverlap(aabbA, aabbB);
|
||||
}
|
||||
|
||||
inline const b2AABB& b2BroadPhase::GetFatAABB(int32 proxyId) const
|
||||
{
|
||||
return m_tree.GetFatAABB(proxyId);
|
||||
}
|
||||
|
||||
inline int32 b2BroadPhase::GetProxyCount() const
|
||||
{
|
||||
return m_proxyCount;
|
||||
}
|
||||
|
||||
inline int32 b2BroadPhase::GetTreeHeight() const
|
||||
{
|
||||
return m_tree.GetHeight();
|
||||
}
|
||||
|
||||
inline int32 b2BroadPhase::GetTreeBalance() const
|
||||
{
|
||||
return m_tree.GetMaxBalance();
|
||||
}
|
||||
|
||||
inline float32 b2BroadPhase::GetTreeQuality() const
|
||||
{
|
||||
return m_tree.GetAreaRatio();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void b2BroadPhase::UpdatePairs(T* callback)
|
||||
{
|
||||
// Reset pair buffer
|
||||
m_pairCount = 0;
|
||||
|
||||
// Perform tree queries for all moving proxies.
|
||||
for (int32 i = 0; i < m_moveCount; ++i)
|
||||
{
|
||||
m_queryProxyId = m_moveBuffer[i];
|
||||
if (m_queryProxyId == e_nullProxy)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// We have to query the tree with the fat AABB so that
|
||||
// we don't fail to create a pair that may touch later.
|
||||
const b2AABB& fatAABB = m_tree.GetFatAABB(m_queryProxyId);
|
||||
|
||||
// Query tree, create pairs and add them pair buffer.
|
||||
m_tree.Query(this, fatAABB);
|
||||
}
|
||||
|
||||
// Reset move buffer
|
||||
m_moveCount = 0;
|
||||
|
||||
// Sort the pair buffer to expose duplicates.
|
||||
std::sort(m_pairBuffer, m_pairBuffer + m_pairCount, b2PairLessThan);
|
||||
|
||||
// Send the pairs back to the client.
|
||||
int32 i = 0;
|
||||
while (i < m_pairCount)
|
||||
{
|
||||
b2Pair* primaryPair = m_pairBuffer + i;
|
||||
void* userDataA = m_tree.GetUserData(primaryPair->proxyIdA);
|
||||
void* userDataB = m_tree.GetUserData(primaryPair->proxyIdB);
|
||||
|
||||
callback->AddPair(userDataA, userDataB);
|
||||
++i;
|
||||
|
||||
// Skip any duplicate pairs.
|
||||
while (i < m_pairCount)
|
||||
{
|
||||
b2Pair* pair = m_pairBuffer + i;
|
||||
if (pair->proxyIdA != primaryPair->proxyIdA || pair->proxyIdB != primaryPair->proxyIdB)
|
||||
{
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to keep the tree balanced.
|
||||
//m_tree.Rebalance(4);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void b2BroadPhase::Query(T* callback, const b2AABB& aabb) const
|
||||
{
|
||||
m_tree.Query(callback, aabb);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void b2BroadPhase::RayCast(T* callback, const b2RayCastInput& input) const
|
||||
{
|
||||
m_tree.RayCast(callback, input);
|
||||
}
|
||||
|
||||
inline void b2BroadPhase::ShiftOrigin(const b2Vec2& newOrigin)
|
||||
{
|
||||
m_tree.ShiftOrigin(newOrigin);
|
||||
}
|
||||
|
||||
#endif
|
||||
277
inc/Box2D/Collision/b2Collision.h
Normal file
277
inc/Box2D/Collision/b2Collision.h
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 <Box2D/Common/b2Math.h>
|
||||
#include <limits.h>
|
||||
|
||||
/// @file
|
||||
/// Structures and functions used for computing contact points, distance
|
||||
/// queries, and TOI queries.
|
||||
|
||||
class b2Shape;
|
||||
class b2CircleShape;
|
||||
class b2EdgeShape;
|
||||
class b2PolygonShape;
|
||||
|
||||
const uint8 b2_nullFeature = UCHAR_MAX;
|
||||
|
||||
/// The features that intersect to form the contact point
|
||||
/// This must be 4 bytes or less.
|
||||
struct b2ContactFeature
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
e_vertex = 0,
|
||||
e_face = 1
|
||||
};
|
||||
|
||||
uint8 indexA; ///< Feature index on shapeA
|
||||
uint8 indexB; ///< Feature index on shapeB
|
||||
uint8 typeA; ///< The feature type on shapeA
|
||||
uint8 typeB; ///< The feature type on shapeB
|
||||
};
|
||||
|
||||
/// Contact ids to facilitate warm starting.
|
||||
union b2ContactID
|
||||
{
|
||||
b2ContactFeature cf;
|
||||
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 local point usage depends on the manifold type:
|
||||
/// -e_circles: the local center of circleB
|
||||
/// -e_faceA: the local center of cirlceB or the clip point of polygonB
|
||||
/// -e_faceB: the clip point of polygonA
|
||||
/// This structure is stored across time steps, so we keep it small.
|
||||
/// Note: the impulses are used for internal caching and may not
|
||||
/// provide reliable contact forces, especially for high speed collisions.
|
||||
struct b2ManifoldPoint
|
||||
{
|
||||
b2Vec2 localPoint; ///< usage depends on manifold type
|
||||
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.
|
||||
/// Box2D supports multiple types of contact:
|
||||
/// - clip point versus plane with radius
|
||||
/// - point versus point with radius (circles)
|
||||
/// The local point usage depends on the manifold type:
|
||||
/// -e_circles: the local center of circleA
|
||||
/// -e_faceA: the center of faceA
|
||||
/// -e_faceB: the center of faceB
|
||||
/// Similarly the local normal usage:
|
||||
/// -e_circles: not used
|
||||
/// -e_faceA: the normal on polygonA
|
||||
/// -e_faceB: the normal on polygonB
|
||||
/// We store contacts in this way so that position correction can
|
||||
/// account for movement, which is critical for continuous physics.
|
||||
/// All contact scenarios must be expressed in one of these types.
|
||||
/// This structure is stored across time steps, so we keep it small.
|
||||
struct b2Manifold
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
e_circles,
|
||||
e_faceA,
|
||||
e_faceB
|
||||
};
|
||||
|
||||
b2ManifoldPoint points[b2_maxManifoldPoints]; ///< the points of contact
|
||||
b2Vec2 localNormal; ///< not use for Type::e_points
|
||||
b2Vec2 localPoint; ///< usage depends on manifold type
|
||||
Type type;
|
||||
int32 pointCount; ///< the number of manifold points
|
||||
};
|
||||
|
||||
/// This is used to compute the current state of a contact manifold.
|
||||
struct b2WorldManifold
|
||||
{
|
||||
/// Evaluate the manifold with supplied transforms. This assumes
|
||||
/// modest motion from the original state. This does not change the
|
||||
/// point count, impulses, etc. The radii must come from the shapes
|
||||
/// that generated the manifold.
|
||||
void Initialize(const b2Manifold* manifold,
|
||||
const b2Transform& xfA, float32 radiusA,
|
||||
const b2Transform& xfB, float32 radiusB);
|
||||
|
||||
b2Vec2 normal; ///< world vector pointing from A to B
|
||||
b2Vec2 points[b2_maxManifoldPoints]; ///< world contact point (point of intersection)
|
||||
float32 separations[b2_maxManifoldPoints]; ///< a negative value indicates overlap, in meters
|
||||
};
|
||||
|
||||
/// This is used for determining the state of contact points.
|
||||
enum b2PointState
|
||||
{
|
||||
b2_nullState, ///< point does not exist
|
||||
b2_addState, ///< point was added in the update
|
||||
b2_persistState, ///< point persisted across the update
|
||||
b2_removeState ///< point was removed in the update
|
||||
};
|
||||
|
||||
/// Compute the point states given two manifolds. The states pertain to the transition from manifold1
|
||||
/// to manifold2. So state1 is either persist or remove while state2 is either add or persist.
|
||||
void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],
|
||||
const b2Manifold* manifold1, const b2Manifold* manifold2);
|
||||
|
||||
/// Used for computing contact manifolds.
|
||||
struct b2ClipVertex
|
||||
{
|
||||
b2Vec2 v;
|
||||
b2ContactID id;
|
||||
};
|
||||
|
||||
/// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
|
||||
struct b2RayCastInput
|
||||
{
|
||||
b2Vec2 p1, p2;
|
||||
float32 maxFraction;
|
||||
};
|
||||
|
||||
/// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2
|
||||
/// come from b2RayCastInput.
|
||||
struct b2RayCastOutput
|
||||
{
|
||||
b2Vec2 normal;
|
||||
float32 fraction;
|
||||
};
|
||||
|
||||
/// An axis aligned bounding box.
|
||||
struct b2AABB
|
||||
{
|
||||
/// Verify that the bounds are sorted.
|
||||
bool IsValid() const;
|
||||
|
||||
/// Get the center of the AABB.
|
||||
b2Vec2 GetCenter() const
|
||||
{
|
||||
return 0.5f * (lowerBound + upperBound);
|
||||
}
|
||||
|
||||
/// Get the extents of the AABB (half-widths).
|
||||
b2Vec2 GetExtents() const
|
||||
{
|
||||
return 0.5f * (upperBound - lowerBound);
|
||||
}
|
||||
|
||||
/// Get the perimeter length
|
||||
float32 GetPerimeter() const
|
||||
{
|
||||
float32 wx = upperBound.x - lowerBound.x;
|
||||
float32 wy = upperBound.y - lowerBound.y;
|
||||
return 2.0f * (wx + wy);
|
||||
}
|
||||
|
||||
/// Combine an AABB into this one.
|
||||
void Combine(const b2AABB& aabb)
|
||||
{
|
||||
lowerBound = b2Min(lowerBound, aabb.lowerBound);
|
||||
upperBound = b2Max(upperBound, aabb.upperBound);
|
||||
}
|
||||
|
||||
/// Combine two AABBs into this one.
|
||||
void Combine(const b2AABB& aabb1, const b2AABB& aabb2)
|
||||
{
|
||||
lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound);
|
||||
upperBound = b2Max(aabb1.upperBound, aabb2.upperBound);
|
||||
}
|
||||
|
||||
/// Does this aabb contain the provided AABB.
|
||||
bool Contains(const b2AABB& aabb) const
|
||||
{
|
||||
bool result = true;
|
||||
result = result && lowerBound.x <= aabb.lowerBound.x;
|
||||
result = result && lowerBound.y <= aabb.lowerBound.y;
|
||||
result = result && aabb.upperBound.x <= upperBound.x;
|
||||
result = result && aabb.upperBound.y <= upperBound.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const;
|
||||
|
||||
b2Vec2 lowerBound; ///< the lower vertex
|
||||
b2Vec2 upperBound; ///< the upper vertex
|
||||
};
|
||||
|
||||
/// Compute the collision manifold between two circles.
|
||||
void b2CollideCircles(b2Manifold* manifold,
|
||||
const b2CircleShape* circleA, const b2Transform& xfA,
|
||||
const b2CircleShape* circleB, const b2Transform& xfB);
|
||||
|
||||
/// Compute the collision manifold between a polygon and a circle.
|
||||
void b2CollidePolygonAndCircle(b2Manifold* manifold,
|
||||
const b2PolygonShape* polygonA, const b2Transform& xfA,
|
||||
const b2CircleShape* circleB, const b2Transform& xfB);
|
||||
|
||||
/// Compute the collision manifold between two polygons.
|
||||
void b2CollidePolygons(b2Manifold* manifold,
|
||||
const b2PolygonShape* polygonA, const b2Transform& xfA,
|
||||
const b2PolygonShape* polygonB, const b2Transform& xfB);
|
||||
|
||||
/// Compute the collision manifold between an edge and a circle.
|
||||
void b2CollideEdgeAndCircle(b2Manifold* manifold,
|
||||
const b2EdgeShape* polygonA, const b2Transform& xfA,
|
||||
const b2CircleShape* circleB, const b2Transform& xfB);
|
||||
|
||||
/// Compute the collision manifold between an edge and a circle.
|
||||
void b2CollideEdgeAndPolygon(b2Manifold* manifold,
|
||||
const b2EdgeShape* edgeA, const b2Transform& xfA,
|
||||
const b2PolygonShape* circleB, const b2Transform& xfB);
|
||||
|
||||
/// Clipping for contact manifolds.
|
||||
int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2],
|
||||
const b2Vec2& normal, float32 offset, int32 vertexIndexA);
|
||||
|
||||
/// Determine if two generic shapes overlap.
|
||||
bool b2TestOverlap( const b2Shape* shapeA, int32 indexA,
|
||||
const b2Shape* shapeB, int32 indexB,
|
||||
const b2Transform& xfA, const b2Transform& xfB);
|
||||
|
||||
// ---------------- 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
|
||||
141
inc/Box2D/Collision/b2Distance.h
Normal file
141
inc/Box2D/Collision/b2Distance.h
Normal file
@@ -0,0 +1,141 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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_H
|
||||
#define B2_DISTANCE_H
|
||||
|
||||
#include <Box2D/Common/b2Math.h>
|
||||
|
||||
class b2Shape;
|
||||
|
||||
/// A distance proxy is used by the GJK algorithm.
|
||||
/// It encapsulates any shape.
|
||||
struct b2DistanceProxy
|
||||
{
|
||||
b2DistanceProxy() : m_vertices(NULL), m_count(0), m_radius(0.0f) {}
|
||||
|
||||
/// Initialize the proxy using the given shape. The shape
|
||||
/// must remain in scope while the proxy is in use.
|
||||
void Set(const b2Shape* shape, int32 index);
|
||||
|
||||
/// Get the supporting vertex index in the given direction.
|
||||
int32 GetSupport(const b2Vec2& d) const;
|
||||
|
||||
/// Get the supporting vertex in the given direction.
|
||||
const b2Vec2& GetSupportVertex(const b2Vec2& d) const;
|
||||
|
||||
/// Get the vertex count.
|
||||
int32 GetVertexCount() const;
|
||||
|
||||
/// Get a vertex by index. Used by b2Distance.
|
||||
const b2Vec2& GetVertex(int32 index) const;
|
||||
|
||||
b2Vec2 m_buffer[2];
|
||||
const b2Vec2* m_vertices;
|
||||
int32 m_count;
|
||||
float32 m_radius;
|
||||
};
|
||||
|
||||
/// Used to warm start b2Distance.
|
||||
/// Set count to zero on first call.
|
||||
struct b2SimplexCache
|
||||
{
|
||||
float32 metric; ///< length or area
|
||||
uint16 count;
|
||||
uint8 indexA[3]; ///< vertices on shape A
|
||||
uint8 indexB[3]; ///< vertices on shape B
|
||||
};
|
||||
|
||||
/// Input for b2Distance.
|
||||
/// You have to option to use the shape radii
|
||||
/// in the computation. Even
|
||||
struct b2DistanceInput
|
||||
{
|
||||
b2DistanceProxy proxyA;
|
||||
b2DistanceProxy proxyB;
|
||||
b2Transform transformA;
|
||||
b2Transform transformB;
|
||||
bool useRadii;
|
||||
};
|
||||
|
||||
/// Output for b2Distance.
|
||||
struct b2DistanceOutput
|
||||
{
|
||||
b2Vec2 pointA; ///< closest point on shapeA
|
||||
b2Vec2 pointB; ///< closest point on shapeB
|
||||
float32 distance;
|
||||
int32 iterations; ///< number of GJK iterations used
|
||||
};
|
||||
|
||||
/// Compute the closest points between two shapes. Supports any combination of:
|
||||
/// b2CircleShape, b2PolygonShape, b2EdgeShape. The simplex cache is input/output.
|
||||
/// On the first call set b2SimplexCache.count to zero.
|
||||
void b2Distance(b2DistanceOutput* output,
|
||||
b2SimplexCache* cache,
|
||||
const b2DistanceInput* input);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline int32 b2DistanceProxy::GetVertexCount() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
inline const b2Vec2& b2DistanceProxy::GetVertex(int32 index) const
|
||||
{
|
||||
b2Assert(0 <= index && index < m_count);
|
||||
return m_vertices[index];
|
||||
}
|
||||
|
||||
inline int32 b2DistanceProxy::GetSupport(const b2Vec2& d) const
|
||||
{
|
||||
int32 bestIndex = 0;
|
||||
float32 bestValue = b2Dot(m_vertices[0], d);
|
||||
for (int32 i = 1; i < m_count; ++i)
|
||||
{
|
||||
float32 value = b2Dot(m_vertices[i], d);
|
||||
if (value > bestValue)
|
||||
{
|
||||
bestIndex = i;
|
||||
bestValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
return bestIndex;
|
||||
}
|
||||
|
||||
inline const b2Vec2& b2DistanceProxy::GetSupportVertex(const b2Vec2& d) const
|
||||
{
|
||||
int32 bestIndex = 0;
|
||||
float32 bestValue = b2Dot(m_vertices[0], d);
|
||||
for (int32 i = 1; i < m_count; ++i)
|
||||
{
|
||||
float32 value = b2Dot(m_vertices[i], d);
|
||||
if (value > bestValue)
|
||||
{
|
||||
bestIndex = i;
|
||||
bestValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
return m_vertices[bestIndex];
|
||||
}
|
||||
|
||||
#endif
|
||||
289
inc/Box2D/Collision/b2DynamicTree.h
Normal file
289
inc/Box2D/Collision/b2DynamicTree.h
Normal file
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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_DYNAMIC_TREE_H
|
||||
#define B2_DYNAMIC_TREE_H
|
||||
|
||||
#include <Box2D/Collision/b2Collision.h>
|
||||
#include <Box2D/Common/b2GrowableStack.h>
|
||||
|
||||
#define b2_nullNode (-1)
|
||||
|
||||
/// A node in the dynamic tree. The client does not interact with this directly.
|
||||
struct b2TreeNode
|
||||
{
|
||||
bool IsLeaf() const
|
||||
{
|
||||
return child1 == b2_nullNode;
|
||||
}
|
||||
|
||||
/// Enlarged AABB
|
||||
b2AABB aabb;
|
||||
|
||||
void* userData;
|
||||
|
||||
union
|
||||
{
|
||||
int32 parent;
|
||||
int32 next;
|
||||
};
|
||||
|
||||
int32 child1;
|
||||
int32 child2;
|
||||
|
||||
// leaf = 0, free node = -1
|
||||
int32 height;
|
||||
};
|
||||
|
||||
/// A dynamic AABB tree broad-phase, inspired by Nathanael Presson's btDbvt.
|
||||
/// A dynamic tree arranges data in a binary tree to accelerate
|
||||
/// queries such as volume queries and ray casts. Leafs are proxies
|
||||
/// with an AABB. In the tree we expand the proxy AABB by b2_fatAABBFactor
|
||||
/// so that the proxy AABB is bigger than the client object. This allows the client
|
||||
/// object to move by small amounts without triggering a tree update.
|
||||
///
|
||||
/// Nodes are pooled and relocatable, so we use node indices rather than pointers.
|
||||
class b2DynamicTree
|
||||
{
|
||||
public:
|
||||
/// Constructing the tree initializes the node pool.
|
||||
b2DynamicTree();
|
||||
|
||||
/// Destroy the tree, freeing the node pool.
|
||||
~b2DynamicTree();
|
||||
|
||||
/// Create a proxy. Provide a tight fitting AABB and a userData pointer.
|
||||
int32 CreateProxy(const b2AABB& aabb, void* userData);
|
||||
|
||||
/// Destroy a proxy. This asserts if the id is invalid.
|
||||
void DestroyProxy(int32 proxyId);
|
||||
|
||||
/// Move a proxy with a swepted AABB. If the proxy has moved outside of its fattened AABB,
|
||||
/// then the proxy is removed from the tree and re-inserted. Otherwise
|
||||
/// the function returns immediately.
|
||||
/// @return true if the proxy was re-inserted.
|
||||
bool MoveProxy(int32 proxyId, const b2AABB& aabb1, const b2Vec2& displacement);
|
||||
|
||||
/// Get proxy user data.
|
||||
/// @return the proxy user data or 0 if the id is invalid.
|
||||
void* GetUserData(int32 proxyId) const;
|
||||
|
||||
/// Get the fat AABB for a proxy.
|
||||
const b2AABB& GetFatAABB(int32 proxyId) const;
|
||||
|
||||
/// Query an AABB for overlapping proxies. The callback class
|
||||
/// is called for each proxy that overlaps the supplied AABB.
|
||||
template <typename T>
|
||||
void Query(T* callback, const b2AABB& aabb) const;
|
||||
|
||||
/// Ray-cast against the proxies in the tree. This relies on the callback
|
||||
/// to perform a exact ray-cast in the case were the proxy contains a shape.
|
||||
/// The callback also performs the any collision filtering. This has performance
|
||||
/// roughly equal to k * log(n), where k is the number of collisions and n is the
|
||||
/// number of proxies in the tree.
|
||||
/// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
|
||||
/// @param callback a callback class that is called for each proxy that is hit by the ray.
|
||||
template <typename T>
|
||||
void RayCast(T* callback, const b2RayCastInput& input) const;
|
||||
|
||||
/// Validate this tree. For testing.
|
||||
void Validate() const;
|
||||
|
||||
/// Compute the height of the binary tree in O(N) time. Should not be
|
||||
/// called often.
|
||||
int32 GetHeight() const;
|
||||
|
||||
/// Get the maximum balance of an node in the tree. The balance is the difference
|
||||
/// in height of the two children of a node.
|
||||
int32 GetMaxBalance() const;
|
||||
|
||||
/// Get the ratio of the sum of the node areas to the root area.
|
||||
float32 GetAreaRatio() const;
|
||||
|
||||
/// Build an optimal tree. Very expensive. For testing.
|
||||
void RebuildBottomUp();
|
||||
|
||||
/// Shift the world origin. Useful for large worlds.
|
||||
/// The shift formula is: position -= newOrigin
|
||||
/// @param newOrigin the new origin with respect to the old origin
|
||||
void ShiftOrigin(const b2Vec2& newOrigin);
|
||||
|
||||
private:
|
||||
|
||||
int32 AllocateNode();
|
||||
void FreeNode(int32 node);
|
||||
|
||||
void InsertLeaf(int32 node);
|
||||
void RemoveLeaf(int32 node);
|
||||
|
||||
int32 Balance(int32 index);
|
||||
|
||||
int32 ComputeHeight() const;
|
||||
int32 ComputeHeight(int32 nodeId) const;
|
||||
|
||||
void ValidateStructure(int32 index) const;
|
||||
void ValidateMetrics(int32 index) const;
|
||||
|
||||
int32 m_root;
|
||||
|
||||
b2TreeNode* m_nodes;
|
||||
int32 m_nodeCount;
|
||||
int32 m_nodeCapacity;
|
||||
|
||||
int32 m_freeList;
|
||||
|
||||
/// This is used to incrementally traverse the tree for re-balancing.
|
||||
uint32 m_path;
|
||||
|
||||
int32 m_insertionCount;
|
||||
};
|
||||
|
||||
inline void* b2DynamicTree::GetUserData(int32 proxyId) const
|
||||
{
|
||||
b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
|
||||
return m_nodes[proxyId].userData;
|
||||
}
|
||||
|
||||
inline const b2AABB& b2DynamicTree::GetFatAABB(int32 proxyId) const
|
||||
{
|
||||
b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
|
||||
return m_nodes[proxyId].aabb;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void b2DynamicTree::Query(T* callback, const b2AABB& aabb) const
|
||||
{
|
||||
b2GrowableStack<int32, 256> stack;
|
||||
stack.Push(m_root);
|
||||
|
||||
while (stack.GetCount() > 0)
|
||||
{
|
||||
int32 nodeId = stack.Pop();
|
||||
if (nodeId == b2_nullNode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const b2TreeNode* node = m_nodes + nodeId;
|
||||
|
||||
if (b2TestOverlap(node->aabb, aabb))
|
||||
{
|
||||
if (node->IsLeaf())
|
||||
{
|
||||
bool proceed = callback->QueryCallback(nodeId);
|
||||
if (proceed == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.Push(node->child1);
|
||||
stack.Push(node->child2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void b2DynamicTree::RayCast(T* callback, const b2RayCastInput& input) const
|
||||
{
|
||||
b2Vec2 p1 = input.p1;
|
||||
b2Vec2 p2 = input.p2;
|
||||
b2Vec2 r = p2 - p1;
|
||||
b2Assert(r.LengthSquared() > 0.0f);
|
||||
r.Normalize();
|
||||
|
||||
// v is perpendicular to the segment.
|
||||
b2Vec2 v = b2Cross(1.0f, r);
|
||||
b2Vec2 abs_v = b2Abs(v);
|
||||
|
||||
// Separating axis for segment (Gino, p80).
|
||||
// |dot(v, p1 - c)| > dot(|v|, h)
|
||||
|
||||
float32 maxFraction = input.maxFraction;
|
||||
|
||||
// Build a bounding box for the segment.
|
||||
b2AABB segmentAABB;
|
||||
{
|
||||
b2Vec2 t = p1 + maxFraction * (p2 - p1);
|
||||
segmentAABB.lowerBound = b2Min(p1, t);
|
||||
segmentAABB.upperBound = b2Max(p1, t);
|
||||
}
|
||||
|
||||
b2GrowableStack<int32, 256> stack;
|
||||
stack.Push(m_root);
|
||||
|
||||
while (stack.GetCount() > 0)
|
||||
{
|
||||
int32 nodeId = stack.Pop();
|
||||
if (nodeId == b2_nullNode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const b2TreeNode* node = m_nodes + nodeId;
|
||||
|
||||
if (b2TestOverlap(node->aabb, segmentAABB) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Separating axis for segment (Gino, p80).
|
||||
// |dot(v, p1 - c)| > dot(|v|, h)
|
||||
b2Vec2 c = node->aabb.GetCenter();
|
||||
b2Vec2 h = node->aabb.GetExtents();
|
||||
float32 separation = b2Abs(b2Dot(v, p1 - c)) - b2Dot(abs_v, h);
|
||||
if (separation > 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (node->IsLeaf())
|
||||
{
|
||||
b2RayCastInput subInput;
|
||||
subInput.p1 = input.p1;
|
||||
subInput.p2 = input.p2;
|
||||
subInput.maxFraction = maxFraction;
|
||||
|
||||
float32 value = callback->RayCastCallback(subInput, nodeId);
|
||||
|
||||
if (value == 0.0f)
|
||||
{
|
||||
// The client has terminated the ray cast.
|
||||
return;
|
||||
}
|
||||
|
||||
if (value > 0.0f)
|
||||
{
|
||||
// Update segment bounding box.
|
||||
maxFraction = value;
|
||||
b2Vec2 t = p1 + maxFraction * (p2 - p1);
|
||||
segmentAABB.lowerBound = b2Min(p1, t);
|
||||
segmentAABB.upperBound = b2Max(p1, t);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.Push(node->child1);
|
||||
stack.Push(node->child2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
58
inc/Box2D/Collision/b2TimeOfImpact.h
Normal file
58
inc/Box2D/Collision/b2TimeOfImpact.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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_TIME_OF_IMPACT_H
|
||||
#define B2_TIME_OF_IMPACT_H
|
||||
|
||||
#include <Box2D/Common/b2Math.h>
|
||||
#include <Box2D/Collision/b2Distance.h>
|
||||
|
||||
/// Input parameters for b2TimeOfImpact
|
||||
struct b2TOIInput
|
||||
{
|
||||
b2DistanceProxy proxyA;
|
||||
b2DistanceProxy proxyB;
|
||||
b2Sweep sweepA;
|
||||
b2Sweep sweepB;
|
||||
float32 tMax; // defines sweep interval [0, tMax]
|
||||
};
|
||||
|
||||
// Output parameters for b2TimeOfImpact.
|
||||
struct b2TOIOutput
|
||||
{
|
||||
enum State
|
||||
{
|
||||
e_unknown,
|
||||
e_failed,
|
||||
e_overlapped,
|
||||
e_touching,
|
||||
e_separated
|
||||
};
|
||||
|
||||
State state;
|
||||
float32 t;
|
||||
};
|
||||
|
||||
/// Compute the upper bound on time before two shapes penetrate. Time is represented as
|
||||
/// a fraction between [0,tMax]. This uses a swept separating axis and may miss some intermediate,
|
||||
/// non-tunneling collision. If you change the time interval, you should call this function
|
||||
/// again.
|
||||
/// Note: use b2Distance to compute the contact point and normal at the time of impact.
|
||||
void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user