prosperon/source/engine/2dphysics.c

128 lines
3.3 KiB
C
Raw Normal View History

2021-11-30 21:29:18 -06:00
#include "2dphysics.h"
#include "gameobject.h"
2022-12-20 08:16:26 -06:00
#include "stb_ds.h"
2023-11-03 22:01:30 -05:00
#include "jsffi.h"
2022-08-17 00:01:51 -05:00
2021-11-30 21:29:18 -06:00
cpSpace *space = NULL;
static JSValue fns[100];
static JSValue hits[100];
static int cb_idx = 0;
2023-05-24 20:45:50 -05:00
void phys2d_init()
{
2023-05-12 13:22:05 -05:00
space = cpSpaceNew();
}
2024-01-14 10:24:31 -06:00
constraint *constraint_make(cpConstraint *c)
{
constraint *cp = malloc(sizeof(*cp));
cp->c = c;
cp->break_cb = JS_UNDEFINED;
cp->remove_cb = JS_UNDEFINED;
cpSpaceAddConstraint(space,c);
cpConstraintSetUserData(c, cp);
return cp;
}
void constraint_break(constraint *constraint)
{
if (!constraint->c) return;
cpSpaceRemoveConstraint(space, constraint->c);
cpConstraintFree(constraint->c);
constraint->c = NULL;
script_call_sym(constraint->break_cb,0,NULL);
2024-01-14 10:24:31 -06:00
}
void constraint_free(constraint *constraint)
{
constraint_break(constraint);
free(constraint);
}
void constraint_test(cpConstraint *constraint, float *dt)
{
float max = cpConstraintGetMaxForce(constraint);
if (!isfinite(max)) return;
float force = cpConstraintGetImpulse(constraint)/ *dt;
if (force > max)
constraint_break(cpConstraintGetUserData(constraint));
}
void phys2d_update(float deltaT) {
cpSpaceStep(space, deltaT);
cpSpaceEachConstraint(space, constraint_test, &deltaT);
cb_idx = 0;
2024-01-14 10:24:31 -06:00
}
2021-11-30 21:29:18 -06:00
2024-01-03 17:19:13 -06:00
JSValue arb2js(cpArbiter *arb)
{
cpBody *body1;
cpBody *body2;
cpArbiterGetBodies(arb, &body1, &body2);
2023-05-12 13:22:05 -05:00
cpShape *shape1;
cpShape *shape2;
cpArbiterGetShapes(arb, &shape1, &shape2);
2024-05-17 12:39:04 -05:00
JSValue *j = cpShapeGetUserData(shape2);
JSValue jg = body2go(body2)->ref;
HMM_Vec2 srfv;
srfv.cp = cpArbiterGetSurfaceVelocity(arb);
2023-05-12 13:22:05 -05:00
JSValue obj = JS_NewObject(js);
JS_SetPropertyStr(js, obj, "normal", vec22js((HMM_Vec2)cpArbiterGetNormal(arb)));
2024-05-17 12:39:04 -05:00
JS_SetPropertyStr(js, obj, "obj", JS_DupValue(js,jg));
JS_SetPropertyStr(js, obj, "shape", JS_DupValue(js, *j));
JS_SetPropertyStr(js, obj, "point", vec22js((HMM_Vec2)cpArbiterGetPointA(arb, 0)));
JS_SetPropertyStr(js, obj, "velocity", vec22js(srfv));
2023-05-27 10:13:20 -05:00
2024-01-03 17:19:13 -06:00
return obj;
2023-02-17 01:16:52 -06:00
}
2024-01-03 17:19:13 -06:00
void phys_run_post(cpSpace *space, JSValue *fn, JSValue *hit)
{
2024-04-03 00:44:08 -05:00
script_call_sym(*fn, 1, hit);
JS_FreeValue(js, *hit);
JS_FreeValue(js, *fn);
2024-01-03 17:19:13 -06:00
}
void register_hit(cpArbiter *arb, gameobject *go, const char *name)
2024-01-03 17:19:13 -06:00
{
2024-04-11 17:17:49 -05:00
if (JS_IsUndefined(go->ref)) return;
JSValue cb = JS_GetPropertyStr(js, go->ref, name);
if (!JS_IsUndefined(cb)) {
JSValue jarb = arb2js(arb);
fns[cb_idx] = JS_DupValue(js, cb);
hits[cb_idx] = jarb;
cpSpaceAddPostStepCallback(space, phys_run_post, &fns[cb_idx], &hits[cb_idx]);
cb_idx++;
2024-03-22 09:02:10 -05:00
}
2024-01-03 17:19:13 -06:00
cpShape *s1, *s2;
2024-05-17 12:39:04 -05:00
cpArbiterGetShapes(arb, &s1, &s2);
JSValue *j1 = cpShapeGetUserData(s1);
JSValue *j2 = cpShapeGetUserData(s2);
cb = JS_GetPropertyStr(js, *j1, name);
if (!JS_IsUndefined(cb)) {
JSValue jarb = arb2js(arb);
fns[cb_idx] = JS_DupValue(js,cb);
hits[cb_idx] = jarb;
cpSpaceAddPostStepCallback(space, phys_run_post, &fns[cb_idx], &hits[cb_idx]);
cb_idx++;
2024-01-03 17:19:13 -06:00
}
}
2024-04-12 13:53:00 -05:00
int script_phys_cb_begin(cpArbiter *arb, cpSpace *space, gameobject *go) { register_hit(arb, go, "collide"); return 1; }
void script_phys_cb_separate(cpArbiter *arb, cpSpace *space, gameobject *go) { register_hit(arb, go, "separate"); }
2023-12-11 08:36:45 -06:00
void phys2d_setup_handlers(gameobject *go) {
cpCollisionHandler *handler = cpSpaceAddWildcardHandler(space, (cpCollisionType)go);
2023-12-11 08:36:45 -06:00
handler->userData = go;
2024-04-11 17:17:49 -05:00
handler->beginFunc = script_phys_cb_begin;
2023-03-17 10:25:35 -05:00
handler->separateFunc = script_phys_cb_separate;
2023-03-10 13:13:48 -06:00
}