rollmorad hinzugefügt
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef B2_CIRCLE_SHAPE_H
|
||||
#define B2_CIRCLE_SHAPE_H
|
||||
|
||||
#include "b2Shape.h"
|
||||
|
||||
/// This structure is used to build circle shapes.
|
||||
struct b2CircleDef : public b2ShapeDef
|
||||
{
|
||||
b2CircleDef()
|
||||
{
|
||||
type = e_circleShape;
|
||||
localPosition.SetZero();
|
||||
radius = 1.0f;
|
||||
}
|
||||
|
||||
b2Vec2 localPosition;
|
||||
float32 radius;
|
||||
};
|
||||
|
||||
/// A circle shape.
|
||||
class b2CircleShape : public b2Shape
|
||||
{
|
||||
public:
|
||||
/// @see b2Shape::TestPoint
|
||||
bool TestPoint(const b2XForm& transform, const b2Vec2& p) const;
|
||||
|
||||
/// @see b2Shape::TestSegment
|
||||
bool TestSegment( const b2XForm& transform,
|
||||
float32* lambda,
|
||||
b2Vec2* normal,
|
||||
const b2Segment& segment,
|
||||
float32 maxLambda) const;
|
||||
|
||||
/// @see b2Shape::ComputeAABB
|
||||
void ComputeAABB(b2AABB* aabb, const b2XForm& transform) const;
|
||||
|
||||
/// @see b2Shape::ComputeSweptAABB
|
||||
void ComputeSweptAABB( b2AABB* aabb,
|
||||
const b2XForm& transform1,
|
||||
const b2XForm& transform2) const;
|
||||
|
||||
/// @see b2Shape::ComputeMass
|
||||
void ComputeMass(b2MassData* massData) const;
|
||||
|
||||
/// Get the local position of this circle in its parent body.
|
||||
const b2Vec2& GetLocalPosition() const;
|
||||
|
||||
/// Get the radius of this circle.
|
||||
float32 GetRadius() const;
|
||||
|
||||
private:
|
||||
|
||||
friend class b2Shape;
|
||||
|
||||
b2CircleShape(const b2ShapeDef* def);
|
||||
|
||||
void UpdateSweepRadius(const b2Vec2& center);
|
||||
|
||||
// Local position in parent body
|
||||
b2Vec2 m_localPosition;
|
||||
float32 m_radius;
|
||||
};
|
||||
|
||||
inline const b2Vec2& b2CircleShape::GetLocalPosition() const
|
||||
{
|
||||
return m_localPosition;
|
||||
}
|
||||
|
||||
inline float32 b2CircleShape::GetRadius() const
|
||||
{
|
||||
return m_radius;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef B2_POLYGON_SHAPE_H
|
||||
#define B2_POLYGON_SHAPE_H
|
||||
|
||||
#include "b2Shape.h"
|
||||
|
||||
/// Convex polygon. The vertices must be in CCW order for a right-handed
|
||||
/// coordinate system with the z-axis coming out of the screen.
|
||||
struct b2PolygonDef : public b2ShapeDef
|
||||
{
|
||||
b2PolygonDef()
|
||||
{
|
||||
type = e_polygonShape;
|
||||
vertexCount = 0;
|
||||
}
|
||||
|
||||
/// Build vertices to represent an axis-aligned box.
|
||||
/// @param hx the half-width.
|
||||
/// @param hy the half-height.
|
||||
void SetAsBox(float32 hx, float32 hy);
|
||||
|
||||
/// Build vertices to represent an oriented box.
|
||||
/// @param hx the half-width.
|
||||
/// @param hy the half-height.
|
||||
/// @param center the center of the box in local coordinates.
|
||||
/// @param angle the rotation of the box in local coordinates.
|
||||
void SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle);
|
||||
|
||||
/// The polygon vertices in local coordinates.
|
||||
b2Vec2 vertices[b2_maxPolygonVertices];
|
||||
|
||||
/// The number of polygon vertices.
|
||||
int32 vertexCount;
|
||||
};
|
||||
|
||||
|
||||
/// A convex polygon.
|
||||
class b2PolygonShape : public b2Shape
|
||||
{
|
||||
public:
|
||||
/// @see b2Shape::TestPoint
|
||||
bool TestPoint(const b2XForm& transform, const b2Vec2& p) const;
|
||||
|
||||
/// @see b2Shape::TestSegment
|
||||
bool TestSegment( const b2XForm& transform,
|
||||
float32* lambda,
|
||||
b2Vec2* normal,
|
||||
const b2Segment& segment,
|
||||
float32 maxLambda) const;
|
||||
|
||||
/// @see b2Shape::ComputeAABB
|
||||
void ComputeAABB(b2AABB* aabb, const b2XForm& transform) const;
|
||||
|
||||
/// @see b2Shape::ComputeSweptAABB
|
||||
void ComputeSweptAABB( b2AABB* aabb,
|
||||
const b2XForm& transform1,
|
||||
const b2XForm& transform2) const;
|
||||
|
||||
/// @see b2Shape::ComputeMass
|
||||
void ComputeMass(b2MassData* massData) const;
|
||||
|
||||
/// Get the oriented bounding box relative to the parent body.
|
||||
const b2OBB& GetOBB() const;
|
||||
|
||||
/// Get local centroid relative to the parent body.
|
||||
const b2Vec2& GetCentroid() const;
|
||||
|
||||
/// Get the vertex count.
|
||||
int32 GetVertexCount() const;
|
||||
|
||||
/// Get the vertices in local coordinates.
|
||||
const b2Vec2* GetVertices() const;
|
||||
|
||||
/// Get the core vertices in local coordinates. These vertices
|
||||
/// represent a smaller polygon that is used for time of impact
|
||||
/// computations.
|
||||
const b2Vec2* GetCoreVertices() const;
|
||||
|
||||
/// Get the edge normal vectors. There is one for each vertex.
|
||||
const b2Vec2* GetNormals() const;
|
||||
|
||||
/// Get the first vertex and apply the supplied transform.
|
||||
b2Vec2 GetFirstVertex(const b2XForm& xf) const;
|
||||
|
||||
/// Get the centroid and apply the supplied transform.
|
||||
b2Vec2 Centroid(const b2XForm& xf) const;
|
||||
|
||||
/// Get the support point in the given world direction.
|
||||
/// Use the supplied transform.
|
||||
b2Vec2 Support(const b2XForm& xf, const b2Vec2& d) const;
|
||||
|
||||
private:
|
||||
|
||||
friend class b2Shape;
|
||||
|
||||
b2PolygonShape(const b2ShapeDef* def);
|
||||
|
||||
void UpdateSweepRadius(const b2Vec2& center);
|
||||
|
||||
// Local position of the polygon centroid.
|
||||
b2Vec2 m_centroid;
|
||||
|
||||
b2OBB m_obb;
|
||||
|
||||
b2Vec2 m_vertices[b2_maxPolygonVertices];
|
||||
b2Vec2 m_normals[b2_maxPolygonVertices];
|
||||
b2Vec2 m_coreVertices[b2_maxPolygonVertices];
|
||||
int32 m_vertexCount;
|
||||
};
|
||||
|
||||
inline b2Vec2 b2PolygonShape::GetFirstVertex(const b2XForm& xf) const
|
||||
{
|
||||
return b2Mul(xf, m_coreVertices[0]);
|
||||
}
|
||||
|
||||
inline const b2OBB& b2PolygonShape::GetOBB() const
|
||||
{
|
||||
return m_obb;
|
||||
}
|
||||
|
||||
inline const b2Vec2& b2PolygonShape::GetCentroid() const
|
||||
{
|
||||
return m_centroid;
|
||||
}
|
||||
|
||||
inline int32 b2PolygonShape::GetVertexCount() const
|
||||
{
|
||||
return m_vertexCount;
|
||||
}
|
||||
|
||||
inline const b2Vec2* b2PolygonShape::GetVertices() const
|
||||
{
|
||||
return m_vertices;
|
||||
}
|
||||
|
||||
inline const b2Vec2* b2PolygonShape::GetCoreVertices() const
|
||||
{
|
||||
return m_coreVertices;
|
||||
}
|
||||
|
||||
inline const b2Vec2* b2PolygonShape::GetNormals() const
|
||||
{
|
||||
return m_normals;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef B2_SHAPE_H
|
||||
#define B2_SHAPE_H
|
||||
|
||||
#include "../../Common/b2Math.h"
|
||||
#include "../b2Collision.h"
|
||||
|
||||
class b2BlockAllocator;
|
||||
class b2Body;
|
||||
class b2BroadPhase;
|
||||
|
||||
/// This holds the mass data computed for a shape.
|
||||
struct b2MassData
|
||||
{
|
||||
/// The mass of the shape, usually in kilograms.
|
||||
float32 mass;
|
||||
|
||||
/// The position of the shape's centroid relative to the shape's origin.
|
||||
b2Vec2 center;
|
||||
|
||||
/// The rotational inertia of the shape.
|
||||
float32 I;
|
||||
};
|
||||
|
||||
/// This holds contact filtering data.
|
||||
struct b2FilterData
|
||||
{
|
||||
/// The collision category bits. Normally you would just set one bit.
|
||||
uint16 categoryBits;
|
||||
|
||||
/// The collision mask bits. This states the categories that this
|
||||
/// shape would accept for collision.
|
||||
uint16 maskBits;
|
||||
|
||||
/// Collision groups allow a certain group of objects to never collide (negative)
|
||||
/// or always collide (positive). Zero means no collision group. Non-zero group
|
||||
/// filtering always wins against the mask bits.
|
||||
int16 groupIndex;
|
||||
};
|
||||
|
||||
/// The various collision shape types supported by Box2D.
|
||||
enum b2ShapeType
|
||||
{
|
||||
e_unknownShape = -1,
|
||||
e_circleShape,
|
||||
e_polygonShape,
|
||||
e_shapeTypeCount,
|
||||
};
|
||||
|
||||
/// A shape definition is used to construct a shape. This class defines an
|
||||
/// abstract shape definition. You can reuse shape definitions safely.
|
||||
struct b2ShapeDef
|
||||
{
|
||||
/// The constructor sets the default shape definition values.
|
||||
b2ShapeDef()
|
||||
{
|
||||
type = e_unknownShape;
|
||||
userData = NULL;
|
||||
friction = 0.2f;
|
||||
restitution = 0.0f;
|
||||
density = 0.0f;
|
||||
filter.categoryBits = 0x0001;
|
||||
filter.maskBits = 0xFFFF;
|
||||
filter.groupIndex = 0;
|
||||
isSensor = false;
|
||||
}
|
||||
|
||||
virtual ~b2ShapeDef() {}
|
||||
|
||||
/// Holds the shape type for down-casting.
|
||||
b2ShapeType type;
|
||||
|
||||
/// Use this to store application specify shape data.
|
||||
void* userData;
|
||||
|
||||
/// The shape's friction coefficient, usually in the range [0,1].
|
||||
float32 friction;
|
||||
|
||||
/// The shape's restitution (elasticity) usually in the range [0,1].
|
||||
float32 restitution;
|
||||
|
||||
/// The shape's density, usually in kg/m^2.
|
||||
float32 density;
|
||||
|
||||
/// A sensor shape collects contact information but never generates a collision
|
||||
/// response.
|
||||
bool isSensor;
|
||||
|
||||
/// Contact filtering data.
|
||||
b2FilterData filter;
|
||||
};
|
||||
|
||||
/// A shape is used for collision detection. Shapes are created in b2World.
|
||||
/// You can use shape for collision detection before they are attached to the world.
|
||||
/// @warning you cannot reuse shapes.
|
||||
class b2Shape
|
||||
{
|
||||
public:
|
||||
/// Get the type of this shape. You can use this to down cast to the concrete shape.
|
||||
/// @return the shape type.
|
||||
b2ShapeType GetType() const;
|
||||
|
||||
/// Is this shape a sensor (non-solid)?
|
||||
/// @return the true if the shape is a sensor.
|
||||
bool IsSensor() const;
|
||||
|
||||
/// Set the contact filtering data. You must call b2World::Refilter to correct
|
||||
/// existing contacts/non-contacts.
|
||||
void SetFilterData(const b2FilterData& filter);
|
||||
|
||||
/// Get the contact filtering data.
|
||||
const b2FilterData& GetFilterData() const;
|
||||
|
||||
/// Get the parent body of this shape. This is NULL if the shape is not attached.
|
||||
/// @return the parent body.
|
||||
b2Body* GetBody();
|
||||
|
||||
/// Get the next shape in the parent body's shape list.
|
||||
/// @return the next shape.
|
||||
b2Shape* GetNext();
|
||||
|
||||
/// Get the user data that was assigned in the shape definition. Use this to
|
||||
/// store your application specific data.
|
||||
void* GetUserData();
|
||||
|
||||
/// Set the user data. Use this to store your application specific data.
|
||||
void SetUserData(void* data);
|
||||
|
||||
/// Test a point for containment in this shape. This only works for convex shapes.
|
||||
/// @param xf the shape world transform.
|
||||
/// @param p a point in world coordinates.
|
||||
virtual bool TestPoint(const b2XForm& xf, const b2Vec2& p) const = 0;
|
||||
|
||||
/// Perform a ray cast against this shape.
|
||||
/// @param xf the shape world transform.
|
||||
/// @param lambda returns the hit fraction. You can use this to compute the contact point
|
||||
/// p = (1 - lambda) * segment.p1 + lambda * segment.p2.
|
||||
/// @param normal returns the normal at the contact point. If there is no intersection, the normal
|
||||
/// is not set.
|
||||
/// @param segment defines the begin and end point of the ray cast.
|
||||
/// @param maxLambda a number typically in the range [0,1].
|
||||
/// @return true if there was an intersection.
|
||||
virtual bool TestSegment( const b2XForm& xf,
|
||||
float32* lambda,
|
||||
b2Vec2* normal,
|
||||
const b2Segment& segment,
|
||||
float32 maxLambda) const = 0;
|
||||
|
||||
/// Given a transform, compute the associated axis aligned bounding box for this shape.
|
||||
/// @param aabb returns the axis aligned box.
|
||||
/// @param xf the world transform of the shape.
|
||||
virtual void ComputeAABB(b2AABB* aabb, const b2XForm& xf) const = 0;
|
||||
|
||||
/// Given two transforms, compute the associated swept axis aligned bounding box for this shape.
|
||||
/// @param aabb returns the axis aligned box.
|
||||
/// @param xf1 the starting shape world transform.
|
||||
/// @param xf2 the ending shape world transform.
|
||||
virtual void ComputeSweptAABB( b2AABB* aabb,
|
||||
const b2XForm& xf1,
|
||||
const b2XForm& xf2) const = 0;
|
||||
|
||||
/// Compute the mass properties of this shape using its dimensions and density.
|
||||
/// The inertia tensor is computed about the local origin, not the centroid.
|
||||
/// @param massData returns the mass data for this shape.
|
||||
virtual void ComputeMass(b2MassData* massData) const = 0;
|
||||
|
||||
/// Get the maximum radius about the parent body's center of mass.
|
||||
float32 GetSweepRadius() const;
|
||||
|
||||
/// Get the coefficient of friction.
|
||||
float32 GetFriction() const;
|
||||
|
||||
/// Get the coefficient of restitution.
|
||||
float32 GetRestitution() const;
|
||||
|
||||
protected:
|
||||
|
||||
friend class b2Body;
|
||||
friend class b2World;
|
||||
|
||||
static b2Shape* Create(const b2ShapeDef* def, b2BlockAllocator* allocator);
|
||||
static void Destroy(b2Shape* shape, b2BlockAllocator* allocator);
|
||||
|
||||
b2Shape(const b2ShapeDef* def);
|
||||
virtual ~b2Shape();
|
||||
|
||||
void CreateProxy(b2BroadPhase* broadPhase, const b2XForm& xf);
|
||||
void DestroyProxy(b2BroadPhase* broadPhase);
|
||||
bool Synchronize(b2BroadPhase* broadPhase, const b2XForm& xf1, const b2XForm& xf2);
|
||||
void RefilterProxy(b2BroadPhase* broadPhase, const b2XForm& xf);
|
||||
|
||||
virtual void UpdateSweepRadius(const b2Vec2& center) = 0;
|
||||
|
||||
b2ShapeType m_type;
|
||||
b2Shape* m_next;
|
||||
b2Body* m_body;
|
||||
|
||||
// Sweep radius relative to the parent body's center of mass.
|
||||
float32 m_sweepRadius;
|
||||
|
||||
float32 m_density;
|
||||
float32 m_friction;
|
||||
float32 m_restitution;
|
||||
|
||||
uint16 m_proxyId;
|
||||
b2FilterData m_filter;
|
||||
|
||||
bool m_isSensor;
|
||||
|
||||
void* m_userData;
|
||||
};
|
||||
|
||||
inline b2ShapeType b2Shape::GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
inline bool b2Shape::IsSensor() const
|
||||
{
|
||||
return m_isSensor;
|
||||
}
|
||||
|
||||
inline void b2Shape::SetFilterData(const b2FilterData& filter)
|
||||
{
|
||||
m_filter = filter;
|
||||
}
|
||||
|
||||
inline const b2FilterData& b2Shape::GetFilterData() const
|
||||
{
|
||||
return m_filter;
|
||||
}
|
||||
|
||||
inline void* b2Shape::GetUserData()
|
||||
{
|
||||
return m_userData;
|
||||
}
|
||||
|
||||
inline void b2Shape::SetUserData(void* data)
|
||||
{
|
||||
m_userData = data;
|
||||
}
|
||||
|
||||
inline b2Body* b2Shape::GetBody()
|
||||
{
|
||||
return m_body;
|
||||
}
|
||||
|
||||
inline b2Shape* b2Shape::GetNext()
|
||||
{
|
||||
return m_next;
|
||||
}
|
||||
|
||||
inline float32 b2Shape::GetSweepRadius() const
|
||||
{
|
||||
return m_sweepRadius;
|
||||
}
|
||||
|
||||
inline float32 b2Shape::GetFriction() const
|
||||
{
|
||||
return m_friction;
|
||||
}
|
||||
|
||||
inline float32 b2Shape::GetRestitution() const
|
||||
{
|
||||
return m_restitution;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef B2_BROAD_PHASE_H
|
||||
#define B2_BROAD_PHASE_H
|
||||
|
||||
/*
|
||||
This broad phase uses the Sweep and Prune algorithm as described in:
|
||||
Collision Detection in Interactive 3D Environments by Gino van den Bergen
|
||||
Also, some ideas, such as using integral values for fast compares comes from
|
||||
Bullet (http:/www.bulletphysics.com).
|
||||
*/
|
||||
|
||||
#include "../Common/b2Settings.h"
|
||||
#include "b2Collision.h"
|
||||
#include "b2PairManager.h"
|
||||
#include <climits>
|
||||
|
||||
#ifdef TARGET_FLOAT32_IS_FIXED
|
||||
#define B2BROADPHASE_MAX (USHRT_MAX/2)
|
||||
#else
|
||||
#define B2BROADPHASE_MAX USHRT_MAX
|
||||
|
||||
#endif
|
||||
|
||||
const uint16 b2_invalid = B2BROADPHASE_MAX;
|
||||
const uint16 b2_nullEdge = B2BROADPHASE_MAX;
|
||||
struct b2BoundValues;
|
||||
|
||||
struct b2Bound
|
||||
{
|
||||
bool IsLower() const { return (value & 1) == 0; }
|
||||
bool IsUpper() const { return (value & 1) == 1; }
|
||||
|
||||
uint16 value;
|
||||
uint16 proxyId;
|
||||
uint16 stabbingCount;
|
||||
};
|
||||
|
||||
struct b2Proxy
|
||||
{
|
||||
uint16 GetNext() const { return lowerBounds[0]; }
|
||||
void SetNext(uint16 next) { lowerBounds[0] = next; }
|
||||
bool IsValid() const { return overlapCount != b2_invalid; }
|
||||
|
||||
uint16 lowerBounds[2], upperBounds[2];
|
||||
uint16 overlapCount;
|
||||
uint16 timeStamp;
|
||||
void* userData;
|
||||
};
|
||||
|
||||
class b2BroadPhase
|
||||
{
|
||||
public:
|
||||
b2BroadPhase(const b2AABB& worldAABB, b2PairCallback* callback);
|
||||
~b2BroadPhase();
|
||||
|
||||
// Use this to see if your proxy is in range. If it is not in range,
|
||||
// it should be destroyed. Otherwise you may get O(m^2) pairs, where m
|
||||
// is the number of proxies that are out of range.
|
||||
bool InRange(const b2AABB& aabb) const;
|
||||
|
||||
// Create and destroy proxies. These call Flush first.
|
||||
uint16 CreateProxy(const b2AABB& aabb, void* userData);
|
||||
void DestroyProxy(int32 proxyId);
|
||||
|
||||
// Call MoveProxy as many times as you like, then when you are done
|
||||
// call Commit to finalized the proxy pairs (for your time step).
|
||||
void MoveProxy(int32 proxyId, const b2AABB& aabb);
|
||||
void Commit();
|
||||
|
||||
// Get a single proxy. Returns NULL if the id is invalid.
|
||||
b2Proxy* GetProxy(int32 proxyId);
|
||||
|
||||
// Query an AABB for overlapping proxies, returns the user data and
|
||||
// the count, up to the supplied maximum count.
|
||||
int32 Query(const b2AABB& aabb, void** userData, int32 maxCount);
|
||||
|
||||
void Validate();
|
||||
void ValidatePairs();
|
||||
|
||||
private:
|
||||
void ComputeBounds(uint16* lowerValues, uint16* upperValues, const b2AABB& aabb);
|
||||
|
||||
bool TestOverlap(b2Proxy* p1, b2Proxy* p2);
|
||||
bool TestOverlap(const b2BoundValues& b, b2Proxy* p);
|
||||
|
||||
void Query(int32* lowerIndex, int32* upperIndex, uint16 lowerValue, uint16 upperValue,
|
||||
b2Bound* bounds, int32 boundCount, int32 axis);
|
||||
void IncrementOverlapCount(int32 proxyId);
|
||||
void IncrementTimeStamp();
|
||||
|
||||
public:
|
||||
friend class b2PairManager;
|
||||
|
||||
b2PairManager m_pairManager;
|
||||
|
||||
b2Proxy m_proxyPool[b2_maxProxies];
|
||||
uint16 m_freeProxy;
|
||||
|
||||
b2Bound m_bounds[2][2*b2_maxProxies];
|
||||
|
||||
uint16 m_queryResults[b2_maxProxies];
|
||||
int32 m_queryResultCount;
|
||||
|
||||
b2AABB m_worldAABB;
|
||||
b2Vec2 m_quantizationFactor;
|
||||
int32 m_proxyCount;
|
||||
uint16 m_timeStamp;
|
||||
|
||||
static bool s_validate;
|
||||
};
|
||||
|
||||
|
||||
inline bool b2BroadPhase::InRange(const b2AABB& aabb) const
|
||||
{
|
||||
b2Vec2 d = b2Max(aabb.lowerBound - m_worldAABB.upperBound, m_worldAABB.lowerBound - aabb.upperBound);
|
||||
return b2Max(d.x, d.y) < 0.0f;
|
||||
}
|
||||
|
||||
inline b2Proxy* b2BroadPhase::GetProxy(int32 proxyId)
|
||||
{
|
||||
if (proxyId == b2_nullProxy || m_proxyPool[proxyId].IsValid() == false)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return m_proxyPool + proxyId;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef B2_COLLISION_H
|
||||
#define B2_COLLISION_H
|
||||
|
||||
#include "../Common/b2Math.h"
|
||||
#include <climits>
|
||||
|
||||
/// @file
|
||||
/// Structures and functions used for computing contact points, distance
|
||||
/// queries, and TOI queries.
|
||||
|
||||
class b2Shape;
|
||||
class b2CircleShape;
|
||||
class b2PolygonShape;
|
||||
|
||||
const uint8 b2_nullFeature = UCHAR_MAX;
|
||||
|
||||
/// Contact ids to facilitate warm starting.
|
||||
union b2ContactID
|
||||
{
|
||||
/// The features that intersect to form the contact point
|
||||
struct Features
|
||||
{
|
||||
uint8 referenceEdge; ///< The edge that defines the outward contact normal.
|
||||
uint8 incidentEdge; ///< The edge most anti-parallel to the reference edge.
|
||||
uint8 incidentVertex; ///< The vertex (0 or 1) on the incident edge that was clipped.
|
||||
uint8 flip; ///< A value of 1 indicates that the reference edge is on shape2.
|
||||
} features;
|
||||
uint32 key; ///< Used to quickly compare contact ids.
|
||||
};
|
||||
|
||||
/// A manifold point is a contact point belonging to a contact
|
||||
/// manifold. It holds details related to the geometry and dynamics
|
||||
/// of the contact points.
|
||||
/// The point is stored in local coordinates because CCD
|
||||
/// requires sub-stepping in which the separation is stale.
|
||||
struct b2ManifoldPoint
|
||||
{
|
||||
b2Vec2 localPoint1; ///< local position of the contact point in body1
|
||||
b2Vec2 localPoint2; ///< local position of the contact point in body2
|
||||
float32 separation; ///< the separation of the shapes along the normal vector
|
||||
float32 normalImpulse; ///< the non-penetration impulse
|
||||
float32 tangentImpulse; ///< the friction impulse
|
||||
b2ContactID id; ///< uniquely identifies a contact point between two shapes
|
||||
};
|
||||
|
||||
/// A manifold for two touching convex shapes.
|
||||
struct b2Manifold
|
||||
{
|
||||
b2ManifoldPoint points[b2_maxManifoldPoints]; ///< the points of contact
|
||||
b2Vec2 normal; ///< the shared unit normal vector
|
||||
int32 pointCount; ///< the number of manifold points
|
||||
};
|
||||
|
||||
/// A line segment.
|
||||
struct b2Segment
|
||||
{
|
||||
/// Ray cast against this segment with another segment.
|
||||
bool TestSegment(float32* lambda, b2Vec2* normal, const b2Segment& segment, float32 maxLambda) const;
|
||||
|
||||
b2Vec2 p1; ///< the starting point
|
||||
b2Vec2 p2; ///< the ending point
|
||||
};
|
||||
|
||||
/// An axis aligned bounding box.
|
||||
struct b2AABB
|
||||
{
|
||||
/// Verify that the bounds are sorted.
|
||||
bool IsValid() const;
|
||||
|
||||
b2Vec2 lowerBound; ///< the lower vertex
|
||||
b2Vec2 upperBound; ///< the upper vertex
|
||||
};
|
||||
|
||||
/// An oriented bounding box.
|
||||
struct b2OBB
|
||||
{
|
||||
b2Mat22 R; ///< the rotation matrix
|
||||
b2Vec2 center; ///< the local centroid
|
||||
b2Vec2 extents; ///< the half-widths
|
||||
};
|
||||
|
||||
/// Compute the collision manifold between two circles.
|
||||
void b2CollideCircles(b2Manifold* manifold,
|
||||
const b2CircleShape* circle1, const b2XForm& xf1,
|
||||
const b2CircleShape* circle2, const b2XForm& xf2);
|
||||
|
||||
/// Compute the collision manifold between a polygon and a circle.
|
||||
void b2CollidePolygonAndCircle(b2Manifold* manifold,
|
||||
const b2PolygonShape* polygon, const b2XForm& xf1,
|
||||
const b2CircleShape* circle, const b2XForm& xf2);
|
||||
|
||||
/// Compute the collision manifold between two circles.
|
||||
void b2CollidePolygons(b2Manifold* manifold,
|
||||
const b2PolygonShape* polygon1, const b2XForm& xf1,
|
||||
const b2PolygonShape* polygon2, const b2XForm& xf2);
|
||||
|
||||
/// Compute the distance between two shapes and the closest points.
|
||||
/// @return the distance between the shapes or zero if they are overlapped/touching.
|
||||
float32 b2Distance(b2Vec2* x1, b2Vec2* x2,
|
||||
const b2Shape* shape1, const b2XForm& xf1,
|
||||
const b2Shape* shape2, const b2XForm& xf2);
|
||||
|
||||
/// Compute the time when two shapes begin to touch or touch at a closer distance.
|
||||
/// @warning the sweeps must have the same time interval.
|
||||
/// @return the fraction between [0,1] in which the shapes first touch.
|
||||
/// fraction=0 means the shapes begin touching/overlapped, and fraction=1 means the shapes don't touch.
|
||||
float32 b2TimeOfImpact(const b2Shape* shape1, const b2Sweep& sweep1,
|
||||
const b2Shape* shape2, const b2Sweep& sweep2);
|
||||
|
||||
|
||||
// ---------------- Inline Functions ------------------------------------------
|
||||
|
||||
inline bool b2AABB::IsValid() const
|
||||
{
|
||||
b2Vec2 d = upperBound - lowerBound;
|
||||
bool valid = d.x >= 0.0f && d.y >= 0.0f;
|
||||
valid = valid && lowerBound.IsValid() && upperBound.IsValid();
|
||||
return valid;
|
||||
}
|
||||
|
||||
inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b)
|
||||
{
|
||||
b2Vec2 d1, d2;
|
||||
d1 = b.lowerBound - a.upperBound;
|
||||
d2 = a.lowerBound - b.upperBound;
|
||||
|
||||
if (d1.x > 0.0f || d1.y > 0.0f)
|
||||
return false;
|
||||
|
||||
if (d2.x > 0.0f || d2.y > 0.0f)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
// The pair manager is used by the broad-phase to quickly add/remove/find pairs
|
||||
// of overlapping proxies. It is based closely on code provided by Pierre Terdiman.
|
||||
// http://www.codercorner.com/IncrementalSAP.txt
|
||||
|
||||
#ifndef B2_PAIR_MANAGER_H
|
||||
#define B2_PAIR_MANAGER_H
|
||||
|
||||
#include "../Common/b2Settings.h"
|
||||
#include "../Common/b2Math.h"
|
||||
|
||||
#include <climits>
|
||||
|
||||
class b2BroadPhase;
|
||||
struct b2Proxy;
|
||||
|
||||
const uint16 b2_nullPair = USHRT_MAX;
|
||||
const uint16 b2_nullProxy = USHRT_MAX;
|
||||
const int32 b2_tableCapacity = b2_maxPairs; // must be a power of two
|
||||
const int32 b2_tableMask = b2_tableCapacity - 1;
|
||||
|
||||
struct b2Pair
|
||||
{
|
||||
enum
|
||||
{
|
||||
e_pairBuffered = 0x0001,
|
||||
e_pairRemoved = 0x0002,
|
||||
e_pairFinal = 0x0004,
|
||||
};
|
||||
|
||||
void SetBuffered() { status |= e_pairBuffered; }
|
||||
void ClearBuffered() { status &= ~e_pairBuffered; }
|
||||
bool IsBuffered() { return (status & e_pairBuffered) == e_pairBuffered; }
|
||||
|
||||
void SetRemoved() { status |= e_pairRemoved; }
|
||||
void ClearRemoved() { status &= ~e_pairRemoved; }
|
||||
bool IsRemoved() { return (status & e_pairRemoved) == e_pairRemoved; }
|
||||
|
||||
void SetFinal() { status |= e_pairFinal; }
|
||||
bool IsFinal() { return (status & e_pairFinal) == e_pairFinal; }
|
||||
|
||||
void* userData;
|
||||
uint16 proxyId1;
|
||||
uint16 proxyId2;
|
||||
uint16 next;
|
||||
uint16 status;
|
||||
};
|
||||
|
||||
struct b2BufferedPair
|
||||
{
|
||||
uint16 proxyId1;
|
||||
uint16 proxyId2;
|
||||
};
|
||||
|
||||
class b2PairCallback
|
||||
{
|
||||
public:
|
||||
virtual ~b2PairCallback() {}
|
||||
|
||||
// This should return the new pair user data. It is ok if the
|
||||
// user data is null.
|
||||
virtual void* PairAdded(void* proxyUserData1, void* proxyUserData2) = 0;
|
||||
|
||||
// This should free the pair's user data. In extreme circumstances, it is possible
|
||||
// this will be called with null pairUserData because the pair never existed.
|
||||
virtual void PairRemoved(void* proxyUserData1, void* proxyUserData2, void* pairUserData) = 0;
|
||||
};
|
||||
|
||||
class b2PairManager
|
||||
{
|
||||
public:
|
||||
b2PairManager();
|
||||
|
||||
void Initialize(b2BroadPhase* broadPhase, b2PairCallback* callback);
|
||||
|
||||
void AddBufferedPair(int32 proxyId1, int32 proxyId2);
|
||||
void RemoveBufferedPair(int32 proxyId1, int32 proxyId2);
|
||||
|
||||
void Commit();
|
||||
|
||||
private:
|
||||
b2Pair* Find(int32 proxyId1, int32 proxyId2);
|
||||
b2Pair* Find(int32 proxyId1, int32 proxyId2, uint32 hashValue);
|
||||
|
||||
b2Pair* AddPair(int32 proxyId1, int32 proxyId2);
|
||||
void* RemovePair(int32 proxyId1, int32 proxyId2);
|
||||
|
||||
void ValidateBuffer();
|
||||
void ValidateTable();
|
||||
|
||||
public:
|
||||
b2BroadPhase *m_broadPhase;
|
||||
b2PairCallback *m_callback;
|
||||
b2Pair m_pairs[b2_maxPairs];
|
||||
uint16 m_freePair;
|
||||
int32 m_pairCount;
|
||||
|
||||
b2BufferedPair m_pairBuffer[b2_maxPairs];
|
||||
int32 m_pairBufferCount;
|
||||
|
||||
uint16 m_hashTable[b2_tableCapacity];
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user