From 2083fb6e9e254716383c04c245d19db4a048ec45 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Tue, 12 Dec 2023 14:46:27 +0000 Subject: [PATCH] Fix rotate, scale, move --- scripts/components.js | 36 +++-------------- scripts/editor.js | 26 +++---------- scripts/engine.js | 12 ++++-- scripts/entity.js | 3 -- scripts/physics.js | 27 +++---------- source/engine/2dphysics.c | 20 ++++++---- source/engine/gameobject.c | 34 +++++++--------- source/engine/gameobject.h | 5 --- source/engine/jsffi.c | 34 +++++++++------- source/engine/script.h | 1 - source/engine/sprite.c | 14 +++---- source/engine/sprite.h | 2 +- source/engine/transform.c | 6 +-- source/engine/yugine.c | 80 +------------------------------------- 14 files changed, 85 insertions(+), 215 deletions(-) diff --git a/scripts/components.js b/scripts/components.js index 4f38a61..ab7f6da 100644 --- a/scripts/components.js +++ b/scripts/components.js @@ -551,13 +551,9 @@ polygon2d.inputs['C-b'].doc = "Freeze mirroring in place."; component.edge2d = Object.copy(collider2d, { dimensions:2, thickness:0, - /* open: 0 - clamped: 1 - beziers: 2 - looped: 3 - */ - type: Spline.type.clamped, + type: Spline.type.catmull, looped: false, + angle: 5, flipx: false, flipy: false, @@ -609,32 +605,12 @@ component.edge2d = Object.copy(collider2d, { sample(n) { var spoints = this.spoints(); +// n = this.samples * this.sample_calc(); - var degrees = 2; - - if (n < spoints.length) n = spoints.length; - - if (spoints.length === 2) - return spoints; - if (spoints.length < 2) - return []; - if (this.samples === 1) { - if (this.looped) return spoints.wrapped(1); - return spoints; - } - - /* - order = degrees+1 - knots = spoints.length + order - assert knots%order != 0 - */ - - n = this.samples * this.sample_calc(); - - if (this.looped) - return Spline.sample(degrees, this.dimensions, Spline.type.open, spoints.wrapped(this.degrees), n); +/* if (this.looped) + return Spline.sample(degrees, this.dimensions, Spline.type.open, spoints.wrapped(this.degrees), n);*/ - return Spline.sample(degrees, this.dimensions, this.type, spoints, n); + return Spline.sample_angle(this.type, spoints, this.angle); }, samples: 1, diff --git a/scripts/editor.js b/scripts/editor.js index df429f9..7575b14 100644 --- a/scripts/editor.js +++ b/scripts/editor.js @@ -27,13 +27,9 @@ var editor = { }, edit_mode: "basic", - get_this() { - return this.edit_level; - }, + get_this() { return this.edit_level; }, - get_that() { - return this.selectlist.length === 1 ? this.selectlist[0] : this.get_this(); - }, + get_that() { return this.selectlist.length === 1 ? this.selectlist[0] : this.get_this(); }, try_select() { /* nullify true if it should set selected to null if it doesn't find an object */ var go = physics.pos_query(Mouse.worldpos); @@ -78,7 +74,7 @@ var editor = { var objs = x.slice(); var duped = []; - objs.forEach(function(x) { duped.push(x.dup()); } ); + objs.forEach(x => duped.push(x.dup())); return duped; }, @@ -404,7 +400,7 @@ var editor = { } GUI.text("0,0", world2screen([0,0])); - GUI.text(editor.edit_level.worldpos().map(function(x) { return Math.round(x); }), world2screen(editor.edit_level.worldpos()), 1, Color.red); + GUI.text(editor.edit_level.worldpos().map(x => Math.round(x)), world2screen(editor.edit_level.worldpos()), 1, Color.red); GUI.text("+", world2screen(editor.edit_level.worldpos()), 1, Color.blue); var thiso = editor.get_this(); @@ -771,21 +767,12 @@ editor.inputs.r = function() { }); }; editor.inputs.r.doc = "Rotate selected using the mouse while held down."; - editor.inputs.r.released = function() { editor.rotlist = []; } -editor.inputs.f5 = function() -{ - editor.start_play_ed(); -} - +editor.inputs.f5 = function() { editor.start_play_ed(); } editor.inputs.f5.doc = "Start game from 'debug' if it exists; otherwise, from 'game'."; -editor.inputs.f6 = function() -{ - editor.start_play(); -} - +editor.inputs.f6 = function() { editor.start_play(); } editor.inputs.f6.doc = "Start game as if the player started it."; editor.inputs['M-p'] = function() { @@ -1137,7 +1124,6 @@ editor.inputs.mouse.move = function(pos, dpos) editor.rotlist?.forEach(function(x) { var anglediff = Math.atan2(relpos.y, relpos.x) - x.rotoffset; - x.obj.angle = x.angle + Math.rad2deg(anglediff); if (x.pos) x.obj.pos = x.pos.sub(x.offset).add(x.offset.rotate(anglediff)); diff --git a/scripts/engine.js b/scripts/engine.js index 15c0971..b4fffca 100644 --- a/scripts/engine.js +++ b/scripts/engine.js @@ -334,15 +334,21 @@ function Color(from) { */ var Spline = {}; +Spline.sample_angle = function(type, points, angle) { + var s = spline_cmd(0, type, 2, points, angle); + return s; +} Spline.sample = function(degrees, dimensions, type, ctrl_points, nsamples) { var s = spline_cmd(0, degrees,dimensions,type,ctrl_points,nsamples); + console.warn(s); return s; } Spline.type = { - open: 0, - clamped: 1, - beziers: 2 + catmull: 0, + beziers: 1, + bspline: 2, + cubichermite: 3 }; load("scripts/components.js"); diff --git a/scripts/entity.js b/scripts/entity.js index c61b99f..78841c3 100644 --- a/scripts/entity.js +++ b/scripts/entity.js @@ -55,7 +55,6 @@ actor.remaster = function(to){ to.padawans.push(this); }; - var gameobject = { full_path() { return this.path_from(Primum); @@ -237,8 +236,6 @@ var gameobject = { this.level?.remove_obj(this); this.level = parent; - - cmd(208,parent.body,this.body); function unique_name(list, obj) { var str = obj.toString().replaceAll('.', '_'); diff --git a/scripts/physics.js b/scripts/physics.js index 054788f..02b67d0 100644 --- a/scripts/physics.js +++ b/scripts/physics.js @@ -1,13 +1,11 @@ /* On collisions, entities are sent a 'hit' object, which looks like this: */ var HIT = { normal: "The normal of the collision point.", - hit: "The gameobject ID of the object that collided.", + hit: "The gameobject of the object that collided.", sensor: "Boolean for if the colliding object was a sensor.", velocity: "Velocity of the contact.", pos: "Position in world space of the contact.", depth: "Depth of the contact.", - id: "Gameobject ID of the colliding object.", - obj: "Entity that collided." }; var Physics = { @@ -21,14 +19,10 @@ var physics = { get gravity() { return cmd(72); }, set damping(x) { cmd(73,Math.clamp(x,0,1)); }, get damping() { return cmd(74); }, - pos_query(pos) { - return cmd(44, pos); - }, + pos_query(pos) { return cmd(44, pos); }, /* Returns a list of body ids that a box collides with */ - box_query(box) { - return cmd(52, box.pos, box.wh); - }, + box_query(box) { return cmd(52, box.pos, box.wh); }, box_point_query(box, points) { if (!box || !points) @@ -37,20 +31,11 @@ var physics = { return cmd(86, box.pos, box.wh, points, points.length); }, - shape_query(shape) { - return cmd(80,shape); - }, + shape_query(shape) { return cmd(80,shape); }, com(pos) { - if (!Array.isArray(pos)) return; - var com = []; - for (var i = 0; i < pos[0].length; i++) { - com[i] = pos.reduce(function(acc,val) { - return acc + val[i]; - }); - com[i] /= pos.length; - } - return com; + if (!Array.isArray(pos)) return [0,0]; + return pos.reduce((a,i) => a.add(i)).map(g => g/pos.length); }, }; diff --git a/source/engine/2dphysics.c b/source/engine/2dphysics.c index bd8d791..59fbe0b 100644 --- a/source/engine/2dphysics.c +++ b/source/engine/2dphysics.c @@ -57,8 +57,16 @@ cpShape *phys2d_query_pos(cpVect pos) { return find; } +int p_compare(void *a, void *b) +{ + if (a > b) return 1; + if (a < b) return -1; + if (a == b) 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) @@ -107,21 +115,20 @@ gameobject *phys2d_query_box(HMM_Vec2 pos, HMM_Vec2 wh) { cpBB bbox = cpShapeGetBB(box); - int *ids = NULL; - querybox qb; qb.bb = bbox; - qb.ids = ids; + qb.ids = NULL; - cpSpaceShapeQuery(space, box, querylist, ids); + cpSpaceShapeQuery(space, box, querylist, qb.ids); cpSpaceEachBody(space, querylistbodies, &qb); cpShapeFree(box); - return clean_ids(ids); + return clean_ids(qb.ids); } -gameobject *phys2d_query_shape(struct phys2d_shape *shape) { +gameobject *phys2d_query_shape(struct phys2d_shape *shape) +{ gameobject **ids = NULL; cpSpaceShapeQuery(space, shape->shape, querylist, ids); return clean_ids(ids); @@ -565,7 +572,6 @@ void duk_call_phys_cb(HMM_Vec2 norm, struct callee c, gameobject *hit, cpArbiter // srfv.cp = cpArbiterGetPointA(arb,0); // JS_SetPropertyStr(js, obj, "pos", vec2js(srfv)); // JS_SetPropertyStr(js,obj,"depth", num2js(cpArbiterGetDepth(arb,0))); - JS_SetPropertyStr(js,obj,"obj", JS_DupValue(js,hit->ref)); struct postphys_cb cb; cb.c = c; diff --git a/source/engine/gameobject.c b/source/engine/gameobject.c index 4a1187a..e3b7b91 100644 --- a/source/engine/gameobject.c +++ b/source/engine/gameobject.c @@ -8,6 +8,8 @@ #include "stb_ds.h" +static gameobject **gameobjects; + gameobject *body2go(cpBody *body) { return cpBodyGetUserData(body); } gameobject *shape2go(cpShape *shape) { @@ -59,16 +61,14 @@ gameobject *pos2gameobject(HMM_Vec2 pos) { if (hit) return shape2go(hit); - return NULL; -/* for (int i = 0; i < arrlen(gameobjects); i++) { - if (!gameobjects[i].body) continue; - cpVect gpos = cpBodyGetPosition(gameobjects[i].body); - float dist = cpvlength(cpvsub(gpos, pos.cp)); + if (!gameobjects[i]->body) continue; + HMM_Vec2 gpos = go_pos(gameobjects[i]); + float dist = HMM_DistV2(gpos,pos); - if (dist <= 25) return i; + if (dist <= 25) return gameobjects[i]; } - */ + return NULL; } @@ -166,14 +166,11 @@ gameobject *MakeGameobject() { .next = -1, .drawlayer = 0, .shape_cbs = NULL, - .children = NULL, .gravity = 1, .cgravity = (HMM_Vec2){0,0}, .damping = NAN, .timescale = 1.0, .ref = JS_UNDEFINED, - .parent = NULL, - .children = NULL }; go.cbs.begin.obj = JS_UNDEFINED; @@ -185,18 +182,10 @@ gameobject *MakeGameobject() { *ngo = go; cpBodySetUserData(go.body, ngo); phys2d_setup_handlers(ngo); + arrpush(gameobjects, ngo); return ngo; } -void gameobject_traverse(gameobject *go, HMM_Mat4 p) -{ - HMM_Mat4 local = transform3d2mat(go2t3(go)); - go->world = HMM_MulM4(local, p); - - for (int i = 0; i < arrlen(go->children); i++) - gameobject_traverse(go->children[i], go->world); -} - void rm_body_shapes(cpBody *body, cpShape *shape, void *data) { struct phys2d_shape *s = cpShapeGetUserData(shape); if (s->data) { @@ -225,7 +214,12 @@ void gameobject_free(gameobject *go) { if (!go) return; YughWarn("FREEING A GAMEOBJECT"); JS_FreeValue(js, go->ref); - dag_clip(go); + + for (int i = arrlen(gameobjects)-1; i >= 0; i--) + if (gameobjects[i] == go) { + arrdelswap(gameobjects, i); + break; + } if (cpSpaceIsLocked(space)) arrpush(go_toclean, go); diff --git a/source/engine/gameobject.h b/source/engine/gameobject.h index 8c3d32e..f979518 100644 --- a/source/engine/gameobject.h +++ b/source/engine/gameobject.h @@ -45,12 +45,9 @@ struct gameobject { struct phys_cbs cbs; struct shape_cb *shape_cbs; JSValue ref; - struct gameobject *master; HMM_Mat4 world; transform2d t; /* The local transformation of this object */ float drawlayer; - struct gameobject *parent; - struct gameobject **children; }; typedef struct gameobject gameobject; @@ -60,8 +57,6 @@ void gameobject_apply(gameobject *go); void gameobject_free(gameobject *go); void gameobjects_cleanup(); -void gameobject_traverse(gameobject *start, HMM_Mat4 p); - transform2d go2t(gameobject *go); transform3d go2t3(gameobject *go); diff --git a/source/engine/jsffi.c b/source/engine/jsffi.c index 04a086a..046391d 100644 --- a/source/engine/jsffi.c +++ b/source/engine/jsffi.c @@ -296,8 +296,8 @@ void vec2float(HMM_Vec2 v, float *f) { JSValue vec2js(HMM_Vec2 v) { JSValue array = JS_NewArray(js); - js_setprop_num(array,0,JS_NewFloat64(js,v.x)); - js_setprop_num(array,1,JS_NewFloat64(js,v.y)); + js_setprop_num(array,0,num2js(v.x)); + js_setprop_num(array,1,num2js(v.y)); return array; } @@ -386,23 +386,29 @@ JSValue bb2js(struct boundingbox bb) } JSValue duk_spline_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) { - int degrees = js2int(argv[1]); /* not used */ - int d = js2int(argv[2]); /* dimensions: 1d, 2d, 3d ...*/ + int cmd = js2int(argv[0]); /* 0: hermite-cubic 1: catmull-rom 2: b-spline 3: bezier */ - int type = js2int(argv[3]); - HMM_Vec2 *points = js2cpvec2arr(argv[4]); - size_t nsamples = js2int(argv[5]); + int type = js2int(argv[1]); + int d = js2int(argv[2]); /* dimensions: 1d, 2d, 3d ...*/ + HMM_Vec2 *points = js2cpvec2arr(argv[3]); + float param = js2number(argv[4]); + HMM_Vec2 *samples = catmull_rom_ma_v2(points, param); - HMM_Vec2 *samples = catmull_rom_ma_v2(points, nsamples); - JSValue arr = vecarr2js(samples, nsamples); - free(samples); + if (!samples) + return JS_UNDEFINED; - return JS_UNDEFINED; +// for (int i = 0; i < arrlen(samples); i++) +// YughWarn("%g,%g", samples[i].x, samples[i].y); + + JSValue arr = vecarr2js(samples, arrlen(samples)); +// arrfree(samples); + + return arr; } JSValue ints2js(int *ints) { @@ -491,7 +497,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) const char *str2 = NULL; const void *d1 = NULL; const void *d2 = NULL; - int *ids = NULL; + gameobject *ids = NULL; gameobject *go = NULL; JSValue ret = JS_UNDEFINED; @@ -691,7 +697,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) case 44: go = pos2gameobject(js2vec2(argv[1])); - ret = go ? go->ref : JS_UNDEFINED; + ret = go ? JS_DupValue(js,go->ref) : JS_UNDEFINED; break; case 45: @@ -1324,7 +1330,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) ret = dsp_node2js(dsp_fwd_delay(js2number(argv[1]), js2number(argv[2]))); break; case 208: - dag_set(js2gameobject(argv[1]), js2gameobject(argv[2])); +// dag_set(js2gameobject(argv[1]), js2gameobject(argv[2])); break; case 209: break; diff --git a/source/engine/script.h b/source/engine/script.h index 9c59104..87ddad4 100644 --- a/source/engine/script.h +++ b/source/engine/script.h @@ -17,7 +17,6 @@ struct phys_cbs { struct callee separate; }; - extern struct callee stacktrace_callee; extern JSValue num_cache[100]; diff --git a/source/engine/sprite.c b/source/engine/sprite.c index 74d2891..089f400 100644 --- a/source/engine/sprite.c +++ b/source/engine/sprite.c @@ -122,7 +122,7 @@ void sprite_draw_all() { if (layers) arrfree(layers); for (int i = 0; i < freelist_len(sprites); i++) - if (sprites[i].next == -1 && sprites[i].go >= 0 && sprites[i].enabled) + if (sprites[i].next == -1 && sprites[i].go != NULL && sprites[i].enabled) arrpush(layers, i); if (!layers || arrlen(layers) == 0) return; @@ -240,14 +240,12 @@ void tex_draw(struct Texture *tex, HMM_Mat3 m, struct glrect r, struct rgba colo } void sprite_draw(struct sprite *sprite) { - gameobject *go = sprite->go; + if (!sprite->tex) return; + HMM_Mat3 m = t_go2world(sprite->go); + HMM_Mat3 sm = transform2d2mat(sprite->t); + + tex_draw(sprite->tex, HMM_MulM3(m, sm), sprite->frame, sprite->color, 0, (HMM_Vec2){0,0}, 0, sprite->emissive); - if (sprite->tex) { - HMM_Mat3 m = t_go2world(go); - HMM_Mat3 sm = transform2d2mat(sprite->t); - - tex_draw(sprite->tex, HMM_MulM3(m, sm), sprite->frame, sprite->color, 0, (HMM_Vec2){0,0}, 0, sprite->emissive); - } } void sprite_setanim(struct sprite *sprite, struct TexAnim *anim, int frame) { diff --git a/source/engine/sprite.h b/source/engine/sprite.h index 8412ccd..0d26d40 100644 --- a/source/engine/sprite.h +++ b/source/engine/sprite.h @@ -13,7 +13,7 @@ struct sprite { transform2d t; struct rgba color; struct rgba emissive; - gameobject *go; /* id of gameobject */ + gameobject *go; struct Texture *tex; struct glrect frame; int enabled; diff --git a/source/engine/transform.c b/source/engine/transform.c index e6fa00e..d5e01f4 100644 --- a/source/engine/transform.c +++ b/source/engine/transform.c @@ -14,7 +14,7 @@ HMM_Vec3 trans_down(const transform3d *trans) { return HMM_QVRot(vDOWN, trans->r HMM_Vec3 trans_right(const transform3d *trans) { return HMM_QVRot(vRIGHT, trans->rotation); } HMM_Vec3 trans_left(const transform3d *trans) { return HMM_QVRot(vLEFT, trans->rotation); } -HMM_Vec2 mat_t_pos(HMM_Mat3 m, HMM_Vec2 pos) { return HMM_MulM3V3(m, (HMM_Vec3){pos.x, pos.y, 0}).xy; } +HMM_Vec2 mat_t_pos(HMM_Mat3 m, HMM_Vec2 pos) { return HMM_MulM3V3(m, (HMM_Vec3){pos.x, pos.y, 1}).xy; } HMM_Vec2 mat_t_dir(HMM_Mat3 m, HMM_Vec2 dir) { @@ -36,9 +36,7 @@ HMM_Vec3 mat3_t_dir(HMM_Mat4 m, HMM_Vec3 dir) return mat3_t_pos(m, dir); } -HMM_Mat3 transform2d2mat(transform2d trn) { - return HMM_MulM3(HMM_Translate2D(trn.pos), HMM_MulM3(HMM_RotateM3(trn.angle), HMM_ScaleM3(trn.scale))); -} +HMM_Mat3 transform2d2mat(transform2d trn) { return HMM_MulM3(HMM_Translate2D(trn.pos), HMM_MulM3(HMM_RotateM3(trn.angle), HMM_ScaleM3(trn.scale))); } transform2d mat2transform2d(HMM_Mat3 m) { diff --git a/source/engine/yugine.c b/source/engine/yugine.c index 3fcf9a5..5963c36 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -25,10 +25,6 @@ #include "2dphysics.h" -#ifdef __GLIBC__ -#include -#endif - #include #include @@ -83,55 +79,6 @@ static int sim_play = SIM_PLAY; int editor_mode = 0; -#ifdef __TINYC__ -int backtrace(void **buffer, int size) { - extern uint64_t *__libc_stack_end; - uint64_t **p, *bp, *frame; - asm ("mov %%rbp, %0;" : "=r" (bp)); - p = (uint64_t**) bp; - int i = 0; - while (i < size) { - frame = p[0]; - if (frame < bp || frame > __libc_stack_end) { - return i; - } - buffer[i++] = p[1]; - p = (uint64_t**) frame; - } - return i; -} -#endif - -void print_stacktrace() { -#ifdef __GLIBC__ - void *ents[512]; - size_t size = backtrace(ents, 512); - - YughCritical("====================BACKTRACE===================="); - char **stackstr = backtrace_symbols(ents, size); - - YughCritical("Stack size is %d.", size); - - for (int i = 0; i < size; i++) - YughCritical(stackstr[i]); - - js_stacktrace(); -#endif -} - -void seghandle(int sig) { -//#ifdef __GLIBC__ -// if (strsignal(sig)) - YughCritical("CRASH! Signal: %d.", sig); - - js_stacktrace(); - - exit(1); -//#endif -// js_stacktrace(); -// exit(1); -} - const char *engine_info() { static char str[100]; @@ -153,19 +100,15 @@ void c_init() { window_set_icon("icons/moon.gif"); window_resize(sapp_width(), sapp_height()); script_evalf("Game.init();"); -// bjork = ds_openvideo("bjork.mpg"); } -int frame_fps() { - return 1.0/sapp_frame_duration(); -} +int frame_fps() { return 1.0/sapp_frame_duration(); } static void process_frame() { double elapsed = stm_sec(stm_laptime(&frame_t)); script_evalf("Register.appupdate.broadcast(%g);", elapsed); call_stack(); -// ds_advance(bjork, elapsed); input_poll(0); /* Timers all update every frame - once per monitor refresh */ timer_update(elapsed, timescale); @@ -318,7 +261,6 @@ void app_name(char *name) { start_desc.window_title = strdup(name); } int main(int argc, char **argv) { #ifndef NDEBUG log_init(); -// #ifdef __linux__ int logout = 0; if (logout) { time_t now = time(NULL); @@ -326,21 +268,6 @@ int main(int argc, char **argv) { snprintf(fname, 100, "yugine-%d.log", now); log_setfile(fname); } - - FILE *sysinfo = NULL; - /* sysinfo = popen("uname -a", "r"); - if (!sysinfo) { - YughWarn("Failed to get sys info."); - } else { - log_cat(sysinfo); - pclose(sysinfo); - }*/ -// #endif - signal(SIGSEGV, seghandle); - signal(SIGABRT, seghandle); - signal(SIGFPE, seghandle); -// signal(SIGBUS, seghandle); - #endif #ifdef STEAM @@ -395,7 +322,4 @@ dam->update_activity(dam, &da, NULL, NULL); return 0; } -double apptime() -{ - return stm_sec(stm_diff(stm_now(), start_t)); -} +double apptime() { return stm_sec(stm_diff(stm_now(), start_t)); }