Skip to content

Commit

Permalink
Add frContextNode parameter to frRaycastQueryFunc
Browse files Browse the repository at this point in the history
  • Loading branch information
jdeokkim committed Oct 6, 2024
1 parent 8b70f68 commit 72f68ed
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 30 deletions.
2 changes: 1 addition & 1 deletion examples/src/cows.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ typedef enum _EntityType {
ENTITY_COUNT_
} EntityType;

typedef struct _EntityData {
typedef struct EntityData_ {
EntityType type;
float attackSpeed;
float movementSpeed;
Expand Down
2 changes: 1 addition & 1 deletion examples/src/melon.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@

/* Typedefs ================================================================ */

typedef struct _MelonKind {
typedef struct MelonKind_ {
int index;
Color color;
} MelonKind;
Expand Down
14 changes: 9 additions & 5 deletions examples/src/raycast.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static void DeinitExample(void);

static void DrawCursor(void);

static void OnRaycastQuery(frRaycastHit raycastHit);
static void OnRaycastQuery(frRaycastHit raycastHit, frContextNode node);

/* Public Functions ======================================================== */

Expand Down Expand Up @@ -191,7 +191,9 @@ static void UpdateExample(void) {
2.0f,
ColorAlpha(LIGHTGRAY, 0.95f));

frComputeRaycastForWorld(world, ray, OnRaycastQuery);
Color ringColor = ColorAlpha(YELLOW, 0.85f);

frComputeWorldRaycast(world, ray, OnRaycastQuery, &ringColor);

frDrawBodyLines(player, 2.0f, ColorAlpha(GREEN, 0.85f));

Expand Down Expand Up @@ -226,11 +228,13 @@ static void DrawCursor(void) {
WHITE);
}

static void OnRaycastQuery(frRaycastHit raycastHit) {
frDrawBodyAABB(raycastHit.body, 1.0f, YELLOW);
static void OnRaycastQuery(frRaycastHit raycastHit, frContextNode node) {
const Color *ringColor = node.ctx;

frDrawBodyAABB(raycastHit.body, 1.0f, *ringColor);

Vector2 center = { .x = frUnitsToPixels(raycastHit.point.x),
.y = frUnitsToPixels(raycastHit.point.y) };

DrawRing(center, 6.0f, 8.0f, 0.0f, 360.0f, 16, YELLOW);
DrawRing(center, 6.0f, 8.0f, 0.0f, 360.0f, 16, *ringColor);
}
2 changes: 1 addition & 1 deletion examples/src/raylib.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ static void InitExample(void) {
pieceWidth = raylibTexture.width / LOGO_WIDTH_IN_PIECES;
pieceHeight = raylibTexture.height / LOGO_HEIGHT_IN_PIECES;

halfPieceWidth = 0.5f * pieceWidth,
halfPieceWidth = 0.5f * pieceWidth;
halfPieceHeight = 0.5f * pieceHeight;

frShape *pieceShape = frCreateRectangle(
Expand Down
11 changes: 7 additions & 4 deletions include/ferox.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ typedef struct frWorld_ frWorld;
/* A structure that represents arbitrary data with an identifier. */
typedef struct frContextNode_ {
int id;
void *data;
void *ctx;
} frContextNode;

/* (From 'broad-phase.c') ================================================== */
Expand All @@ -131,7 +131,7 @@ typedef struct frContextNode_ {
typedef struct frSpatialHash_ frSpatialHash;

/* A callback function type for `frQuerySpatialHash()`. */
typedef bool (*frHashQueryFunc)(frContextNode ctx);
typedef bool (*frHashQueryFunc)(frContextNode node);

/* (From 'collision.c') ==================================================== */

Expand Down Expand Up @@ -252,7 +252,7 @@ typedef struct frCollisionHandler_ {
} frCollisionHandler;

/* A callback function type for `frComputeRaycastForWorld()`. */
typedef void (*frRaycastQueryFunc)(frRaycastHit raycastHit);
typedef void (*frRaycastQueryFunc)(frRaycastHit raycastHit, frContextNode node);

/* Public Function Prototypes ============================================== */

Expand Down Expand Up @@ -581,7 +581,10 @@ void frUpdateWorld(frWorld *w, float dt);
Casts a `ray` against all objects in `w`,
then calls `func` for each object that collides with `ray`.
*/
void frComputeRaycastForWorld(frWorld *w, frRay ray, frRaycastQueryFunc func);
void frComputeWorldRaycast(frWorld *w,
frRay ray,
frRaycastQueryFunc func,
void *ctx);

/* Inline Functions ======================================================== */

Expand Down
2 changes: 1 addition & 1 deletion src/broad-phase.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ void frQuerySpatialHash(frSpatialHash *sh,
will be called with the user data pointer `ctx`.
*/
for (int i = 0; i < arrlen(sh->queryResult); i++)
func((frContextNode) { .id = sh->queryResult[i], .data = ctx });
func((frContextNode) { .id = sh->queryResult[i], .ctx = ctx });
}

/* Private Functions ======================================================= */
Expand Down
39 changes: 22 additions & 17 deletions src/world.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,10 @@ typedef struct frPreStepHashQueryCtx_ {
for `frRaycastHashQueryCallback()`.
*/
typedef struct frRaycastHashQueryCtx_ {
frRay ray;
frWorld *world;
frRaycastQueryFunc func;
frWorld *world;
frRay ray;
void *ctx;
} frRaycastHashQueryCtx;

/* Private Function Prototypes ============================================= */
Expand Down Expand Up @@ -144,17 +145,17 @@ bool frAddBodyToWorld(frWorld *w, frBody *b) {
return false;

return frAddNodeToRingBuffer(w->rbf,
(frContextNode) { .id = FR_OPT_ADD_BODY,
.data = b });
(frContextNode) { .id = FR_OPT_ADD_BODY,
.ctx = b });
}

/* Removes a rigid `b`ody from `w`. */
bool frRemoveBodyFromWorld(frWorld *w, frBody *b) {
if (w == NULL || b == NULL) return false;

return frAddNodeToRingBuffer(w->rbf,
(frContextNode) { .id = FR_OPT_REMOVE_BODY,
.data = b });
(frContextNode) { .id = FR_OPT_REMOVE_BODY,
.ctx = b });
}

/* Checks if the given `b`ody is in `w`. */
Expand Down Expand Up @@ -275,7 +276,10 @@ void frUpdateWorld(frWorld *w, float dt) {
Casts a `ray` against all objects in `w`,
then calls `func` for each object that collides with `ray`.
*/
void frComputeRaycastForWorld(frWorld *w, frRay ray, frRaycastQueryFunc func) {
void frComputeWorldRaycast(frWorld *w,
frRay ray,
frRaycastQueryFunc func,
void *ctx) {
if (w == NULL || func == NULL) return;

frClearSpatialHash(w->hash);
Expand All @@ -296,7 +300,7 @@ void frComputeRaycastForWorld(frWorld *w, frRay ray, frRaycastQueryFunc func) {
.height = fabsf(maxVertex.y - minVertex.y) },
frRaycastHashQueryCallback,
&(frRaycastHashQueryCtx) {
.ray = ray, .world = w, .func = func });
.ctx = ctx, .ray = ray, .world = w, .func = func });
}

/* Private Functions ======================================================= */
Expand All @@ -305,10 +309,10 @@ void frComputeRaycastForWorld(frWorld *w, frRay ray, frRaycastQueryFunc func) {
A callback function for `frQuerySpatialHash()`
that will be called during `frPreStepWorld()`.
*/
static bool frPreStepHashQueryCallback(frContextNode ctx) {
frPreStepHashQueryCtx *queryCtx = ctx.data;
static bool frPreStepHashQueryCallback(frContextNode node) {
frPreStepHashQueryCtx *queryCtx = node.ctx;

int firstIndex = queryCtx->bodyIndex, secondIndex = ctx.id;
int firstIndex = queryCtx->bodyIndex, secondIndex = node.id;

if (firstIndex >= secondIndex) return false;

Expand Down Expand Up @@ -392,17 +396,18 @@ static bool frPreStepHashQueryCallback(frContextNode ctx) {
A callback function for `frQuerySpatialHash()`
that will be called during `frComputeRaycastForWorld()`.
*/
static bool frRaycastHashQueryCallback(frContextNode ctx) {
frRaycastHashQueryCtx *queryCtx = ctx.data;
static bool frRaycastHashQueryCallback(frContextNode node) {
frRaycastHashQueryCtx *queryCtx = node.ctx;

frRaycastHit raycastHit = { .distance = 0.0f };

if (!frComputeRaycast(queryCtx->world->bodies[ctx.id],
if (!frComputeRaycast(queryCtx->world->bodies[node.id],
queryCtx->ray,
&raycastHit))
return false;

queryCtx->func(raycastHit);
queryCtx->func(raycastHit,
(frContextNode) { .id = node.id, .ctx = queryCtx->ctx });

return true;
}
Expand Down Expand Up @@ -430,13 +435,13 @@ static void frPostStepWorld(frWorld *w) {
while (frRemoveNodeFromRingBuffer(w->rbf, &node)) {
switch (node.id) {
case FR_OPT_ADD_BODY:
arrput(w->bodies, node.data);
arrput(w->bodies, node.ctx);

break;

case FR_OPT_REMOVE_BODY:
for (int i = 0; i < arrlen(w->bodies); i++)
if (w->bodies[i] == node.data) {
if (w->bodies[i] == node.ctx) {
arrdelswap(w->bodies, i);

break;
Expand Down

0 comments on commit 72f68ed

Please sign in to comment.