Skip to content

Commit 42e5300

Browse files
committed
feat: added gjk, epa. EPA needs point computation
1 parent f5d809f commit 42e5300

6 files changed

Lines changed: 718 additions & 19 deletions

File tree

examples/example_basic_6.c

Lines changed: 120 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Index of this file:
4747
#include "pl_draw_ext.h"
4848
#include "pl_starter_ext.h"
4949
#include "pl_collision_ext.h"
50+
#include "pl_gjk_ext.h"
5051
#include "pl_screen_log_ext.h"
5152

5253
//-----------------------------------------------------------------------------
@@ -95,6 +96,7 @@ const plGraphicsI* gptGfx = NULL;
9596
const plDrawI* gptDraw = NULL;
9697
const plStarterI* gptStarter = NULL;
9798
const plCollisionI* gptCollision = NULL;
99+
const plGjkI* gptGjk = NULL;
98100
const plScreenLogI* gptScreenLog = NULL;
99101

100102
//-----------------------------------------------------------------------------
@@ -133,6 +135,7 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
133135
gptDraw = pl_get_api_latest(ptApiRegistry, plDrawI);
134136
gptStarter = pl_get_api_latest(ptApiRegistry, plStarterI);
135137
gptCollision = pl_get_api_latest(ptApiRegistry, plCollisionI);
138+
gptGjk = pl_get_api_latest(ptApiRegistry, plGjkI);
136139
gptScreenLog = pl_get_api_latest(ptApiRegistry, plScreenLogI);
137140

138141
return ptAppData;
@@ -159,6 +162,7 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
159162
gptDraw = pl_get_api_latest(ptApiRegistry, plDrawI);
160163
gptStarter = pl_get_api_latest(ptApiRegistry, plStarterI);
161164
gptCollision = pl_get_api_latest(ptApiRegistry, plCollisionI);
165+
gptGjk = pl_get_api_latest(ptApiRegistry, plGjkI);
162166
gptScreenLog = pl_get_api_latest(ptApiRegistry, plScreenLogI);
163167

164168
// use window API to create a window
@@ -275,13 +279,19 @@ pl_app_update(plAppData* ptAppData)
275279

276280
// simple variation setting to check things (until gizmo extension is stable)
277281
static uint32_t uVariation = 0;
278-
if(gptIO->is_key_pressed(PL_KEY_V, false))
282+
if(gptIO->is_key_pressed(PL_KEY_V, false) && uVariation < 3)
279283
uVariation++;
280-
if(gptIO->is_key_pressed(PL_KEY_B, false))
284+
if(gptIO->is_key_pressed(PL_KEY_B, false) && uVariation > 0)
281285
uVariation--;
282286

283-
// use screen log extension to display variation
287+
// toggle GJK mode
288+
static bool bUseGjk = false;
289+
if(gptIO->is_key_pressed(PL_KEY_G, false))
290+
bUseGjk = !bUseGjk;
291+
292+
// use screen log extension to display variation and mode
284293
gptScreenLog->add_message_ex(117, 0, PL_COLOR_32_WHITE, 2.0, "Variation: %u", uVariation);
294+
gptScreenLog->add_message_ex(118, 0, PL_COLOR_32_WHITE, 2.0, "Mode: %s (G to toggle)", bUseGjk ? "GJK" : "Collision Ext");
285295

286296
// sphere <-> sphere collision
287297
{
@@ -303,19 +313,35 @@ pl_app_update(plAppData* ptAppData)
303313
uint32_t uColor0 = PL_COLOR_32_RED;
304314
uint32_t uColor1 = PL_COLOR_32_RED;
305315

306-
if(gptCollision->sphere_sphere(&tSphere0, &tSphere1))
307-
uColor0 = PL_COLOR_32_GREEN;
308-
309-
plCollisionInfo tInfo = {0};
310-
if(gptCollision->pen_sphere_sphere(&tSphere0, &tSphere1, &tInfo))
316+
if(bUseGjk)
311317
{
312-
uColor1 = PL_COLOR_32_GREEN;
313-
gptDraw->add_3d_cross(ptAppData->pt3dDrawlist, tInfo.tPoint, 0.1f, (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_RED});
314-
gptDraw->add_3d_line(ptAppData->pt3dDrawlist, tInfo.tPoint, pl_add_vec3(tInfo.tPoint, pl_mul_vec3_scalarf(tInfo.tNormal, tInfo.fPenetration)), (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_GREEN});
318+
if(gptGjk->pen(gptGjk->support_sphere, &tSphere0, gptGjk->support_sphere, &tSphere1, NULL))
319+
uColor0 = PL_COLOR_32_GREEN;
320+
321+
plGjkCollisionInfo tInfo = {0};
322+
if(gptGjk->pen(gptGjk->support_sphere, &tSphere0, gptGjk->support_sphere, &tSphere1, &tInfo))
323+
{
324+
uColor1 = PL_COLOR_32_GREEN;
325+
gptDraw->add_3d_cross(ptAppData->pt3dDrawlist, tInfo.tPoint, 0.1f, (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_RED});
326+
gptDraw->add_3d_line(ptAppData->pt3dDrawlist, tInfo.tPoint, pl_add_vec3(tInfo.tPoint, pl_mul_vec3_scalarf(tInfo.tNormal, tInfo.fPenetration)), (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_GREEN});
327+
}
328+
}
329+
else
330+
{
331+
if(gptCollision->sphere_sphere(&tSphere0, &tSphere1))
332+
uColor0 = PL_COLOR_32_GREEN;
333+
334+
plCollisionInfo tInfo = {0};
335+
if(gptCollision->pen_sphere_sphere(&tSphere0, &tSphere1, &tInfo))
336+
{
337+
uColor1 = PL_COLOR_32_GREEN;
338+
gptDraw->add_3d_cross(ptAppData->pt3dDrawlist, tInfo.tPoint, 0.1f, (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_RED});
339+
gptDraw->add_3d_line(ptAppData->pt3dDrawlist, tInfo.tPoint, pl_add_vec3(tInfo.tPoint, pl_mul_vec3_scalarf(tInfo.tNormal, tInfo.fPenetration)), (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_GREEN});
340+
}
315341
}
316342

317343
gptDraw->add_3d_band_xy_filled(ptAppData->pt3dDrawlist, (plVec3){2.0f, 4.0f, 0.0f}, 0.05f, 0.25f, 0, (plDrawSolidOptions){.uColor = uColor0});
318-
gptDraw->add_3d_band_xy_filled(ptAppData->pt3dDrawlist, (plVec3){2.0f, 4.5f, 0.0f}, 0.05f, 0.25f, 0, (plDrawSolidOptions){.uColor = uColor1});
344+
gptDraw->add_3d_band_xy_filled(ptAppData->pt3dDrawlist, (plVec3){2.0f, 4.5f, 0.0f}, 0.05f, 0.25f, 0, (plDrawSolidOptions){.uColor = uColor1});
319345
}
320346

321347
// box <-> sphere collision
@@ -334,26 +360,101 @@ pl_app_update(plAppData* ptAppData)
334360
if(uVariation == 2) tSphere1.tCenter = (plVec3){5.2f, 2.9f, 0.0f};
335361
if(uVariation == 3) tSphere1.tCenter = (plVec3){4.3f, 2.0f, 0.0f};
336362
gptDraw->add_3d_sphere(ptAppData->pt3dDrawlist, tSphere1, 0, 0, (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_CYAN});
337-
363+
364+
uint32_t uColor0 = PL_COLOR_32_RED;
365+
uint32_t uColor1 = PL_COLOR_32_RED;
366+
367+
if(bUseGjk)
368+
{
369+
if(gptGjk->pen(gptGjk->support_box, &tBox0, gptGjk->support_sphere, &tSphere1, NULL))
370+
uColor0 = PL_COLOR_32_GREEN;
371+
372+
plGjkCollisionInfo tInfo = {0};
373+
if(gptGjk->pen(gptGjk->support_box, &tBox0, gptGjk->support_sphere, &tSphere1, &tInfo))
374+
{
375+
uColor1 = PL_COLOR_32_GREEN;
376+
gptDraw->add_3d_cross(ptAppData->pt3dDrawlist, tInfo.tPoint, 0.1f, (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_RED});
377+
gptDraw->add_3d_line(ptAppData->pt3dDrawlist, tInfo.tPoint, pl_add_vec3(tInfo.tPoint, pl_mul_vec3_scalarf(tInfo.tNormal, tInfo.fPenetration)), (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_GREEN});
378+
}
379+
}
380+
else
381+
{
382+
if(gptCollision->box_sphere(&tBox0, &tSphere1))
383+
uColor0 = PL_COLOR_32_GREEN;
384+
385+
plCollisionInfo tInfo = {0};
386+
if(gptCollision->pen_box_sphere(&tBox0, &tSphere1, &tInfo))
387+
{
388+
uColor1 = PL_COLOR_32_GREEN;
389+
gptDraw->add_3d_cross(ptAppData->pt3dDrawlist, tInfo.tPoint, 0.1f, (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_RED});
390+
gptDraw->add_3d_line(ptAppData->pt3dDrawlist, tInfo.tPoint, pl_add_vec3(tInfo.tPoint, pl_mul_vec3_scalarf(tInfo.tNormal, tInfo.fPenetration)), (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_GREEN});
391+
}
392+
}
393+
394+
gptDraw->add_3d_band_xy_filled(ptAppData->pt3dDrawlist, (plVec3){5.0f, 4.0f, 0.0f}, 0.05f, 0.25f, 0, (plDrawSolidOptions){.uColor = uColor0});
395+
gptDraw->add_3d_band_xy_filled(ptAppData->pt3dDrawlist, (plVec3){5.0f, 4.5f, 0.0f}, 0.05f, 0.25f, 0, (plDrawSolidOptions){.uColor = uColor1});
396+
}
397+
398+
// convex poly (icosahedron) <-> sphere collision (GJK only)
399+
{
400+
static const float fPhi = 1.618033988f; // golden ratio
401+
static const plVec3 tPolyCenter = {9.0f, 2.0f, 0.0f};
402+
static const float fScale = 0.5f;
403+
404+
// icosahedron vertices (centered at origin, then offset)
405+
plVec3 atIcoVerts[12] = {
406+
{-1, fPhi, 0}, { 1, fPhi, 0}, {-1, -fPhi, 0}, { 1, -fPhi, 0},
407+
{ 0, -1, fPhi}, { 0, 1, fPhi}, { 0, -1, -fPhi}, { 0, 1, -fPhi},
408+
{ fPhi, 0, -1}, { fPhi, 0, 1}, {-fPhi, 0, -1}, {-fPhi, 0, 1}
409+
};
410+
for (int ii = 0; ii < 12; ii++) {
411+
atIcoVerts[ii].x = atIcoVerts[ii].x * fScale + tPolyCenter.x;
412+
atIcoVerts[ii].y = atIcoVerts[ii].y * fScale + tPolyCenter.y;
413+
atIcoVerts[ii].z = atIcoVerts[ii].z * fScale + tPolyCenter.z;
414+
}
415+
416+
plConvexPoly tPoly = {
417+
.pVertices = atIcoVerts,
418+
.iVertexCount = 12
419+
};
420+
421+
// draw icosahedron edges
422+
static const int aiEdges[][2] = {
423+
{0,1},{0,5},{0,7},{0,10},{0,11},{1,5},{1,7},{1,8},{1,9},
424+
{2,3},{2,4},{2,6},{2,10},{2,11},{3,4},{3,6},{3,8},{3,9},
425+
{4,5},{4,9},{4,11},{5,9},{5,11},{6,7},{6,8},{6,10},{7,8},
426+
{7,10},{8,9},{10,11}
427+
};
428+
for (int ii = 0; ii < 30; ii++)
429+
gptDraw->add_3d_line(ptAppData->pt3dDrawlist, atIcoVerts[aiEdges[ii][0]], atIcoVerts[aiEdges[ii][1]], (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_WHITE});
430+
431+
plSphere tSphere1 = {
432+
.fRadius = 0.5f,
433+
.tCenter = {8.1f, 2.0f, 0.0f}
434+
};
435+
if(uVariation == 1) tSphere1.tCenter = (plVec3){8.5f, 2.0f, 0.0f};
436+
if(uVariation == 2) tSphere1.tCenter = (plVec3){9.0f, 2.8f, 0.0f};
437+
if(uVariation == 3) tSphere1.tCenter = (plVec3){7.5f, 2.0f, 0.0f};
438+
gptDraw->add_3d_sphere(ptAppData->pt3dDrawlist, tSphere1, 0, 0, (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_CYAN});
439+
338440
uint32_t uColor0 = PL_COLOR_32_RED;
339441
uint32_t uColor1 = PL_COLOR_32_RED;
340442

341-
if(gptCollision->box_sphere(&tBox0, &tSphere1))
443+
if(gptGjk->pen(gptGjk->support_convex_poly, &tPoly, gptGjk->support_sphere, &tSphere1, NULL))
342444
uColor0 = PL_COLOR_32_GREEN;
343445

344-
plCollisionInfo tInfo = {0};
345-
if(gptCollision->pen_box_sphere(&tBox0, &tSphere1, &tInfo))
446+
plGjkCollisionInfo tInfo = {0};
447+
if(gptGjk->pen(gptGjk->support_convex_poly, &tPoly, gptGjk->support_sphere, &tSphere1, &tInfo))
346448
{
347449
uColor1 = PL_COLOR_32_GREEN;
348450
gptDraw->add_3d_cross(ptAppData->pt3dDrawlist, tInfo.tPoint, 0.1f, (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_RED});
349451
gptDraw->add_3d_line(ptAppData->pt3dDrawlist, tInfo.tPoint, pl_add_vec3(tInfo.tPoint, pl_mul_vec3_scalarf(tInfo.tNormal, tInfo.fPenetration)), (plDrawLineOptions){.fThickness = 0.01f, .uColor = PL_COLOR_32_GREEN});
350452
}
351453

352-
gptDraw->add_3d_band_xy_filled(ptAppData->pt3dDrawlist, (plVec3){5.0f, 4.0f, 0.0f}, 0.05f, 0.25f, 0, (plDrawSolidOptions){.uColor = uColor0});
353-
gptDraw->add_3d_band_xy_filled(ptAppData->pt3dDrawlist, (plVec3){5.0f, 4.5f, 0.0f}, 0.05f, 0.25f, 0, (plDrawSolidOptions){.uColor = uColor1});
454+
gptDraw->add_3d_band_xy_filled(ptAppData->pt3dDrawlist, (plVec3){8.0f, 4.0f, 0.0f}, 0.05f, 0.25f, 0, (plDrawSolidOptions){.uColor = uColor0});
455+
gptDraw->add_3d_band_xy_filled(ptAppData->pt3dDrawlist, (plVec3){8.0f, 4.5f, 0.0f}, 0.05f, 0.25f, 0, (plDrawSolidOptions){.uColor = uColor1});
354456
}
355457

356-
357458
// start main pass & return the encoder being used
358459
plRenderEncoder* ptEncoder = gptStarter->begin_main_pass();
359460

0 commit comments

Comments
 (0)