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) { void duk_call_phys_cb(cpArbiter *arb, struct callee c, int hit)
cpBody *body1; {
cpBody *body2; duk_push_heapptr(duk, c.fn);
cpArbiterGetBodies(arb, &body1, &body2); duk_push_heapptr(duk, c.obj);
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);
int obj = duk_push_object(duk); int obj = duk_push_object(duk);
vect2duk(cpArbiterGetNormal(arb)); vect2duk(cpArbiterGetNormal(arb));
duk_put_prop_literal(duk, obj, "normal"); 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_put_prop_literal(duk, obj, "hit");
duk_call_method(duk, 1); duk_call_method(duk, 1);
duk_pop(duk); 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; return 1;
} }

View file

@ -106,6 +106,11 @@ struct phys_cbs {
struct callee separate; 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 phys2d_add_handler_type(int cmd, int go, struct callee c);
void register_collide(void *sym); void register_collide(void *sym);
void phys2d_set_gravity(cpVect v); void phys2d_set_gravity(cpVect v);

View file

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

View file

@ -12,17 +12,6 @@ struct shader;
struct sprite; struct sprite;
struct component; 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 { struct gameobject {
cpBodyType bodytype; cpBodyType bodytype;
int next; int next;
@ -36,6 +25,7 @@ struct gameobject {
cpBody *body; /* NULL if this object is dead */ cpBody *body; /* NULL if this object is dead */
int id; int id;
struct phys_cbs cbs; struct phys_cbs cbs;
struct shape_cb *shape_cbs;
}; };
extern struct gameobject *gameobjects; extern struct gameobject *gameobjects;