Shape specific collision handling

This commit is contained in:
John Alanbrook 2023-02-17 07:16:52 +00:00
parent 260374c14d
commit afa9f963ef
4 changed files with 54 additions and 27 deletions

View file

@ -559,27 +559,45 @@ void register_collide(void *sym) {
}
static cpBool script_phys_cb_begin(cpArbiter *arb, cpSpace *space, void *data) {
cpBody *body1;
cpBody *body2;
cpArbiterGetBodies(arb, &body1, &body2);
int g1 = cpBodyGetUserData(body1);
int g2 = cpBodyGetUserData(body2);
duk_push_heapptr(duk, id2go(g1)->cbs.begin.fn);
duk_push_heapptr(duk, id2go(g1)->cbs.begin.obj);
void duk_call_phys_cb(cpArbiter *arb, struct callee c, int hit)
{
duk_push_heapptr(duk, c.fn);
duk_push_heapptr(duk, c.obj);
int obj = duk_push_object(duk);
vect2duk(cpArbiterGetNormal(arb));
duk_put_prop_literal(duk, obj, "normal");
duk_push_int(duk, g2);
duk_push_int(duk, hit);
duk_put_prop_literal(duk, obj, "hit");
duk_call_method(duk, 1);
duk_pop(duk);
}
static cpBool script_phys_cb_begin(cpArbiter *arb, cpSpace *space, void *data) {
cpBody *body1;
cpBody *body2;
cpArbiterGetBodies(arb, &body1, &body2);
cpShape *shape1;
cpShape *shape2;
cpArbiterGetShapes(arb, &shape1, &shape2);
int g1 = cpBodyGetUserData(body1);
int g2 = cpBodyGetUserData(body2);
struct gameobject *go = id2go(g1);
for (int i = 0; i < arrlen(go->shape_cbs); i++) {
if (go->shape_cbs[i].shape != shape1) continue;
duk_call_phys_cb(arb, go->shape_cbs[i].cbs.begin, g2);
}
duk_call_phys_cb(arb, go->cbs.begin, g2);
return 1;
}

View file

@ -106,6 +106,11 @@ struct phys_cbs {
struct callee separate;
};
struct shape_cb {
cpShape *shape;
struct phys_cbs cbs;
};
void phys2d_add_handler_type(int cmd, int go, struct callee c);
void register_collide(void *sym);
void phys2d_set_gravity(cpVect v);

View file

@ -742,14 +742,30 @@ duk_ret_t duk_register(duk_context *duk) {
return 0;
}
void gameobject_add_shape_collider(int go, struct callee c, struct phys2d_shape *shape)
{
struct shape_cb shapecb;
shapecb.shape = shape->shape;
shapecb.cbs.begin = c;
arrpush(id2go(go)->shape_cbs, shapecb);
}
duk_ret_t duk_register_collide(duk_context *duk) {
int cmd = duk_to_int(duk, 0);
void *fn = duk_get_heapptr(duk, 1);
void *obj = duk_get_heapptr(duk, 2);
int go = duk_get_int(duk, 3);
struct callee c = {fn, obj};
switch(cmd) {
case 0:
phys2d_add_handler_type(cmd, go, c);
break;
case 1:
gameobject_add_shape_collider(go, c, duk_get_pointer(duk,4));
break;
}
return 0;
}
@ -833,8 +849,6 @@ duk_ret_t duk_yughlog(duk_context *duk) {
return 0;
}
duk_ret_t duk_set_body(duk_context *duk) {
int cmd = duk_to_int(duk, 0);
int id = duk_to_int(duk, 1);
@ -1174,7 +1188,7 @@ void ffi_load()
DUK_FUNC(cmd, DUK_VARARGS);
DUK_FUNC(register, 3);
DUK_FUNC(register_collide, 4);
DUK_FUNC(register_collide, DUK_VARARGS);
DUK_FUNC(gui_text, 3);
DUK_FUNC(gui_img, 2);

View file

@ -12,17 +12,6 @@ struct shader;
struct sprite;
struct component;
struct editor {
mfloat_t color[3];
int id;
bool active;
bool prefabSync;
char mname[MAXNAME];
char *curPrefabPath;
char prefabName[MAXNAME];
char rootPrefabName[MAXNAME];
};
struct gameobject {
cpBodyType bodytype;
int next;
@ -36,6 +25,7 @@ struct gameobject {
cpBody *body; /* NULL if this object is dead */
int id;
struct phys_cbs cbs;
struct shape_cb *shape_cbs;
};
extern struct gameobject *gameobjects;