power_play/src/collider/collider.h
2025-10-22 03:22:23 -05:00

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);