Skip to content

Commit

Permalink
Refactor include/ferox.h
Browse files Browse the repository at this point in the history
  • Loading branch information
jdeokkim committed Oct 6, 2024
1 parent 72f68ed commit 178a867
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 57 deletions.
6 changes: 3 additions & 3 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, frContextNode node);
static void OnRaycastQuery(frRaycastHit raycastHit, frContextNode queryResult);

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

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

static void OnRaycastQuery(frRaycastHit raycastHit, frContextNode node) {
const Color *ringColor = node.ctx;
static void OnRaycastQuery(frRaycastHit raycastHit, frContextNode queryResult) {
const Color *ringColor = queryResult.ctx;

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

Expand Down
17 changes: 9 additions & 8 deletions include/ferox.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ typedef struct frContextNode_ {
typedef struct frSpatialHash_ frSpatialHash;

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

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

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

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

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

Expand All @@ -277,7 +278,7 @@ void frInsertIntoSpatialHash(frSpatialHash *sh, frAABB key, int value);
void frQuerySpatialHash(frSpatialHash *sh,
frAABB aabb,
frHashQueryFunc func,
void *ctx);
void *userData);

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

Expand Down Expand Up @@ -471,8 +472,8 @@ void frSetBodyVelocity(frBody *b, frVector2 v);
/* Sets the `angularVelocity` of `b`. */
void frSetBodyAngularVelocity(frBody *b, float angularVelocity);

/* Sets the user data of `b` to `ctx`. */
void frSetBodyUserData(frBody *b, void *ctx);
/* Sets the user data of `b` to `userData`. */
void frSetBodyUserData(frBody *b, void *userData);

/* Checks if the given `point` lies inside `b`. */
bool frBodyContainsPoint(const frBody *b, frVector2 point);
Expand All @@ -490,7 +491,7 @@ void frApplyGravityToBody(frBody *b, frVector2 g);
void frApplyImpulseToBody(frBody *b, frVector2 point, frVector2 impulse);

/* Applies accumulated impulses to `b1` and `b2`. */
void frApplyAccumulatedImpulses(frBody *b1, frBody *b2, frCollision *ctx);
void frApplyAccumulatedImpulses(frBody *b1, frBody *b2, frCollision *collision);

/*
Calculates the acceleration of `b` from the accumulated forces,
Expand All @@ -508,7 +509,7 @@ void frIntegrateForBodyPosition(frBody *b, float dt);
/* Resolves the collision between `b1` and `b2`. */
void frResolveCollision(frBody *b1,
frBody *b2,
frCollision *ctx,
frCollision *collision,
float inverseDt);

/* (From 'timer.c') ======================================================== */
Expand Down Expand Up @@ -584,7 +585,7 @@ void frUpdateWorld(frWorld *w, float dt);
void frComputeWorldRaycast(frWorld *w,
frRay ray,
frRaycastQueryFunc func,
void *ctx);
void *userData);

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

Expand Down
4 changes: 2 additions & 2 deletions src/broad-phase.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ void frInsertIntoSpatialHash(frSpatialHash *sh, frAABB key, int value) {
void frQuerySpatialHash(frSpatialHash *sh,
frAABB aabb,
frHashQueryFunc func,
void *ctx) {
void *userData) {
if (sh == NULL) return;

float inverseCellSize = sh->inverseCellSize;
Expand Down 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], .ctx = ctx });
func((frContextNode) { .id = sh->queryResult[i], .ctx = userData });
}

/* Private Functions ======================================================= */
Expand Down
73 changes: 39 additions & 34 deletions src/rigid-body.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,8 @@ void frSetBodyAngularVelocity(frBody *b, float angularVelocity) {
}

/* Sets the user data of `b` to `ctx`. */
void frSetBodyUserData(frBody *b, void *ctx) {
if (b != NULL) b->ctx = ctx;
void frSetBodyUserData(frBody *b, void *userData) {
if (b != NULL) b->ctx = userData;
}

/* Checks if the given `point` lies inside `b`. */
Expand Down Expand Up @@ -332,8 +332,10 @@ void frApplyImpulseToBody(frBody *b, frVector2 point, frVector2 impulse) {
}

/* Applies accumulated impulses to `b1` and `b2`. */
void frApplyAccumulatedImpulses(frBody *b1, frBody *b2, frCollision *ctx) {
if (b1 == NULL || b2 == NULL || ctx == NULL) return;
void frApplyAccumulatedImpulses(frBody *b1,
frBody *b2,
frCollision *collision) {
if (b1 == NULL || b2 == NULL || collision == NULL) return;

if (b1->mtn.inverseMass + b2->mtn.inverseMass <= 0.0f) {
if (frGetBodyType(b1) == FR_BODY_STATIC)
Expand All @@ -347,29 +349,31 @@ void frApplyAccumulatedImpulses(frBody *b1, frBody *b2, frCollision *ctx) {
return;
}

frVector2 ctxTangent = frVector2RightNormal(ctx->direction);
frVector2 ctxTangent = frVector2RightNormal(collision->direction);

for (int i = 0; i < ctx->count; i++) {
frVector2 contactPoint = ctx->contacts[i].point;
for (int i = 0; i < collision->count; i++) {
frVector2 contactPoint = collision->contacts[i].point;

frVector2 relPosition1 = frVector2Subtract(contactPoint,
frGetBodyPosition(b1));
frVector2 relPosition2 = frVector2Subtract(contactPoint,
frGetBodyPosition(b2));

float relPositionCross1 = frVector2Cross(relPosition1, ctx->direction);
float relPositionCross2 = frVector2Cross(relPosition2, ctx->direction);
float relPositionCross1 = frVector2Cross(relPosition1,
collision->direction);
float relPositionCross2 = frVector2Cross(relPosition2,
collision->direction);

float normalMass = (b1->mtn.inverseMass + b2->mtn.inverseMass)
+ b1->mtn.inverseInertia
* (relPositionCross1 * relPositionCross1)
+ b2->mtn.inverseInertia
* (relPositionCross2 * relPositionCross2);

ctx->contacts[i].cache.normalMass = 1.0f / normalMass;
collision->contacts[i].cache.normalMass = 1.0f / normalMass;

frVector2 accNormalImpulse = frVector2ScalarMultiply(
ctx->direction, ctx->contacts[i].cache.normalScalar);
collision->direction, collision->contacts[i].cache.normalScalar);

relPositionCross1 = frVector2Cross(relPosition1, ctxTangent);
relPositionCross2 = frVector2Cross(relPosition2, ctxTangent);
Expand All @@ -380,10 +384,10 @@ void frApplyAccumulatedImpulses(frBody *b1, frBody *b2, frCollision *ctx) {
+ b2->mtn.inverseInertia
* (relPositionCross2 * relPositionCross2);

ctx->contacts[i].cache.tangentMass = 1.0f / tangentMass;
collision->contacts[i].cache.tangentMass = 1.0f / tangentMass;

frVector2 accTangentImpulse = frVector2ScalarMultiply(
ctxTangent, ctx->contacts[i].cache.tangentScalar);
ctxTangent, collision->contacts[i].cache.tangentScalar);

{
frVector2 accImpulse = frVector2Add(accNormalImpulse,
Expand Down Expand Up @@ -443,17 +447,17 @@ void frIntegrateForBodyPosition(frBody *b, float dt) {
/* Resolves the collision between `b1` and `b2`. */
void frResolveCollision(frBody *b1,
frBody *b2,
frCollision *ctx,
frCollision *collision,
float inverseDt) {
if (b1 == NULL || b2 == NULL
|| b1->mtn.inverseMass + b2->mtn.inverseMass <= 0.0f || ctx == NULL
|| inverseDt <= 0.0f)
|| b1->mtn.inverseMass + b2->mtn.inverseMass <= 0.0f
|| collision == NULL || inverseDt <= 0.0f)
return;

frVector2 ctxTangent = frVector2RightNormal(ctx->direction);
frVector2 ctxTangent = frVector2RightNormal(collision->direction);

for (int i = 0; i < ctx->count; i++) {
frVector2 contactPoint = ctx->contacts[i].point;
for (int i = 0; i < collision->count; i++) {
frVector2 contactPoint = collision->contacts[i].point;

frVector2 relPosition1 = frVector2Subtract(contactPoint,
frGetBodyPosition(b1));
Expand All @@ -471,29 +475,29 @@ void frResolveCollision(frBody *b1,
frVector2ScalarMultiply(relNormal1,
b1->mtn.angularVelocity)));

float relVelocityDot = frVector2Dot(relVelocity, ctx->direction);
float relVelocityDot = frVector2Dot(relVelocity, collision->direction);

float biasScalar = -(FR_WORLD_BAUMGARTE_FACTOR * inverseDt)
* fminf(0.0f,
-ctx->contacts[i].depth
-collision->contacts[i].depth
+ FR_WORLD_BAUMGARTE_SLOP);

float normalScalar = ((-(1.0f + ctx->restitution) * relVelocityDot)
float normalScalar = ((-(1.0f + collision->restitution)
* relVelocityDot)
+ biasScalar)
* ctx->contacts[i].cache.normalMass;
* collision->contacts[i].cache.normalMass;

{
float oldNormalScalar = ctx->contacts[i].cache.normalScalar;
float oldNormalScalar = collision->contacts[i].cache.normalScalar;

ctx->contacts[i].cache.normalScalar = fmaxf(0.0f,
oldNormalScalar
+ normalScalar);
collision->contacts[i].cache.normalScalar =
fmaxf(0.0f, oldNormalScalar + normalScalar);

normalScalar = ctx->contacts[i].cache.normalScalar
normalScalar = collision->contacts[i].cache.normalScalar
- oldNormalScalar;
}

frVector2 normalImpulse = frVector2ScalarMultiply(ctx->direction,
frVector2 normalImpulse = frVector2ScalarMultiply(collision->direction,
normalScalar);

relVelocity = frVector2Subtract(
Expand All @@ -505,19 +509,20 @@ void frResolveCollision(frBody *b1,
b1->mtn.angularVelocity)));

float tangentScalar = -frVector2Dot(relVelocity, ctxTangent)
* ctx->contacts[i].cache.tangentMass;
* collision->contacts[i].cache.tangentMass;

{
float maxTangentScalar = fabsf(
ctx->friction * ctx->contacts[i].cache.normalScalar);
collision->friction
* collision->contacts[i].cache.normalScalar);

float oldTangentScalar = ctx->contacts[i].cache.tangentScalar;
float oldTangentScalar = collision->contacts[i].cache.tangentScalar;

ctx->contacts[i].cache.tangentScalar = fminf(
collision->contacts[i].cache.tangentScalar = fminf(
fmaxf(oldTangentScalar + tangentScalar, -maxTangentScalar),
maxTangentScalar);

tangentScalar = ctx->contacts[i].cache.tangentScalar
tangentScalar = collision->contacts[i].cache.tangentScalar
- oldTangentScalar;
}

Expand Down
23 changes: 13 additions & 10 deletions src/world.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ void frUpdateWorld(frWorld *w, float dt) {
void frComputeWorldRaycast(frWorld *w,
frRay ray,
frRaycastQueryFunc func,
void *ctx) {
void *userData) {
if (w == NULL || func == NULL) return;

frClearSpatialHash(w->hash);
Expand All @@ -299,8 +299,10 @@ void frComputeWorldRaycast(frWorld *w,
.width = fabsf(maxVertex.x - minVertex.x),
.height = fabsf(maxVertex.y - minVertex.y) },
frRaycastHashQueryCallback,
&(frRaycastHashQueryCtx) {
.ctx = ctx, .ray = ray, .world = w, .func = func });
&(frRaycastHashQueryCtx) { .ctx = userData,
.ray = ray,
.world = w,
.func = func });
}

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

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

if (firstIndex >= secondIndex) return false;

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

frRaycastHit raycastHit = { .distance = 0.0f };

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

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

return true;
}
Expand Down

0 comments on commit 178a867

Please sign in to comment.