Add MOI calculations for gameobject sync

This commit is contained in:
John Alanbrook 2023-02-24 18:11:36 +00:00
parent a613e19ffa
commit a3428f0d36
6 changed files with 82 additions and 9 deletions

View file

@ -192,11 +192,17 @@ struct phys2d_circle *Make2DCircle(int go)
new->shape.shape = cpSpaceAddShape(space, cpCircleShapeNew(id2go(go)->body, new->radius, cpvzero)); new->shape.shape = cpSpaceAddShape(space, cpCircleShapeNew(id2go(go)->body, new->radius, cpvzero));
new->shape.debugdraw = phys2d_dbgdrawcircle; new->shape.debugdraw = phys2d_dbgdrawcircle;
new->shape.moi = phys2d_circle_moi;
init_phys2dshape(&new->shape, go, new); init_phys2dshape(&new->shape, go, new);
return new; return new;
} }
float phys2d_circle_moi(struct phys2d_circle *c, float m)
{
return cpMomentForCircle(m, 0, c->radius, c->offset);
}
void phys2d_circledel(struct phys2d_circle *c) void phys2d_circledel(struct phys2d_circle *c)
{ {
phys2d_shape_del(&c->shape); phys2d_shape_del(&c->shape);
@ -288,10 +294,16 @@ struct phys2d_box *Make2DBox(int go)
new->shape.go = go; new->shape.go = go;
phys2d_applybox(new); phys2d_applybox(new);
new->shape.debugdraw = phys2d_dbgdrawbox; new->shape.debugdraw = phys2d_dbgdrawbox;
new->shape.moi = phys2d_box_moi;
return new; return new;
} }
float phys2d_box_moi(struct phys2d_box *box, float m)
{
return cpMomentForBox(m, box->w, box->h);
}
cpTransform go2transform(struct gameobject *go, cpVect offset, float angle) cpTransform go2transform(struct gameobject *go, cpVect offset, float angle)
{ {
cpTransform T = {0}; cpTransform T = {0};
@ -346,10 +358,16 @@ struct phys2d_poly *Make2DPoly(int go)
new->shape.shape = cpSpaceAddShape(space, cpPolyShapeNewRaw(id2go(go)->body, 0, new->points, new->radius)); new->shape.shape = cpSpaceAddShape(space, cpPolyShapeNewRaw(id2go(go)->body, 0, new->points, new->radius));
new->shape.debugdraw = phys2d_dbgdrawpoly; new->shape.debugdraw = phys2d_dbgdrawpoly;
new->shape.moi = phys2d_poly_moi;
init_phys2dshape(&new->shape, go, new); init_phys2dshape(&new->shape, go, new);
return new; return new;
} }
float phys2d_poly_moi(struct phys2d_poly *poly, float m)
{
return cpMomentForPoly(m, arrlen(poly->points), poly->points, cpvzero, poly->radius);
}
void phys2d_polydel(struct phys2d_poly *poly) void phys2d_polydel(struct phys2d_poly *poly)
{ {
arrfree(poly->points); arrfree(poly->points);
@ -409,12 +427,18 @@ struct phys2d_edge *Make2DEdge(int go)
new->shape.go = go; new->shape.go = go;
new->shape.data = new; new->shape.data = new;
new->shape.debugdraw = phys2d_dbgdrawedge; new->shape.debugdraw = phys2d_dbgdrawedge;
new->shape.moi = phys2d_edge_moi;
new->shape.shape = NULL; new->shape.shape = NULL;
phys2d_applyedge(new); phys2d_applyedge(new);
return new; return new;
} }
float phys2d_edge_moi(struct phys2d_edge *edge, float m)
{
return m;
}
void phys2d_edgedel(struct phys2d_edge *edge) void phys2d_edgedel(struct phys2d_edge *edge)
{ {
phys2d_shape_del(&edge->shape); phys2d_shape_del(&edge->shape);
@ -585,7 +609,8 @@ void duk_call_phys_cb(cpArbiter *arb, struct callee c, int hit)
duk_pop(duk); duk_pop(duk);
} }
static cpBool script_phys_cb_begin(cpArbiter *arb, cpSpace *space, void *data) { static cpBool script_phys_cb_begin(cpArbiter *arb, cpSpace *space, void *data)
{
cpBody *body1; cpBody *body1;
cpBody *body2; cpBody *body2;
@ -603,11 +628,20 @@ static cpBool script_phys_cb_begin(cpArbiter *arb, cpSpace *space, void *data) {
duk_call_phys_cb(arb, go->shape_cbs[i].cbs.begin, g2); duk_call_phys_cb(arb, go->shape_cbs[i].cbs.begin, g2);
} }
duk_call_phys_cb(arb, go->cbs.begin, g2); if (go->cbs.begin.obj)
duk_call_phys_cb(arb, go->cbs.begin, g2);
return 1; return 1;
} }
void phys2d_rm_go_handlers(int go)
{
cpCollisionHandler *handler = cpSpaceAddWildcardHandler(space, go);
handler->userData = NULL;
handler->beginFunc = NULL;
handler->separateFunc = NULL;
}
void phys2d_add_handler_type(int cmd, int go, struct callee c) { void phys2d_add_handler_type(int cmd, int go, struct callee c) {
cpCollisionHandler *handler = cpSpaceAddWildcardHandler(space, go); cpCollisionHandler *handler = cpSpaceAddWildcardHandler(space, go);

View file

@ -20,6 +20,7 @@ struct phys2d_shape {
int go; int go;
void *data; void *data;
void (*debugdraw)(void *data); void (*debugdraw)(void *data);
float (*moi)(void *data, float mass);
}; };
/* Circles are the fastest collier type */ /* Circles are the fastest collier type */
@ -68,11 +69,13 @@ struct phys2d_circle *Make2DCircle(int go);
void phys2d_circledel(struct phys2d_circle *c); void phys2d_circledel(struct phys2d_circle *c);
void phys2d_applycircle(struct phys2d_circle *circle); void phys2d_applycircle(struct phys2d_circle *circle);
void phys2d_dbgdrawcircle(struct phys2d_circle *circle); void phys2d_dbgdrawcircle(struct phys2d_circle *circle);
float phys2d_circle_moi(struct phys2d_circle *c, float m);
struct phys2d_box *Make2DBox(int go); struct phys2d_box *Make2DBox(int go);
void phys2d_boxdel(struct phys2d_box *box); void phys2d_boxdel(struct phys2d_box *box);
void phys2d_applybox(struct phys2d_box *box); void phys2d_applybox(struct phys2d_box *box);
void phys2d_dbgdrawbox(struct phys2d_box *box); void phys2d_dbgdrawbox(struct phys2d_box *box);
float phys2d_box_moi(struct phys2d_box *box, float m);
struct phys2d_poly *Make2DPoly(int go); struct phys2d_poly *Make2DPoly(int go);
void phys2d_polydel(struct phys2d_poly *poly); void phys2d_polydel(struct phys2d_poly *poly);
@ -80,6 +83,7 @@ void phys2d_applypoly(struct phys2d_poly *poly);
void phys2d_dbgdrawpoly(struct phys2d_poly *poly); void phys2d_dbgdrawpoly(struct phys2d_poly *poly);
void phys2d_polyaddvert(struct phys2d_poly *poly); void phys2d_polyaddvert(struct phys2d_poly *poly);
void phys2d_poly_setverts(struct phys2d_poly *poly, cpVect *verts); void phys2d_poly_setverts(struct phys2d_poly *poly, cpVect *verts);
float phys2d_poly_moi(struct phys2d_poly *poly, float m);
struct phys2d_edge *Make2DEdge(int go); struct phys2d_edge *Make2DEdge(int go);
void phys2d_edgedel(struct phys2d_edge *edge); void phys2d_edgedel(struct phys2d_edge *edge);
@ -87,6 +91,7 @@ void phys2d_applyedge(struct phys2d_edge *edge);
void phys2d_dbgdrawedge(struct phys2d_edge *edge); void phys2d_dbgdrawedge(struct phys2d_edge *edge);
void phys2d_edgeaddvert(struct phys2d_edge *edge); void phys2d_edgeaddvert(struct phys2d_edge *edge);
void phys2d_edge_rmvert(struct phys2d_edge *edge, int index); void phys2d_edge_rmvert(struct phys2d_edge *edge, int index);
float phys2d_edge_moi(struct phys2d_edge *edge, float m);
void phys2d_edge_setvert(struct phys2d_edge *edge, int index, cpVect val); void phys2d_edge_setvert(struct phys2d_edge *edge, int index, cpVect val);
void phys2d_edge_clearverts(struct phys2d_edge *edge); void phys2d_edge_clearverts(struct phys2d_edge *edge);
@ -111,6 +116,7 @@ struct shape_cb {
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_rm_go_handlers(int go);
void phys2d_set_gravity(cpVect v); void phys2d_set_gravity(cpVect v);
void shape_enabled(struct phys2d_shape *shape, int enabled); void shape_enabled(struct phys2d_shape *shape, int enabled);

View file

@ -659,12 +659,10 @@ duk_ret_t duk_cmd(duk_context *duk) {
case 55: case 55:
duk2go(duk, 1)->flipx = duk_to_boolean(duk, 2) ? -1 : 1; duk2go(duk, 1)->flipx = duk_to_boolean(duk, 2) ? -1 : 1;
gameobject_apply(duk2go(duk, 1));
return 0; return 0;
case 56: case 56:
duk2go(duk, 1)->flipy = duk_to_boolean(duk, 2) ? -1 : 1; duk2go(duk, 1)->flipy = duk_to_boolean(duk, 2) ? -1 : 1;
gameobject_apply(duk2go(duk, 1));
return 0; return 0;
case 57: case 57:
@ -767,6 +765,11 @@ duk_ret_t duk_register(duk_context *duk) {
case 3: case 3:
register_nk_gui(c); register_nk_gui(c);
break; break;
case 4:
unregister_obj(obj);
break;
} }
return 0; return 0;
@ -795,6 +798,9 @@ duk_ret_t duk_register_collide(duk_context *duk) {
case 1: case 1:
gameobject_add_shape_collider(go, c, duk_get_pointer(duk,4)); gameobject_add_shape_collider(go, c, duk_get_pointer(duk,4));
break; break;
case 2:
phys2d_rm_go_handlers(go);
} }
return 0; return 0;
@ -892,7 +898,7 @@ duk_ret_t duk_set_body(duk_context *duk) {
break; break;
case 1: case 1:
cpBodySetType(go->body, duk_to_int(duk, 2)); go->bodytype = duk_to_int(duk,2);
break; break;
case 2: case 2:

View file

@ -97,17 +97,28 @@ void go_shape_apply(cpBody *body, cpShape *shape, struct gameobject *go)
cpShapeSetElasticity(shape, go->e); cpShapeSetElasticity(shape, go->e);
cpShapeSetSensor(shape, go->sensor); cpShapeSetSensor(shape, go->sensor);
cpShapeSetCollisionType(shape, go2id(go)); cpShapeSetCollisionType(shape, go2id(go));
float moment = cpBodyGetMoment(go->body);
struct phys2d_shape *s = cpShapeGetUserData(shape);
if (!s) {
cpBodySetMoment(go->body, moment+1);
return;
}
moment += s->moi(s->data, go->mass);
cpBodySetMoment(go->body, moment);
// cpShapeSetFilter(shape, go->filter); // cpShapeSetFilter(shape, go->filter);
} }
void gameobject_apply(struct gameobject *go) void gameobject_apply(struct gameobject *go)
{ {
cpBodySetType(go->body, go->bodytype); cpBodySetType(go->body, go->bodytype);
cpBodySetMoment(go->body, 0.f);
cpBodyEachShape(go->body, go_shape_apply, go);
if (go->bodytype == CP_BODY_TYPE_DYNAMIC) if (go->bodytype == CP_BODY_TYPE_DYNAMIC)
cpBodySetMass(go->body, go->mass); cpBodySetMass(go->body, go->mass);
cpBodyEachShape(go->body, go_shape_apply, go);
} }
static void gameobject_setpickcolor(struct gameobject *go) static void gameobject_setpickcolor(struct gameobject *go)

View file

@ -156,6 +156,21 @@ struct callee *physics = NULL;
struct callee *guis = NULL; struct callee *guis = NULL;
struct callee *nk_guis = NULL; struct callee *nk_guis = NULL;
void unregister_obj(void *obj)
{
for (int i = arrlen(updates)-1; i >= 0; i--)
if (updates[i].obj == obj) arrdel(updates, i);
for (int i = arrlen(physics)-1; i >= 0; i--)
if (physics[i].obj == obj) arrdel(physics,i);
for (int i = arrlen(guis)-1; i >= 0; i--)
if (guis[i].obj == obj) arrdel(guis,i);
for (int i = arrlen(nk_guis)-1; i >= 0; i--)
if (guis[i].obj == obj) arrdel(nk_guis,i);
}
void register_update(struct callee c) { void register_update(struct callee c) {
arrput(updates, c); arrput(updates, c);
} }

View file

@ -40,6 +40,7 @@ void register_gui(struct callee c);
void register_nk_gui(struct callee c); void register_nk_gui(struct callee c);
void call_gui(); void call_gui();
void call_nk_gui(); void call_nk_gui();
void unregister_obj(void *obj);
void register_physics(struct callee c); void register_physics(struct callee c);
void call_physics(double dt); void call_physics(double dt);