2d physics to javascript
This commit is contained in:
parent
ee72949029
commit
ba2409fc56
|
@ -14,13 +14,6 @@ gameobject *shape2go(cpShape *shape) {
|
||||||
return pshape->go;
|
return pshape->go;
|
||||||
}
|
}
|
||||||
|
|
||||||
HMM_Vec3 go_pos(gameobject *go)
|
|
||||||
{
|
|
||||||
cpVect p = cpBodyGetPosition(go->body);
|
|
||||||
return (HMM_Vec3){p.x, p.y, 0};
|
|
||||||
}
|
|
||||||
float go_angle(gameobject *go) { return cpBodyGetAngle(go->body); }
|
|
||||||
|
|
||||||
transform go2t(gameobject *go)
|
transform go2t(gameobject *go)
|
||||||
{
|
{
|
||||||
transform t = {0};
|
transform t = {0};
|
||||||
|
@ -75,6 +68,8 @@ void gameobject_apply(gameobject *go) {
|
||||||
if (cpBodyGetMoment(go->body) <= 0.f)
|
if (cpBodyGetMoment(go->body) <= 0.f)
|
||||||
cpBodySetMoment(go->body, 1.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)
|
||||||
|
@ -159,11 +154,6 @@ void gameobject_free(gameobject *go) {
|
||||||
free(go);
|
free(go);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gameobject_setangle(gameobject *go, float angle) {
|
|
||||||
cpBodySetAngle(go->body, angle);
|
|
||||||
phys2d_reindex_body(go->body);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -42,6 +42,7 @@ struct gameobject {
|
||||||
unsigned int warp_mask;
|
unsigned int warp_mask;
|
||||||
HMM_Vec3 scale;
|
HMM_Vec3 scale;
|
||||||
JSValue ref;
|
JSValue ref;
|
||||||
|
transform *t; // the transform this body controls
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -67,16 +68,10 @@ void gameobject_free(gameobject *go);
|
||||||
transform go2t(gameobject *go);
|
transform go2t(gameobject *go);
|
||||||
|
|
||||||
HMM_Vec3 go_pos(gameobject *go);
|
HMM_Vec3 go_pos(gameobject *go);
|
||||||
void gameobject_setpos(gameobject *go, cpVect vec);
|
|
||||||
float go_angle(gameobject *go);
|
|
||||||
void gameobject_setangle(gameobject *go, float angle);
|
|
||||||
|
|
||||||
gameobject *body2go(cpBody *body);
|
gameobject *body2go(cpBody *body);
|
||||||
gameobject *shape2go(cpShape *shape);
|
gameobject *shape2go(cpShape *shape);
|
||||||
|
|
||||||
void go_shape_apply(cpBody *body, cpShape *shape, gameobject *go);
|
void go_shape_apply(cpBody *body, cpShape *shape, gameobject *go);
|
||||||
|
|
||||||
/* Tries a few methods to select a gameobject; if none is selected returns -1 */
|
|
||||||
|
|
||||||
void gameobject_draw_debug(gameobject *go);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "par/par_streamlines.h"
|
#include "par/par_streamlines.h"
|
||||||
#include "par/par_shapes.h"
|
#include "par/par_shapes.h"
|
||||||
#include "sokol_glue.h"
|
#include "sokol_glue.h"
|
||||||
|
#include <chipmunk/chipmunk_unsafe.h>
|
||||||
|
|
||||||
#if (defined(_WIN32) || defined(__WIN32__))
|
#if (defined(_WIN32) || defined(__WIN32__))
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
|
@ -78,6 +79,11 @@ void sg_buffer_free(sg_buffer *b)
|
||||||
free(b);
|
free(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cpShape_free(cpShape *s)
|
||||||
|
{
|
||||||
|
cpShapeFree(s);
|
||||||
|
}
|
||||||
|
|
||||||
void sg_image_free(sg_image *t){}
|
void sg_image_free(sg_image *t){}
|
||||||
|
|
||||||
void jsfreestr(const char *s) { JS_FreeCString(js, s); }
|
void jsfreestr(const char *s) { JS_FreeCString(js, s); }
|
||||||
|
@ -94,6 +100,7 @@ QJSCLASS(constraint)
|
||||||
QJSCLASS(sg_buffer)
|
QJSCLASS(sg_buffer)
|
||||||
QJSCLASS(sg_image)
|
QJSCLASS(sg_image)
|
||||||
QJSCLASS(datastream)
|
QJSCLASS(datastream)
|
||||||
|
QJSCLASS(cpShape)
|
||||||
|
|
||||||
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; }
|
||||||
|
@ -563,34 +570,6 @@ int point2segindex(HMM_Vec2 p, HMM_Vec2 *segs, double slop) {
|
||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
circle2d *js2circle2d(JSValue v) { return js2ptr(v); }
|
|
||||||
|
|
||||||
JSC_CCALL(circle2d_set_radius, js2circle2d(argv[0])->radius = js2number(argv[1]))
|
|
||||||
JSC_CCALL(circle2d_get_radius, return number2js(js2circle2d(argv[0])->radius))
|
|
||||||
JSC_CCALL(circle2d_set_offset, js2circle2d(argv[0])->offset = js2vec2(argv[1]))
|
|
||||||
JSC_CCALL(circle2d_get_offset, return vec22js(js2circle2d(argv[0])->offset))
|
|
||||||
JSC_CCALL(circle2d_sync, phys2d_shape_apply(&js2circle2d(argv[0])->shape))
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_circle2d_funcs[] = {
|
|
||||||
MIST_FUNC_DEF(circle2d, set_radius, 2),
|
|
||||||
MIST_FUNC_DEF(circle2d, get_radius, 1),
|
|
||||||
MIST_FUNC_DEF(circle2d, set_offset, 2),
|
|
||||||
MIST_FUNC_DEF(circle2d, get_offset, 1),
|
|
||||||
MIST_FUNC_DEF(circle2d, sync, 1),
|
|
||||||
};
|
|
||||||
|
|
||||||
struct phys2d_poly *js2poly2d(JSValue v) { return js2ptr(v); }
|
|
||||||
|
|
||||||
JSC_CCALL(poly2d_setverts,
|
|
||||||
struct phys2d_poly *p = js2poly2d(argv[0]);
|
|
||||||
HMM_Vec2 *v = js2cpvec2arr(argv[1]);
|
|
||||||
phys2d_poly_setverts(p,v);
|
|
||||||
arrfree(v);
|
|
||||||
)
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_poly2d_funcs[] = {
|
|
||||||
MIST_FUNC_DEF(poly2d, setverts, 2),
|
|
||||||
};
|
|
||||||
|
|
||||||
JSC_GETSET(warp_gravity, strength, number)
|
JSC_GETSET(warp_gravity, strength, number)
|
||||||
JSC_GETSET(warp_gravity, decay, number)
|
JSC_GETSET(warp_gravity, decay, number)
|
||||||
|
@ -1487,16 +1466,18 @@ static const JSCFunctionListEntry js_window_funcs[] = {
|
||||||
MIST_FUNC_DEF(window, set_icon, 1)
|
MIST_FUNC_DEF(window, set_icon, 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
JSValue js_gameobject_set_rpos(JSContext *js, JSValue this, JSValue val) {
|
JSValue js_gameobject_set_pos(JSContext *js, JSValue this, JSValue val) {
|
||||||
cpBody *b = js2gameobject(this)->body;
|
cpBody *b = js2gameobject(this)->body;
|
||||||
cpBodySetPosition(b, js2cvec2(val));
|
cpBodySetPosition(b, js2cvec2(val));
|
||||||
if (cpBodyGetType(b) == CP_BODY_TYPE_STATIC)
|
if (cpBodyGetType(b) == CP_BODY_TYPE_STATIC)
|
||||||
cpSpaceReindexShapesForBody(space, b);
|
cpSpaceReindexShapesForBody(space, b);
|
||||||
|
|
||||||
|
gameobject_apply(js2gameobject(this));
|
||||||
return JS_UNDEFINED;
|
return JS_UNDEFINED;
|
||||||
}
|
}
|
||||||
JSValue js_gameobject_get_rpos(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_rangle (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_rangle (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_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; }
|
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)
|
||||||
|
@ -1521,7 +1502,20 @@ JSC_GETSET(gameobject, categories, bitmask)
|
||||||
JSC_GETSET(gameobject, mask, bitmask)
|
JSC_GETSET(gameobject, mask, bitmask)
|
||||||
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) {
|
||||||
|
JSValue v = cpShape2js(shape);
|
||||||
|
script_call_sym(*fn, 1, &v);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSC_CCALL(gameobject_eachshape,
|
||||||
|
gameobject *g = js2gameobject(this);
|
||||||
|
JSValue fn = argv[0];
|
||||||
|
cpBodyEachShape(g->body, body_shape_fn, &fn);
|
||||||
|
)
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_gameobject_funcs[] = {
|
static const JSCFunctionListEntry js_gameobject_funcs[] = {
|
||||||
|
CGETSET_ADD(gameobject, pos),
|
||||||
|
CGETSET_ADD(gameobject, angle),
|
||||||
CGETSET_ADD(gameobject, friction),
|
CGETSET_ADD(gameobject, friction),
|
||||||
CGETSET_ADD(gameobject, elasticity),
|
CGETSET_ADD(gameobject, elasticity),
|
||||||
CGETSET_ADD(gameobject,mass),
|
CGETSET_ADD(gameobject,mass),
|
||||||
|
@ -1542,6 +1536,7 @@ 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)
|
||||||
};
|
};
|
||||||
|
|
||||||
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))))
|
||||||
|
@ -1795,30 +1790,100 @@ JSC_CCALL(os_gc, script_gc());
|
||||||
JSC_SSCALL(os_eval, ret = script_eval(str, str2))
|
JSC_SSCALL(os_eval, ret = script_eval(str, str2))
|
||||||
|
|
||||||
JSC_CCALL(os_make_gameobject,
|
JSC_CCALL(os_make_gameobject,
|
||||||
ret = gameobject2js(MakeGameobject());
|
gameobject *g = MakeGameobject();
|
||||||
JS_SetPropertyFunctionList(js, ret, js_gameobject_funcs, countof(js_gameobject_funcs));
|
g->t = js2transform(argv[0]);
|
||||||
js2gameobject(ret)->ref = ret;
|
ret = gameobject2js(g);
|
||||||
|
// JS_SetPropertyFunctionList(js, ret, js_gameobject_funcs, countof(js_gameobject_funcs));
|
||||||
|
g->ref = ret;
|
||||||
return ret;
|
return ret;
|
||||||
)
|
)
|
||||||
|
|
||||||
|
JSValue js_circle2d_set_radius(JSContext *js, JSValue this, JSValue val) {
|
||||||
|
cpCircleShapeSetRadius(js2cpShape(this), js2number(val));
|
||||||
|
}
|
||||||
|
JSC_CCALL(circle2d_get_radius, return number2js(cpCircleShapeGetRadius(js2cpShape(this))))
|
||||||
|
JSValue js_circle2d_set_offset(JSContext *js, JSValue this, JSValue val) {
|
||||||
|
cpCircleShapeSetOffset(js2cpShape(this), js2vec2(val).cp);
|
||||||
|
}
|
||||||
|
JSC_CCALL(circle2d_get_offset, return vec22js((HMM_Vec2)cpCircleShapeGetOffset(js2cpShape(this))))
|
||||||
|
|
||||||
|
static const JSCFunctionListEntry js_circle2d_funcs[] = {
|
||||||
|
CGETSET_ADD(circle2d, radius),
|
||||||
|
CGETSET_ADD(circle2d, offset)
|
||||||
|
};
|
||||||
|
|
||||||
JSC_CCALL(os_make_circle2d,
|
JSC_CCALL(os_make_circle2d,
|
||||||
gameobject *go = js2gameobject(argv[0]);
|
gameobject *go = js2gameobject(argv[0]);
|
||||||
struct phys2d_circle *circle = Make2DCircle(go);
|
cpShape *shape = cpCircleShapeNew(go->body, 10, (cpVect){0,0});
|
||||||
JSValue circleval = JS_NewObject(js);
|
cpSpaceAddShape(space, shape);
|
||||||
js_setprop_str(circleval, "id", ptr2js(circle));
|
ret = cpShape2js(shape);
|
||||||
js_setprop_str(circleval, "shape", ptr2js(&circle->shape));
|
JS_SetPropertyFunctionList(js, ret, js_circle2d_funcs, countof(js_circle2d_funcs));
|
||||||
circle->shape.ref = JS_DupValue(js,argv[1]);
|
return ret;
|
||||||
return circleval;
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(poly2d_setverts,
|
||||||
|
cpShape *s = js2cpShape(this);
|
||||||
|
HMM_Vec2 *v = js2cpvec2arr(argv[0]);
|
||||||
|
cpTransform t = {0};
|
||||||
|
t.a = 1;
|
||||||
|
t.b = 0;
|
||||||
|
t.tx = 0;
|
||||||
|
t.c = 0;
|
||||||
|
t.d = 1;
|
||||||
|
t.ty = 0;
|
||||||
|
cpPolyShapeSetVerts(s, arrlen(v), v, t);
|
||||||
|
arrfree(v);
|
||||||
|
)
|
||||||
|
|
||||||
|
JSValue js_poly2d_set_radius(JSContext *js, JSValue this, JSValue val) {
|
||||||
|
cpPolyShapeSetRadius(js2cpShape(this), js2number(val));
|
||||||
|
}
|
||||||
|
JSC_CCALL(poly2d_get_radius, return number2js(cpPolyShapeGetRadius(js2cpShape(this))))
|
||||||
|
|
||||||
|
static const JSCFunctionListEntry js_poly2d_funcs[] = {
|
||||||
|
MIST_FUNC_DEF(poly2d, setverts, 2),
|
||||||
|
CGETSET_ADD(poly2d, radius)
|
||||||
|
};
|
||||||
|
|
||||||
JSC_CCALL(os_make_poly2d,
|
JSC_CCALL(os_make_poly2d,
|
||||||
gameobject *go = js2gameobject(argv[0]);
|
gameobject *go = js2gameobject(argv[0]);
|
||||||
struct phys2d_poly *poly = Make2DPoly(go);
|
cpShape *shape = cpPolyShapeNew(go->body, 0, NULL, (cpTransform){0}, 0);
|
||||||
phys2d_poly_setverts(poly, NULL);
|
cpSpaceAddShape(space, shape);
|
||||||
JSValue polyval = JS_NewObject(js);
|
ret = cpShape2js(shape);
|
||||||
js_setprop_str(polyval, "id", ptr2js(poly));
|
JS_SetPropertyFunctionList(js, ret, js_poly2d_funcs, countof(js_poly2d_funcs));
|
||||||
js_setprop_str(polyval, "shape", ptr2js(&poly->shape));
|
return ret;
|
||||||
poly->shape.ref = JS_DupValue(js,argv[1]);
|
)
|
||||||
return polyval;
|
|
||||||
|
JSC_CCALL(seg2d_set_endpoints,
|
||||||
|
HMM_Vec2 a = js2vec2(argv[0]);
|
||||||
|
HMM_Vec2 b = js2vec2(argv[1]);
|
||||||
|
cpSegmentShapeSetEndpoints(js2cpShape(this), a.cp, b.cp);
|
||||||
|
)
|
||||||
|
|
||||||
|
JSValue js_seg2d_set_radius(JSContext *js, JSValue this, JSValue val) {
|
||||||
|
cpSegmentShapeSetRadius(js2cpShape(this), js2number(val));
|
||||||
|
}
|
||||||
|
JSC_CCALL(seg2d_get_radius, return number2js(cpSegmentShapeGetRadius(js2cpShape(this))))
|
||||||
|
|
||||||
|
JSC_CCALL(seg2d_set_neighbors,
|
||||||
|
HMM_Vec2 prev = js2vec2(argv[0]);
|
||||||
|
HMM_Vec2 next = js2vec2(argv[1]);
|
||||||
|
cpSegmentShapeSetNeighbors(js2cpShape(this), prev.cp, next.cp);
|
||||||
|
)
|
||||||
|
|
||||||
|
static const JSCFunctionListEntry js_seg2d_funcs[] = {
|
||||||
|
MIST_FUNC_DEF(seg2d, set_endpoints, 2),
|
||||||
|
CGETSET_ADD(seg2d, radius),
|
||||||
|
MIST_FUNC_DEF(seg2d, set_neighbors, 2)
|
||||||
|
};
|
||||||
|
|
||||||
|
JSC_CCALL(os_make_seg2d,
|
||||||
|
gameobject *go = js2gameobject(argv[0]);
|
||||||
|
cpShape *shape = cpSegmentShapeNew(go->body, (cpVect){0,0}, (cpVect){0,0}, 0);
|
||||||
|
cpSpaceAddShape(space, shape);
|
||||||
|
ret = cpShape2js(shape);
|
||||||
|
JS_SetPropertyFunctionList(js, ret, js_seg2d_funcs, countof(js_seg2d_funcs));
|
||||||
|
return ret;
|
||||||
)
|
)
|
||||||
|
|
||||||
JSC_CCALL(os_make_edge2d,
|
JSC_CCALL(os_make_edge2d,
|
||||||
|
@ -2064,10 +2129,11 @@ static const JSCFunctionListEntry js_os_funcs[] = {
|
||||||
MIST_FUNC_DEF(os, reindex_static, 0),
|
MIST_FUNC_DEF(os, reindex_static, 0),
|
||||||
MIST_FUNC_DEF(os, gc, 0),
|
MIST_FUNC_DEF(os, gc, 0),
|
||||||
MIST_FUNC_DEF(os, eval, 2),
|
MIST_FUNC_DEF(os, eval, 2),
|
||||||
MIST_FUNC_DEF(os, make_gameobject, 0),
|
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_edge2d, 2),
|
||||||
|
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),
|
||||||
MIST_FUNC_DEF(os, make_model, 1),
|
MIST_FUNC_DEF(os, make_model, 1),
|
||||||
|
@ -2128,7 +2194,7 @@ void ffi_load() {
|
||||||
QJSGLOBALCLASS(dspsound);
|
QJSGLOBALCLASS(dspsound);
|
||||||
QJSGLOBALCLASS(pshape);
|
QJSGLOBALCLASS(pshape);
|
||||||
QJSGLOBALCLASS(performance);
|
QJSGLOBALCLASS(performance);
|
||||||
QJSGLOBALCLASS(circle2d);
|
|
||||||
QJSGLOBALCLASS(poly2d);
|
QJSGLOBALCLASS(poly2d);
|
||||||
QJSGLOBALCLASS(edge2d);
|
QJSGLOBALCLASS(edge2d);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue