collider layer refactor
This commit is contained in:
parent
9731a5742a
commit
3d863022fb
@ -160,7 +160,7 @@ void P_AppStartup(String args_str)
|
||||
|
||||
#if !RtcIsEnabled
|
||||
/* Verify test modes aren't left on by accident in release mode */
|
||||
StaticAssert(BB_DebugIsEnabled == 0);
|
||||
StaticAssert(BITBUFF_DEBUG == 0);
|
||||
StaticAssert(BITBUFF_TEST == 0);
|
||||
#endif
|
||||
|
||||
|
||||
@ -1,3 +1,82 @@
|
||||
////////////////////////////////
|
||||
//~ Sheet types
|
||||
|
||||
Struct(Ase_Slice)
|
||||
{
|
||||
u32 start;
|
||||
i32 x1;
|
||||
i32 y1;
|
||||
i32 x2;
|
||||
i32 y2;
|
||||
Ase_Slice *next;
|
||||
};
|
||||
|
||||
Struct(Ase_SliceKey)
|
||||
{
|
||||
String name;
|
||||
u32 num_slices;
|
||||
Ase_Slice *slice_head;
|
||||
Ase_SliceKey *next;
|
||||
};
|
||||
|
||||
Struct(Ase_Span)
|
||||
{
|
||||
String name;
|
||||
u32 start;
|
||||
u32 end;
|
||||
Ase_Span *next;
|
||||
};
|
||||
|
||||
Struct(Ase_Frame)
|
||||
{
|
||||
u32 index;
|
||||
u32 x1;
|
||||
u32 y1;
|
||||
u32 x2;
|
||||
u32 y2;
|
||||
f64 duration;
|
||||
Ase_Frame *next;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ Decoder result types
|
||||
|
||||
Struct(Ase_Error)
|
||||
{
|
||||
String msg;
|
||||
Ase_Error *next;
|
||||
};
|
||||
|
||||
Struct(Ase_ErrorList)
|
||||
{
|
||||
u64 count;
|
||||
Ase_Error *first;
|
||||
Ase_Error *last;
|
||||
};
|
||||
|
||||
Struct(Ase_DecodedImage)
|
||||
{
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 *pixels; /* Array of [width * height] pixels */
|
||||
Ase_ErrorList errors;
|
||||
b32 success;
|
||||
};
|
||||
|
||||
Struct(Ase_DecodedSheet)
|
||||
{
|
||||
Vec2 image_size;
|
||||
Vec2 frame_size;
|
||||
u32 num_frames;
|
||||
u32 num_spans;
|
||||
u32 num_slice_keys;
|
||||
Ase_Frame *frame_head;
|
||||
Ase_Span *span_head;
|
||||
Ase_SliceKey *slice_key_head;
|
||||
Ase_ErrorList errors;
|
||||
b32 success;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ Inflator types
|
||||
|
||||
@ -131,88 +210,6 @@ Struct(Ace_Cel)
|
||||
Ace_Cel *next;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ Error types
|
||||
|
||||
Struct(Ase_Error)
|
||||
{
|
||||
String msg;
|
||||
Ase_Error *next;
|
||||
};
|
||||
|
||||
Struct(Ase_ErrorList)
|
||||
{
|
||||
u64 count;
|
||||
Ase_Error *first;
|
||||
Ase_Error *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ Sheet types
|
||||
|
||||
Struct(Ase_Slice)
|
||||
{
|
||||
u32 start;
|
||||
i32 x1;
|
||||
i32 y1;
|
||||
i32 x2;
|
||||
i32 y2;
|
||||
Ase_Slice *next;
|
||||
};
|
||||
|
||||
Struct(Ase_SliceKey)
|
||||
{
|
||||
String name;
|
||||
u32 num_slices;
|
||||
Ase_Slice *slice_head;
|
||||
Ase_SliceKey *next;
|
||||
};
|
||||
|
||||
Struct(Ase_Span)
|
||||
{
|
||||
String name;
|
||||
u32 start;
|
||||
u32 end;
|
||||
Ase_Span *next;
|
||||
};
|
||||
|
||||
Struct(Ase_Frame)
|
||||
{
|
||||
u32 index;
|
||||
u32 x1;
|
||||
u32 y1;
|
||||
u32 x2;
|
||||
u32 y2;
|
||||
f64 duration;
|
||||
Ase_Frame *next;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ Decoder result types
|
||||
|
||||
Struct(Ase_DecodedImage)
|
||||
{
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 *pixels; /* Array of [width * height] pixels */
|
||||
Ase_ErrorList errors;
|
||||
b32 success;
|
||||
};
|
||||
|
||||
Struct(Ase_DecodedSheet)
|
||||
{
|
||||
Vec2 image_size;
|
||||
Vec2 frame_size;
|
||||
u32 num_frames;
|
||||
u32 num_spans;
|
||||
u32 num_slice_keys;
|
||||
Ase_Frame *frame_head;
|
||||
Ase_Span *span_head;
|
||||
Ase_SliceKey *slice_key_head;
|
||||
Ase_ErrorList errors;
|
||||
b32 success;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ Ase bitbuff operations
|
||||
|
||||
@ -231,12 +228,8 @@ void Ase_Inflate(u8 *dst, u8 *encoded);
|
||||
////////////////////////////////
|
||||
//~ Error handling operations
|
||||
|
||||
void Ase_PushError(Arena *arena, Ase_ErrorList *list, String msg_src);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Decoder operations
|
||||
|
||||
//- Helpers
|
||||
void Ase_PushError(Arena *arena, Ase_ErrorList *list, String msg_src);
|
||||
u32 Ase_BlendMulU8(u32 a, u32 b);
|
||||
u32 Ase_Blend(u32 src, u32 dst, u8 opacity);
|
||||
void Ase_MakeDimensionsSquareish(Ase_Header *header, u32 *frames_x, u32 *frames_y, u64 *image_width, u64 *image_height);
|
||||
|
||||
@ -10,7 +10,7 @@ Struct(Vec2) {
|
||||
f32 x, y;
|
||||
};
|
||||
|
||||
Struct(V2Array) {
|
||||
Struct(Vec2Array) {
|
||||
Vec2 *points;
|
||||
u64 count;
|
||||
};
|
||||
@ -22,7 +22,7 @@ Struct(Vec3) {
|
||||
f32 x, y, z;
|
||||
};
|
||||
|
||||
Struct(V3Array) {
|
||||
Struct(Vec3Array) {
|
||||
Vec3 *points;
|
||||
u64 count;
|
||||
};
|
||||
@ -34,7 +34,7 @@ Struct(Vec4) {
|
||||
f32 x, y, z, w;
|
||||
};
|
||||
|
||||
Struct(V4Array) {
|
||||
Struct(Vec4Array) {
|
||||
Vec4 *points;
|
||||
u64 count;
|
||||
};
|
||||
|
||||
@ -43,7 +43,7 @@ BB_Writer BB_WriterFromBuff(BB_Buff *bb)
|
||||
result.base = bb->fixed_buffer.text;
|
||||
}
|
||||
result.cur_bit = 0;
|
||||
#if BB_DebugIsEnabled
|
||||
#if BITBUFF_DEBUG
|
||||
result.debug_enabled = 1;
|
||||
#endif
|
||||
return result;
|
||||
@ -53,7 +53,7 @@ BB_Writer BB_WriterFromBuff(BB_Buff *bb)
|
||||
BB_Writer BB_WriterFromBuffNoDebug(BB_Buff *bb)
|
||||
{
|
||||
BB_Writer result = BB_WriterFromBuff(bb);
|
||||
#if BB_DebugIsEnabled
|
||||
#if BITBUFF_DEBUG
|
||||
result.debug_enabled = 0;
|
||||
#endif
|
||||
return result;
|
||||
@ -131,7 +131,7 @@ b32 BB_CheckWriterOverflowBits(BB_Writer *bw, u64 num_bits)
|
||||
/* Align the pos to the next byte */
|
||||
void BB_AlignWriter(BB_Writer *bw)
|
||||
{
|
||||
#if BB_DebugIsEnabled
|
||||
#if BITBUFF_DEBUG
|
||||
if ((bw->cur_bit & 7) != 0)
|
||||
{
|
||||
BB_WriteDebugMagic(bw, BB_DebugMagicKind_Align, 0);
|
||||
@ -317,7 +317,7 @@ void BB_WriteBytes(BB_Writer *bw, String bytes)
|
||||
////////////////////////////////
|
||||
//~ Writer debug
|
||||
|
||||
#if BB_DebugIsEnabled
|
||||
#if BITBUFF_DEBUG
|
||||
void BB_WriteDebugMarker(BB_Writer *bw, String name)
|
||||
{
|
||||
bw->cur_bit += (8 - (bw->cur_bit & 7)) & 7;
|
||||
@ -359,7 +359,7 @@ BB_Reader BB_ReaderFromBuff(BB_Buff *bb)
|
||||
result.base_len = arena->pos;
|
||||
}
|
||||
result.cur_bit = 0;
|
||||
#if BB_DebugIsEnabled
|
||||
#if BITBUFF_DEBUG
|
||||
result.debug_enabled = 1;
|
||||
#endif
|
||||
return result;
|
||||
@ -369,7 +369,7 @@ BB_Reader BB_ReaderFromBuff(BB_Buff *bb)
|
||||
BB_Reader BB_ReaderFromBuffNoDebug(BB_Buff *bb)
|
||||
{
|
||||
BB_Reader result = BB_ReaderFromBuff(bb);
|
||||
#if BB_DebugIsEnabled
|
||||
#if BITBUFF_DEBUG
|
||||
result.debug_enabled = 0;
|
||||
#endif
|
||||
return result;
|
||||
@ -432,7 +432,7 @@ b32 BB_CheckReaderOverflowBits(BB_Reader *br, u64 num_bits)
|
||||
/* Align the pos to the next byte */
|
||||
void BB_AlignReader(BB_Reader *br)
|
||||
{
|
||||
#if BB_DebugIsEnabled
|
||||
#if BITBUFF_DEBUG
|
||||
if ((br->cur_bit & 7) != 0)
|
||||
{
|
||||
BB_ReadDebugMagic(br, BB_DebugMagicKind_Align, 0);
|
||||
@ -676,7 +676,7 @@ void BB_SeekToByte(BB_Reader *br, u64 pos)
|
||||
////////////////////////////////
|
||||
//~ Reader debug
|
||||
|
||||
#if BB_DebugIsEnabled
|
||||
#if BITBUFF_DEBUG
|
||||
|
||||
void BB_ReadDebugMagic(BB_Reader *br, BB_DebugMagicKind expected_magic, u8 expected_num_bits)
|
||||
{
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
////////////////////////////////
|
||||
//~ Bitbuff types
|
||||
|
||||
#define BB_DebugIsEnabled DebugBitbuff
|
||||
|
||||
//- Buff
|
||||
Struct(BB_Buff)
|
||||
{
|
||||
@ -24,7 +22,7 @@ Struct(BB_Writer)
|
||||
BB_Buff *bb;
|
||||
u8 *base;
|
||||
u64 cur_bit;
|
||||
#if BB_DebugIsEnabled
|
||||
#if BITBUFF_DEBUG
|
||||
b32 debug_enabled;
|
||||
#endif
|
||||
};
|
||||
@ -36,7 +34,7 @@ Struct(BB_Reader)
|
||||
u64 base_len;
|
||||
u8 *base;
|
||||
u64 cur_bit;
|
||||
#if BB_DebugIsEnabled
|
||||
#if BITBUFF_DEBUG
|
||||
b32 debug_enabled;
|
||||
#endif
|
||||
};
|
||||
@ -44,7 +42,7 @@ Struct(BB_Reader)
|
||||
////////////////////////////////
|
||||
//~ Debug types
|
||||
|
||||
#if BB_DebugIsEnabled
|
||||
#if BITBUFF_DEBUG
|
||||
|
||||
/* Magic numbers inserted to verify read/write type & length */
|
||||
typedef u32 BB_DebugMagicKind; enum
|
||||
@ -114,7 +112,7 @@ void BB_WriteBytes(BB_Writer *bw, String bytes);
|
||||
////////////////////////////////
|
||||
//~ Writer debug
|
||||
|
||||
#if BB_DebugIsEnabled
|
||||
#if BITBUFF_DEBUG
|
||||
void BB_WriteDebugMagic(BB_Writer *bw, BB_DebugMagicKind magic, u8 num_bits);
|
||||
void BB_WriteDebugMarker(BB_Writer *bw, String name);
|
||||
#else
|
||||
@ -169,7 +167,7 @@ void BB_SeekToByte(BB_Reader *br, u64 pos);
|
||||
////////////////////////////////
|
||||
//~ Reader debug
|
||||
|
||||
#if BB_DebugIsEnabled
|
||||
#if BITBUFF_DEBUG
|
||||
void BB_ReadDebugMagic(BB_Reader *br, BB_DebugMagicKind expected_magic, u8 expected_num_bits);
|
||||
void BB_ReadDebugMarker(BB_Reader *br, String name);
|
||||
#else
|
||||
|
||||
@ -1,32 +1,34 @@
|
||||
/* How close can non-overlapping shapes be before collision is considered */
|
||||
#define COLLISION_TOLERANCE 0.005f
|
||||
|
||||
/* NOTE: Should always be less than tolerance, since colliding = 1 if origin is within this distance. */
|
||||
#define MIN_UNIQUE_PT_DIST_SQ (0.001f * 0.001f)
|
||||
|
||||
/* To prevent extremely large prototypes when origin is in exact center of rounded feature */
|
||||
#define MAX_EPA_ITERATIONS 64
|
||||
////////////////////////////////
|
||||
//~ Debug
|
||||
|
||||
#if COLLIDER_DEBUG
|
||||
internal void _dbgbreakable(void)
|
||||
void CLD_DebugBreakable(void)
|
||||
{
|
||||
#if RtcIsEnabled
|
||||
DEBUGBREAKABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define DBGSTEP \
|
||||
dbg_step++; \
|
||||
if (dbg_step >= GetGstat(GSTAT_DEBUG_STEPS)) { \
|
||||
goto abort; \
|
||||
} else if (dbg_step >= GetGstat(GSTAT_DEBUG_STEPS) - 1) { \
|
||||
_dbgbreakable(); \
|
||||
} (void)0
|
||||
#else
|
||||
#define DBGSTEP
|
||||
#endif
|
||||
|
||||
internal CLD_SupportPoint collider_get_support_point_internal(CLD_Shape *shape, Xform xf, Vec2 dir, i32 ignore)
|
||||
////////////////////////////////
|
||||
//~ Shape
|
||||
|
||||
CLD_Shape CLD_ShapeFromQuad(Quad quad)
|
||||
{
|
||||
CLD_Shape result;
|
||||
result.points[0] = quad.p0;
|
||||
result.points[1] = quad.p1;
|
||||
result.points[2] = quad.p2;
|
||||
result.points[3] = quad.p3;
|
||||
result.count = 4;
|
||||
result.radius = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ Menkowski support point
|
||||
|
||||
CLD_SupportPoint CLD_SupportPointFromDirInternal(CLD_Shape *shape, Xform xf, Vec2 dir, i32 ignore)
|
||||
{
|
||||
Vec2 *points = shape->points;
|
||||
u32 count = shape->count;
|
||||
@ -69,47 +71,34 @@ internal CLD_SupportPoint collider_get_support_point_internal(CLD_Shape *shape,
|
||||
return result;
|
||||
}
|
||||
|
||||
CLD_Shape collider_from_quad(Quad quad)
|
||||
CLD_SupportPoint CLD_SupportPointFromDir(CLD_Shape *shape, Xform xf, Vec2 dir)
|
||||
{
|
||||
CLD_Shape result;
|
||||
result.points[0] = quad.p0;
|
||||
result.points[1] = quad.p1;
|
||||
result.points[2] = quad.p2;
|
||||
result.points[3] = quad.p3;
|
||||
result.count = 4;
|
||||
result.radius = 0;
|
||||
return result;
|
||||
return CLD_SupportPointFromDirInternal(shape, xf, dir, -1);
|
||||
}
|
||||
|
||||
CLD_SupportPoint collider_get_support_point(CLD_Shape *shape, Xform xf, Vec2 dir)
|
||||
{
|
||||
return collider_get_support_point_internal(shape, xf, dir, -1);
|
||||
}
|
||||
|
||||
internal CLD_MenkowskiPoint get_menkowski_point(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, Vec2 dir)
|
||||
CLD_MenkowskiPoint CLD_MenkowskiPointFromDir(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, Vec2 dir)
|
||||
{
|
||||
CLD_MenkowskiPoint result;
|
||||
result.s0 = collider_get_support_point(shape0, xf0, dir);
|
||||
result.s1 = collider_get_support_point(shape1, xf1, NegVec2(dir));
|
||||
result.s0 = CLD_SupportPointFromDir(shape0, xf0, dir);
|
||||
result.s1 = CLD_SupportPointFromDir(shape1, xf1, NegVec2(dir));
|
||||
result.p = SubVec2(result.s0.p, result.s1.p);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* AABB
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Aabb
|
||||
|
||||
Aabb collider_aabb_from_collider(CLD_Shape *shape, Xform xf)
|
||||
Aabb CLD_AabbFromShape(CLD_Shape *shape, Xform xf)
|
||||
{
|
||||
Aabb result;
|
||||
result.p0.x = collider_get_support_point(shape, xf, VEC2(-1, 0)).p.x - COLLISION_TOLERANCE;
|
||||
result.p0.y = collider_get_support_point(shape, xf, VEC2(0, -1)).p.y - COLLISION_TOLERANCE;
|
||||
result.p1.x = collider_get_support_point(shape, xf, VEC2(1, 0)).p.x + COLLISION_TOLERANCE;
|
||||
result.p1.y = collider_get_support_point(shape, xf, VEC2(0, 1)).p.y + COLLISION_TOLERANCE;
|
||||
result.p0.x = CLD_SupportPointFromDir(shape, xf, VEC2(-1, 0)).p.x - CLD_CollisionTolerance;
|
||||
result.p0.y = CLD_SupportPointFromDir(shape, xf, VEC2(0, -1)).p.y - CLD_CollisionTolerance;
|
||||
result.p1.x = CLD_SupportPointFromDir(shape, xf, VEC2(1, 0)).p.x + CLD_CollisionTolerance;
|
||||
result.p1.y = CLD_SupportPointFromDir(shape, xf, VEC2(0, 1)).p.y + CLD_CollisionTolerance;
|
||||
return result;
|
||||
}
|
||||
|
||||
Aabb collider_aabb_from_combined_aabb(Aabb b0, Aabb b1)
|
||||
Aabb CLD_CombineAabb(Aabb b0, Aabb b1)
|
||||
{
|
||||
Aabb result;
|
||||
result.p0.x = MinF32(MinF32(b0.p0.x, b0.p1.x), MinF32(b1.p0.x, b1.p1.x));
|
||||
@ -119,7 +108,7 @@ Aabb collider_aabb_from_combined_aabb(Aabb b0, Aabb b1)
|
||||
return result;
|
||||
}
|
||||
|
||||
b32 collider_test_aabb(Aabb box0, Aabb box1)
|
||||
b32 CLD_TestAabb(Aabb box0, Aabb box1)
|
||||
{
|
||||
f32 b0_x0 = box0.p0.x;
|
||||
f32 b0_x1 = box0.p1.x;
|
||||
@ -133,32 +122,19 @@ b32 collider_test_aabb(Aabb box0, Aabb box1)
|
||||
((b0_y0 >= b1_y0 && b0_y0 <= b1_y1) || (b0_y1 >= b1_y0 && b0_y1 <= b1_y1) || (b1_y0 >= b0_y0 && b1_y0 <= b0_y1) || (b1_y1 >= b0_y0 && b1_y1 <= b0_y1));
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* GJK
|
||||
*
|
||||
////////////////////////////////
|
||||
//~ Gjk
|
||||
|
||||
/*
|
||||
* Determine simplex in menkowksi difference that encapsulates origin if shapes
|
||||
* overlap, or closest edge / point to origin on menkowski difference if they
|
||||
* overlap, or closest edge / point to origin on CLD_Menkowski difference if they
|
||||
* do not.
|
||||
* ========================== */
|
||||
|
||||
struct gjk_result {
|
||||
CLD_MenkowskiSimplex simplex;
|
||||
Vec2 final_dir;
|
||||
|
||||
/* If 1, simplex represents triangle inside of menkowski difference
|
||||
* encapsulating the origin. If 0, simplex represents the closest
|
||||
* feature on menkowski difference to the origin. */
|
||||
b32 overlapping;
|
||||
*/
|
||||
|
||||
#if COLLIDER_DEBUG
|
||||
u32 dbg_step;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if COLLIDER_DEBUG
|
||||
internal struct gjk_result gjk_get_simplex(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, f32 min_unique_pt_dist_sq, u32 dbg_step)
|
||||
CLD_GjkData CLD_GjkDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, f32 min_unique_pt_dist_sq, u32 dbg_step)
|
||||
#else
|
||||
internal struct gjk_result gjk_get_simplex(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, f32 min_unique_pt_dist_sq)
|
||||
CLD_GjkData CLD_GjkDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, f32 min_unique_pt_dist_sq)
|
||||
#endif
|
||||
{
|
||||
b32 overlapping = 0;
|
||||
@ -169,7 +145,7 @@ internal struct gjk_result gjk_get_simplex(CLD_Shape *shape0, CLD_Shape *shape1,
|
||||
/* First point is support point in shape's general directions to eachother */
|
||||
dir = SubVec2(xf1.og, xf0.og);
|
||||
if (IsVec2Zero(dir)) dir = VEC2(1, 0);
|
||||
s.a = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
|
||||
s.a = CLD_MenkowskiPointFromDir(shape0, shape1, xf0, xf1, dir);
|
||||
s.len = 1;
|
||||
|
||||
Vec2 removed_a = ZI;
|
||||
@ -180,8 +156,8 @@ internal struct gjk_result gjk_get_simplex(CLD_Shape *shape0, CLD_Shape *shape1,
|
||||
/* Second point is support point towards origin */
|
||||
dir = NegVec2(s.a.p);
|
||||
|
||||
DBGSTEP;
|
||||
m = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
|
||||
CLD_DBGSTEP;
|
||||
m = CLD_MenkowskiPointFromDir(shape0, shape1, xf0, xf1, dir);
|
||||
/* Check that new point is far enough away from existing point */
|
||||
if (Vec2LenSq(SubVec2(m.p, s.a.p)) < min_unique_pt_dist_sq) {
|
||||
overlapping = 0;
|
||||
@ -196,8 +172,8 @@ internal struct gjk_result gjk_get_simplex(CLD_Shape *shape0, CLD_Shape *shape1,
|
||||
}
|
||||
|
||||
{
|
||||
DBGSTEP;
|
||||
m = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
|
||||
CLD_DBGSTEP;
|
||||
m = CLD_MenkowskiPointFromDir(shape0, shape1, xf0, xf1, dir);
|
||||
/* Check that new point is far enough away from existing points */
|
||||
if (Vec2LenSq(SubVec2(m.p, s.a.p)) < min_unique_pt_dist_sq ||
|
||||
Vec2LenSq(SubVec2(m.p, s.b.p)) < min_unique_pt_dist_sq ||
|
||||
@ -225,7 +201,7 @@ internal struct gjk_result gjk_get_simplex(CLD_Shape *shape0, CLD_Shape *shape1,
|
||||
}
|
||||
|
||||
/* Determine region of the simplex in which the origin lies */
|
||||
DBGSTEP;
|
||||
CLD_DBGSTEP;
|
||||
Vec2 vab = SubVec2(s.b.p, s.a.p);
|
||||
Vec2 vac = SubVec2(s.c.p, s.a.p);
|
||||
Vec2 vbc = SubVec2(s.c.p, s.b.p);
|
||||
@ -294,7 +270,7 @@ internal struct gjk_result gjk_get_simplex(CLD_Shape *shape0, CLD_Shape *shape1,
|
||||
abort:
|
||||
#endif
|
||||
|
||||
struct gjk_result result = {
|
||||
CLD_GjkData result = {
|
||||
.simplex = s,
|
||||
.overlapping = overlapping,
|
||||
.final_dir = dir,
|
||||
@ -306,26 +282,17 @@ internal struct gjk_result gjk_get_simplex(CLD_Shape *shape0, CLD_Shape *shape1,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* EPA
|
||||
*
|
||||
* Expands upon result of GJK calculation to determine collision normal & closest edge when shapes are overlapping
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Epa
|
||||
|
||||
struct epa_result {
|
||||
Vec2 normal;
|
||||
CLD_MenkowskiFeature closest_feature; /* Represents closest feature (edge or point) to origin on menkowski difference */
|
||||
/* Expands upon result of GJK calculation to determine collision normal &
|
||||
* closest edge when shapes are overlapping
|
||||
*/
|
||||
|
||||
#if COLLIDER_DEBUG
|
||||
CLD_Prototype prototype;
|
||||
u32 dbg_step;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if COLLIDER_DEBUG
|
||||
internal struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, struct gjk_result gjk_result, f32 min_unique_pt_dist_sq, u32 max_iterations, u32 dbg_step)
|
||||
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
|
||||
internal struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, struct gjk_result gjk_result, f32 min_unique_pt_dist_sq, u32 max_iterations)
|
||||
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
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
@ -383,7 +350,7 @@ internal struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape
|
||||
|
||||
/* Find new point in dir */
|
||||
Vec2 dir = MulVec2(PerpVec2(vab), winding);
|
||||
CLD_MenkowskiPoint m = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
|
||||
CLD_MenkowskiPoint m = CLD_MenkowskiPointFromDir(shape0, shape1, xf0, xf1, dir);
|
||||
|
||||
#if COLLIDER_DEBUG
|
||||
{
|
||||
@ -396,7 +363,7 @@ internal struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape
|
||||
#endif
|
||||
|
||||
/* Check validity of new point */
|
||||
DBGSTEP;
|
||||
CLD_DBGSTEP;
|
||||
{
|
||||
b32 valid = 1;
|
||||
|
||||
@ -454,7 +421,7 @@ internal struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape
|
||||
abort:
|
||||
#endif
|
||||
|
||||
struct epa_result result = {
|
||||
CLD_EpaData result = {
|
||||
.normal = normal,
|
||||
.closest_feature = closest_feature
|
||||
};
|
||||
@ -472,16 +439,10 @@ internal struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Clipping
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Clipping
|
||||
|
||||
struct clip_line_to_line_result {
|
||||
Vec2 a0_clipped, b0_clipped;
|
||||
Vec2 a1_clipped, b1_clipped;
|
||||
};
|
||||
|
||||
internal struct clip_line_to_line_result clip_line_to_line(Vec2 a0, Vec2 b0, Vec2 a1, Vec2 b1, Vec2 normal)
|
||||
CLD_ClippedLine CLD_ClipLineToLine(Vec2 a0, Vec2 b0, Vec2 a1, Vec2 b1, Vec2 normal)
|
||||
{
|
||||
Vec2 vab0 = SubVec2(b0, a0);
|
||||
Vec2 vab1 = SubVec2(b1, a1);
|
||||
@ -508,7 +469,7 @@ internal struct clip_line_to_line_result clip_line_to_line(Vec2 a0, Vec2 b0, Vec
|
||||
b1t = ClampF32(-vb0b1_w * -w, 0, 1);
|
||||
}
|
||||
|
||||
struct clip_line_to_line_result result;
|
||||
CLD_ClippedLine result;
|
||||
result.a0_clipped = AddVec2(a0, MulVec2(vab0, a0t));
|
||||
result.a1_clipped = AddVec2(a1, MulVec2(vab1, a1t));
|
||||
result.b0_clipped = AddVec2(b0, MulVec2(vab0, -b0t));
|
||||
@ -516,7 +477,7 @@ internal struct clip_line_to_line_result clip_line_to_line(Vec2 a0, Vec2 b0, Vec
|
||||
return result;
|
||||
}
|
||||
|
||||
internal Vec2 clip_point_to_line(Vec2 a, Vec2 b, Vec2 p, Vec2 normal)
|
||||
Vec2 CLD_ClipPointToLine(Vec2 a, Vec2 b, Vec2 p, Vec2 normal)
|
||||
{
|
||||
Vec2 vab = SubVec2(b, a);
|
||||
Vec2 vap = SubVec2(p, a);
|
||||
@ -534,17 +495,16 @@ internal Vec2 clip_point_to_line(Vec2 a, Vec2 b, Vec2 p, Vec2 normal)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Collision points
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Collision points
|
||||
|
||||
CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1)
|
||||
CLD_CollisionData CLD_CollisionDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1)
|
||||
{
|
||||
CLD_CollisionResult result = ZI;
|
||||
CLD_CollisionData result = ZI;
|
||||
|
||||
const f32 tolerance = COLLISION_TOLERANCE;
|
||||
const f32 min_unique_pt_dist_sq = MIN_UNIQUE_PT_DIST_SQ;
|
||||
const u32 max_epa_iterations = MAX_EPA_ITERATIONS;
|
||||
const f32 tolerance = CLD_CollisionTolerance;
|
||||
const f32 min_unique_pt_dist_sq = CLD_MinUniquePtDistSq;
|
||||
const u32 max_epa_iterations = CLD_MaxEpaIterations;
|
||||
|
||||
CLD_CollisionPoint points[2] = ZI;
|
||||
u32 num_points = 0;
|
||||
@ -555,27 +515,27 @@ CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shap
|
||||
u32 dbg_step = 0;
|
||||
#endif
|
||||
|
||||
struct gjk_result gjk_result = ZI;
|
||||
struct epa_result epa_result = ZI;
|
||||
CLD_GjkData gjk_result = ZI;
|
||||
CLD_EpaData epa_result = ZI;
|
||||
|
||||
/* Run GJK */
|
||||
#if COLLIDER_DEBUG
|
||||
gjk_result = gjk_get_simplex(shape0, shape1, xf0, xf1, min_unique_pt_dist_sq, dbg_step);
|
||||
gjk_result = CLD_GjkDataFromShapes(shape0, shape1, xf0, xf1, min_unique_pt_dist_sq, dbg_step);
|
||||
dbg_step = gjk_result.dbg_step;
|
||||
#else
|
||||
gjk_result = gjk_get_simplex(shape0, shape1, xf0, xf1, min_unique_pt_dist_sq);
|
||||
gjk_result = CLD_GjkDataFromShapes(shape0, shape1, xf0, xf1, min_unique_pt_dist_sq);
|
||||
#endif
|
||||
DBGSTEP;
|
||||
CLD_DBGSTEP;
|
||||
|
||||
/* Run EPA */
|
||||
#if COLLIDER_DEBUG
|
||||
epa_result = epa_get_normal_from_gjk(shape0, shape1, xf0, xf1, gjk_result, min_unique_pt_dist_sq, max_epa_iterations, dbg_step);
|
||||
epa_result = CLD_EpaDataFromShapes(shape0, shape1, xf0, xf1, gjk_result, min_unique_pt_dist_sq, max_epa_iterations, dbg_step);
|
||||
dbg_step = epa_result.dbg_step;
|
||||
#else
|
||||
epa_result = epa_get_normal_from_gjk(shape0, shape1, xf0, xf1, gjk_result, min_unique_pt_dist_sq, max_epa_iterations);
|
||||
epa_result = CLD_EpaDataFromShapes(shape0, shape1, xf0, xf1, gjk_result, min_unique_pt_dist_sq, max_epa_iterations);
|
||||
#endif
|
||||
normal = epa_result.normal;
|
||||
DBGSTEP;
|
||||
CLD_DBGSTEP;
|
||||
|
||||
/* Determine collision */
|
||||
if (gjk_result.overlapping) {
|
||||
@ -620,7 +580,7 @@ CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shap
|
||||
if (f.len == 2) {
|
||||
if (a0.i == b0.i) {
|
||||
if (shape0->count > 1) {
|
||||
b0 = collider_get_support_point_internal(shape0, xf0, normal, b0.i);
|
||||
b0 = CLD_SupportPointFromDirInternal(shape0, xf0, normal, b0.i);
|
||||
} else {
|
||||
collapse0 = 1;
|
||||
b0 = a0;
|
||||
@ -628,7 +588,7 @@ CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shap
|
||||
}
|
||||
if (a1.i == b1.i) {
|
||||
if (shape1->count > 1) {
|
||||
b1 = collider_get_support_point_internal(shape1, xf1, NegVec2(normal), b1.i);
|
||||
b1 = CLD_SupportPointFromDirInternal(shape1, xf1, NegVec2(normal), b1.i);
|
||||
} else {
|
||||
collapse1 = 1;
|
||||
b1 = a1;
|
||||
@ -691,7 +651,7 @@ CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shap
|
||||
b32 ignore_b = 1;
|
||||
if (!collapse0 && !collapse1) {
|
||||
/* Clip line to line */
|
||||
struct clip_line_to_line_result clip_result = clip_line_to_line(a0.p, b0.p, a1.p, b1.p, normal);
|
||||
CLD_ClippedLine clip_result = CLD_ClipLineToLine(a0.p, b0.p, a1.p, b1.p, normal);
|
||||
Vec2 a0_clipped = clip_result.a0_clipped;
|
||||
Vec2 a1_clipped = clip_result.a1_clipped;
|
||||
Vec2 b0_clipped = clip_result.b0_clipped;
|
||||
@ -723,11 +683,11 @@ CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shap
|
||||
/* TODO: Choose ID based on closest clipped point */
|
||||
if (collapse1 && !collapse0) {
|
||||
/* Project a1 onto vab0 */
|
||||
p0 = clip_point_to_line(a0.p, b0.p, a1.p, normal);
|
||||
p0 = CLD_ClipPointToLine(a0.p, b0.p, a1.p, normal);
|
||||
}
|
||||
if (collapse0 && !collapse1) {
|
||||
/* Project a0 onto vab1 */
|
||||
p1 = clip_point_to_line(a1.p, b1.p, a0.p, normal);
|
||||
p1 = CLD_ClipPointToLine(a1.p, b1.p, a0.p, normal);
|
||||
}
|
||||
/* Calc midpoint */
|
||||
Vec2 vsep = SubVec2(p1, p0);
|
||||
@ -775,19 +735,18 @@ CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shap
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Closest points
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Closest points
|
||||
|
||||
/* TODO: De-duplicate code between collider_closest_points & collider_collision_points */
|
||||
/* TODO: De-duplicate code between CLD_ClosestPointDataFromShapes & CLD_CollisionDataFromShapes */
|
||||
|
||||
CLD_ClosestResult collider_closest_points(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1)
|
||||
CLD_ClosestPointData CLD_ClosestPointDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1)
|
||||
{
|
||||
CLD_ClosestResult result = ZI;
|
||||
CLD_ClosestPointData result = ZI;
|
||||
|
||||
const f32 tolerance = COLLISION_TOLERANCE;
|
||||
const f32 min_unique_pt_dist_sq = MIN_UNIQUE_PT_DIST_SQ;
|
||||
const u32 max_epa_iterations = MAX_EPA_ITERATIONS;
|
||||
const f32 tolerance = CLD_CollisionTolerance;
|
||||
const f32 min_unique_pt_dist_sq = CLD_MinUniquePtDistSq;
|
||||
const u32 max_epa_iterations = CLD_MaxEpaIterations;
|
||||
|
||||
Vec2 p0 = ZI;
|
||||
Vec2 p1 = ZI;
|
||||
@ -797,26 +756,26 @@ CLD_ClosestResult collider_closest_points(CLD_Shape *shape0, CLD_Shape *shape1,
|
||||
u32 dbg_step = 0;
|
||||
#endif
|
||||
|
||||
struct gjk_result gjk_result = ZI;
|
||||
struct epa_result epa_result = ZI;
|
||||
CLD_GjkData gjk_result = ZI;
|
||||
CLD_EpaData epa_result = ZI;
|
||||
|
||||
/* Run GJK */
|
||||
#if COLLIDER_DEBUG
|
||||
gjk_result = gjk_get_simplex(shape0, shape1, xf0, xf1, min_unique_pt_dist_sq, dbg_step);
|
||||
gjk_result = CLD_GjkDataFromShapes(shape0, shape1, xf0, xf1, min_unique_pt_dist_sq, dbg_step);
|
||||
dbg_step = gjk_result.dbg_step;
|
||||
#else
|
||||
gjk_result = gjk_get_simplex(shape0, shape1, xf0, xf1, min_unique_pt_dist_sq);
|
||||
gjk_result = CLD_GjkDataFromShapes(shape0, shape1, xf0, xf1, min_unique_pt_dist_sq);
|
||||
#endif
|
||||
DBGSTEP;
|
||||
CLD_DBGSTEP;
|
||||
|
||||
/* Run EPA */
|
||||
#if COLLIDER_DEBUG
|
||||
epa_result = epa_get_normal_from_gjk(shape0, shape1, xf0, xf1, gjk_result, min_unique_pt_dist_sq, max_epa_iterations, dbg_step);
|
||||
epa_result = CLD_EpaDataFromShapes(shape0, shape1, xf0, xf1, gjk_result, min_unique_pt_dist_sq, max_epa_iterations, dbg_step);
|
||||
dbg_step = epa_result.dbg_step;
|
||||
#else
|
||||
epa_result = epa_get_normal_from_gjk(shape0, shape1, xf0, xf1, gjk_result, min_unique_pt_dist_sq, max_epa_iterations);
|
||||
epa_result = CLD_EpaDataFromShapes(shape0, shape1, xf0, xf1, gjk_result, min_unique_pt_dist_sq, max_epa_iterations);
|
||||
#endif
|
||||
DBGSTEP;
|
||||
CLD_DBGSTEP;
|
||||
|
||||
/* ========================== *
|
||||
* Resolve points
|
||||
@ -863,16 +822,12 @@ CLD_ClosestResult collider_closest_points(CLD_Shape *shape0, CLD_Shape *shape1,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Time of impact
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Time of impact
|
||||
|
||||
/* Takes 2 shapes and their xforms at t=0 and t=1.
|
||||
/* Takes 2 shapes and their xforms at t=0 and t=1.
|
||||
* Returns time of impact in range [0, 1]. */
|
||||
f32 collider_time_of_impact(CLD_Shape *c0, CLD_Shape *c1,
|
||||
Xform xf0_t0, Xform xf1_t0,
|
||||
Xform xf0_t1, Xform xf1_t1,
|
||||
f32 tolerance, u32 max_iterations)
|
||||
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)
|
||||
{
|
||||
f32 t0 = 0;
|
||||
f32 t1 = 1;
|
||||
@ -885,7 +840,7 @@ f32 collider_time_of_impact(CLD_Shape *c0, CLD_Shape *c1,
|
||||
Vec2 dir;
|
||||
Vec2 dir_neg;
|
||||
{
|
||||
CLD_ClosestResult closest_points = collider_closest_points(c0, c1, xf0_t0, xf1_t0);
|
||||
CLD_ClosestPointData closest_points = CLD_ClosestPointDataFromShapes(c0, c1, xf0_t0, xf1_t0);
|
||||
if (closest_points.colliding) {
|
||||
/* Shapes are penetrating at t=0 */
|
||||
return 0;
|
||||
@ -897,8 +852,8 @@ f32 collider_time_of_impact(CLD_Shape *c0, CLD_Shape *c1,
|
||||
}
|
||||
|
||||
{
|
||||
Vec2 p0 = collider_get_support_point(c0, xf0_t1, dir).p;
|
||||
Vec2 p1 = collider_get_support_point(c1, xf1_t1, dir_neg).p;
|
||||
Vec2 p0 = CLD_SupportPointFromDir(c0, xf0_t1, dir).p;
|
||||
Vec2 p1 = CLD_SupportPointFromDir(c1, xf1_t1, dir_neg).p;
|
||||
t1_sep = DotVec2(dir, SubVec2(p1, p0));
|
||||
if (t1_sep > 0) {
|
||||
/* Shapes are not penetrating at t=1 */
|
||||
@ -922,8 +877,8 @@ f32 collider_time_of_impact(CLD_Shape *c0, CLD_Shape *c1,
|
||||
Xform xf0 = LerpXform(xf0_t0, xf0_t1, t);
|
||||
Xform xf1 = LerpXform(xf1_t0, xf1_t1, t);
|
||||
|
||||
Vec2 p0 = collider_get_support_point(c0, xf0, dir).p;
|
||||
Vec2 p1 = collider_get_support_point(c1, xf1, dir_neg).p;
|
||||
Vec2 p0 = CLD_SupportPointFromDir(c0, xf0, dir).p;
|
||||
Vec2 p1 = CLD_SupportPointFromDir(c1, xf1, dir_neg).p;
|
||||
t_sep = DotVec2(dir, SubVec2(p1, p0));
|
||||
|
||||
/* Update bracket */
|
||||
@ -941,19 +896,17 @@ f32 collider_time_of_impact(CLD_Shape *c0, CLD_Shape *c1,
|
||||
return t;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Debug functions
|
||||
* TODO: Remove these
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Point cloud debugging
|
||||
|
||||
/* TODO: Remove this (debugging) */
|
||||
V2Array menkowski(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, u32 detail)
|
||||
/* TODO: Remove this (debugging) */
|
||||
Vec2Array CLD_Menkowski(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, u32 detail)
|
||||
{
|
||||
V2Array result = { .points = PushDry(arena, Vec2) };
|
||||
Vec2Array result = { .points = PushDry(arena, Vec2) };
|
||||
for (u64 i = 0; i < detail; ++i) {
|
||||
f32 angle = ((f32)i / detail) * (2 * Pi);
|
||||
Vec2 dir = Vec2FromAngle(angle);
|
||||
CLD_MenkowskiPoint m = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
|
||||
CLD_MenkowskiPoint m = CLD_MenkowskiPointFromDir(shape0, shape1, xf0, xf1, dir);
|
||||
if (result.count == 0 || !EqVec2(m.p, result.points[result.count - 1])) {
|
||||
*PushStructNoZero(arena, Vec2) = m.p;
|
||||
++result.count;
|
||||
@ -963,10 +916,10 @@ V2Array menkowski(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0,
|
||||
}
|
||||
|
||||
/* TODO: Remove this (debugging) */
|
||||
V2Array cloud(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1)
|
||||
Vec2Array CLD_PointCloud(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1)
|
||||
{
|
||||
/* FIXME: Account for radius */
|
||||
V2Array result = { .points = PushDry(arena, Vec2) };
|
||||
Vec2Array result = { .points = PushDry(arena, Vec2) };
|
||||
Vec2 *points0 = shape0->points;
|
||||
Vec2 *points1 = shape1->points;
|
||||
u32 count0 = shape0->count;
|
||||
@ -982,12 +935,11 @@ V2Array cloud(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xfo
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Boolean GJK (UNUSED)
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Boolean GJK (unused)
|
||||
|
||||
#if 0
|
||||
b32 collider_collision_boolean(CLD_Shape *shape0, CLD_Shape *shape1)
|
||||
b32 CLD_GjkBoolean(CLD_Shape *shape0, CLD_Shape *shape1)
|
||||
{
|
||||
struct { Vec2 a, b, c; } s = ZI;
|
||||
|
||||
@ -997,18 +949,18 @@ b32 collider_collision_boolean(CLD_Shape *shape0, CLD_Shape *shape1)
|
||||
/* First point is support point in shape's general directions to eachother */
|
||||
dir = SubVec2(starting_point(shape1), starting_point(shape0));
|
||||
if (IsVec2Zero(dir)) dir = VEC2(1, 0);
|
||||
s.a = get_menkowski_point(shape0, shape1, dir);
|
||||
s.a = CLD_MenkowskiPointFromDir(shape0, shape1, dir);
|
||||
|
||||
/* Second point is support point towards origin */
|
||||
dir = NegVec2(s.a);
|
||||
p = get_menkowski_point(shape0, shape1, dir);
|
||||
p = CLD_MenkowskiPointFromDir(shape0, shape1, dir);
|
||||
if (DotVec2(dir, p) >= 0) {
|
||||
s.b = s.a;
|
||||
s.a = p;
|
||||
for (;;) {
|
||||
/* Third point is support point in direction of line normal towards origin */
|
||||
dir = PerpVec2TowardsDir(SubVec2(s.b, s.a), NegVec2(s.a));
|
||||
p = get_menkowski_point(shape0, shape1, dir);
|
||||
p = CLD_MenkowskiPointFromDir(shape0, shape1, dir);
|
||||
if (DotVec2(dir, p) < 0) {
|
||||
/* New point did not cross origin, collision impossible */
|
||||
break;
|
||||
|
||||
@ -1,42 +1,59 @@
|
||||
Struct(CLD_Shape) {
|
||||
////////////////////////////////
|
||||
//~ Shape types
|
||||
|
||||
Struct(CLD_Shape)
|
||||
{
|
||||
Vec2 points[8];
|
||||
u32 count;
|
||||
f32 radius;
|
||||
};
|
||||
|
||||
Struct(CLD_SupportPoint) {
|
||||
////////////////////////////////
|
||||
//~ Menkowski types
|
||||
|
||||
Struct(CLD_SupportPoint)
|
||||
{
|
||||
Vec2 p;
|
||||
u32 i; /* Index of original point in shape */
|
||||
};
|
||||
|
||||
Struct(CLD_MenkowskiPoint) {
|
||||
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) {
|
||||
Struct(CLD_MenkowskiSimplex)
|
||||
{
|
||||
u32 len;
|
||||
CLD_MenkowskiPoint a, b, c;
|
||||
};
|
||||
|
||||
Struct(CLD_MenkowskiFeature) {
|
||||
Struct(CLD_MenkowskiFeature)
|
||||
{
|
||||
u32 len;
|
||||
CLD_MenkowskiPoint a, b;
|
||||
};
|
||||
|
||||
Struct(CLD_CollisionPoint) {
|
||||
////////////////////////////////
|
||||
//~ Collision types
|
||||
|
||||
Struct(CLD_CollisionPoint)
|
||||
{
|
||||
Vec2 point;
|
||||
f32 separation;
|
||||
u32 id; /* Based on polygon edge-to-edge */
|
||||
};
|
||||
|
||||
Struct(CLD_Prototype) {
|
||||
Struct(CLD_Prototype)
|
||||
{
|
||||
Vec2 points[64];
|
||||
u32 len;
|
||||
};
|
||||
|
||||
Struct(CLD_CollisionResult) {
|
||||
Struct(CLD_CollisionData)
|
||||
{
|
||||
Vec2 normal;
|
||||
CLD_CollisionPoint points[2];
|
||||
u32 num_points;
|
||||
@ -51,7 +68,8 @@ Struct(CLD_CollisionResult) {
|
||||
Vec2 a0_clipped, b0_clipped, a1_clipped, b1_clipped;
|
||||
};
|
||||
|
||||
Struct(CLD_ClosestResult) {
|
||||
Struct(CLD_ClosestPointData)
|
||||
{
|
||||
Vec2 p0, p1;
|
||||
b32 colliding;
|
||||
|
||||
@ -61,21 +79,137 @@ Struct(CLD_ClosestResult) {
|
||||
CLD_Prototype prototype;
|
||||
};
|
||||
|
||||
CLD_Shape collider_from_quad(Quad quad);
|
||||
////////////////////////////////
|
||||
//~ Clipping types
|
||||
|
||||
CLD_SupportPoint collider_get_support_point(CLD_Shape *shape, Xform xf, Vec2 dir);
|
||||
Struct(CLD_ClippedLine) {
|
||||
Vec2 a0_clipped, b0_clipped;
|
||||
Vec2 a1_clipped, b1_clipped;
|
||||
};
|
||||
|
||||
Aabb collider_aabb_from_collider(CLD_Shape *shape, Xform xf);
|
||||
////////////////////////////////
|
||||
//~ Gjk types
|
||||
|
||||
Aabb collider_aabb_from_combined_aabb(Aabb b0, Aabb b1);
|
||||
Struct(CLD_GjkData)
|
||||
{
|
||||
CLD_MenkowskiSimplex simplex;
|
||||
Vec2 final_dir;
|
||||
|
||||
b32 collider_test_aabb(Aabb box0, Aabb box1);
|
||||
/* 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;
|
||||
|
||||
CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1);
|
||||
#if COLLIDER_DEBUG
|
||||
u32 dbg_step;
|
||||
#endif
|
||||
};
|
||||
|
||||
CLD_ClosestResult collider_closest_points(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1);
|
||||
////////////////////////////////
|
||||
//~ Epa types
|
||||
|
||||
f32 collider_time_of_impact(CLD_Shape *c0, CLD_Shape *c1, Xform xf0_t0, Xform xf1_t0, Xform xf0_t1, Xform xf1_t1, f32 tolerance, u32 max_iterations);
|
||||
Struct(CLD_EpaData)
|
||||
{
|
||||
Vec2 normal;
|
||||
CLD_MenkowskiFeature closest_feature; /* Represents closest feature (edge or point) to origin on CLD_Menkowski difference */
|
||||
|
||||
V2Array menkowski(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, u32 detail);
|
||||
V2Array cloud(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1);
|
||||
#if COLLIDER_DEBUG
|
||||
CLD_Prototype prototype;
|
||||
u32 dbg_step;
|
||||
#endif
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ Shared state
|
||||
|
||||
/* 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
|
||||
|
||||
////////////////////////////////
|
||||
//~ 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_SupportPointFromDirInternal(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);
|
||||
|
||||
@ -69,14 +69,14 @@
|
||||
# define SIM_MAX_ANGULAR_VELOCITY F32Infinity
|
||||
#endif
|
||||
|
||||
#define COLLIDER_DEBUG 1
|
||||
#define COLLIDER_DEBUG 0
|
||||
#define COLLIDER_DEBUG_DETAILED 1
|
||||
#define COLLIDER_DEBUG_DETAILED_DRAW_MENKOWSKI 1
|
||||
|
||||
#define FLOOD_DEBUG 0
|
||||
|
||||
/* If enabled, bitbuffs will insert/verify magic numbers & length for each read & write */
|
||||
#define DebugBitbuff 0
|
||||
#define BITBUFF_DEBUG 0
|
||||
#define BITBUFF_TEST RtcIsEnabled
|
||||
|
||||
/* If enabled, things like network writes & memory allocations will be tracked in a global statistics struct */
|
||||
|
||||
@ -36,7 +36,7 @@ void draw_material(G_RenderSig *sig, D_MaterialParams params)
|
||||
* Fill shapes
|
||||
* ========================== */
|
||||
|
||||
void draw_poly_ex(G_RenderSig *sig, V2Array vertices, G_Indices indices, u32 color)
|
||||
void draw_poly_ex(G_RenderSig *sig, Vec2Array vertices, G_Indices indices, u32 color)
|
||||
{
|
||||
G_RenderCmdDesc cmd = ZI;
|
||||
cmd.kind = GP_RENDER_CMD_KIND_DRAW_UI_SHAPE;
|
||||
@ -47,7 +47,7 @@ void draw_poly_ex(G_RenderSig *sig, V2Array vertices, G_Indices indices, u32 col
|
||||
}
|
||||
|
||||
/* Draws a filled polygon using triangles in a fan pattern */
|
||||
void draw_poly(G_RenderSig *sig, V2Array vertices, u32 color)
|
||||
void draw_poly(G_RenderSig *sig, Vec2Array vertices, u32 color)
|
||||
{
|
||||
if (vertices.count >= 3) {
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
@ -87,7 +87,7 @@ void draw_circle(G_RenderSig *sig, Vec2 pos, f32 radius, u32 color, u32 detail)
|
||||
points[i] = AddVec2(pos, p);
|
||||
}
|
||||
|
||||
V2Array vertices = {
|
||||
Vec2Array vertices = {
|
||||
.points = points,
|
||||
.count = detail
|
||||
};
|
||||
@ -102,7 +102,7 @@ void draw_quad(G_RenderSig *sig, Quad quad, u32 color)
|
||||
0, 1, 2,
|
||||
0, 2, 3
|
||||
};
|
||||
V2Array vertices = { .count = 4, .points = quad.e };
|
||||
Vec2Array vertices = { .count = 4, .points = quad.e };
|
||||
G_Indices indices = { .count = 6, .indices = indices_array };
|
||||
draw_poly_ex(sig, vertices, indices, color);
|
||||
}
|
||||
@ -136,7 +136,7 @@ void draw_ray(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, u32 color)
|
||||
draw_quad(sig, quad, color);
|
||||
}
|
||||
|
||||
void draw_poly_line(G_RenderSig *sig, V2Array points, b32 loop, f32 thickness, u32 color)
|
||||
void draw_poly_line(G_RenderSig *sig, Vec2Array points, b32 loop, f32 thickness, u32 color)
|
||||
{
|
||||
if (points.count >= 2) {
|
||||
for (u64 i = 1; i < points.count; ++i) {
|
||||
@ -168,7 +168,7 @@ void draw_circle_line(G_RenderSig *sig, Vec2 pos, f32 radius, f32 thickness, u32
|
||||
points[i] = AddVec2(pos, p);
|
||||
}
|
||||
|
||||
V2Array a = {
|
||||
Vec2Array a = {
|
||||
.points = points,
|
||||
.count = detail
|
||||
};
|
||||
@ -180,7 +180,7 @@ void draw_circle_line(G_RenderSig *sig, Vec2 pos, f32 radius, f32 thickness, u32
|
||||
void draw_quad_line(G_RenderSig *sig, Quad quad, f32 thickness, u32 color)
|
||||
{
|
||||
Vec2 points[] = { quad.p0, quad.p1, quad.p2, quad.p3 };
|
||||
V2Array a = { .points = points, .count = countof(points) };
|
||||
Vec2Array a = { .points = points, .count = countof(points) };
|
||||
draw_poly_line(sig, a, 1, thickness, color);
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ void draw_arrow_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, f32
|
||||
Vec2 head_p2 = AddVec2(head_start, head_p2_dir);
|
||||
|
||||
Vec2 head_points[] = { end, head_p1, head_p2 };
|
||||
V2Array head_points_v2_array = {
|
||||
Vec2Array head_points_v2_array = {
|
||||
.points = head_points,
|
||||
.count = countof(head_points)
|
||||
};
|
||||
@ -223,7 +223,7 @@ void draw_arrow_ray(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, f32 arr
|
||||
void draw_collider_line(G_RenderSig *sig, CLD_Shape shape, Xform shape_xf, f32 thickness, u32 color, u32 detail)
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
V2Array poly = ZI;
|
||||
Vec2Array poly = ZI;
|
||||
if (shape.radius == 0) {
|
||||
poly.count = shape.count;
|
||||
poly.points = PushStructsNoZero(scratch.arena, Vec2, shape.count);
|
||||
@ -237,7 +237,7 @@ void draw_collider_line(G_RenderSig *sig, CLD_Shape shape, Xform shape_xf, f32 t
|
||||
for (u32 i = 0; i < detail; ++i) {
|
||||
f32 angle = ((f32)i / (f32)detail) * Tau;
|
||||
Vec2 dir = VEC2(CosF32(angle), SinF32(angle));
|
||||
Vec2 p = collider_get_support_point(&shape, shape_xf, dir).p;
|
||||
Vec2 p = CLD_SupportPointFromDir(&shape, shape_xf, dir).p;
|
||||
poly.points[i] = p;
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,9 +26,9 @@ void draw_material(G_RenderSig *sig, D_MaterialParams params);
|
||||
* Fill shapes
|
||||
* ========================== */
|
||||
|
||||
void draw_poly_ex(G_RenderSig *sig, V2Array vertices, G_Indices indices, u32 color);
|
||||
void draw_poly_ex(G_RenderSig *sig, Vec2Array vertices, G_Indices indices, u32 color);
|
||||
|
||||
void draw_poly(G_RenderSig *sig, V2Array points, u32 color);
|
||||
void draw_poly(G_RenderSig *sig, Vec2Array points, u32 color);
|
||||
|
||||
void draw_circle(G_RenderSig *sig, Vec2 pos, f32 radius, u32 color, u32 detail);
|
||||
|
||||
@ -44,7 +44,7 @@ void draw_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 color)
|
||||
|
||||
void draw_ray(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, u32 color);
|
||||
|
||||
void draw_poly_line(G_RenderSig *sig, V2Array points, b32 loop, f32 thickness, u32 color);
|
||||
void draw_poly_line(G_RenderSig *sig, Vec2Array points, b32 loop, f32 thickness, u32 color);
|
||||
|
||||
void draw_circle_line(G_RenderSig *sig, Vec2 pos, f32 radius, f32 thickness, u32 color, u32 detail);
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ Struct(G_RenderCmdDesc)
|
||||
} ui_rect;
|
||||
struct
|
||||
{
|
||||
V2Array vertices;
|
||||
Vec2Array vertices;
|
||||
G_Indices indices;
|
||||
u32 color;
|
||||
} ui_shape;
|
||||
|
||||
@ -34,7 +34,7 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_
|
||||
|
||||
Xform check0_xf = sim_ent_get_xform(check0);
|
||||
CLD_Shape check0_collider = check0->local_collider;
|
||||
Aabb aabb = collider_aabb_from_collider(&check0_collider, check0_xf);
|
||||
Aabb aabb = CLD_AabbFromShape(&check0_collider, check0_xf);
|
||||
|
||||
SpaceIter iter = space_iter_begin_aabb(space, aabb);
|
||||
SpaceEntry *space_entry;
|
||||
@ -81,7 +81,7 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_
|
||||
}
|
||||
|
||||
/* Calculate collision */
|
||||
CLD_CollisionResult collision_result = collider_collision_points(&e0_collider, &e1_collider, e0_xf, e1_xf);
|
||||
CLD_CollisionData collision_result = CLD_CollisionDataFromShapes(&e0_collider, &e1_collider, e0_xf, e1_xf);
|
||||
|
||||
/* Parts of algorithm are hard-coded to support 2 contact points */
|
||||
StaticAssert(countof(constraint_ent->contact_constraint_data.points) == 2);
|
||||
@ -254,7 +254,7 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_
|
||||
|
||||
/* Update closest points */
|
||||
{
|
||||
CLD_ClosestResult closest_points = collider_closest_points(&e0_collider, &e1_collider, e0_xf, e1_xf);
|
||||
CLD_ClosestPointData closest_points = CLD_ClosestPointDataFromShapes(&e0_collider, &e1_collider, e0_xf, e1_xf);
|
||||
dbg->closest0 = closest_points.p0;
|
||||
dbg->closest1 = closest_points.p1;
|
||||
}
|
||||
@ -1177,9 +1177,9 @@ f32 phys_determine_earliest_toi(PhysStepCtx *ctx, f32 step_dt, f32 tolerance, u3
|
||||
Xform e0_xf_t1 = get_derived_xform(e0, step_dt);
|
||||
|
||||
/* TODO: Use swept aabb rather than combined aabb. This should prevent spikes from bullets returning 0 positive TOIs with irrelevant entities. */
|
||||
Aabb aabb_t0 = collider_aabb_from_collider(&e0_collider, e0_xf_t0);
|
||||
Aabb aabb_t1 = collider_aabb_from_collider(&e0_collider, e0_xf_t1);
|
||||
Aabb combined_aabb = collider_aabb_from_combined_aabb(aabb_t0, aabb_t1);
|
||||
Aabb aabb_t0 = CLD_AabbFromShape(&e0_collider, e0_xf_t0);
|
||||
Aabb aabb_t1 = CLD_AabbFromShape(&e0_collider, e0_xf_t1);
|
||||
Aabb combined_aabb = CLD_CombineAabb(aabb_t0, aabb_t1);
|
||||
|
||||
SpaceIter iter = space_iter_begin_aabb(space, combined_aabb);
|
||||
SpaceEntry *entry;
|
||||
@ -1194,7 +1194,7 @@ f32 phys_determine_earliest_toi(PhysStepCtx *ctx, f32 step_dt, f32 tolerance, u3
|
||||
Xform e1_xf_t0 = sim_ent_get_xform(e1);
|
||||
Xform e1_xf_t1 = get_derived_xform(e1, step_dt);
|
||||
|
||||
f32 t = collider_time_of_impact(&e0_collider, &e1_collider, e0_xf_t0, e1_xf_t0, e0_xf_t1, e1_xf_t1, tolerance, max_iterations);
|
||||
f32 t = CLD_TimeOfImpact(&e0_collider, &e1_collider, e0_xf_t0, e1_xf_t0, e0_xf_t1, e1_xf_t1, tolerance, max_iterations);
|
||||
if (t != 0 && t < smallest_t) {
|
||||
smallest_t = t;
|
||||
}
|
||||
@ -1224,7 +1224,7 @@ void phys_update_aabbs(PhysStepCtx *ctx)
|
||||
space_entry = space_entry_alloc(space, ent->id);
|
||||
ent->space_handle = space_entry->handle;
|
||||
}
|
||||
Aabb aabb = collider_aabb_from_collider(&ent->local_collider, xf);
|
||||
Aabb aabb = CLD_AabbFromShape(&ent->local_collider, xf);
|
||||
space_entry_update_aabb(space_entry, aabb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ typedef struct CollisionDebugData CollisionDebugData;
|
||||
struct CollisionDebugData {
|
||||
EntId e0;
|
||||
EntId e1;
|
||||
CLD_CollisionResult collision_result;
|
||||
CLD_CollisionData collision_result;
|
||||
|
||||
ContactPoint points[2];
|
||||
u32 num_points;
|
||||
|
||||
@ -400,7 +400,7 @@ SpaceEntry *space_iter_next(SpaceIter *iter)
|
||||
if (next_node) {
|
||||
SpaceEntry *entry = next_node->entry;
|
||||
Aabb entry_aabb = entry->aabb;
|
||||
if (collider_test_aabb(entry_aabb, iter_aabb)) {
|
||||
if (CLD_TestAabb(entry_aabb, iter_aabb)) {
|
||||
break;
|
||||
} else {
|
||||
next_node = next_node->next_in_cell;
|
||||
|
||||
@ -263,7 +263,7 @@ internal void test_spawn_entities2(Ent *parent, Vec2 pos)
|
||||
|
||||
sim_ent_enable_prop(e, SEPROP_SOLID);
|
||||
Quad collider_quad = QuadFromRect(RectFromScalar(-0.5, -0.5, 1, 1));
|
||||
e->local_collider = collider_from_quad(collider_quad);
|
||||
e->local_collider = CLD_ShapeFromQuad(collider_quad);
|
||||
|
||||
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
|
||||
|
||||
@ -332,7 +332,7 @@ internal void test_spawn_entities3(Ent *parent, Vec2 pos)
|
||||
|
||||
sim_ent_enable_prop(e, SEPROP_SOLID);
|
||||
Quad collider_quad = QuadFromRect(RectFromScalar(-0.5, -0.5, 1, 1));
|
||||
e->local_collider = collider_from_quad(collider_quad);
|
||||
e->local_collider = CLD_ShapeFromQuad(collider_quad);
|
||||
}
|
||||
}
|
||||
|
||||
@ -390,7 +390,7 @@ internal void test_spawn_tile(Snapshot *world, Vec2 world_pos)
|
||||
|
||||
sim_ent_enable_prop(e, SEPROP_SOLID);
|
||||
Quad collider_quad = QuadFromRect(RectFromScalar(-tile_size.x / 2, -tile_size.y / 2, tile_size.y, tile_size.y));
|
||||
e->local_collider = collider_from_quad(collider_quad);
|
||||
e->local_collider = CLD_ShapeFromQuad(collider_quad);
|
||||
#else
|
||||
Vec2I32 tile_index = sim_world_tile_index_from_pos(world_pos);
|
||||
sim_snapshot_set_tile(world, tile_index, SIM_TILE_KIND_WALL);
|
||||
@ -792,7 +792,7 @@ internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
|
||||
origin_collider.count = 1;
|
||||
|
||||
Xform victim_xf = sim_ent_get_xform(victim);
|
||||
CLD_ClosestResult closest_points = collider_closest_points(&origin_collider, &victim->local_collider, xf, victim_xf);
|
||||
CLD_ClosestPointData closest_points = CLD_ClosestPointDataFromShapes(&origin_collider, &victim->local_collider, xf, victim_xf);
|
||||
Vec2 dir = SubVec2(closest_points.p1, closest_points.p0);
|
||||
Vec2 point = closest_points.p1;
|
||||
f32 distance = Vec2Len(dir);
|
||||
@ -1224,7 +1224,7 @@ void sim_step(SimStepCtx *ctx)
|
||||
Xform cxf = ent->sprite_local_xform;
|
||||
|
||||
S_SheetSlice slice = sprite_sheet_get_slice(sheet, ent->sprite_collider_slice, ent->animation_frame);
|
||||
ent->local_collider = collider_from_quad(MulXformQuad(cxf, QuadFromRect(slice.rect)));
|
||||
ent->local_collider = CLD_ShapeFromQuad(MulXformQuad(cxf, QuadFromRect(slice.rect)));
|
||||
}
|
||||
|
||||
/* Test collider */
|
||||
|
||||
@ -766,7 +766,7 @@ internal void user_update(P_Window *window)
|
||||
if (ent_collider.count > 0) {
|
||||
/* TODO: Can just use boolean GJK */
|
||||
Xform ent_xf = sim_ent_get_xform(ent);
|
||||
CLD_CollisionResult collision_result = collider_collision_points(&ent_collider, &mouse_shape, ent_xf, mouse_xf);
|
||||
CLD_CollisionData collision_result = CLD_CollisionDataFromShapes(&ent_collider, &mouse_shape, ent_xf, mouse_xf);
|
||||
if (collision_result.num_points > 0) {
|
||||
hovered_ent = sim_ent_from_id(G.ss_blended, ent->top);
|
||||
break;
|
||||
@ -1279,7 +1279,7 @@ internal void user_update(P_Window *window)
|
||||
|
||||
/* Draw AABB */
|
||||
if (ent->local_collider.count > 0) {
|
||||
Aabb aabb = collider_aabb_from_collider(&ent->local_collider, xf);
|
||||
Aabb aabb = CLD_AabbFromShape(&ent->local_collider, xf);
|
||||
f32 thickness = 1;
|
||||
u32 color = Rgba32F(1, 0, 1, 0.5);
|
||||
Quad quad = QuadFromAabb(aabb);
|
||||
@ -1387,7 +1387,7 @@ internal void user_update(P_Window *window)
|
||||
if (collider.count == 1 && collider.radius > 0) {
|
||||
/* Draw upwards line for circle */
|
||||
Vec2 start = xf.og;
|
||||
Vec2 end = collider_get_support_point(&collider, xf, NegVec2(xf.by)).p;
|
||||
Vec2 end = CLD_SupportPointFromDir(&collider, xf, NegVec2(xf.by)).p;
|
||||
start = MulXformV2(G.world_to_ui_xf, start);
|
||||
end = MulXformV2(G.world_to_ui_xf, end);
|
||||
draw_line(G.render_sig, start, end, thickness, color);
|
||||
@ -1474,7 +1474,7 @@ internal void user_update(P_Window *window)
|
||||
#if COLLIDER_DEBUG
|
||||
if (sim_ent_has_prop(ent, SEPROP_COLLISION_DEBUG)) {
|
||||
CollisionDebugData *data = &ent->collision_debug_data;
|
||||
CLD_CollisionResult collision_reuslt = data->collision_result;
|
||||
CLD_CollisionData collision_reuslt = data->collision_result;
|
||||
Ent *e0 = sim_ent_from_id(G.ss_blended, data->e0);
|
||||
Ent *e1 = sim_ent_from_id(G.ss_blended, data->e1);
|
||||
CLD_Shape e0_collider = e0->local_collider;
|
||||
@ -1574,7 +1574,7 @@ internal void user_update(P_Window *window)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Draw menkowski */
|
||||
/* Draw CLD_Menkowski */
|
||||
{
|
||||
|
||||
u32 color = collision_reuslt.solved ? Rgba32F(0, 0, 0.25, 1) : Rgba32F(0, 0.25, 0.25, 1);
|
||||
@ -1582,19 +1582,19 @@ internal void user_update(P_Window *window)
|
||||
u32 detail = 512;
|
||||
(UNUSED)thickness;
|
||||
|
||||
V2Array m = menkowski(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf, detail);
|
||||
Vec2Array m = CLD_Menkowski(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf, detail);
|
||||
|
||||
for (u64 i = 0; i < m.count; ++i) m.points[i] = MulXformV2(G.world_to_ui_xf, m.points[i]);
|
||||
draw_poly_line(G.render_sig, m, 1, thickness, color);
|
||||
//draw_poly(G.render_sig, m, color);
|
||||
}
|
||||
|
||||
/* Draw cloud */
|
||||
/* Draw CLD_PointCloud */
|
||||
{
|
||||
u32 color = Rgba32F(1, 1, 1, 1);
|
||||
f32 radius = 2;
|
||||
|
||||
V2Array m = cloud(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf);
|
||||
Vec2Array m = CLD_PointCloud(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf);
|
||||
|
||||
for (u64 i = 0; i < m.count; ++i) {
|
||||
Vec2 p = MulXformV2(G.world_to_ui_xf, m.points[i]);
|
||||
@ -1607,7 +1607,7 @@ internal void user_update(P_Window *window)
|
||||
f32 thickness = 2;
|
||||
u32 color = Rgba32F(1, 1, 1, 0.25);
|
||||
|
||||
V2Array m = {
|
||||
Vec2Array m = {
|
||||
.points = collision_reuslt.prototype.points,
|
||||
.count = collision_reuslt.prototype.len
|
||||
};
|
||||
@ -1627,7 +1627,7 @@ internal void user_update(P_Window *window)
|
||||
CLD_MenkowskiSimplex simplex = collision_reuslt.simplex;
|
||||
Vec2 simplex_points[] = { simplex.a.p, simplex.b.p, simplex.c.p };
|
||||
for (u64 i = 0; i < countof(simplex_points); ++i) simplex_points[i] = MulXformV2(G.world_to_ui_xf, simplex_points[i]);
|
||||
V2Array simplex_array = { .count = simplex.len, .points = simplex_points };
|
||||
Vec2Array simplex_array = { .count = simplex.len, .points = simplex_points };
|
||||
|
||||
if (simplex.len >= 1) {
|
||||
u32 color = simplex.len == 1 ? color_first : (simplex.len == 2 ? color_second : color_third);
|
||||
@ -1933,7 +1933,7 @@ internal void user_update(P_Window *window)
|
||||
String text = ZI;
|
||||
text.text = PushDry(temp.arena, u8);
|
||||
|
||||
#if BB_DebugIsEnabled
|
||||
#if BITBUFF_DEBUG
|
||||
text.len += CopyString(temp.arena, Lit("(bitbuff debug enabled)")).len;
|
||||
text.len += CopyString(temp.arena, Lit("\n")).len;
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user