From 08725d474d57d667009c3e07380733322c6b5453 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Tue, 23 Jul 2024 14:30:41 -0500 Subject: [PATCH] add transform cache mat4 --- scripts/base.js | 3 +++ scripts/render.js | 33 ++++++++++++++++++++------------- source/engine/HandmadeMath.c | 5 ----- source/engine/jsffi.c | 20 +++++++++++--------- source/engine/model.c | 2 +- source/engine/transform.c | 15 ++++++++++++--- source/engine/transform.h | 3 ++- 7 files changed, 49 insertions(+), 32 deletions(-) diff --git a/scripts/base.js b/scripts/base.js index dc2b61f..4542607 100644 --- a/scripts/base.js +++ b/scripts/base.js @@ -1525,6 +1525,9 @@ Vector.random = function() { return Vector.norm(vec); } +Vector.midpoint = function(a,b) { return [(a.x+b.x)/2, (a.y+b.y)/2]; } +Vector.distance = function(a,b) { return Math.hypot(b.x-a.x, b.y-a.y); } + Vector.angle_between = function(a,b) { var dot = Vector.dot(a,b); diff --git a/scripts/render.js b/scripts/render.js index cb9e374..bcbe0bd 100644 --- a/scripts/render.js +++ b/scripts/render.js @@ -541,11 +541,9 @@ render.flush_poly = function() render.line = function(points, color = Color.white, thickness = 1) { var transform = os.make_transform(); - var vv = points[1].sub(points[0]); - var dist = Vector.length(vv); - var center = vv.scale(0.5).add(points[0]); - transform.move([center.x,center.y,0]); - transform.rotate([0,0,-1], Vector.angle(vv)); + var dist = Vector.distance(points[0],points[1]); + transform.move(Vector.midpoint(points[0],points[1])); + transform.rotate([0,0,-1], Vector.angle([points[1].x-points[0].x, points[1].y-points[0].y])); transform.scale = [dist, thickness, 1]; poly_cache.push({ transform:transform, @@ -598,17 +596,26 @@ render.boundingbox = function(bb, color = Color.white) { } render.rectangle = function(lowerleft, upperright, color) { - var thickness = upperright.x-lowerleft.x; - var mid = thickness/2; - var from = [mid+lowerleft.x, lowerleft.y]; - var to = [mid+lowerleft.x, upperright.y]; - render.line([from,to], color, thickness); + var transform = os.make_transform(); + var wh = [upperright.x-lowerleft.x, upperright.y-lowerleft.y]; + transform.move(Vector.midpoint(lowerleft,upperright)); + transform.scale = [wh.x,wh.y,1]; + poly_cache.push({ + transform:transform, + color:color + }); + check_flush(render.flush_poly); }; render.box = function(pos, wh, color = Color.white) { - var lower = pos.sub(wh.scale(0.5)); - var upper = pos.add(wh.scale(0.5)); - render.rectangle(lower,upper,color); + var transform = os.make_transform(); + transform.move(pos); + transform.scale = [wh.x,wh.y,1]; + poly_cache.push({ + transform:transform, + color:color + }); + check_flush(render.flush_poly); }; render.window = function(pos, wh, color) { diff --git a/source/engine/HandmadeMath.c b/source/engine/HandmadeMath.c index b0a641f..7cc2b58 100644 --- a/source/engine/HandmadeMath.c +++ b/source/engine/HandmadeMath.c @@ -1769,11 +1769,6 @@ HMM_Mat4 HMM_QToM4(HMM_Quat Left) { HMM_Mat4 HMM_M4TRS(HMM_Vec3 t, HMM_Quat q, HMM_Vec3 s) { - HMM_Mat4 T = HMM_Translate(t); - HMM_Mat4 R = HMM_QToM4(q); - HMM_Mat4 S = HMM_Scale(s); - return HMM_MulM4(T, HMM_MulM4(R, S)); - //return HMM_MulM4(T,S); HMM_Mat4 l; float *lm = (float*)&l; diff --git a/source/engine/jsffi.c b/source/engine/jsffi.c index f4e4b8d..f08f9aa 100644 --- a/source/engine/jsffi.c +++ b/source/engine/jsffi.c @@ -920,15 +920,15 @@ JSC_CCALL(render_setunim4, JSValue arr = argv[2]; int n = js_arrlen(arr); if (n == 1) - m = transform2mat(*js2transform(js_getpropidx(arr,0))); + m = transform2mat(js2transform(js_getpropidx(arr,0))); else { for (int i = 0; i < n; i++) { - HMM_Mat4 p = transform2mat(*js2transform(js_getpropidx(arr, i))); + HMM_Mat4 p = transform2mat(js2transform(js_getpropidx(arr, i))); m = HMM_MulM4(p,m); } } } else if (!JS_IsUndefined(argv[2])) - m = transform2mat(*js2transform(argv[2])); + m = transform2mat(js2transform(argv[2])); sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(m.e)); ); @@ -963,7 +963,7 @@ JSC_CCALL(render_make_particle_ssbo, for (int i = 0; i < js_arrlen(array); i++) { JSValue sub = js_getpropidx(array,i); - ms[i].model = transform2mat(*js2transform(js_getpropstr(sub, "transform"))); + ms[i].model = transform2mat(js2transform(js_getpropstr(sub, "transform"))); ms[i].color = js2vec4(js_getpropstr(sub,"color")); } @@ -998,7 +998,7 @@ JSC_CCALL(render_make_sprite_ssbo, for (int i = 0; i < js_arrlen(array); i++) { JSValue sub = js_getpropidx(array,i); - ms[i].model = transform2mat(*js2transform(js_getpropstr(sub, "transform"))); + ms[i].model = transform2mat(js2transform(js_getpropstr(sub, "transform"))); ms[i].rect = js2vec4(js_getpropstr(sub,"rect")); } @@ -1027,7 +1027,7 @@ JSC_CCALL(render_make_t_ssbo, } for (int i = 0; i < js_arrlen(array); i++) - ms[i] = transform2mat(*js2transform(js_getpropidx(array, i))); + ms[i] = transform2mat(js2transform(js_getpropidx(array, i))); sg_append_buffer(*b, (&(sg_range){ .ptr = ms, @@ -1533,9 +1533,9 @@ static const JSCFunctionListEntry js_physics_funcs[] = { CGETSET_ADD(physics, collision_persistence), }; -JSC_GETSET(transform, pos, vec3) -JSC_GETSET(transform, scale, vec3) -JSC_GETSET(transform, rotation, quat) +JSC_GETSET_APPLY(transform, pos, vec3) +JSC_GETSET_APPLY(transform, scale, vec3) +JSC_GETSET_APPLY(transform, rotation, quat) JSC_CCALL(transform_move, transform_move(js2transform(self), js2vec3(argv[0])); ) JSC_CCALL(transform_lookat, @@ -1543,6 +1543,7 @@ JSC_CCALL(transform_lookat, transform *go = js2transform(self); HMM_Mat4 m = HMM_LookAt_LH(go->pos, point, vUP); go->rotation = HMM_M4ToQ_LH(m); + go->dirty = true; ) JSC_CCALL(transform_rotate, @@ -1550,6 +1551,7 @@ JSC_CCALL(transform_rotate, transform *t = js2transform(self); HMM_Quat rot = HMM_QFromAxisAngle_LH(axis, js2angle(argv[1])); t->rotation = HMM_MulQ(t->rotation,rot); + t->dirty = true; ) JSC_CCALL(transform_angle, diff --git a/source/engine/model.c b/source/engine/model.c index 5369ba3..da13ed4 100644 --- a/source/engine/model.c +++ b/source/engine/model.c @@ -508,7 +508,7 @@ sg_bindings primitive_bind(primitive *p) void model_draw_go(model *model, transform *go) { - HMM_Mat4 gom = transform2mat(*go); + HMM_Mat4 gom = transform2mat(go); animation_run(&model->anim, apptime()); diff --git a/source/engine/transform.c b/source/engine/transform.c index 8ac56fa..de07041 100644 --- a/source/engine/transform.c +++ b/source/engine/transform.c @@ -5,16 +5,21 @@ transform *make_transform() { transform *t = calloc(sizeof(transform),1); + t->scale = (HMM_Vec3){1,1,1}; t->rotation = (HMM_Quat){0,0,0,1}; + t->dirty = 1; return t; } void transform_free(transform *t) { free(t); } +void transform_apply(transform *t) { t->dirty = 1; } + void transform_move(transform *t, HMM_Vec3 v) { t->pos = HMM_AddV3(t->pos, v); + t->dirty = 1; } HMM_Vec3 transform_direction(transform *t, HMM_Vec3 dir) @@ -42,7 +47,6 @@ HMM_Vec2 mat_right(HMM_Mat3 m) { return HMM_NormV2(m.Columns[0].XY); } float vec_angle(HMM_Vec2 a, HMM_Vec2 b) { return acos(HMM_DotV2(a,b)/(HMM_LenV2(a)*HMM_LenV2(b))); } float vec_dirangle(HMM_Vec2 a, HMM_Vec2 b) { return atan2(b.x, b.y) - atan2(a.x, a.y); } - HMM_Vec3 mat3_t_pos(HMM_Mat4 m, HMM_Vec3 pos) { return HMM_MulM4V4(m, (HMM_Vec4){pos.X, pos.Y, pos.Z, 1}).XYZ; } HMM_Vec3 mat3_t_dir(HMM_Mat4 m, HMM_Vec3 dir) @@ -51,8 +55,13 @@ HMM_Vec3 mat3_t_dir(HMM_Mat4 m, HMM_Vec3 dir) return mat3_t_pos(m, dir); } -HMM_Mat4 transform2mat(transform t) { - return HMM_M4TRS(t.pos, t.rotation, t.scale); +HMM_Mat4 transform2mat(transform *t) { + if (t->dirty) { + t->cache = HMM_M4TRS(t->pos, t->rotation, t->scale); + t->dirty = 0; + } + + return t->cache; } HMM_Quat angle2rotation(float angle) diff --git a/source/engine/transform.h b/source/engine/transform.h index 2ed1d22..4783179 100644 --- a/source/engine/transform.h +++ b/source/engine/transform.h @@ -12,6 +12,7 @@ typedef struct transform { } transform; transform *make_transform(); +void transform_apply(transform *t); void transform_free(transform *t); #define VEC2_FMT "[%g,%g]" @@ -33,7 +34,7 @@ float vec_dirangle(HMM_Vec2 a, HMM_Vec2 b); HMM_Vec3 mat3_t_pos(HMM_Mat4 m, HMM_Vec3 pos); HMM_Vec3 mat3_t_dir(HMM_Mat4 m, HMM_Vec3 dir); -HMM_Mat4 transform2mat(transform t); +HMM_Mat4 transform2mat(transform *t); transform mat2transform(HMM_Mat4 m); HMM_Quat angle2rotation(float angle);