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