removed unnecessary physics code
This commit is contained in:
parent
ba2409fc56
commit
4e4667db50
|
@ -1,3 +1,5 @@
|
|||
var debug = {};
|
||||
|
||||
debug.fn_break = function(fn,obj = globalThis) {
|
||||
if (typeof fn !== 'function') return;
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ prosperon.textinput = function(c){
|
|||
};
|
||||
prosperon.mousemove = function(pos, dx){
|
||||
mousepos = pos;
|
||||
mousepos.y = window.size.y - mousepos.y;
|
||||
player[0].mouse_input("move", pos, dx);
|
||||
};
|
||||
prosperon.mousescroll = function(dx){
|
||||
|
|
|
@ -1,140 +1,18 @@
|
|||
#include "2dphysics.h"
|
||||
|
||||
#include "gameobject.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "stb_ds.h"
|
||||
#include <assert.h>
|
||||
#include <chipmunk/chipmunk_unsafe.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "2dphysics.h"
|
||||
|
||||
#include "jsffi.h"
|
||||
#include "script.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
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 hits[100];
|
||||
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()
|
||||
{
|
||||
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)
|
||||
|
@ -178,299 +56,6 @@ void phys2d_update(float deltaT) {
|
|||
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)
|
||||
{
|
||||
cpBody *body1;
|
||||
|
@ -481,17 +66,18 @@ JSValue arb2js(cpArbiter *arb)
|
|||
cpShape *shape2;
|
||||
cpArbiterGetShapes(arb, &shape1, &shape2);
|
||||
|
||||
struct phys2d_shape *pshape = cpShapeGetUserData(shape2);
|
||||
gameobject *go2 = cpBodyGetUserData(body2);
|
||||
JSValue *j = cpShapeGetUserData(shape2);
|
||||
|
||||
JSValue jg = body2go(body2)->ref;
|
||||
|
||||
HMM_Vec2 srfv;
|
||||
srfv.cp = cpArbiterGetSurfaceVelocity(arb);
|
||||
|
||||
JSValue obj = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, obj, "normal", vec22js((HMM_Vec2)cpArbiterGetNormal(arb)));
|
||||
JS_SetPropertyStr(js, obj, "obj", JS_DupValue(js,go2->ref));
|
||||
JS_SetPropertyStr(js, obj, "shape", JS_DupValue(js, pshape->ref));
|
||||
// JS_SetPropertyStr(js, obj, "point", vec22js((HMM_Vec2)cpArbiterGetPointA(arb, 0)));
|
||||
|
||||
HMM_Vec2 srfv;
|
||||
srfv.cp = cpArbiterGetSurfaceVelocity(arb);
|
||||
JS_SetPropertyStr(js, obj, "obj", JS_DupValue(js,jg));
|
||||
JS_SetPropertyStr(js, obj, "shape", JS_DupValue(js, *j));
|
||||
JS_SetPropertyStr(js, obj, "point", vec22js((HMM_Vec2)cpArbiterGetPointA(arb, 0)));
|
||||
JS_SetPropertyStr(js, obj, "velocity", vec22js(srfv));
|
||||
|
||||
return obj;
|
||||
|
@ -517,18 +103,10 @@ void register_hit(cpArbiter *arb, gameobject *go, const char *name)
|
|||
}
|
||||
|
||||
cpShape *s1, *s2;
|
||||
cpArbiterGetShapes(arb, &s1, &s2);
|
||||
gameobject *g1, *g2;
|
||||
g1 = shape2go(s1);
|
||||
g2 = shape2go(g2);
|
||||
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);
|
||||
cpArbiterGetShapes(arb, &s1, &s2);
|
||||
JSValue *j1 = cpShapeGetUserData(s1);
|
||||
JSValue *j2 = cpShapeGetUserData(s2);
|
||||
cb = JS_GetPropertyStr(js, *j1, name);
|
||||
if (!JS_IsUndefined(cb)) {
|
||||
JSValue jarb = arb2js(arb);
|
||||
fns[cb_idx] = JS_DupValue(js,cb);
|
||||
|
|
|
@ -7,16 +7,8 @@
|
|||
#include "render.h"
|
||||
#include "transform.h"
|
||||
|
||||
extern float phys2d_gravity;
|
||||
extern int physOn;
|
||||
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 {
|
||||
cpConstraint *c;
|
||||
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_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_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);
|
||||
int query_point(HMM_Vec2 pos);
|
||||
|
||||
void phys2d_reindex_body(cpBody *body);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,43 +7,28 @@
|
|||
|
||||
#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 t = {0};
|
||||
t.pos.cp = cpBodyGetPosition(go->body);
|
||||
t.rotation = angle2rotation(cpBodyGetAngle(go->body));
|
||||
t.scale = go->scale;
|
||||
if (!isfinite(t.scale.X)) t.scale.X = 1;
|
||||
if (!isfinite(t.scale.Y)) t.scale.Y = 1;
|
||||
t.scale = go->t->scale;
|
||||
return t;
|
||||
}
|
||||
|
||||
void go_shape_apply(cpBody *body, cpShape *shape, gameobject *go) {
|
||||
cpShapeSetFriction(shape, go->friction);
|
||||
cpShapeSetElasticity(shape, go->elasticity);
|
||||
cpShapeSetCollisionType(shape, (cpCollisionType)go);
|
||||
gameobject *body2go(cpBody *b)
|
||||
{
|
||||
return cpBodyGetUserData(b);
|
||||
}
|
||||
|
||||
cpShapeFilter filter;
|
||||
filter.group = (cpCollisionType)go;
|
||||
filter.categories = go->categories;
|
||||
filter.mask = go->mask;
|
||||
// filter.mask = CP_ALL_CATEGORIES;
|
||||
cpShapeSetFilter(shape, filter);
|
||||
|
||||
struct phys2d_shape *ape = cpShapeGetUserData(shape);
|
||||
if (ape && ape->apply)
|
||||
ape->apply(ape->data);
|
||||
gameobject *shape2go(cpShape *s)
|
||||
{
|
||||
cpBody *b = cpShapeGetBody(s);
|
||||
return cpBodyGetUserData(b);
|
||||
}
|
||||
|
||||
void go_shape_moi(cpBody *body, cpShape *shape, gameobject *go) {
|
||||
float moment = cpBodyGetMoment(body);
|
||||
/* float moment = cpBodyGetMoment(body);
|
||||
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
||||
if (!s) {
|
||||
cpBodySetMoment(body, moment + 1);
|
||||
|
@ -52,25 +37,10 @@ void go_shape_moi(cpBody *body, cpShape *shape, gameobject *go) {
|
|||
|
||||
moment += s->moi(s->data);
|
||||
if (moment < 0) moment = 0;
|
||||
cpBodySetMoment(body, moment);
|
||||
cpBodySetMoment(body, moment);*/
|
||||
}
|
||||
|
||||
void gameobject_apply(gameobject *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);
|
||||
}
|
||||
void gameobject_apply(gameobject *go) { *go->t = go2t(go); }
|
||||
|
||||
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 *ngo = malloc(sizeof(*ngo));
|
||||
gameobject go = {
|
||||
.scale = (HMM_Vec3){1.f,1.f,1.f},
|
||||
.phys = CP_BODY_TYPE_STATIC,
|
||||
.maxvelocity = INFINITY,
|
||||
.maxangularvelocity = INFINITY,
|
||||
.mass = 1.f,
|
||||
.damping = INFINITY,
|
||||
.timescale = 1.0,
|
||||
.ref = JS_UNDEFINED,
|
||||
.mask = ~0,
|
||||
.categories = 1,
|
||||
.warp_mask = ~0,
|
||||
};
|
||||
|
||||
go.body = cpSpaceAddBody(space, cpBodyNew(go.mass, 1.f));
|
||||
go.body = cpSpaceAddBody(space, cpBodyNew(1, 1));
|
||||
cpBodySetVelocityUpdateFunc(go.body, velocityFn);
|
||||
|
||||
*ngo = go;
|
||||
|
@ -123,19 +88,6 @@ gameobject *MakeGameobject() {
|
|||
}
|
||||
|
||||
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);
|
||||
cpShapeFree(shape);
|
||||
}
|
||||
|
@ -147,8 +99,8 @@ void rm_body_constraints(cpBody *body, cpConstraint *constraint, void *data)
|
|||
|
||||
void gameobject_free(gameobject *go) {
|
||||
go->ref = JS_UNDEFINED;
|
||||
cpBodyEachShape(go->body, rm_body_shapes, NULL);
|
||||
cpBodyEachConstraint(go->body, rm_body_constraints, NULL);
|
||||
// cpBodyEachShape(go->body, rm_body_shapes, NULL);
|
||||
// cpBodyEachConstraint(go->body, rm_body_constraints, NULL);
|
||||
cpSpaceRemoveBody(space, go->body);
|
||||
cpBodyFree(go->body);
|
||||
free(go);
|
||||
|
@ -157,5 +109,5 @@ void gameobject_free(gameobject *go) {
|
|||
void gameobject_setpos(gameobject *go, cpVect vec) {
|
||||
if (!go || !go->body) return;
|
||||
cpBodySetPosition(go->body, vec);
|
||||
phys2d_reindex_body(go->body);
|
||||
// phys2d_reindex_body(go->body);
|
||||
}
|
||||
|
|
|
@ -27,20 +27,13 @@
|
|||
}while(0)
|
||||
|
||||
struct gameobject {
|
||||
cpBodyType phys;
|
||||
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 timescale;
|
||||
float maxvelocity;
|
||||
float maxangularvelocity;
|
||||
unsigned int layer;
|
||||
cpBitmask categories;
|
||||
cpBitmask mask;
|
||||
unsigned int warp_mask;
|
||||
HMM_Vec3 scale;
|
||||
JSValue ref;
|
||||
transform *t; // the transform this body controls
|
||||
};
|
||||
|
@ -69,8 +62,8 @@ transform go2t(gameobject *go);
|
|||
|
||||
HMM_Vec3 go_pos(gameobject *go);
|
||||
|
||||
gameobject *body2go(cpBody *body);
|
||||
gameobject *shape2go(cpShape *shape);
|
||||
gameobject *shape2go(cpShape *s);
|
||||
gameobject *body2go(cpBody *b);
|
||||
|
||||
void go_shape_apply(cpBody *body, cpShape *shape, gameobject *go);
|
||||
|
||||
|
|
|
@ -81,6 +81,9 @@ void sg_buffer_free(sg_buffer *b)
|
|||
|
||||
void cpShape_free(cpShape *s)
|
||||
{
|
||||
JSValue *cb = cpShapeGetUserData(s);
|
||||
free(cb);
|
||||
cpSpaceRemoveShape(space, s);
|
||||
cpShapeFree(s);
|
||||
}
|
||||
|
||||
|
@ -102,6 +105,10 @@ QJSCLASS(sg_image)
|
|||
QJSCLASS(datastream)
|
||||
QJSCLASS(cpShape)
|
||||
|
||||
static JSValue js_circle2d;
|
||||
static JSValue js_poly2d;
|
||||
static JSValue js_seg2d;
|
||||
|
||||
static JSValue sound_proto;
|
||||
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)
|
||||
};
|
||||
|
||||
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,
|
||||
void *v1 = js2cpvec2arr(argv[1]);
|
||||
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,
|
||||
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)
|
||||
|
@ -1310,7 +1297,7 @@ JSC_CCALL(physics_ray_query,
|
|||
static void point_query_fn(cpShape *shape, float dist, cpVect point, JSValue *cb)
|
||||
{
|
||||
JSValue argv[3] = {
|
||||
JS_DupValue(js, shape2go(shape)->ref),
|
||||
JS_DupValue(js,*(JSValue*)cpShapeGetUserData(shape)),
|
||||
vec22js((HMM_Vec2)point),
|
||||
number2js(dist)
|
||||
};
|
||||
|
@ -1325,9 +1312,9 @@ JSC_CCALL(physics_point_query,
|
|||
JSValue pointinfo2js(cpPointQueryInfo info)
|
||||
{
|
||||
JSValue o = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, o, "distance", number2js(info.distance));
|
||||
JS_SetPropertyStr(js, o, "point", vec22js((HMM_Vec2)info.point));
|
||||
JS_SetPropertyStr(js, o, "entity", JS_DupValue(js, shape2go(info.shape)->ref));
|
||||
js_setpropstr(o, "distance", number2js(info.distance));
|
||||
js_setpropstr(o, "point", vec22js((HMM_Vec2)info.point));
|
||||
js_setpropstr(o, "entity", JS_DupValue(js, shape2go(info.shape)->ref));
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -1338,8 +1325,20 @@ JSC_CCALL(physics_point_query_nearest,
|
|||
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[] = {
|
||||
MIST_FUNC_DEF(physics, sgscale, 2),
|
||||
MIST_FUNC_DEF(physics, point_query, 3),
|
||||
MIST_FUNC_DEF(physics, point_query_nearest, 2),
|
||||
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, make_damp, 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[] = {
|
||||
|
@ -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_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_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)
|
||||
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)); }
|
||||
|
@ -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_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_GETSET_APPLY(gameobject, friction, number)
|
||||
JSC_GETSET_APPLY(gameobject, elasticity, number)
|
||||
JSC_GETSET_APPLY(gameobject, mass, number)
|
||||
JSC_GETSET_APPLY(gameobject, phys, number)
|
||||
JSC_GETSET_BODY(mass, Mass, number)
|
||||
JSC_GETSET_BODY(phys, Type, number)
|
||||
JSC_GETSET_APPLY(gameobject, layer, number)
|
||||
JSC_GETSET(gameobject, damping, number)
|
||||
JSC_GETSET(gameobject, timescale, number)
|
||||
JSC_GETSET(gameobject, maxvelocity, number)
|
||||
JSC_GETSET(gameobject, maxangularvelocity, number)
|
||||
JSC_GETSET(gameobject, warp_mask, bitmask)
|
||||
JSC_GETSET(gameobject, categories, bitmask)
|
||||
JSC_GETSET(gameobject, mask, bitmask)
|
||||
JSC_CCALL(gameobject_sleeping, return boolean2js(cpBodyIsSleeping(js2gameobject(this)->body)))
|
||||
JSC_CCALL(gameobject_sleep, cpBodySleep(js2gameobject(this)->body))
|
||||
JSC_CCALL(gameobject_wake, cpBodyActivate(js2gameobject(this)->body))
|
||||
JSC_CCALL(gameobject_selfsync, gameobject_apply(js2gameobject(this)))
|
||||
|
||||
void body_shape_fn(cpBody *body, cpShape *shape, JSValue *fn) {
|
||||
|
@ -1516,8 +1518,6 @@ JSC_CCALL(gameobject_eachshape,
|
|||
static const JSCFunctionListEntry js_gameobject_funcs[] = {
|
||||
CGETSET_ADD(gameobject, pos),
|
||||
CGETSET_ADD(gameobject, angle),
|
||||
CGETSET_ADD(gameobject, friction),
|
||||
CGETSET_ADD(gameobject, elasticity),
|
||||
CGETSET_ADD(gameobject,mass),
|
||||
CGETSET_ADD(gameobject,damping),
|
||||
CGETSET_ADD(gameobject,timescale),
|
||||
|
@ -1525,8 +1525,6 @@ static const JSCFunctionListEntry js_gameobject_funcs[] = {
|
|||
CGETSET_ADD(gameobject,maxangularvelocity),
|
||||
CGETSET_ADD(gameobject,layer),
|
||||
CGETSET_ADD(gameobject,warp_mask),
|
||||
CGETSET_ADD(gameobject, categories),
|
||||
CGETSET_ADD(gameobject, mask),
|
||||
CGETSET_ADD(gameobject, velocity),
|
||||
CGETSET_ADD(gameobject, angularvelocity),
|
||||
// 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_local, 2),
|
||||
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))))
|
||||
|
@ -1627,18 +1628,6 @@ static const JSCFunctionListEntry js_datastream_funcs[] = {
|
|||
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, height, number)
|
||||
JSC_GET(texture, frames, number)
|
||||
|
@ -1680,22 +1669,6 @@ static const JSCFunctionListEntry js_constraint_funcs[] = {
|
|||
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";
|
||||
|
||||
JSC_CCALL(performance_barecall,)
|
||||
|
@ -1793,11 +1766,51 @@ JSC_CCALL(os_make_gameobject,
|
|||
gameobject *g = MakeGameobject();
|
||||
g->t = js2transform(argv[0]);
|
||||
ret = gameobject2js(g);
|
||||
// JS_SetPropertyFunctionList(js, ret, js_gameobject_funcs, countof(js_gameobject_funcs));
|
||||
g->ref = ret;
|
||||
g->ref = 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) {
|
||||
cpCircleShapeSetRadius(js2cpShape(this), js2number(val));
|
||||
}
|
||||
|
@ -1812,12 +1825,29 @@ static const JSCFunctionListEntry js_circle2d_funcs[] = {
|
|||
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,
|
||||
gameobject *go = js2gameobject(argv[0]);
|
||||
cpShape *shape = cpCircleShapeNew(go->body, 10, (cpVect){0,0});
|
||||
cpSpaceAddShape(space, shape);
|
||||
ret = cpShape2js(shape);
|
||||
JS_SetPropertyFunctionList(js, ret, js_circle2d_funcs, countof(js_circle2d_funcs));
|
||||
ret = prep_cpshape(shape,go);
|
||||
JS_SetPrototype(js, ret, js_circle2d);
|
||||
return ret;
|
||||
)
|
||||
|
||||
|
@ -1848,9 +1878,8 @@ static const JSCFunctionListEntry js_poly2d_funcs[] = {
|
|||
JSC_CCALL(os_make_poly2d,
|
||||
gameobject *go = js2gameobject(argv[0]);
|
||||
cpShape *shape = cpPolyShapeNew(go->body, 0, NULL, (cpTransform){0}, 0);
|
||||
cpSpaceAddShape(space, shape);
|
||||
ret = cpShape2js(shape);
|
||||
JS_SetPropertyFunctionList(js, ret, js_poly2d_funcs, countof(js_poly2d_funcs));
|
||||
ret = prep_cpshape(shape,go);
|
||||
JS_SetPrototype(js, ret, js_poly2d);
|
||||
return ret;
|
||||
)
|
||||
|
||||
|
@ -1880,26 +1909,11 @@ static const JSCFunctionListEntry js_seg2d_funcs[] = {
|
|||
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));
|
||||
ret = prep_cpshape(shape,go);
|
||||
JS_SetPrototype(js, ret, js_seg2d);
|
||||
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,
|
||||
ret = texture2js(texture_from_file(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_circle2d, 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_texture, 1),
|
||||
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_emitter, 0),
|
||||
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_cone, 2),
|
||||
MIST_FUNC_DEF(os, make_disk, 2),
|
||||
|
@ -2174,6 +2187,7 @@ void ffi_load() {
|
|||
QJSCLASSPREP_FUNCS(constraint);
|
||||
QJSCLASSPREP_FUNCS(window);
|
||||
QJSCLASSPREP_FUNCS(datastream);
|
||||
QJSCLASSPREP_FUNCS(cpShape);
|
||||
|
||||
QJSGLOBALCLASS(nota);
|
||||
QJSGLOBALCLASS(input);
|
||||
|
@ -2185,18 +2199,15 @@ void ffi_load() {
|
|||
QJSGLOBALCLASS(profile);
|
||||
QJSGLOBALCLASS(game);
|
||||
QJSGLOBALCLASS(gui);
|
||||
QJSGLOBALCLASS(debug);
|
||||
QJSGLOBALCLASS(render);
|
||||
QJSGLOBALCLASS(physics);
|
||||
QJSGLOBALCLASS(vector);
|
||||
QJSGLOBALCLASS(spline);
|
||||
QJSGLOBALCLASS(joint);
|
||||
QJSGLOBALCLASS(dspsound);
|
||||
QJSGLOBALCLASS(pshape);
|
||||
QJSGLOBALCLASS(performance);
|
||||
|
||||
QJSGLOBALCLASS(poly2d);
|
||||
QJSGLOBALCLASS(edge2d);
|
||||
|
||||
JS_SetPropertyStr(js, prosperon, "version", str2js(VER));
|
||||
JS_SetPropertyStr(js, prosperon, "revision", str2js(COM));
|
||||
|
@ -2209,6 +2220,18 @@ void ffi_load() {
|
|||
JS_SetPropertyStr(js,globalThis, "sound_proto", sound_proto);
|
||||
JS_SetPropertyFunctionList(js, sound_proto, js_sound_funcs, countof(js_sound_funcs));
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#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, \
|
||||
const char *str = js2str(argv[0]); \
|
||||
FN ; \
|
||||
|
@ -41,7 +43,7 @@
|
|||
} \
|
||||
|
||||
#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); \
|
||||
{FN;} \
|
||||
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_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); \
|
||||
return JS_UNDEFINED; \
|
||||
} \
|
||||
|
@ -66,7 +68,7 @@ JSValue js_global_get_##ENTRY (JSContext *js, JSValue this) { \
|
|||
} \
|
||||
|
||||
#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; \
|
||||
cpBodySet##CPENTRY (b, js2##TYPE (val)); \
|
||||
return JS_UNDEFINED; \
|
||||
|
|
|
@ -57,12 +57,7 @@ HMM_Mat4 transform2mat(transform t) {
|
|||
|
||||
HMM_Quat angle2rotation(float angle)
|
||||
{
|
||||
return HMM_QFromAxisAngle_LH(vUP, angle);
|
||||
}
|
||||
|
||||
float transform2angle(HMM_Vec3 axis)
|
||||
{
|
||||
|
||||
return HMM_QFromAxisAngle_LH(vBKWD, angle);
|
||||
}
|
||||
|
||||
transform mat2transform(HMM_Mat4 m)
|
||||
|
|
Loading…
Reference in a new issue