218 lines
5.9 KiB
C
218 lines
5.9 KiB
C
////////////////////////////////////////////////////////////
|
|
//~ Tweakable defines
|
|
|
|
/* How close can non-overlapping shapes be before collision is considered */
|
|
#define CLD_CollisionTolerance 0.005f
|
|
|
|
/* NOTE: Should always be less than tolerance, since colliding = 1 if origin is within this distance. */
|
|
#define CLD_MinUniquePtDistSq (0.001f * 0.001f)
|
|
|
|
/* To prevent extremely large prototypes when origin is in exact center of rounded feature */
|
|
#define CLD_MaxEpaIterations 64
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Shape types
|
|
|
|
Struct(CLD_Shape)
|
|
{
|
|
Vec2 points[8];
|
|
u32 count;
|
|
f32 radius;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Menkowski types
|
|
|
|
Struct(CLD_SupportPoint)
|
|
{
|
|
Vec2 p;
|
|
u32 i; /* Index of original point in shape */
|
|
};
|
|
|
|
Struct(CLD_MenkowskiPoint)
|
|
{
|
|
Vec2 p; /* Menkowski difference point */
|
|
CLD_SupportPoint s0; /* Support point of first shape in dir */
|
|
CLD_SupportPoint s1; /* Support point of second shape in -dir */
|
|
};
|
|
|
|
Struct(CLD_MenkowskiSimplex)
|
|
{
|
|
u32 len;
|
|
CLD_MenkowskiPoint a, b, c;
|
|
};
|
|
|
|
Struct(CLD_MenkowskiFeature)
|
|
{
|
|
u32 len;
|
|
CLD_MenkowskiPoint a, b;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Collision types
|
|
|
|
Struct(CLD_CollisionPoint)
|
|
{
|
|
Vec2 point;
|
|
f32 separation;
|
|
u32 id; /* Based on polygon edge-to-edge */
|
|
};
|
|
|
|
Struct(CLD_Prototype)
|
|
{
|
|
Vec2 points[64];
|
|
u32 len;
|
|
};
|
|
|
|
Struct(CLD_CollisionData)
|
|
{
|
|
Vec2 normal;
|
|
CLD_CollisionPoint points[2];
|
|
u32 num_points;
|
|
|
|
/* For debugging */
|
|
b32 solved;
|
|
CLD_MenkowskiSimplex simplex;
|
|
CLD_Prototype prototype;
|
|
|
|
/* For debugging */
|
|
Vec2 a0, b0, a1, b1;
|
|
Vec2 a0_clipped, b0_clipped, a1_clipped, b1_clipped;
|
|
};
|
|
|
|
Struct(CLD_ClosestPointData)
|
|
{
|
|
Vec2 p0, p1;
|
|
b32 colliding;
|
|
|
|
/* For debugging */
|
|
b32 solved;
|
|
CLD_MenkowskiSimplex simplex;
|
|
CLD_Prototype prototype;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Clipping types
|
|
|
|
Struct(CLD_ClippedLine)
|
|
{
|
|
Vec2 a0_clipped, b0_clipped;
|
|
Vec2 a1_clipped, b1_clipped;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Gjk types
|
|
|
|
Struct(CLD_GjkData)
|
|
{
|
|
CLD_MenkowskiSimplex simplex;
|
|
Vec2 final_dir;
|
|
|
|
/* If 1, simplex represents triangle inside of CLD_Menkowski difference
|
|
* encapsulating the origin. If 0, simplex represents the closest
|
|
* feature on CLD_Menkowski difference to the origin. */
|
|
b32 overlapping;
|
|
|
|
#if COLLIDER_DEBUG
|
|
u32 dbg_step;
|
|
#endif
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Epa types
|
|
|
|
Struct(CLD_EpaData)
|
|
{
|
|
Vec2 normal;
|
|
CLD_MenkowskiFeature closest_feature; /* Represents closest feature (edge or point) to origin on CLD_Menkowski difference */
|
|
|
|
#if COLLIDER_DEBUG
|
|
CLD_Prototype prototype;
|
|
u32 dbg_step;
|
|
#endif
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Debug helpers
|
|
|
|
#if COLLIDER_DEBUG
|
|
void CLD_DebugBreakable(void);
|
|
|
|
#define CLD_DBGSTEP \
|
|
dbg_step++; \
|
|
if (dbg_step >= GetGstat(GSTAT_DEBUG_STEPS)) \
|
|
{ \
|
|
goto abort; \
|
|
} \
|
|
else if (dbg_step >= GetGstat(GSTAT_DEBUG_STEPS) - 1) \
|
|
{ \
|
|
CLD_DebugBreakable(); \
|
|
} (void)0
|
|
#else
|
|
#define CLD_DBGSTEP
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Shape operations
|
|
|
|
CLD_Shape CLD_ShapeFromQuad(Quad quad);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Menkowski operations
|
|
|
|
CLD_SupportPoint CLD_SupportPointFromDirEx(CLD_Shape *shape, Xform xf, Vec2 dir, i32 ignore);
|
|
CLD_SupportPoint CLD_SupportPointFromDir(CLD_Shape *shape, Xform xf, Vec2 dir);
|
|
CLD_MenkowskiPoint CLD_MenkowskiPointFromDir(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, Vec2 dir);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Aabb operations
|
|
|
|
Aabb CLD_AabbFromShape(CLD_Shape *shape, Xform xf);
|
|
Aabb CLD_CombineAabb(Aabb b0, Aabb b1);
|
|
b32 CLD_TestAabb(Aabb box0, Aabb box1);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Gjk operations
|
|
|
|
#if COLLIDER_DEBUG
|
|
CLD_GjkData CLD_GjkDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, f32 min_unique_pt_dist_sq, u32 dbg_step);
|
|
#else
|
|
CLD_GjkData CLD_GjkDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, f32 min_unique_pt_dist_sq);
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Epa operations
|
|
|
|
#if COLLIDER_DEBUG
|
|
CLD_EpaData CLD_EpaDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, CLD_GjkData gjk_result, f32 min_unique_pt_dist_sq, u32 max_iterations, u32 dbg_step);
|
|
#else
|
|
CLD_EpaData CLD_EpaDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, CLD_GjkData gjk_result, f32 min_unique_pt_dist_sq, u32 max_iterations);
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Clipping operations
|
|
|
|
CLD_ClippedLine CLD_ClipLineToLine(Vec2 a0, Vec2 b0, Vec2 a1, Vec2 b1, Vec2 normal);
|
|
Vec2 CLD_ClipPointToLine(Vec2 a, Vec2 b, Vec2 p, Vec2 normal);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Collision point operations
|
|
|
|
CLD_CollisionData CLD_CollisionDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Closest point operations
|
|
|
|
CLD_ClosestPointData CLD_ClosestPointDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Time of impact operations
|
|
|
|
f32 CLD_TimeOfImpact(CLD_Shape *c0, CLD_Shape *c1, Xform xf0_t0, Xform xf1_t0, Xform xf0_t1, Xform xf1_t1, f32 tolerance, u32 max_iterations);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Point cloud debugging operations
|
|
|
|
Vec2Array CLD_Menkowski(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, u32 detail);
|
|
Vec2Array CLD_PointCloud(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1);
|