834 lines
31 KiB
C
834 lines
31 KiB
C
// SPDX-FileCopyrightText: 2023 Erin Catto
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#pragma once
|
|
|
|
#include "base.h"
|
|
#include "math_functions.h"
|
|
|
|
#include <stdbool.h>
|
|
|
|
typedef struct b2SimplexCache b2SimplexCache;
|
|
typedef struct b2Hull b2Hull;
|
|
|
|
/**
|
|
* @defgroup geometry Geometry
|
|
* @brief Geometry types and algorithms
|
|
*
|
|
* Definitions of circles, capsules, segments, and polygons. Various algorithms to compute hulls, mass properties, and so on.
|
|
* @{
|
|
*/
|
|
|
|
/// The maximum number of vertices on a convex polygon. Changing this affects performance even if you
|
|
/// don't use more vertices.
|
|
#define B2_MAX_POLYGON_VERTICES 8
|
|
|
|
/// Low level ray cast input data
|
|
typedef struct b2RayCastInput
|
|
{
|
|
/// Start point of the ray cast
|
|
b2Vec2 origin;
|
|
|
|
/// Translation of the ray cast
|
|
b2Vec2 translation;
|
|
|
|
/// The maximum fraction of the translation to consider, typically 1
|
|
float maxFraction;
|
|
} b2RayCastInput;
|
|
|
|
/// A distance proxy is used by the GJK algorithm. It encapsulates any shape.
|
|
/// You can provide between 1 and B2_MAX_POLYGON_VERTICES and a radius.
|
|
typedef struct b2ShapeProxy
|
|
{
|
|
/// The point cloud
|
|
b2Vec2 points[B2_MAX_POLYGON_VERTICES];
|
|
|
|
/// The number of points. Must be greater than 0.
|
|
int count;
|
|
|
|
/// The external radius of the point cloud. May be zero.
|
|
float radius;
|
|
} b2ShapeProxy;
|
|
|
|
/// Low level shape cast input in generic form. This allows casting an arbitrary point
|
|
/// cloud wrap with a radius. For example, a circle is a single point with a non-zero radius.
|
|
/// A capsule is two points with a non-zero radius. A box is four points with a zero radius.
|
|
typedef struct b2ShapeCastInput
|
|
{
|
|
/// A generic shape
|
|
b2ShapeProxy proxy;
|
|
|
|
/// The translation of the shape cast
|
|
b2Vec2 translation;
|
|
|
|
/// The maximum fraction of the translation to consider, typically 1
|
|
float maxFraction;
|
|
|
|
/// Allow shape cast to encroach when initially touching. This only works if the radius is greater than zero.
|
|
bool canEncroach;
|
|
} b2ShapeCastInput;
|
|
|
|
/// Low level ray cast or shape-cast output data. Returns a zero fraction and normal in the case of initial overlap.
|
|
typedef struct b2CastOutput
|
|
{
|
|
/// The surface normal at the hit point
|
|
b2Vec2 normal;
|
|
|
|
/// The surface hit point
|
|
b2Vec2 point;
|
|
|
|
/// The fraction of the input translation at collision
|
|
float fraction;
|
|
|
|
/// The number of iterations used
|
|
int iterations;
|
|
|
|
/// Did the cast hit?
|
|
bool hit;
|
|
} b2CastOutput;
|
|
|
|
/// This holds the mass data computed for a shape.
|
|
typedef struct b2MassData
|
|
{
|
|
/// The mass of the shape, usually in kilograms.
|
|
float 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.
|
|
float rotationalInertia;
|
|
} b2MassData;
|
|
|
|
/// A solid circle
|
|
typedef struct b2Circle
|
|
{
|
|
/// The local center
|
|
b2Vec2 center;
|
|
|
|
/// The radius
|
|
float radius;
|
|
} b2Circle;
|
|
|
|
/// A solid capsule can be viewed as two semicircles connected
|
|
/// by a rectangle.
|
|
typedef struct b2Capsule
|
|
{
|
|
/// Local center of the first semicircle
|
|
b2Vec2 center1;
|
|
|
|
/// Local center of the second semicircle
|
|
b2Vec2 center2;
|
|
|
|
/// The radius of the semicircles
|
|
float radius;
|
|
} b2Capsule;
|
|
|
|
/// A solid 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_MAX_POLYGON_VERTICES.
|
|
/// In most cases you should not need many vertices for a convex polygon.
|
|
/// @warning DO NOT fill this out manually, instead use a helper function like
|
|
/// b2MakePolygon or b2MakeBox.
|
|
typedef struct b2Polygon
|
|
{
|
|
/// The polygon vertices
|
|
b2Vec2 vertices[B2_MAX_POLYGON_VERTICES];
|
|
|
|
/// The outward normal vectors of the polygon sides
|
|
b2Vec2 normals[B2_MAX_POLYGON_VERTICES];
|
|
|
|
/// The centroid of the polygon
|
|
b2Vec2 centroid;
|
|
|
|
/// The external radius for rounded polygons
|
|
float radius;
|
|
|
|
/// The number of polygon vertices
|
|
int count;
|
|
} b2Polygon;
|
|
|
|
/// A line segment with two-sided collision.
|
|
typedef struct b2Segment
|
|
{
|
|
/// The first point
|
|
b2Vec2 point1;
|
|
|
|
/// The second point
|
|
b2Vec2 point2;
|
|
} b2Segment;
|
|
|
|
/// A line segment with one-sided collision. Only collides on the right side.
|
|
/// Several of these are generated for a chain shape.
|
|
/// ghost1 -> point1 -> point2 -> ghost2
|
|
typedef struct b2ChainSegment
|
|
{
|
|
/// The tail ghost vertex
|
|
b2Vec2 ghost1;
|
|
|
|
/// The line segment
|
|
b2Segment segment;
|
|
|
|
/// The head ghost vertex
|
|
b2Vec2 ghost2;
|
|
|
|
/// The owning chain shape index (internal usage only)
|
|
int chainId;
|
|
} b2ChainSegment;
|
|
|
|
/// Validate ray cast input data (NaN, etc)
|
|
B2_API bool b2IsValidRay( const b2RayCastInput* input );
|
|
|
|
/// Make a convex polygon from a convex hull. This will assert if the hull is not valid.
|
|
/// @warning Do not manually fill in the hull data, it must come directly from b2ComputeHull
|
|
B2_API b2Polygon b2MakePolygon( const b2Hull* hull, float radius );
|
|
|
|
/// Make an offset convex polygon from a convex hull. This will assert if the hull is not valid.
|
|
/// @warning Do not manually fill in the hull data, it must come directly from b2ComputeHull
|
|
B2_API b2Polygon b2MakeOffsetPolygon( const b2Hull* hull, b2Vec2 position, b2Rot rotation );
|
|
|
|
/// Make an offset convex polygon from a convex hull. This will assert if the hull is not valid.
|
|
/// @warning Do not manually fill in the hull data, it must come directly from b2ComputeHull
|
|
B2_API b2Polygon b2MakeOffsetRoundedPolygon( const b2Hull* hull, b2Vec2 position, b2Rot rotation, float radius );
|
|
|
|
/// Make a square polygon, bypassing the need for a convex hull.
|
|
/// @param halfWidth the half-width
|
|
B2_API b2Polygon b2MakeSquare( float halfWidth );
|
|
|
|
/// Make a box (rectangle) polygon, bypassing the need for a convex hull.
|
|
/// @param halfWidth the half-width (x-axis)
|
|
/// @param halfHeight the half-height (y-axis)
|
|
B2_API b2Polygon b2MakeBox( float halfWidth, float halfHeight );
|
|
|
|
/// Make a rounded box, bypassing the need for a convex hull.
|
|
/// @param halfWidth the half-width (x-axis)
|
|
/// @param halfHeight the half-height (y-axis)
|
|
/// @param radius the radius of the rounded extension
|
|
B2_API b2Polygon b2MakeRoundedBox( float halfWidth, float halfHeight, float radius );
|
|
|
|
/// Make an offset box, bypassing the need for a convex hull.
|
|
/// @param halfWidth the half-width (x-axis)
|
|
/// @param halfHeight the half-height (y-axis)
|
|
/// @param center the local center of the box
|
|
/// @param rotation the local rotation of the box
|
|
B2_API b2Polygon b2MakeOffsetBox( float halfWidth, float halfHeight, b2Vec2 center, b2Rot rotation );
|
|
|
|
/// Make an offset rounded box, bypassing the need for a convex hull.
|
|
/// @param halfWidth the half-width (x-axis)
|
|
/// @param halfHeight the half-height (y-axis)
|
|
/// @param center the local center of the box
|
|
/// @param rotation the local rotation of the box
|
|
/// @param radius the radius of the rounded extension
|
|
B2_API b2Polygon b2MakeOffsetRoundedBox( float halfWidth, float halfHeight, b2Vec2 center, b2Rot rotation, float radius );
|
|
|
|
/// Transform a polygon. This is useful for transferring a shape from one body to another.
|
|
B2_API b2Polygon b2TransformPolygon( b2Transform transform, const b2Polygon* polygon );
|
|
|
|
/// Compute mass properties of a circle
|
|
B2_API b2MassData b2ComputeCircleMass( const b2Circle* shape, float density );
|
|
|
|
/// Compute mass properties of a capsule
|
|
B2_API b2MassData b2ComputeCapsuleMass( const b2Capsule* shape, float density );
|
|
|
|
/// Compute mass properties of a polygon
|
|
B2_API b2MassData b2ComputePolygonMass( const b2Polygon* shape, float density );
|
|
|
|
/// Compute the bounding box of a transformed circle
|
|
B2_API b2AABB b2ComputeCircleAABB( const b2Circle* shape, b2Transform transform );
|
|
|
|
/// Compute the bounding box of a transformed capsule
|
|
B2_API b2AABB b2ComputeCapsuleAABB( const b2Capsule* shape, b2Transform transform );
|
|
|
|
/// Compute the bounding box of a transformed polygon
|
|
B2_API b2AABB b2ComputePolygonAABB( const b2Polygon* shape, b2Transform transform );
|
|
|
|
/// Compute the bounding box of a transformed line segment
|
|
B2_API b2AABB b2ComputeSegmentAABB( const b2Segment* shape, b2Transform transform );
|
|
|
|
/// Test a point for overlap with a circle in local space
|
|
B2_API bool b2PointInCircle( b2Vec2 point, const b2Circle* shape );
|
|
|
|
/// Test a point for overlap with a capsule in local space
|
|
B2_API bool b2PointInCapsule( b2Vec2 point, const b2Capsule* shape );
|
|
|
|
/// Test a point for overlap with a convex polygon in local space
|
|
B2_API bool b2PointInPolygon( b2Vec2 point, const b2Polygon* shape );
|
|
|
|
/// Ray cast versus circle shape in local space. Initial overlap is treated as a miss.
|
|
B2_API b2CastOutput b2RayCastCircle( const b2RayCastInput* input, const b2Circle* shape );
|
|
|
|
/// Ray cast versus capsule shape in local space. Initial overlap is treated as a miss.
|
|
B2_API b2CastOutput b2RayCastCapsule( const b2RayCastInput* input, const b2Capsule* shape );
|
|
|
|
/// Ray cast versus segment shape in local space. Optionally treat the segment as one-sided with hits from
|
|
/// the left side being treated as a miss.
|
|
B2_API b2CastOutput b2RayCastSegment( const b2RayCastInput* input, const b2Segment* shape, bool oneSided );
|
|
|
|
/// Ray cast versus polygon shape in local space. Initial overlap is treated as a miss.
|
|
B2_API b2CastOutput b2RayCastPolygon( const b2RayCastInput* input, const b2Polygon* shape );
|
|
|
|
/// Shape cast versus a circle. Initial overlap is treated as a miss.
|
|
B2_API b2CastOutput b2ShapeCastCircle( const b2ShapeCastInput* input, const b2Circle* shape );
|
|
|
|
/// Shape cast versus a capsule. Initial overlap is treated as a miss.
|
|
B2_API b2CastOutput b2ShapeCastCapsule( const b2ShapeCastInput* input, const b2Capsule* shape );
|
|
|
|
/// Shape cast versus a line segment. Initial overlap is treated as a miss.
|
|
B2_API b2CastOutput b2ShapeCastSegment( const b2ShapeCastInput* input, const b2Segment* shape );
|
|
|
|
/// Shape cast versus a convex polygon. Initial overlap is treated as a miss.
|
|
B2_API b2CastOutput b2ShapeCastPolygon( const b2ShapeCastInput* input, const b2Polygon* shape );
|
|
|
|
/// A convex hull. Used to create convex polygons.
|
|
/// @warning Do not modify these values directly, instead use b2ComputeHull()
|
|
typedef struct b2Hull
|
|
{
|
|
/// The final points of the hull
|
|
b2Vec2 points[B2_MAX_POLYGON_VERTICES];
|
|
|
|
/// The number of points
|
|
int count;
|
|
} b2Hull;
|
|
|
|
/// Compute the convex hull of a set of points. Returns an empty hull if it fails.
|
|
/// Some failure cases:
|
|
/// - all points very close together
|
|
/// - all points on a line
|
|
/// - less than 3 points
|
|
/// - more than B2_MAX_POLYGON_VERTICES points
|
|
/// This welds close points and removes collinear points.
|
|
/// @warning Do not modify a hull once it has been computed
|
|
B2_API b2Hull b2ComputeHull( const b2Vec2* points, int count );
|
|
|
|
/// This determines if a hull is valid. Checks for:
|
|
/// - convexity
|
|
/// - collinear points
|
|
/// This is expensive and should not be called at runtime.
|
|
B2_API bool b2ValidateHull( const b2Hull* hull );
|
|
|
|
/**@}*/
|
|
|
|
/**
|
|
* @defgroup distance Distance
|
|
* Functions for computing the distance between shapes.
|
|
*
|
|
* These are advanced functions you can use to perform distance calculations. There
|
|
* are functions for computing the closest points between shapes, doing linear shape casts,
|
|
* and doing rotational shape casts. The latter is called time of impact (TOI).
|
|
* @{
|
|
*/
|
|
|
|
/// Result of computing the distance between two line segments
|
|
typedef struct b2SegmentDistanceResult
|
|
{
|
|
/// The closest point on the first segment
|
|
b2Vec2 closest1;
|
|
|
|
/// The closest point on the second segment
|
|
b2Vec2 closest2;
|
|
|
|
/// The barycentric coordinate on the first segment
|
|
float fraction1;
|
|
|
|
/// The barycentric coordinate on the second segment
|
|
float fraction2;
|
|
|
|
/// The squared distance between the closest points
|
|
float distanceSquared;
|
|
} b2SegmentDistanceResult;
|
|
|
|
/// Compute the distance between two line segments, clamping at the end points if needed.
|
|
B2_API b2SegmentDistanceResult b2SegmentDistance( b2Vec2 p1, b2Vec2 q1, b2Vec2 p2, b2Vec2 q2 );
|
|
|
|
/// Used to warm start the GJK simplex. If you call this function multiple times with nearby
|
|
/// transforms this might improve performance. Otherwise you can zero initialize this.
|
|
/// The distance cache must be initialized to zero on the first call.
|
|
/// Users should generally just zero initialize this structure for each call.
|
|
typedef struct b2SimplexCache
|
|
{
|
|
/// The number of stored simplex points
|
|
uint16_t count;
|
|
|
|
/// The cached simplex indices on shape A
|
|
uint8_t indexA[3];
|
|
|
|
/// The cached simplex indices on shape B
|
|
uint8_t indexB[3];
|
|
} b2SimplexCache;
|
|
|
|
static const b2SimplexCache b2_emptySimplexCache = B2_ZERO_INIT;
|
|
|
|
/// Input for b2ShapeDistance
|
|
typedef struct b2DistanceInput
|
|
{
|
|
/// The proxy for shape A
|
|
b2ShapeProxy proxyA;
|
|
|
|
/// The proxy for shape B
|
|
b2ShapeProxy proxyB;
|
|
|
|
/// The world transform for shape A
|
|
b2Transform transformA;
|
|
|
|
/// The world transform for shape B
|
|
b2Transform transformB;
|
|
|
|
/// Should the proxy radius be considered?
|
|
bool useRadii;
|
|
} b2DistanceInput;
|
|
|
|
/// Output for b2ShapeDistance
|
|
typedef struct b2DistanceOutput
|
|
{
|
|
b2Vec2 pointA; ///< Closest point on shapeA
|
|
b2Vec2 pointB; ///< Closest point on shapeB
|
|
b2Vec2 normal; ///< Normal vector that points from A to B. Invalid if distance is zero.
|
|
float distance; ///< The final distance, zero if overlapped
|
|
int iterations; ///< Number of GJK iterations used
|
|
int simplexCount; ///< The number of simplexes stored in the simplex array
|
|
} b2DistanceOutput;
|
|
|
|
/// Simplex vertex for debugging the GJK algorithm
|
|
typedef struct b2SimplexVertex
|
|
{
|
|
b2Vec2 wA; ///< support point in proxyA
|
|
b2Vec2 wB; ///< support point in proxyB
|
|
b2Vec2 w; ///< wB - wA
|
|
float a; ///< barycentric coordinate for closest point
|
|
int indexA; ///< wA index
|
|
int indexB; ///< wB index
|
|
} b2SimplexVertex;
|
|
|
|
/// Simplex from the GJK algorithm
|
|
typedef struct b2Simplex
|
|
{
|
|
b2SimplexVertex v1, v2, v3; ///< vertices
|
|
int count; ///< number of valid vertices
|
|
} b2Simplex;
|
|
|
|
/// Compute the closest points between two shapes represented as point clouds.
|
|
/// b2SimplexCache cache is input/output. On the first call set b2SimplexCache.count to zero.
|
|
/// The underlying GJK algorithm may be debugged by passing in debug simplexes and capacity. You may pass in NULL and 0 for these.
|
|
B2_API b2DistanceOutput b2ShapeDistance( const b2DistanceInput* input, b2SimplexCache* cache, b2Simplex* simplexes,
|
|
int simplexCapacity );
|
|
|
|
/// Input parameters for b2ShapeCast
|
|
typedef struct b2ShapeCastPairInput
|
|
{
|
|
b2ShapeProxy proxyA; ///< The proxy for shape A
|
|
b2ShapeProxy proxyB; ///< The proxy for shape B
|
|
b2Transform transformA; ///< The world transform for shape A
|
|
b2Transform transformB; ///< The world transform for shape B
|
|
b2Vec2 translationB; ///< The translation of shape B
|
|
float maxFraction; ///< The fraction of the translation to consider, typically 1
|
|
bool canEncroach; ///< Allows shapes with a radius to move slightly closer if already touching
|
|
} b2ShapeCastPairInput;
|
|
|
|
/// Perform a linear shape cast of shape B moving and shape A fixed. Determines the hit point, normal, and translation fraction.
|
|
/// Initially touching shapes are treated as a miss.
|
|
B2_API b2CastOutput b2ShapeCast( const b2ShapeCastPairInput* input );
|
|
|
|
/// Make a proxy for use in overlap, shape cast, and related functions. This is a deep copy of the points.
|
|
B2_API b2ShapeProxy b2MakeProxy( const b2Vec2* points, int count, float radius );
|
|
|
|
/// Make a proxy with a transform. This is a deep copy of the points.
|
|
B2_API b2ShapeProxy b2MakeOffsetProxy( const b2Vec2* points, int count, float radius, b2Vec2 position, b2Rot rotation );
|
|
|
|
/// This describes the motion of a body/shape for TOI computation. Shapes are defined with respect to the body origin,
|
|
/// which may not coincide with the center of mass. However, to support dynamics we must interpolate the center of mass
|
|
/// position.
|
|
typedef struct b2Sweep
|
|
{
|
|
b2Vec2 localCenter; ///< Local center of mass position
|
|
b2Vec2 c1; ///< Starting center of mass world position
|
|
b2Vec2 c2; ///< Ending center of mass world position
|
|
b2Rot q1; ///< Starting world rotation
|
|
b2Rot q2; ///< Ending world rotation
|
|
} b2Sweep;
|
|
|
|
/// Evaluate the transform sweep at a specific time.
|
|
B2_API b2Transform b2GetSweepTransform( const b2Sweep* sweep, float time );
|
|
|
|
/// Input parameters for b2TimeOfImpact
|
|
typedef struct b2TOIInput
|
|
{
|
|
b2ShapeProxy proxyA; ///< The proxy for shape A
|
|
b2ShapeProxy proxyB; ///< The proxy for shape B
|
|
b2Sweep sweepA; ///< The movement of shape A
|
|
b2Sweep sweepB; ///< The movement of shape B
|
|
float maxFraction; ///< Defines the sweep interval [0, maxFraction]
|
|
} b2TOIInput;
|
|
|
|
/// Describes the TOI output
|
|
typedef enum b2TOIState
|
|
{
|
|
b2_toiStateUnknown,
|
|
b2_toiStateFailed,
|
|
b2_toiStateOverlapped,
|
|
b2_toiStateHit,
|
|
b2_toiStateSeparated
|
|
} b2TOIState;
|
|
|
|
/// Output parameters for b2TimeOfImpact.
|
|
typedef struct b2TOIOutput
|
|
{
|
|
b2TOIState state; ///< The type of result
|
|
float fraction; ///< The sweep time of the collision
|
|
} b2TOIOutput;
|
|
|
|
/// 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 collisions. If you change the time interval, you should call this function
|
|
/// again.
|
|
B2_API b2TOIOutput b2TimeOfImpact( const b2TOIInput* input );
|
|
|
|
/**@}*/
|
|
|
|
/**
|
|
* @defgroup collision Collision
|
|
* @brief Functions for colliding pairs of shapes
|
|
* @{
|
|
*/
|
|
|
|
/// 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.
|
|
/// Box2D uses speculative collision so some contact points may be separated.
|
|
/// You may use the totalNormalImpulse to determine if there was an interaction during
|
|
/// the time step.
|
|
typedef struct b2ManifoldPoint
|
|
{
|
|
/// Location of the contact point in world space. Subject to precision loss at large coordinates.
|
|
/// @note Should only be used for debugging.
|
|
b2Vec2 point;
|
|
|
|
/// Location of the contact point relative to shapeA's origin in world space
|
|
/// @note When used internally to the Box2D solver, this is relative to the body center of mass.
|
|
b2Vec2 anchorA;
|
|
|
|
/// Location of the contact point relative to shapeB's origin in world space
|
|
/// @note When used internally to the Box2D solver, this is relative to the body center of mass.
|
|
b2Vec2 anchorB;
|
|
|
|
/// The separation of the contact point, negative if penetrating
|
|
float separation;
|
|
|
|
/// The impulse along the manifold normal vector.
|
|
float normalImpulse;
|
|
|
|
/// The friction impulse
|
|
float tangentImpulse;
|
|
|
|
/// The total normal impulse applied across sub-stepping and restitution. This is important
|
|
/// to identify speculative contact points that had an interaction in the time step.
|
|
float totalNormalImpulse;
|
|
|
|
/// Relative normal velocity pre-solve. Used for hit events. If the normal impulse is
|
|
/// zero then there was no hit. Negative means shapes are approaching.
|
|
float normalVelocity;
|
|
|
|
/// Uniquely identifies a contact point between two shapes
|
|
uint16_t id;
|
|
|
|
/// Did this contact point exist the previous step?
|
|
bool persisted;
|
|
} b2ManifoldPoint;
|
|
|
|
/// A contact manifold describes the contact points between colliding shapes.
|
|
/// @note Box2D uses speculative collision so some contact points may be separated.
|
|
typedef struct b2Manifold
|
|
{
|
|
/// The unit normal vector in world space, points from shape A to bodyB
|
|
b2Vec2 normal;
|
|
|
|
/// Angular impulse applied for rolling resistance. N * m * s = kg * m^2 / s
|
|
float rollingImpulse;
|
|
|
|
/// The manifold points, up to two are possible in 2D
|
|
b2ManifoldPoint points[2];
|
|
|
|
/// The number of contacts points, will be 0, 1, or 2
|
|
int pointCount;
|
|
|
|
} b2Manifold;
|
|
|
|
/// Compute the contact manifold between two circles
|
|
B2_API b2Manifold b2CollideCircles( const b2Circle* circleA, b2Transform xfA, const b2Circle* circleB, b2Transform xfB );
|
|
|
|
/// Compute the contact manifold between a capsule and circle
|
|
B2_API b2Manifold b2CollideCapsuleAndCircle( const b2Capsule* capsuleA, b2Transform xfA, const b2Circle* circleB,
|
|
b2Transform xfB );
|
|
|
|
/// Compute the contact manifold between an segment and a circle
|
|
B2_API b2Manifold b2CollideSegmentAndCircle( const b2Segment* segmentA, b2Transform xfA, const b2Circle* circleB,
|
|
b2Transform xfB );
|
|
|
|
/// Compute the contact manifold between a polygon and a circle
|
|
B2_API b2Manifold b2CollidePolygonAndCircle( const b2Polygon* polygonA, b2Transform xfA, const b2Circle* circleB,
|
|
b2Transform xfB );
|
|
|
|
/// Compute the contact manifold between a capsule and circle
|
|
B2_API b2Manifold b2CollideCapsules( const b2Capsule* capsuleA, b2Transform xfA, const b2Capsule* capsuleB, b2Transform xfB );
|
|
|
|
/// Compute the contact manifold between an segment and a capsule
|
|
B2_API b2Manifold b2CollideSegmentAndCapsule( const b2Segment* segmentA, b2Transform xfA, const b2Capsule* capsuleB,
|
|
b2Transform xfB );
|
|
|
|
/// Compute the contact manifold between a polygon and capsule
|
|
B2_API b2Manifold b2CollidePolygonAndCapsule( const b2Polygon* polygonA, b2Transform xfA, const b2Capsule* capsuleB,
|
|
b2Transform xfB );
|
|
|
|
/// Compute the contact manifold between two polygons
|
|
B2_API b2Manifold b2CollidePolygons( const b2Polygon* polygonA, b2Transform xfA, const b2Polygon* polygonB, b2Transform xfB );
|
|
|
|
/// Compute the contact manifold between an segment and a polygon
|
|
B2_API b2Manifold b2CollideSegmentAndPolygon( const b2Segment* segmentA, b2Transform xfA, const b2Polygon* polygonB,
|
|
b2Transform xfB );
|
|
|
|
/// Compute the contact manifold between a chain segment and a circle
|
|
B2_API b2Manifold b2CollideChainSegmentAndCircle( const b2ChainSegment* segmentA, b2Transform xfA, const b2Circle* circleB,
|
|
b2Transform xfB );
|
|
|
|
/// Compute the contact manifold between a chain segment and a capsule
|
|
B2_API b2Manifold b2CollideChainSegmentAndCapsule( const b2ChainSegment* segmentA, b2Transform xfA, const b2Capsule* capsuleB,
|
|
b2Transform xfB, b2SimplexCache* cache );
|
|
|
|
/// Compute the contact manifold between a chain segment and a rounded polygon
|
|
B2_API b2Manifold b2CollideChainSegmentAndPolygon( const b2ChainSegment* segmentA, b2Transform xfA, const b2Polygon* polygonB,
|
|
b2Transform xfB, b2SimplexCache* cache );
|
|
|
|
/**@}*/
|
|
|
|
/**
|
|
* @defgroup tree Dynamic Tree
|
|
* The dynamic tree is a binary AABB tree to organize and query large numbers of geometric objects
|
|
*
|
|
* Box2D uses the dynamic tree internally to sort collision shapes into a binary bounding volume hierarchy.
|
|
* This data structure may have uses in games for organizing other geometry data and may be used independently
|
|
* of Box2D rigid body simulation.
|
|
*
|
|
* 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 AABB queries and ray casts. Leaf nodes are proxies
|
|
* with an AABB. These are used to hold a user collision object.
|
|
* Nodes are pooled and relocatable, so I use node indices rather than pointers.
|
|
* The dynamic tree is made available for advanced users that would like to use it to organize
|
|
* spatial game data besides rigid bodies.
|
|
* @{
|
|
*/
|
|
|
|
/// The dynamic tree structure. This should be considered private data.
|
|
/// It is placed here for performance reasons.
|
|
typedef struct b2DynamicTree
|
|
{
|
|
/// The tree nodes
|
|
struct b2TreeNode* nodes;
|
|
|
|
/// The root index
|
|
int root;
|
|
|
|
/// The number of nodes
|
|
int nodeCount;
|
|
|
|
/// The allocated node space
|
|
int nodeCapacity;
|
|
|
|
/// Node free list
|
|
int freeList;
|
|
|
|
/// Number of proxies created
|
|
int proxyCount;
|
|
|
|
/// Leaf indices for rebuild
|
|
int* leafIndices;
|
|
|
|
/// Leaf bounding boxes for rebuild
|
|
b2AABB* leafBoxes;
|
|
|
|
/// Leaf bounding box centers for rebuild
|
|
b2Vec2* leafCenters;
|
|
|
|
/// Bins for sorting during rebuild
|
|
int* binIndices;
|
|
|
|
/// Allocated space for rebuilding
|
|
int rebuildCapacity;
|
|
} b2DynamicTree;
|
|
|
|
/// These are performance results returned by dynamic tree queries.
|
|
typedef struct b2TreeStats
|
|
{
|
|
/// Number of internal nodes visited during the query
|
|
int nodeVisits;
|
|
|
|
/// Number of leaf nodes visited during the query
|
|
int leafVisits;
|
|
} b2TreeStats;
|
|
|
|
/// Constructing the tree initializes the node pool.
|
|
B2_API b2DynamicTree b2DynamicTree_Create( void );
|
|
|
|
/// Destroy the tree, freeing the node pool.
|
|
B2_API void b2DynamicTree_Destroy( b2DynamicTree* tree );
|
|
|
|
/// Create a proxy. Provide an AABB and a userData value.
|
|
B2_API int b2DynamicTree_CreateProxy( b2DynamicTree* tree, b2AABB aabb, uint64_t categoryBits, uint64_t userData );
|
|
|
|
/// Destroy a proxy. This asserts if the id is invalid.
|
|
B2_API void b2DynamicTree_DestroyProxy( b2DynamicTree* tree, int proxyId );
|
|
|
|
/// Move a proxy to a new AABB by removing and reinserting into the tree.
|
|
B2_API void b2DynamicTree_MoveProxy( b2DynamicTree* tree, int proxyId, b2AABB aabb );
|
|
|
|
/// Enlarge a proxy and enlarge ancestors as necessary.
|
|
B2_API void b2DynamicTree_EnlargeProxy( b2DynamicTree* tree, int proxyId, b2AABB aabb );
|
|
|
|
/// Modify the category bits on a proxy. This is an expensive operation.
|
|
B2_API void b2DynamicTree_SetCategoryBits( b2DynamicTree* tree, int proxyId, uint64_t categoryBits );
|
|
|
|
/// Get the category bits on a proxy.
|
|
B2_API uint64_t b2DynamicTree_GetCategoryBits( b2DynamicTree* tree, int proxyId );
|
|
|
|
/// This function receives proxies found in the AABB query.
|
|
/// @return true if the query should continue
|
|
typedef bool b2TreeQueryCallbackFcn( int proxyId, uint64_t userData, void* context );
|
|
|
|
/// Query an AABB for overlapping proxies. The callback class is called for each proxy that overlaps the supplied AABB.
|
|
/// @return performance data
|
|
B2_API b2TreeStats b2DynamicTree_Query( const b2DynamicTree* tree, b2AABB aabb, uint64_t maskBits,
|
|
b2TreeQueryCallbackFcn* callback, void* context );
|
|
|
|
/// This function receives clipped ray cast input for a proxy. The function
|
|
/// returns the new ray fraction.
|
|
/// - return a value of 0 to terminate the ray cast
|
|
/// - return a value less than input->maxFraction to clip the ray
|
|
/// - return a value of input->maxFraction to continue the ray cast without clipping
|
|
typedef float b2TreeRayCastCallbackFcn( const b2RayCastInput* input, int proxyId, uint64_t userData, void* context );
|
|
|
|
/// 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.
|
|
/// Bit-wise filtering using mask bits can greatly improve performance in some scenarios.
|
|
/// However, this filtering may be approximate, so the user should still apply filtering to results.
|
|
/// @param tree the dynamic tree to ray cast
|
|
/// @param input the ray cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1)
|
|
/// @param maskBits mask bit hint: `bool accept = (maskBits & node->categoryBits) != 0;`
|
|
/// @param callback a callback class that is called for each proxy that is hit by the ray
|
|
/// @param context user context that is passed to the callback
|
|
/// @return performance data
|
|
B2_API b2TreeStats b2DynamicTree_RayCast( const b2DynamicTree* tree, const b2RayCastInput* input, uint64_t maskBits,
|
|
b2TreeRayCastCallbackFcn* callback, void* context );
|
|
|
|
/// This function receives clipped ray cast input for a proxy. The function
|
|
/// returns the new ray fraction.
|
|
/// - return a value of 0 to terminate the ray cast
|
|
/// - return a value less than input->maxFraction to clip the ray
|
|
/// - return a value of input->maxFraction to continue the ray cast without clipping
|
|
typedef float b2TreeShapeCastCallbackFcn( const b2ShapeCastInput* input, int proxyId, uint64_t userData, void* context );
|
|
|
|
/// 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 tree the dynamic tree to ray cast
|
|
/// @param input the ray cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
|
|
/// @param maskBits filter bits: `bool accept = (maskBits & node->categoryBits) != 0;`
|
|
/// @param callback a callback class that is called for each proxy that is hit by the shape
|
|
/// @param context user context that is passed to the callback
|
|
/// @return performance data
|
|
B2_API b2TreeStats b2DynamicTree_ShapeCast( const b2DynamicTree* tree, const b2ShapeCastInput* input, uint64_t maskBits,
|
|
b2TreeShapeCastCallbackFcn* callback, void* context );
|
|
|
|
/// Get the height of the binary tree.
|
|
B2_API int b2DynamicTree_GetHeight( const b2DynamicTree* tree );
|
|
|
|
/// Get the ratio of the sum of the node areas to the root area.
|
|
B2_API float b2DynamicTree_GetAreaRatio( const b2DynamicTree* tree );
|
|
|
|
/// Get the bounding box that contains the entire tree
|
|
B2_API b2AABB b2DynamicTree_GetRootBounds( const b2DynamicTree* tree );
|
|
|
|
/// Get the number of proxies created
|
|
B2_API int b2DynamicTree_GetProxyCount( const b2DynamicTree* tree );
|
|
|
|
/// Rebuild the tree while retaining subtrees that haven't changed. Returns the number of boxes sorted.
|
|
B2_API int b2DynamicTree_Rebuild( b2DynamicTree* tree, bool fullBuild );
|
|
|
|
/// Get the number of bytes used by this tree
|
|
B2_API int b2DynamicTree_GetByteCount( const b2DynamicTree* tree );
|
|
|
|
/// Get proxy user data
|
|
B2_API uint64_t b2DynamicTree_GetUserData( const b2DynamicTree* tree, int proxyId );
|
|
|
|
/// Get the AABB of a proxy
|
|
B2_API b2AABB b2DynamicTree_GetAABB( const b2DynamicTree* tree, int proxyId );
|
|
|
|
/// Validate this tree. For testing.
|
|
B2_API void b2DynamicTree_Validate( const b2DynamicTree* tree );
|
|
|
|
/// Validate this tree has no enlarged AABBs. For testing.
|
|
B2_API void b2DynamicTree_ValidateNoEnlarged( const b2DynamicTree* tree );
|
|
|
|
/**@}*/
|
|
|
|
/**
|
|
* @defgroup character Character mover
|
|
* Character movement solver
|
|
* @{
|
|
*/
|
|
|
|
/// These are the collision planes returned from b2World_CollideMover
|
|
typedef struct b2PlaneResult
|
|
{
|
|
/// The collision plane between the mover and a convex shape
|
|
b2Plane plane;
|
|
|
|
// The collision point on the shape.
|
|
b2Vec2 point;
|
|
|
|
/// Did the collision register a hit? If not this plane should be ignored.
|
|
bool hit;
|
|
} b2PlaneResult;
|
|
|
|
/// These are collision planes that can be fed to b2SolvePlanes. Normally
|
|
/// this is assembled by the user from plane results in b2PlaneResult
|
|
typedef struct b2CollisionPlane
|
|
{
|
|
/// The collision plane between the mover and some shape
|
|
b2Plane plane;
|
|
|
|
/// Setting this to FLT_MAX makes the plane as rigid as possible. Lower values can
|
|
/// make the plane collision soft. Usually in meters.
|
|
float pushLimit;
|
|
|
|
/// The push on the mover determined by b2SolvePlanes. Usually in meters.
|
|
float push;
|
|
|
|
/// Indicates if b2ClipVector should clip against this plane. Should be false for soft collision.
|
|
bool clipVelocity;
|
|
} b2CollisionPlane;
|
|
|
|
/// Result returned by b2SolvePlanes
|
|
typedef struct b2PlaneSolverResult
|
|
{
|
|
/// The translation of the mover
|
|
b2Vec2 translation;
|
|
|
|
/// The number of iterations used by the plane solver. For diagnostics.
|
|
int iterationCount;
|
|
} b2PlaneSolverResult;
|
|
|
|
/// Solves the position of a mover that satisfies the given collision planes.
|
|
/// @param targetDelta the desired movement from the position used to generate the collision planes
|
|
/// @param planes the collision planes
|
|
/// @param count the number of collision planes
|
|
B2_API b2PlaneSolverResult b2SolvePlanes( b2Vec2 targetDelta, b2CollisionPlane* planes, int count );
|
|
|
|
/// Clips the velocity against the given collision planes. Planes with zero push or clipVelocity
|
|
/// set to false are skipped.
|
|
B2_API b2Vec2 b2ClipVector( b2Vec2 vector, const b2CollisionPlane* planes, int count );
|
|
|
|
/**@}*/
|