removed unnecessary physics code

This commit is contained in:
John Alanbrook 2024-05-17 12:39:04 -05:00
parent ba2409fc56
commit 4e4667db50
9 changed files with 160 additions and 716 deletions

View file

@ -1,3 +1,5 @@
var debug = {};
debug.fn_break = function(fn,obj = globalThis) { debug.fn_break = function(fn,obj = globalThis) {
if (typeof fn !== 'function') return; if (typeof fn !== 'function') return;

View file

@ -119,6 +119,7 @@ prosperon.textinput = function(c){
}; };
prosperon.mousemove = function(pos, dx){ prosperon.mousemove = function(pos, dx){
mousepos = pos; mousepos = pos;
mousepos.y = window.size.y - mousepos.y;
player[0].mouse_input("move", pos, dx); player[0].mouse_input("move", pos, dx);
}; };
prosperon.mousescroll = function(dx){ prosperon.mousescroll = function(dx){

View file

@ -1,140 +1,18 @@
#include "2dphysics.h" #include "2dphysics.h"
#include "gameobject.h" #include "gameobject.h"
#include <string.h>
#include "stb_ds.h" #include "stb_ds.h"
#include <assert.h>
#include <chipmunk/chipmunk_unsafe.h>
#include <math.h>
#include "2dphysics.h"
#include "jsffi.h" #include "jsffi.h"
#include "script.h"
#include "log.h"
cpSpace *space = NULL; cpSpace *space = NULL;
struct rgba color_white = {255,255,255,255};
struct rgba color_black = {0,0,0,255};
struct rgba color_clear = {0,0,0,0};
struct rgba disabled_color = {148,148,148,255};
struct rgba sleep_color = {255,140,228,255};
struct rgba dynamic_color = {255,70,46,255};
struct rgba kinematic_color = {255, 194, 64, 255};
struct rgba static_color = {73,209,80,255};
static JSValue fns[100]; static JSValue fns[100];
static JSValue hits[100]; static JSValue hits[100];
static int cb_idx = 0; static int cb_idx = 0;
static const unsigned char col_alpha = 40;
static const float sensor_seg = 10;
cpTransform m3_to_cpt(HMM_Mat4 m)
{
cpTransform t;
t.a = m.Columns[0].x;
t.b = m.Columns[0].y;
t.tx = m.Columns[3].x;
t.c = m.Columns[1].x;
t.d = m.Columns[1].y;
t.ty = m.Columns[3].y;
return t;
}
cpShape *phys2d_query_pos(cpVect pos) {
return cpSpacePointQueryNearest(space, pos, 0.f, CP_SHAPE_FILTER_ALL, NULL);
}
static int qhit;
void qpoint(cpShape *shape, cpFloat dist, cpVect point, int *data)
{
qhit++;
}
void bbhit(cpShape *shape, int *data)
{
qhit++;
}
int query_point(HMM_Vec2 pos)
{
qhit = 0;
// cpSpacePointQuery(space, pos.cp, 0, filter, qpoint, &qhit);
cpSpaceBBQuery(space, cpBBNewForCircle(pos.cp, 2), CP_SHAPE_FILTER_ALL, bbhit, &qhit);
return qhit;
}
int p_compare(void *a, void *b)
{
if (a > b) return 1;
if (a < b) return -1;
return 0;
}
gameobject **clean_ids(gameobject **ids)
{
qsort(ids, arrlen(ids), sizeof(*ids), p_compare);
gameobject *curid = NULL;
for (int i = arrlen(ids)-1; i >= 0; i--)
if (ids[i] == curid)
arrdelswap(ids, i);
else
curid = ids[i];
return ids;
}
int cpshape_enabled(cpShape *c) {
cpShapeFilter filter = cpShapeGetFilter(c);
if (filter.categories == ~CP_ALL_CATEGORIES && filter.mask == ~CP_ALL_CATEGORIES)
return 0;
return 1;
}
struct rgba shape_color(cpShape *shape) {
if (!cpshape_enabled(shape)) return disabled_color;
switch (cpBodyGetType(cpShapeGetBody(shape))) {
case CP_BODY_TYPE_DYNAMIC:
// cpBodySleep(cpShapeGetBody(shape));
if (cpBodyIsSleeping(cpShapeGetBody(shape)))
return sleep_color;
return dynamic_color;
case CP_BODY_TYPE_KINEMATIC:
return kinematic_color;
case CP_BODY_TYPE_STATIC:
return static_color;
}
return static_color;
}
static warp_gravity *space_gravity;
void phys2d_init() void phys2d_init()
{ {
space = cpSpaceNew(); space = cpSpaceNew();
cpSpaceSetSleepTimeThreshold(space, 1);
cpSpaceSetCollisionSlop(space, 0.01);
cpSpaceSetCollisionBias(space, cpfpow(1.0-0.5, 165.f));
space_gravity = warp_gravity_make();
}
void phys2d_set_gravity(HMM_Vec2 v)
{
float str = HMM_LenV2(v);
HMM_Vec2 dir = HMM_NormV2(v);
space_gravity->strength = str;
space_gravity->t.scale = (HMM_Vec3){v.x,v.y, 0};
space_gravity->planar_force = (HMM_Vec3){v.x,v.y,0};
} }
constraint *constraint_make(cpConstraint *c) constraint *constraint_make(cpConstraint *c)
@ -178,299 +56,6 @@ void phys2d_update(float deltaT) {
cb_idx = 0; cb_idx = 0;
} }
void init_phys2dshape(struct phys2d_shape *shape, gameobject *go, void *data) {
shape->go = go;
shape->data = data;
shape->t.scale = (HMM_Vec3){1.0,1.0,1.0};
go_shape_apply(go->body, shape->shape, go);
cpShapeSetCollisionType(shape->shape, (cpCollisionType)go);
cpShapeSetUserData(shape->shape, shape);
}
void phys2d_shape_del(struct phys2d_shape *shape) {
if (!shape->shape) return;
cpSpaceRemoveShape(space, shape->shape);
cpShapeFree(shape->shape);
}
/***************** CIRCLE2D *****************/
struct phys2d_circle *Make2DCircle(gameobject *go) {
struct phys2d_circle *new = malloc(sizeof(struct phys2d_circle));
new->radius = 10.f;
new->offset = v2zero;
new->shape.shape = cpSpaceAddShape(space, cpCircleShapeNew(go->body, new->radius, cpvzero));
new->shape.moi = phys2d_circle_moi;
new->shape.apply = phys2d_applycircle;
new->shape.free = NULL;
init_phys2dshape(&new->shape, go, new);
phys2d_applycircle(new);
return new;
}
float phys2d_circle_moi(struct phys2d_circle *c) {
float m = c->shape.go->mass;
return cpMomentForCircle(m, 0, cpCircleShapeGetRadius(c->shape.shape), cpCircleShapeGetOffset(c->shape.shape));
}
void phys2d_circledel(struct phys2d_circle *c) { phys2d_shape_del(&c->shape); }
void circle2d_free(circle2d *c) { phys2d_circledel(c); }
void phys2d_shape_apply(struct phys2d_shape *s)
{
float moment = cpBodyGetMoment(s->go->body);
float moi = s->moi(s->data);
s->apply(s->data);
float newmoi = s->moi(s->data);
moment-=moi;
moment += newmoi;
if (moment < 0) moment = 0;
cpBodySetMoment(s->go->body, moment);
}
void phys2d_applycircle(struct phys2d_circle *circle) {
gameobject *go = circle->shape.go;
float radius = circle->radius * HMM_MAX(HMM_ABS(go->scale.X), HMM_ABS(go->scale.Y));
cpCircleShapeSetRadius(circle->shape.shape, radius);
cpCircleShapeSetOffset(circle->shape.shape, circle->offset.cp);
}
/************** POLYGON ************/
struct phys2d_poly *Make2DPoly(gameobject *go) {
struct phys2d_poly *new = malloc(sizeof(struct phys2d_poly));
new->points = NULL;
arrsetlen(new->points, 0);
new->radius = 0.f;
new->shape.shape = cpSpaceAddShape(space, cpPolyShapeNewRaw(go->body, 0, (cpVect*)new->points, new->radius));
new->shape.moi = phys2d_poly_moi;
new->shape.free = phys2d_poly_free;
new->shape.apply = phys2d_applypoly;
init_phys2dshape(&new->shape, go, new);
return new;
}
void phys2d_poly_free(struct phys2d_poly *poly)
{
arrfree(poly->points);
free(poly);
}
float phys2d_poly_moi(struct phys2d_poly *poly) {
float m = poly->shape.go->mass;
int len = cpPolyShapeGetCount(poly->shape.shape);
if (!len) {
YughWarn("Cannot evaluate the MOI of a polygon of length %d.", len);
return 0;
}
cpVect points[len];
for (int i = 0; i < len; i++)
points[i] = cpPolyShapeGetVert(poly->shape.shape, i);
float moi = cpMomentForPoly(m, len, points, cpvzero, poly->radius);
if (!isfinite(moi))
return 0;
return moi;
}
void phys2d_polydel(struct phys2d_poly *poly) {
arrfree(poly->points);
phys2d_shape_del(&poly->shape);
}
void phys2d_polyaddvert(struct phys2d_poly *poly) {
arrput(poly->points, v2zero);
}
void phys2d_poly_setverts(struct phys2d_poly *poly, HMM_Vec2 *verts) {
if (!verts) return;
if (poly->points)
arrfree(poly->points);
arrsetlen(poly->points, arrlen(verts));
for (int i = 0; i < arrlen(verts); i++)
poly->points[i] = verts[i];
phys2d_shape_apply(&poly->shape);
}
void phys2d_applypoly(struct phys2d_poly *poly) {
if (arrlen(poly->points) <= 0) return;
assert(sizeof(poly->points[0]) == sizeof(cpVect));
struct gameobject *go = poly->shape.go;
transform t = go2t(shape2go(poly->shape.shape));
t.pos.xy = v2zero;
t.rotation = QUAT1;
cpTransform T = m3_to_cpt(transform2mat(t));
cpPolyShapeSetVerts(poly->shape.shape, arrlen(poly->points), (cpVect*)poly->points, T);
cpPolyShapeSetRadius(poly->shape.shape, poly->radius);
cpSpaceReindexShapesForBody(space, cpShapeGetBody(poly->shape.shape));
}
/****************** EDGE 2D**************/
struct phys2d_edge *Make2DEdge(gameobject *go) {
struct phys2d_edge *new = malloc(sizeof(struct phys2d_edge));
new->points = NULL;
arrsetlen(new->points, 0);
new->thickness = 0.f;
new->shapes = NULL;
arrsetlen(new->shapes, 0);
new->shape.go = go;
new->shape.data = new;
new->shape.moi = phys2d_edge_moi;
new->shape.shape = NULL;
new->shape.apply = NULL;
new->shape.free = phys2d_edge_free;
new->draws = 0;
phys2d_applyedge(new);
return new;
}
void phys2d_edge_free(struct phys2d_edge *edge)
{
for (int i = 0; i < arrlen(edge->shapes); i++)
cpShapeSetUserData(edge->shapes[i], NULL);
arrfree(edge->points);
arrfree(edge->shapes);
free(edge);
}
float phys2d_edge_moi(struct phys2d_edge *edge) {
float m = edge->shape.go->mass;
float moi = 0;
for (int i = 0; i < arrlen(edge->points) - 1; i++)
moi += cpMomentForSegment(m, edge->points[i].cp, edge->points[i + 1].cp, edge->thickness);
return moi;
}
void phys2d_edgedel(struct phys2d_edge *edge) { phys2d_shape_del(&edge->shape); }
void phys2d_edgeaddvert(struct phys2d_edge *edge, HMM_Vec2 v) {
arrput(edge->points, v);
if (arrlen(edge->points) > 1)
arrput(edge->shapes, cpSpaceAddShape(space, cpSegmentShapeNew(edge->shape.go->body, cpvzero, cpvzero, edge->thickness)));
}
void phys2d_edge_rmvert(struct phys2d_edge *edge, int index) {
if (index>arrlen(edge->points) || index < 0) return;
arrdel(edge->points, index);
if (arrlen(edge->points) == 0) return;
if (index == 0) {
cpSpaceRemoveShape(space, edge->shapes[index]);
cpShapeFree(edge->shapes[index]);
arrdel(edge->shapes, index);
return;
}
if (index != arrlen(edge->points))
cpSegmentShapeSetEndpoints(edge->shapes[index - 1], edge->points[index - 1].cp, edge->points[index].cp);
cpSpaceRemoveShape(space, edge->shapes[index - 1]);
cpShapeFree(edge->shapes[index - 1]);
arrdel(edge->shapes, index - 1);
}
void phys2d_edge_setvert(struct phys2d_edge *edge, int index, cpVect val) {
assert(arrlen(edge->points) > index && index >= 0);
edge->points[index].cp = val;
}
void phys2d_edge_update_verts(struct phys2d_edge *edge, HMM_Vec2 *verts)
{
if (arrlen(edge->points) == arrlen(verts)) {
for (int i = 0; i < arrlen(verts); i++)
phys2d_edge_setvert(edge,i,verts[i].cp);
} else {
int vertchange = arrlen(verts)-arrlen(edge->points);
phys2d_edge_clearverts(edge);
phys2d_edge_addverts(edge,verts);
}
phys2d_applyedge(edge);
}
void phys2d_edge_clearverts(struct phys2d_edge *edge) {
for (int i = arrlen(edge->points) - 1; i >= 0; i--)
phys2d_edge_rmvert(edge, i);
}
void phys2d_edge_addverts(struct phys2d_edge *edge, HMM_Vec2 *verts) {
for (int i = 0; i < arrlen(verts); i++)
phys2d_edgeaddvert(edge, verts[i]);
}
/* Calculates all true positions of verts, links them up, and so on */
void phys2d_applyedge(struct phys2d_edge *edge) {
struct gameobject *go = edge->shape.go;
for (int i = 0; i < arrlen(edge->shapes); i++) {
/* Points must be scaled with gameobject, */
HMM_Vec2 a = HMM_MulV2(go->scale.xy, edge->points[i]);
HMM_Vec2 b = HMM_MulV2(go->scale.xy, edge->points[i+1]);
cpSegmentShapeSetEndpoints(edge->shapes[i], a.cp, b.cp);
cpSegmentShapeSetRadius(edge->shapes[i], edge->thickness);
if (i > 0 && i < arrlen(edge->shapes) - 1)
cpSegmentShapeSetNeighbors(edge->shapes[i], HMM_MulV2(go->scale.xy,edge->points[i-1]).cp, HMM_MulV2(go->scale.xy,edge->points[i+2]).cp);
go_shape_apply(NULL, edge->shapes[i], go);
cpShapeSetUserData(edge->shapes[i], &edge->shape);
}
cpSpaceReindexShapesForBody(space, edge->shape.go->body);
}
/************ COLLIDER ****************/
void shape_enabled(struct phys2d_shape *shape, int enabled) {
cpShapeFilter set = enabled ? CP_SHAPE_FILTER_ALL : CP_SHAPE_FILTER_NONE;
if (!shape->shape) {
struct phys2d_edge *edge = shape->data;
for (int i = 0; i < arrlen(edge->shapes[i]); i++)
cpShapeSetFilter(edge->shapes[i], set);
} else
cpShapeSetFilter(shape->shape, set);
}
int shape_is_enabled(struct phys2d_shape *shape) {
if (cpshape_enabled(shape->shape))
return 1;
return 0;
}
void shape_set_sensor(struct phys2d_shape *shape, int sensor) {
if (!shape->shape) {
struct phys2d_edge *edge = shape->data;
for (int i = 0; i < arrlen(edge->shapes); i++)
cpShapeSetSensor(edge->shapes[i], sensor);
} else
cpShapeSetSensor(shape->shape, sensor);
}
int shape_get_sensor(struct phys2d_shape *shape) {
if (!shape->shape) {
struct phys2d_edge *edge = shape->data;
if (arrlen(edge->shapes) > 0) return cpShapeGetSensor(edge->shapes[0]);
return 0;
}
return cpShapeGetSensor(shape->shape);
}
void phys2d_reindex_body(cpBody *body) { cpSpaceReindexShapesForBody(space, body); }
JSValue arb2js(cpArbiter *arb) JSValue arb2js(cpArbiter *arb)
{ {
cpBody *body1; cpBody *body1;
@ -481,17 +66,18 @@ JSValue arb2js(cpArbiter *arb)
cpShape *shape2; cpShape *shape2;
cpArbiterGetShapes(arb, &shape1, &shape2); cpArbiterGetShapes(arb, &shape1, &shape2);
struct phys2d_shape *pshape = cpShapeGetUserData(shape2); JSValue *j = cpShapeGetUserData(shape2);
gameobject *go2 = cpBodyGetUserData(body2);
JSValue jg = body2go(body2)->ref;
HMM_Vec2 srfv;
srfv.cp = cpArbiterGetSurfaceVelocity(arb);
JSValue obj = JS_NewObject(js); JSValue obj = JS_NewObject(js);
JS_SetPropertyStr(js, obj, "normal", vec22js((HMM_Vec2)cpArbiterGetNormal(arb))); JS_SetPropertyStr(js, obj, "normal", vec22js((HMM_Vec2)cpArbiterGetNormal(arb)));
JS_SetPropertyStr(js, obj, "obj", JS_DupValue(js,go2->ref)); JS_SetPropertyStr(js, obj, "obj", JS_DupValue(js,jg));
JS_SetPropertyStr(js, obj, "shape", JS_DupValue(js, pshape->ref)); JS_SetPropertyStr(js, obj, "shape", JS_DupValue(js, *j));
// JS_SetPropertyStr(js, obj, "point", vec22js((HMM_Vec2)cpArbiterGetPointA(arb, 0))); JS_SetPropertyStr(js, obj, "point", vec22js((HMM_Vec2)cpArbiterGetPointA(arb, 0)));
HMM_Vec2 srfv;
srfv.cp = cpArbiterGetSurfaceVelocity(arb);
JS_SetPropertyStr(js, obj, "velocity", vec22js(srfv)); JS_SetPropertyStr(js, obj, "velocity", vec22js(srfv));
return obj; return obj;
@ -517,18 +103,10 @@ void register_hit(cpArbiter *arb, gameobject *go, const char *name)
} }
cpShape *s1, *s2; cpShape *s1, *s2;
cpArbiterGetShapes(arb, &s1, &s2); cpArbiterGetShapes(arb, &s1, &s2);
gameobject *g1, *g2; JSValue *j1 = cpShapeGetUserData(s1);
g1 = shape2go(s1); JSValue *j2 = cpShapeGetUserData(s2);
g2 = shape2go(g2); cb = JS_GetPropertyStr(js, *j1, name);
if (!g1) return;
if (!g2) return;
if (JS_IsUndefined(g1->ref)) return;
if (JS_IsUndefined(g2->ref)) return;
struct phys2d_shape *pshape1 = cpShapeGetUserData(s1);
if (JS_IsUndefined(pshape1->ref)) return;
cb = JS_GetPropertyStr(js, pshape1->ref, name);
if (!JS_IsUndefined(cb)) { if (!JS_IsUndefined(cb)) {
JSValue jarb = arb2js(arb); JSValue jarb = arb2js(arb);
fns[cb_idx] = JS_DupValue(js,cb); fns[cb_idx] = JS_DupValue(js,cb);

View file

@ -7,16 +7,8 @@
#include "render.h" #include "render.h"
#include "transform.h" #include "transform.h"
extern float phys2d_gravity;
extern int physOn;
extern cpSpace *space; extern cpSpace *space;
extern struct rgba disabled_color;
extern struct rgba dynamic_color;
extern struct rgba kinematic_color;
extern struct rgba static_color;
extern struct rgba sleep_color;
typedef struct constraint { typedef struct constraint {
cpConstraint *c; cpConstraint *c;
JSValue break_cb; /* function called when it is forcibly broken */ JSValue break_cb; /* function called when it is forcibly broken */
@ -27,102 +19,8 @@ constraint *constraint_make(cpConstraint *c);
void constraint_break(constraint *constraint); void constraint_break(constraint *constraint);
void constraint_free(constraint *constraint); void constraint_free(constraint *constraint);
struct phys2d_shape {
cpShape *shape; /* user data is this phys2d_shape */
JSValue ref;
transform t;
gameobject *go;
void *data; /* The specific subtype; phys2d_circle, etc */
float (*moi)(void *data);
void (*apply)(void *data);
void (*free)(void *data);
};
void phys2d_shape_apply(struct phys2d_shape *s);
/* Circles are the fastest colldier type */
struct phys2d_circle {
float radius;
HMM_Vec2 offset;
struct phys2d_shape shape;
};
typedef struct phys2d_circle circle2d;
/* A convex polygon; defined as the convex hull around the given set of points */
struct phys2d_poly {
HMM_Vec2 *points;
float radius;
struct phys2d_shape shape;
};
/* An edge with no volume. Cannot collide with each other. Join to make levels. Static only. */
struct phys2d_edge {
HMM_Vec2 *points; /* Points defined relative to the gameobject */
float thickness;
cpShape **shapes;
struct phys2d_shape shape;
int draws;
};
struct phys2d_circle *Make2DCircle(gameobject *go);
void phys2d_circledel(struct phys2d_circle *c);
void circle2d_free(circle2d *c);
void phys2d_applycircle(struct phys2d_circle *circle);
void phys2d_dbgdrawcircle(struct phys2d_circle *circle);
float phys2d_circle_moi(struct phys2d_circle *c);
struct phys2d_poly *Make2DPoly(gameobject *go);
void phys2d_poly_free(struct phys2d_poly *poly);
void phys2d_polydel(struct phys2d_poly *poly);
void phys2d_applypoly(struct phys2d_poly *poly);
void phys2d_dbgdrawpoly(struct phys2d_poly *poly);
void phys2d_polyaddvert(struct phys2d_poly *poly);
void phys2d_poly_setverts(struct phys2d_poly *poly, HMM_Vec2 *verts);
float phys2d_poly_moi(struct phys2d_poly *poly);
struct phys2d_edge *Make2DEdge(gameobject *go);
void phys2d_edge_free(struct phys2d_edge *edge);
void phys2d_edgedel(struct phys2d_edge *edge);
void phys2d_applyedge(struct phys2d_edge *edge);
void phys2d_dbgdrawedge(struct phys2d_edge *edge);
void phys2d_edgeaddvert(struct phys2d_edge *edge, HMM_Vec2 v);
void phys2d_edge_rmvert(struct phys2d_edge *edge, int index);
float phys2d_edge_moi(struct phys2d_edge *edge);
void phys2d_edge_setvert(struct phys2d_edge *edge, int index, cpVect val);
void phys2d_edge_clearverts(struct phys2d_edge *edge);
void phys2d_edge_rmvert(struct phys2d_edge *edge, int index);
void phys2d_edge_update_verts(struct phys2d_edge *edge, HMM_Vec2 *verts);
void phys2d_edge_addverts(struct phys2d_edge *edge, HMM_Vec2 *verts);
void phys2d_edge_set_sensor(struct phys2d_edge *edge, int sensor);
void phys2d_edge_set_enabled(struct phys2d_edge *edge, int enabled);
void phys2d_init(); void phys2d_init();
void phys2d_update(float deltaT); void phys2d_update(float deltaT);
cpShape *phys2d_query_pos(cpVect pos);
void phys2d_query_ray(HMM_Vec2 start, HMM_Vec2 end, float radius, cpShapeFilter filter, JSValue cb);
struct shape_cb {
struct phys2d_shape *shape;
struct phys_cbs cbs;
};
void fire_hits();
void phys2d_set_gravity(HMM_Vec2 v);
void shape_enabled(struct phys2d_shape *shape, int enabled);
int shape_is_enabled(struct phys2d_shape *shape);
void shape_set_sensor(struct phys2d_shape *shape, int sensor);
int shape_get_sensor(struct phys2d_shape *shape);
struct rgba shape_color_s(cpShape *shape);
void shape_gui(struct phys2d_shape *shape);
void phys2d_setup_handlers(gameobject *go); void phys2d_setup_handlers(gameobject *go);
int query_point(HMM_Vec2 pos);
void phys2d_reindex_body(cpBody *body);
#endif #endif

View file

@ -7,43 +7,28 @@
#include "stb_ds.h" #include "stb_ds.h"
gameobject *body2go(cpBody *body) { return cpBodyGetUserData(body); }
gameobject *shape2go(cpShape *shape) {
struct phys2d_shape *pshape = cpShapeGetUserData(shape);
if (!pshape) return NULL;
return pshape->go;
}
transform go2t(gameobject *go) transform go2t(gameobject *go)
{ {
transform t = {0}; transform t = {0};
t.pos.cp = cpBodyGetPosition(go->body); t.pos.cp = cpBodyGetPosition(go->body);
t.rotation = angle2rotation(cpBodyGetAngle(go->body)); t.rotation = angle2rotation(cpBodyGetAngle(go->body));
t.scale = go->scale; t.scale = go->t->scale;
if (!isfinite(t.scale.X)) t.scale.X = 1;
if (!isfinite(t.scale.Y)) t.scale.Y = 1;
return t; return t;
} }
void go_shape_apply(cpBody *body, cpShape *shape, gameobject *go) { gameobject *body2go(cpBody *b)
cpShapeSetFriction(shape, go->friction); {
cpShapeSetElasticity(shape, go->elasticity); return cpBodyGetUserData(b);
cpShapeSetCollisionType(shape, (cpCollisionType)go); }
cpShapeFilter filter; gameobject *shape2go(cpShape *s)
filter.group = (cpCollisionType)go; {
filter.categories = go->categories; cpBody *b = cpShapeGetBody(s);
filter.mask = go->mask; return cpBodyGetUserData(b);
// filter.mask = CP_ALL_CATEGORIES;
cpShapeSetFilter(shape, filter);
struct phys2d_shape *ape = cpShapeGetUserData(shape);
if (ape && ape->apply)
ape->apply(ape->data);
} }
void go_shape_moi(cpBody *body, cpShape *shape, gameobject *go) { void go_shape_moi(cpBody *body, cpShape *shape, gameobject *go) {
float moment = cpBodyGetMoment(body); /* float moment = cpBodyGetMoment(body);
struct phys2d_shape *s = cpShapeGetUserData(shape); struct phys2d_shape *s = cpShapeGetUserData(shape);
if (!s) { if (!s) {
cpBodySetMoment(body, moment + 1); cpBodySetMoment(body, moment + 1);
@ -52,25 +37,10 @@ void go_shape_moi(cpBody *body, cpShape *shape, gameobject *go) {
moment += s->moi(s->data); moment += s->moi(s->data);
if (moment < 0) moment = 0; if (moment < 0) moment = 0;
cpBodySetMoment(body, moment); cpBodySetMoment(body, moment);*/
} }
void gameobject_apply(gameobject *go) { void gameobject_apply(gameobject *go) { *go->t = go2t(go); }
YughSpam("Applying gameobject %p", go);
cpBodySetType(go->body, go->phys);
cpBodyEachShape(go->body, go_shape_apply, go);
if (go->phys == CP_BODY_TYPE_DYNAMIC) {
cpBodySetMass(go->body, go->mass);
cpBodySetMoment(go->body, 0.f);
cpBodyEachShape(go->body, go_shape_moi, go);
if (cpBodyGetMoment(go->body) <= 0.f)
cpBodySetMoment(go->body, 1.f);
}
*go->t = go2t(go);
}
static void velocityFn(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt) static void velocityFn(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
{ {
@ -100,20 +70,15 @@ static void velocityFn(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt
gameobject *MakeGameobject() { gameobject *MakeGameobject() {
gameobject *ngo = malloc(sizeof(*ngo)); gameobject *ngo = malloc(sizeof(*ngo));
gameobject go = { gameobject go = {
.scale = (HMM_Vec3){1.f,1.f,1.f},
.phys = CP_BODY_TYPE_STATIC,
.maxvelocity = INFINITY, .maxvelocity = INFINITY,
.maxangularvelocity = INFINITY, .maxangularvelocity = INFINITY,
.mass = 1.f,
.damping = INFINITY, .damping = INFINITY,
.timescale = 1.0, .timescale = 1.0,
.ref = JS_UNDEFINED, .ref = JS_UNDEFINED,
.mask = ~0,
.categories = 1,
.warp_mask = ~0, .warp_mask = ~0,
}; };
go.body = cpSpaceAddBody(space, cpBodyNew(go.mass, 1.f)); go.body = cpSpaceAddBody(space, cpBodyNew(1, 1));
cpBodySetVelocityUpdateFunc(go.body, velocityFn); cpBodySetVelocityUpdateFunc(go.body, velocityFn);
*ngo = go; *ngo = go;
@ -123,19 +88,6 @@ gameobject *MakeGameobject() {
} }
void rm_body_shapes(cpBody *body, cpShape *shape, void *data) { void rm_body_shapes(cpBody *body, cpShape *shape, void *data) {
struct phys2d_shape *s = cpShapeGetUserData(shape);
if (s) {
JS_FreeValue(js, s->ref);
s->ref = JS_UNDEFINED;
if (s->free)
s->free(s->data);
else
free(s->data);
}
cpShapeSetFilter(shape, CP_SHAPE_FILTER_NONE);
cpSpaceRemoveShape(space, shape); cpSpaceRemoveShape(space, shape);
cpShapeFree(shape); cpShapeFree(shape);
} }
@ -147,8 +99,8 @@ void rm_body_constraints(cpBody *body, cpConstraint *constraint, void *data)
void gameobject_free(gameobject *go) { void gameobject_free(gameobject *go) {
go->ref = JS_UNDEFINED; go->ref = JS_UNDEFINED;
cpBodyEachShape(go->body, rm_body_shapes, NULL); // cpBodyEachShape(go->body, rm_body_shapes, NULL);
cpBodyEachConstraint(go->body, rm_body_constraints, NULL); // cpBodyEachConstraint(go->body, rm_body_constraints, NULL);
cpSpaceRemoveBody(space, go->body); cpSpaceRemoveBody(space, go->body);
cpBodyFree(go->body); cpBodyFree(go->body);
free(go); free(go);
@ -157,5 +109,5 @@ void gameobject_free(gameobject *go) {
void gameobject_setpos(gameobject *go, cpVect vec) { void gameobject_setpos(gameobject *go, cpVect vec) {
if (!go || !go->body) return; if (!go || !go->body) return;
cpBodySetPosition(go->body, vec); cpBodySetPosition(go->body, vec);
phys2d_reindex_body(go->body); // phys2d_reindex_body(go->body);
} }

View file

@ -27,20 +27,13 @@
}while(0) }while(0)
struct gameobject { struct gameobject {
cpBodyType phys;
cpBody *body; /* NULL if this object is dead; has 2d position and rotation, relative to global 0 */ cpBody *body; /* NULL if this object is dead; has 2d position and rotation, relative to global 0 */
float mass;
float friction;
float elasticity;
float damping; float damping;
float timescale; float timescale;
float maxvelocity; float maxvelocity;
float maxangularvelocity; float maxangularvelocity;
unsigned int layer; unsigned int layer;
cpBitmask categories;
cpBitmask mask;
unsigned int warp_mask; unsigned int warp_mask;
HMM_Vec3 scale;
JSValue ref; JSValue ref;
transform *t; // the transform this body controls transform *t; // the transform this body controls
}; };
@ -69,8 +62,8 @@ transform go2t(gameobject *go);
HMM_Vec3 go_pos(gameobject *go); HMM_Vec3 go_pos(gameobject *go);
gameobject *body2go(cpBody *body); gameobject *shape2go(cpShape *s);
gameobject *shape2go(cpShape *shape); gameobject *body2go(cpBody *b);
void go_shape_apply(cpBody *body, cpShape *shape, gameobject *go); void go_shape_apply(cpBody *body, cpShape *shape, gameobject *go);

View file

@ -81,6 +81,9 @@ void sg_buffer_free(sg_buffer *b)
void cpShape_free(cpShape *s) void cpShape_free(cpShape *s)
{ {
JSValue *cb = cpShapeGetUserData(s);
free(cb);
cpSpaceRemoveShape(space, s);
cpShapeFree(s); cpShapeFree(s);
} }
@ -102,6 +105,10 @@ QJSCLASS(sg_image)
QJSCLASS(datastream) QJSCLASS(datastream)
QJSCLASS(cpShape) QJSCLASS(cpShape)
static JSValue js_circle2d;
static JSValue js_poly2d;
static JSValue js_seg2d;
static JSValue sound_proto; static JSValue sound_proto;
sound *js2sound(JSValue v) { return js2dsp_node(v)->data; } sound *js2sound(JSValue v) { return js2dsp_node(v)->data; }
@ -1232,26 +1239,6 @@ static const JSCFunctionListEntry js_io_funcs[] = {
MIST_FUNC_DEF(io, mod,1) MIST_FUNC_DEF(io, mod,1)
}; };
JSC_GETSET_GLOBAL(disabled_color, color)
JSC_GETSET_GLOBAL(sleep_color, color)
JSC_GETSET_GLOBAL(dynamic_color, color)
JSC_GETSET_GLOBAL(kinematic_color, color)
JSC_GETSET_GLOBAL(static_color, color)
static const JSCFunctionListEntry js_debug_funcs[] = {
CGETSET_ADD(global, disabled_color),
CGETSET_ADD(global, sleep_color),
CGETSET_ADD(global, dynamic_color),
CGETSET_ADD(global, kinematic_color),
CGETSET_ADD(global, static_color),
};
JSC_CCALL(physics_sgscale,
js2gameobject(argv[0])->scale.xy = js2vec2(argv[1]);
gameobject_apply(js2gameobject(argv[0]));
cpSpaceReindexShapesForBody(space, js2gameobject(argv[0])->body);
)
JSC_CCALL(physics_closest_point, JSC_CCALL(physics_closest_point,
void *v1 = js2cpvec2arr(argv[1]); void *v1 = js2cpvec2arr(argv[1]);
JSValue ret = number2js(point2segindex(js2vec2(argv[0]), v1, js2number(argv[2]))); JSValue ret = number2js(point2segindex(js2vec2(argv[0]), v1, js2number(argv[2])));
@ -1289,7 +1276,7 @@ static void shape_query_fn(cpShape *shape, cpContactPointSet *points, JSValue *c
} }
JSC_CCALL(physics_shape_query, JSC_CCALL(physics_shape_query,
cpSpaceShapeQuery(space, ((struct phys2d_shape*)js2ptr(argv[0]))->shape, shape_query_fn, &argv[1]); //cpSpaceShapeQuery(space, ((struct phys2d_shape*)js2ptr(argv[0]))->shape, shape_query_fn, &argv[1]);
) )
static void ray_query_fn(cpShape *shape, float t, cpVect n, float a, JSValue *cb) static void ray_query_fn(cpShape *shape, float t, cpVect n, float a, JSValue *cb)
@ -1310,7 +1297,7 @@ JSC_CCALL(physics_ray_query,
static void point_query_fn(cpShape *shape, float dist, cpVect point, JSValue *cb) static void point_query_fn(cpShape *shape, float dist, cpVect point, JSValue *cb)
{ {
JSValue argv[3] = { JSValue argv[3] = {
JS_DupValue(js, shape2go(shape)->ref), JS_DupValue(js,*(JSValue*)cpShapeGetUserData(shape)),
vec22js((HMM_Vec2)point), vec22js((HMM_Vec2)point),
number2js(dist) number2js(dist)
}; };
@ -1325,9 +1312,9 @@ JSC_CCALL(physics_point_query,
JSValue pointinfo2js(cpPointQueryInfo info) JSValue pointinfo2js(cpPointQueryInfo info)
{ {
JSValue o = JS_NewObject(js); JSValue o = JS_NewObject(js);
JS_SetPropertyStr(js, o, "distance", number2js(info.distance)); js_setpropstr(o, "distance", number2js(info.distance));
JS_SetPropertyStr(js, o, "point", vec22js((HMM_Vec2)info.point)); js_setpropstr(o, "point", vec22js((HMM_Vec2)info.point));
JS_SetPropertyStr(js, o, "entity", JS_DupValue(js, shape2go(info.shape)->ref)); js_setpropstr(o, "entity", JS_DupValue(js, shape2go(info.shape)->ref));
return o; return o;
} }
@ -1338,8 +1325,20 @@ JSC_CCALL(physics_point_query_nearest,
return pointinfo2js(info); return pointinfo2js(info);
) )
#define SPACE_GETSET(ENTRY, CPENTRY, TYPE) \
JSC_CCALL(physics_get_##ENTRY, return TYPE##2js(cpSpaceGet##CPENTRY (space))) \
JSValue js_physics_set_##ENTRY (JS_SETSIG) { \
cpSpaceSet##CPENTRY(space, js2##TYPE(val)); \
} \
SPACE_GETSET(iterations, Iterations, number)
SPACE_GETSET(idle_speed, IdleSpeedThreshold, number)
SPACE_GETSET(collision_slop, CollisionSlop, number)
SPACE_GETSET(sleep_time, SleepTimeThreshold, number)
SPACE_GETSET(collision_bias, CollisionBias, number)
SPACE_GETSET(collision_persistence, CollisionPersistence, number)
static const JSCFunctionListEntry js_physics_funcs[] = { static const JSCFunctionListEntry js_physics_funcs[] = {
MIST_FUNC_DEF(physics, sgscale, 2),
MIST_FUNC_DEF(physics, point_query, 3), MIST_FUNC_DEF(physics, point_query, 3),
MIST_FUNC_DEF(physics, point_query_nearest, 2), MIST_FUNC_DEF(physics, point_query_nearest, 2),
MIST_FUNC_DEF(physics, ray_query, 4), MIST_FUNC_DEF(physics, ray_query, 4),
@ -1348,6 +1347,12 @@ static const JSCFunctionListEntry js_physics_funcs[] = {
MIST_FUNC_DEF(physics, closest_point, 3), MIST_FUNC_DEF(physics, closest_point, 3),
MIST_FUNC_DEF(physics, make_damp, 0), MIST_FUNC_DEF(physics, make_damp, 0),
MIST_FUNC_DEF(physics, make_gravity, 0), MIST_FUNC_DEF(physics, make_gravity, 0),
CGETSET_ADD(physics, iterations),
CGETSET_ADD(physics, idle_speed),
CGETSET_ADD(physics, sleep_time),
CGETSET_ADD(physics, collision_slop),
CGETSET_ADD(physics, collision_bias),
CGETSET_ADD(physics, collision_persistence),
}; };
static const JSCFunctionListEntry js_emitter_funcs[] = { static const JSCFunctionListEntry js_emitter_funcs[] = {
@ -1478,8 +1483,6 @@ JSValue js_gameobject_set_pos(JSContext *js, JSValue this, JSValue val) {
JSValue js_gameobject_get_pos(JSContext *js, JSValue this) { return cvec22js(cpBodyGetPosition(js2gameobject(this)->body)); } JSValue js_gameobject_get_pos(JSContext *js, JSValue this) { return cvec22js(cpBodyGetPosition(js2gameobject(this)->body)); }
JSValue js_gameobject_set_angle (JSContext *js, JSValue this, JSValue val) { cpBodySetAngle(js2gameobject(this)->body, HMM_TurnToRad*js2number(val)); return JS_UNDEFINED; } JSValue js_gameobject_set_angle (JSContext *js, JSValue this, JSValue val) { cpBodySetAngle(js2gameobject(this)->body, HMM_TurnToRad*js2number(val)); return JS_UNDEFINED; }
JSValue js_gameobject_get_angle (JSContext *js, JSValue this) { return number2js(HMM_RadToTurn*cpBodyGetAngle(js2gameobject(this)->body)); } JSValue js_gameobject_get_angle (JSContext *js, JSValue this) { return number2js(HMM_RadToTurn*cpBodyGetAngle(js2gameobject(this)->body)); }
JSValue js_gameobject_get_rscale(JSContext *js, JSValue this) { return vec32js(js2gameobject(this)->scale); }
JSValue js_gameobject_set_rscale(JSContext *js, JSValue this, JSValue val) { js2gameobject(this)->scale = js2vec3(val); return JS_UNDEFINED; }
JSC_GETSET_BODY(velocity, Velocity, cvec2) JSC_GETSET_BODY(velocity, Velocity, cvec2)
JSValue js_gameobject_set_angularvelocity (JSContext *js, JSValue this, JSValue val) { cpBodySetAngularVelocity(js2gameobject(this)->body, HMM_TurnToRad*js2number(val)); return JS_UNDEFINED;} JSValue js_gameobject_set_angularvelocity (JSContext *js, JSValue this, JSValue val) { cpBodySetAngularVelocity(js2gameobject(this)->body, HMM_TurnToRad*js2number(val)); return JS_UNDEFINED;}
JSValue js_gameobject_get_angularvelocity (JSContext *js, JSValue this) { return number2js(HMM_RadToTurn*cpBodyGetAngularVelocity(js2gameobject(this)->body)); } JSValue js_gameobject_get_angularvelocity (JSContext *js, JSValue this) { return number2js(HMM_RadToTurn*cpBodyGetAngularVelocity(js2gameobject(this)->body)); }
@ -1488,18 +1491,17 @@ JSC_GETSET_BODY(torque, Torque, number)
JSC_CCALL(gameobject_impulse, cpBodyApplyImpulseAtWorldPoint(js2gameobject(this)->body, js2vec2(argv[0]).cp, cpBodyGetPosition(js2gameobject(this)->body))) JSC_CCALL(gameobject_impulse, cpBodyApplyImpulseAtWorldPoint(js2gameobject(this)->body, js2vec2(argv[0]).cp, cpBodyGetPosition(js2gameobject(this)->body)))
JSC_CCALL(gameobject_force, cpBodyApplyForceAtWorldPoint(js2gameobject(this)->body, js2vec2(argv[0]).cp, cpBodyGetPosition(js2gameobject(this)->body))) JSC_CCALL(gameobject_force, cpBodyApplyForceAtWorldPoint(js2gameobject(this)->body, js2vec2(argv[0]).cp, cpBodyGetPosition(js2gameobject(this)->body)))
JSC_CCALL(gameobject_force_local, cpBodyApplyForceAtLocalPoint(js2gameobject(this)->body, js2vec2(argv[0]).cp, js2vec2(argv[1]).cp)) JSC_CCALL(gameobject_force_local, cpBodyApplyForceAtLocalPoint(js2gameobject(this)->body, js2vec2(argv[0]).cp, js2vec2(argv[1]).cp))
JSC_GETSET_APPLY(gameobject, friction, number) JSC_GETSET_BODY(mass, Mass, number)
JSC_GETSET_APPLY(gameobject, elasticity, number) JSC_GETSET_BODY(phys, Type, number)
JSC_GETSET_APPLY(gameobject, mass, number)
JSC_GETSET_APPLY(gameobject, phys, number)
JSC_GETSET_APPLY(gameobject, layer, number) JSC_GETSET_APPLY(gameobject, layer, number)
JSC_GETSET(gameobject, damping, number) JSC_GETSET(gameobject, damping, number)
JSC_GETSET(gameobject, timescale, number) JSC_GETSET(gameobject, timescale, number)
JSC_GETSET(gameobject, maxvelocity, number) JSC_GETSET(gameobject, maxvelocity, number)
JSC_GETSET(gameobject, maxangularvelocity, number) JSC_GETSET(gameobject, maxangularvelocity, number)
JSC_GETSET(gameobject, warp_mask, bitmask) JSC_GETSET(gameobject, warp_mask, bitmask)
JSC_GETSET(gameobject, categories, bitmask) JSC_CCALL(gameobject_sleeping, return boolean2js(cpBodyIsSleeping(js2gameobject(this)->body)))
JSC_GETSET(gameobject, mask, bitmask) JSC_CCALL(gameobject_sleep, cpBodySleep(js2gameobject(this)->body))
JSC_CCALL(gameobject_wake, cpBodyActivate(js2gameobject(this)->body))
JSC_CCALL(gameobject_selfsync, gameobject_apply(js2gameobject(this))) JSC_CCALL(gameobject_selfsync, gameobject_apply(js2gameobject(this)))
void body_shape_fn(cpBody *body, cpShape *shape, JSValue *fn) { void body_shape_fn(cpBody *body, cpShape *shape, JSValue *fn) {
@ -1516,8 +1518,6 @@ JSC_CCALL(gameobject_eachshape,
static const JSCFunctionListEntry js_gameobject_funcs[] = { static const JSCFunctionListEntry js_gameobject_funcs[] = {
CGETSET_ADD(gameobject, pos), CGETSET_ADD(gameobject, pos),
CGETSET_ADD(gameobject, angle), CGETSET_ADD(gameobject, angle),
CGETSET_ADD(gameobject, friction),
CGETSET_ADD(gameobject, elasticity),
CGETSET_ADD(gameobject,mass), CGETSET_ADD(gameobject,mass),
CGETSET_ADD(gameobject,damping), CGETSET_ADD(gameobject,damping),
CGETSET_ADD(gameobject,timescale), CGETSET_ADD(gameobject,timescale),
@ -1525,8 +1525,6 @@ static const JSCFunctionListEntry js_gameobject_funcs[] = {
CGETSET_ADD(gameobject,maxangularvelocity), CGETSET_ADD(gameobject,maxangularvelocity),
CGETSET_ADD(gameobject,layer), CGETSET_ADD(gameobject,layer),
CGETSET_ADD(gameobject,warp_mask), CGETSET_ADD(gameobject,warp_mask),
CGETSET_ADD(gameobject, categories),
CGETSET_ADD(gameobject, mask),
CGETSET_ADD(gameobject, velocity), CGETSET_ADD(gameobject, velocity),
CGETSET_ADD(gameobject, angularvelocity), CGETSET_ADD(gameobject, angularvelocity),
// CGETSET_ADD(gameobject, moi), // CGETSET_ADD(gameobject, moi),
@ -1536,7 +1534,10 @@ static const JSCFunctionListEntry js_gameobject_funcs[] = {
MIST_FUNC_DEF(gameobject, force, 1), MIST_FUNC_DEF(gameobject, force, 1),
MIST_FUNC_DEF(gameobject, force_local, 2), MIST_FUNC_DEF(gameobject, force_local, 2),
MIST_FUNC_DEF(gameobject, selfsync, 0), MIST_FUNC_DEF(gameobject, selfsync, 0),
MIST_FUNC_DEF(gameobject, eachshape, 1) MIST_FUNC_DEF(gameobject, eachshape, 1),
MIST_FUNC_DEF(gameobject, sleep, 0),
MIST_FUNC_DEF(gameobject, sleeping, 0),
MIST_FUNC_DEF(gameobject, wake, 0)
}; };
JSC_CCALL(joint_pin, return constraint2js(constraint_make(cpPinJointNew(js2gameobject(argv[0])->body, js2gameobject(argv[1])->body, cpvzero,cpvzero)))) JSC_CCALL(joint_pin, return constraint2js(constraint_make(cpPinJointNew(js2gameobject(argv[0])->body, js2gameobject(argv[1])->body, cpvzero,cpvzero))))
@ -1627,18 +1628,6 @@ static const JSCFunctionListEntry js_datastream_funcs[] = {
MIST_FUNC_DEF(datastream, framerate, 0), MIST_FUNC_DEF(datastream, framerate, 0),
}; };
JSC_CCALL(pshape_set_sensor, shape_set_sensor(js2ptr(argv[0]), js2boolean(argv[1])))
JSC_CCALL(pshape_get_sensor, return boolean2js(shape_get_sensor(js2ptr(argv[0]))))
JSC_CCALL(pshape_set_enabled, shape_enabled(js2ptr(argv[0]), js2boolean(argv[1])))
JSC_CCALL(pshape_get_enabled, return boolean2js(shape_is_enabled(js2ptr(argv[0]))))
static const JSCFunctionListEntry js_pshape_funcs[] = {
MIST_FUNC_DEF(pshape, set_sensor, 2),
MIST_FUNC_DEF(pshape, get_sensor, 1),
MIST_FUNC_DEF(pshape, set_enabled, 2),
MIST_FUNC_DEF(pshape, get_enabled, 1)
};
JSC_GET(texture, width, number) JSC_GET(texture, width, number)
JSC_GET(texture, height, number) JSC_GET(texture, height, number)
JSC_GET(texture, frames, number) JSC_GET(texture, frames, number)
@ -1680,22 +1669,6 @@ static const JSCFunctionListEntry js_constraint_funcs[] = {
CGETSET_ADD(constraint, collide), CGETSET_ADD(constraint, collide),
}; };
struct phys2d_edge *js2edge2d(JSValue v) { return js2ptr(v); }
JSC_CCALL(edge2d_setverts,
struct phys2d_edge *edge = js2edge2d(argv[0]);
HMM_Vec2 *v = js2cpvec2arr(argv[1]);
phys2d_edge_update_verts(edge,v);
arrfree(v);
)
JSC_CCALL(edge2d_set_thickness, js2edge2d(argv[0])->thickness = js2number(argv[1]))
JSC_CCALL(edge2d_get_thickness, return number2js(js2edge2d(argv[0])->thickness))
static const JSCFunctionListEntry js_edge2d_funcs[] = {
MIST_FUNC_DEF(edge2d, setverts, 2),
MIST_FUNC_DEF(edge2d, set_thickness, 2),
MIST_FUNC_DEF(edge2d, get_thickness, 1),
};
const char *STRTEST = "TEST STRING"; const char *STRTEST = "TEST STRING";
JSC_CCALL(performance_barecall,) JSC_CCALL(performance_barecall,)
@ -1793,11 +1766,51 @@ JSC_CCALL(os_make_gameobject,
gameobject *g = MakeGameobject(); gameobject *g = MakeGameobject();
g->t = js2transform(argv[0]); g->t = js2transform(argv[0]);
ret = gameobject2js(g); ret = gameobject2js(g);
// JS_SetPropertyFunctionList(js, ret, js_gameobject_funcs, countof(js_gameobject_funcs)); g->ref = ret;
g->ref = ret;
return ret; return ret;
) )
#define CP_GETSET(ENTRY, CPENTRY, TYPE) \
JSC_CCALL(cpShape_get_##ENTRY, return TYPE##2js(cpShapeGet##CPENTRY (js2cpShape(this)))) \
JSValue js_cpShape_set_##ENTRY (JSContext *js, JSValue this, JSValue val) { \
cpShapeSet##CPENTRY (js2cpShape(this), js2##TYPE (val)); \
} \
CP_GETSET(sensor, Sensor, boolean)
CP_GETSET(friction, Friction, number)
CP_GETSET(elasticity, Elasticity, number)
JSC_CCALL(cpShape_get_surface_velocity, return vec22js((HMM_Vec2)cpShapeGetSurfaceVelocity(js2cpShape(this))))
JSValue js_cpShape_set_surface_velocity(JS_SETSIG) {
HMM_Vec2 v = js2vec2(val);
cpShapeSetSurfaceVelocity(js2cpShape(this), v.cp);
return JS_UNDEFINED;
}
JSC_CCALL(cpShape_get_mask, return bitmask2js(cpShapeGetFilter(js2cpShape(this)).mask));
JSValue js_cpShape_set_mask (JS_SETSIG) {
cpShapeFilter f = cpShapeGetFilter(js2cpShape(this));
f.mask = js2bitmask(val);
cpShapeSetFilter(js2cpShape(this), f);
return JS_UNDEFINED;
}
JSC_CCALL(cpShape_get_category, return bitmask2js(cpShapeGetFilter(js2cpShape(this)).categories))
JSValue js_cpShape_set_category (JS_SETSIG) {
cpShapeFilter f = cpShapeGetFilter(js2cpShape(this));
f.categories = js2bitmask(val);
cpShapeSetFilter(js2cpShape(this), f);
return JS_UNDEFINED;
}
static const JSCFunctionListEntry js_cpShape_funcs[] = {
CGETSET_ADD(cpShape, sensor),
CGETSET_ADD(cpShape, friction),
CGETSET_ADD(cpShape, elasticity),
CGETSET_ADD(cpShape, surface_velocity),
CGETSET_ADD(cpShape, mask),
CGETSET_ADD(cpShape, category),
};
JSValue js_circle2d_set_radius(JSContext *js, JSValue this, JSValue val) { JSValue js_circle2d_set_radius(JSContext *js, JSValue this, JSValue val) {
cpCircleShapeSetRadius(js2cpShape(this), js2number(val)); cpCircleShapeSetRadius(js2cpShape(this), js2number(val));
} }
@ -1812,12 +1825,29 @@ static const JSCFunctionListEntry js_circle2d_funcs[] = {
CGETSET_ADD(circle2d, offset) CGETSET_ADD(circle2d, offset)
}; };
JSValue prep_cpshape(cpShape *shape, gameobject *go)
{
cpSpaceAddShape(space, shape);
// cpShapeSetFilter(shape, (cpShapeFilter) {
// .group = (cpGroup)go,
// .mask = CP_ALL_CATEGORIES,
// .categories = CP_ALL_CATEGORIES
// });
cpShapeSetFilter(shape, CP_SHAPE_FILTER_ALL);
cpShapeSetCollisionType(shape, (cpCollisionType)go);
JSValue ret = cpShape2js(shape);
JSValue *cb = malloc(sizeof(JSValue));
*cb = ret;
cpShapeSetUserData(shape, cb);
return ret;
}
JSC_CCALL(os_make_circle2d, JSC_CCALL(os_make_circle2d,
gameobject *go = js2gameobject(argv[0]); gameobject *go = js2gameobject(argv[0]);
cpShape *shape = cpCircleShapeNew(go->body, 10, (cpVect){0,0}); cpShape *shape = cpCircleShapeNew(go->body, 10, (cpVect){0,0});
cpSpaceAddShape(space, shape); ret = prep_cpshape(shape,go);
ret = cpShape2js(shape); JS_SetPrototype(js, ret, js_circle2d);
JS_SetPropertyFunctionList(js, ret, js_circle2d_funcs, countof(js_circle2d_funcs));
return ret; return ret;
) )
@ -1848,9 +1878,8 @@ static const JSCFunctionListEntry js_poly2d_funcs[] = {
JSC_CCALL(os_make_poly2d, JSC_CCALL(os_make_poly2d,
gameobject *go = js2gameobject(argv[0]); gameobject *go = js2gameobject(argv[0]);
cpShape *shape = cpPolyShapeNew(go->body, 0, NULL, (cpTransform){0}, 0); cpShape *shape = cpPolyShapeNew(go->body, 0, NULL, (cpTransform){0}, 0);
cpSpaceAddShape(space, shape); ret = prep_cpshape(shape,go);
ret = cpShape2js(shape); JS_SetPrototype(js, ret, js_poly2d);
JS_SetPropertyFunctionList(js, ret, js_poly2d_funcs, countof(js_poly2d_funcs));
return ret; return ret;
) )
@ -1880,26 +1909,11 @@ static const JSCFunctionListEntry js_seg2d_funcs[] = {
JSC_CCALL(os_make_seg2d, JSC_CCALL(os_make_seg2d,
gameobject *go = js2gameobject(argv[0]); gameobject *go = js2gameobject(argv[0]);
cpShape *shape = cpSegmentShapeNew(go->body, (cpVect){0,0}, (cpVect){0,0}, 0); cpShape *shape = cpSegmentShapeNew(go->body, (cpVect){0,0}, (cpVect){0,0}, 0);
cpSpaceAddShape(space, shape); ret = prep_cpshape(shape,go);
ret = cpShape2js(shape); JS_SetPrototype(js, ret, js_seg2d);
JS_SetPropertyFunctionList(js, ret, js_seg2d_funcs, countof(js_seg2d_funcs));
return ret; return ret;
) )
JSC_CCALL(os_make_edge2d,
gameobject *go = js2gameobject(argv[0]);
struct phys2d_edge *edge = Make2DEdge(go);
HMM_Vec2 *points = js2cpvec2arr(argv[1]);
phys2d_edge_update_verts(edge, points);
arrfree(points);
JSValue edgeval = JS_NewObject(js);
js_setprop_str(edgeval, "id", ptr2js(edge));
js_setprop_str(edgeval, "shape", ptr2js(&edge->shape));
edge->shape.ref = JS_DupValue(js, argv[1]);
return edgeval;
)
JSC_SCALL(os_make_texture, JSC_SCALL(os_make_texture,
ret = texture2js(texture_from_file(str)); ret = texture2js(texture_from_file(str));
YughInfo("Made texture with %s", str); YughInfo("Made texture with %s", str);
@ -2132,7 +2146,6 @@ static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os, make_gameobject, 1), MIST_FUNC_DEF(os, make_gameobject, 1),
MIST_FUNC_DEF(os, make_circle2d, 2), MIST_FUNC_DEF(os, make_circle2d, 2),
MIST_FUNC_DEF(os, make_poly2d, 2), MIST_FUNC_DEF(os, make_poly2d, 2),
MIST_FUNC_DEF(os, make_edge2d, 2),
MIST_FUNC_DEF(os, make_seg2d, 1), MIST_FUNC_DEF(os, make_seg2d, 1),
MIST_FUNC_DEF(os, make_texture, 1), MIST_FUNC_DEF(os, make_texture, 1),
MIST_FUNC_DEF(os, make_font, 2), MIST_FUNC_DEF(os, make_font, 2),
@ -2140,7 +2153,7 @@ static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os, make_transform, 0), MIST_FUNC_DEF(os, make_transform, 0),
MIST_FUNC_DEF(os, make_emitter, 0), MIST_FUNC_DEF(os, make_emitter, 0),
MIST_FUNC_DEF(os, make_buffer, 1), MIST_FUNC_DEF(os, make_buffer, 1),
MIST_FUNC_DEF(os, make_line_prim, 2), MIST_FUNC_DEF(os, make_line_prim, 4),
MIST_FUNC_DEF(os, make_cylinder, 2), MIST_FUNC_DEF(os, make_cylinder, 2),
MIST_FUNC_DEF(os, make_cone, 2), MIST_FUNC_DEF(os, make_cone, 2),
MIST_FUNC_DEF(os, make_disk, 2), MIST_FUNC_DEF(os, make_disk, 2),
@ -2174,6 +2187,7 @@ void ffi_load() {
QJSCLASSPREP_FUNCS(constraint); QJSCLASSPREP_FUNCS(constraint);
QJSCLASSPREP_FUNCS(window); QJSCLASSPREP_FUNCS(window);
QJSCLASSPREP_FUNCS(datastream); QJSCLASSPREP_FUNCS(datastream);
QJSCLASSPREP_FUNCS(cpShape);
QJSGLOBALCLASS(nota); QJSGLOBALCLASS(nota);
QJSGLOBALCLASS(input); QJSGLOBALCLASS(input);
@ -2185,18 +2199,15 @@ void ffi_load() {
QJSGLOBALCLASS(profile); QJSGLOBALCLASS(profile);
QJSGLOBALCLASS(game); QJSGLOBALCLASS(game);
QJSGLOBALCLASS(gui); QJSGLOBALCLASS(gui);
QJSGLOBALCLASS(debug);
QJSGLOBALCLASS(render); QJSGLOBALCLASS(render);
QJSGLOBALCLASS(physics); QJSGLOBALCLASS(physics);
QJSGLOBALCLASS(vector); QJSGLOBALCLASS(vector);
QJSGLOBALCLASS(spline); QJSGLOBALCLASS(spline);
QJSGLOBALCLASS(joint); QJSGLOBALCLASS(joint);
QJSGLOBALCLASS(dspsound); QJSGLOBALCLASS(dspsound);
QJSGLOBALCLASS(pshape);
QJSGLOBALCLASS(performance); QJSGLOBALCLASS(performance);
QJSGLOBALCLASS(poly2d); QJSGLOBALCLASS(poly2d);
QJSGLOBALCLASS(edge2d);
JS_SetPropertyStr(js, prosperon, "version", str2js(VER)); JS_SetPropertyStr(js, prosperon, "version", str2js(VER));
JS_SetPropertyStr(js, prosperon, "revision", str2js(COM)); JS_SetPropertyStr(js, prosperon, "revision", str2js(COM));
@ -2209,6 +2220,18 @@ void ffi_load() {
JS_SetPropertyStr(js,globalThis, "sound_proto", sound_proto); JS_SetPropertyStr(js,globalThis, "sound_proto", sound_proto);
JS_SetPropertyFunctionList(js, sound_proto, js_sound_funcs, countof(js_sound_funcs)); JS_SetPropertyFunctionList(js, sound_proto, js_sound_funcs, countof(js_sound_funcs));
JS_SetPrototype(js, sound_proto, dsp_node_proto); JS_SetPrototype(js, sound_proto, dsp_node_proto);
js_circle2d = JS_NewObject(js);
JS_SetPropertyFunctionList(js, js_circle2d, js_circle2d_funcs, countof(js_circle2d_funcs));
JS_SetPrototype(js, js_circle2d, cpShape_proto);
js_poly2d = JS_NewObject(js);
JS_SetPropertyFunctionList(js, js_poly2d, js_poly2d_funcs, countof(js_poly2d_funcs));
JS_SetPrototype(js, js_poly2d, cpShape_proto);
js_seg2d = JS_NewObject(js);
JS_SetPropertyFunctionList(js, js_seg2d, js_seg2d_funcs, countof(js_seg2d_funcs));
JS_SetPrototype(js, js_seg2d, cpShape_proto);
JS_FreeValue(js,globalThis); JS_FreeValue(js,globalThis);
} }

View file

@ -11,6 +11,8 @@
#define GETFN(ID, ENTRY, TYPE) JSC_CCALL(ID##_##ENTRY, return TYPE##2js(js2##ID (this)->ENTRY)) #define GETFN(ID, ENTRY, TYPE) JSC_CCALL(ID##_##ENTRY, return TYPE##2js(js2##ID (this)->ENTRY))
#define JS_SETSIG JSContext *js, JSValue this, JSValue val
#define JSC_SCALL(NAME, FN) JSC_CCALL(NAME, \ #define JSC_SCALL(NAME, FN) JSC_CCALL(NAME, \
const char *str = js2str(argv[0]); \ const char *str = js2str(argv[0]); \
FN ; \ FN ; \
@ -41,7 +43,7 @@
} \ } \
#define GETSETPAIR(ID, ENTRY, TYPE, FN) \ #define GETSETPAIR(ID, ENTRY, TYPE, FN) \
JSValue js_##ID##_set_##ENTRY (JSContext *js, JSValue this, JSValue val) { \ JSValue js_##ID##_set_##ENTRY (JS_SETSIG) { \
js2##ID (this)->ENTRY = js2##TYPE (val); \ js2##ID (this)->ENTRY = js2##TYPE (val); \
{FN;} \ {FN;} \
return JS_UNDEFINED; \ return JS_UNDEFINED; \
@ -56,7 +58,7 @@ JSValue js_##ID##_get_##ENTRY (JSContext *js, JSValue this) { \
#define JSC_GETSET_HOOK(ID, ENTRY) GETSETPAIR(ID, ENTRY, JSValue, ;) #define JSC_GETSET_HOOK(ID, ENTRY) GETSETPAIR(ID, ENTRY, JSValue, ;)
#define JSC_GETSET_GLOBAL(ENTRY, TYPE) \ #define JSC_GETSET_GLOBAL(ENTRY, TYPE) \
JSValue js_global_set_##ENTRY (JSContext *js, JSValue this, JSValue val) { \ JSValue js_global_set_##ENTRY (JS_SETSIG) { \
ENTRY = js2##TYPE (val); \ ENTRY = js2##TYPE (val); \
return JS_UNDEFINED; \ return JS_UNDEFINED; \
} \ } \
@ -66,7 +68,7 @@ JSValue js_global_get_##ENTRY (JSContext *js, JSValue this) { \
} \ } \
#define JSC_GETSET_BODY(ENTRY, CPENTRY, TYPE) \ #define JSC_GETSET_BODY(ENTRY, CPENTRY, TYPE) \
JSValue js_gameobject_set_##ENTRY (JSContext *js, JSValue this, JSValue val) { \ JSValue js_gameobject_set_##ENTRY (JS_SETSIG) { \
cpBody *b = js2gameobject(this)->body; \ cpBody *b = js2gameobject(this)->body; \
cpBodySet##CPENTRY (b, js2##TYPE (val)); \ cpBodySet##CPENTRY (b, js2##TYPE (val)); \
return JS_UNDEFINED; \ return JS_UNDEFINED; \

View file

@ -57,12 +57,7 @@ HMM_Mat4 transform2mat(transform t) {
HMM_Quat angle2rotation(float angle) HMM_Quat angle2rotation(float angle)
{ {
return HMM_QFromAxisAngle_LH(vUP, angle); return HMM_QFromAxisAngle_LH(vBKWD, angle);
}
float transform2angle(HMM_Vec3 axis)
{
} }
transform mat2transform(HMM_Mat4 m) transform mat2transform(HMM_Mat4 m)