in C sprites; transform parent child hooks
This commit is contained in:
@@ -94,8 +94,7 @@ var sprite = {
|
||||
this.sync();
|
||||
this.play();
|
||||
this.transform.scale = [this.image.texture.width, this.image.texture.height];
|
||||
// spritetree.remove(this);
|
||||
|
||||
this._sprite.set_image(this.image);
|
||||
},
|
||||
stop() {
|
||||
this.del_anim?.();
|
||||
@@ -143,6 +142,7 @@ var sprite = {
|
||||
anchor: [0, 0],
|
||||
sync: function sync() {
|
||||
this.layer = this.gameobject.drawlayer;
|
||||
this._sprite.layer = this.layer;
|
||||
},
|
||||
pick() {
|
||||
return this;
|
||||
@@ -234,15 +234,26 @@ sprite.inputs.kp1 = function () {
|
||||
|
||||
component.sprite = function (obj) {
|
||||
var sp = Object.create(sprite);
|
||||
|
||||
var msp = os.make_sprite();
|
||||
sp._sprite = msp;
|
||||
msp.color = Color.white;
|
||||
|
||||
sp.gameobject = obj;
|
||||
sp.transform = os.make_transform();
|
||||
sp.transform.parent = obj.transform;
|
||||
sp.guid = prosperon.guid();
|
||||
allsprites.push(sp);
|
||||
sp.transform.change_hook = function() {
|
||||
sprite_qt.remove(sp);
|
||||
sp.rect = sp.transform.torect();
|
||||
sprite_qt.insert(sp);
|
||||
sprite_qt.remove(msp);
|
||||
msp.rect = sp.transform.torect();
|
||||
msp.set_affine(sp.transform);
|
||||
sprite_qt.insert(msp);
|
||||
|
||||
/* sprite_qt.remove(sp)
|
||||
sp.rect = sp.transform.torect()
|
||||
sprite_qt.insert(sp)
|
||||
*/
|
||||
}
|
||||
return sp;
|
||||
};
|
||||
|
||||
@@ -2003,3 +2003,15 @@ HMM_Quat HMM_QFromAxisAngle_LH(HMM_Vec3 Axis, float AngleOfRotation) {
|
||||
|
||||
return HMM_QFromAxisAngle_RH(Axis, -AngleOfRotation);
|
||||
}
|
||||
|
||||
HMM_Mat3 HMM_Mat4ToMat3(HMM_Mat4 m4)
|
||||
{
|
||||
HMM_Mat3 result = {
|
||||
.Elements = {
|
||||
m4.Elements[0][0], m4.Elements[0][1], m4.Elements[0][2],
|
||||
m4.Elements[1][0], m4.Elements[1][1], m4.Elements[1][2],
|
||||
m4.Elements[2][0], m4.Elements[2][1], m4.Elements[2][2]
|
||||
}
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -661,6 +661,7 @@ HMM_Quat HMM_SLerp(HMM_Quat Left, float Time, HMM_Quat Right);
|
||||
HMM_Mat4 HMM_QToM4(HMM_Quat Left);
|
||||
HMM_Mat4 HMM_M4TRS(HMM_Vec3 t, HMM_Quat q, HMM_Vec3 s);
|
||||
HMM_Mat3 HMM_M3TRS(HMM_Vec2 t, float angle, HMM_Vec2 s);
|
||||
HMM_Mat3 HMM_Mat4ToMat3(HMM_Mat4 m);
|
||||
|
||||
HMM_Quat HMM_M4ToQ_RH(HMM_Mat4 M);
|
||||
HMM_Quat HMM_M4ToQ_LH(HMM_Mat4 M);
|
||||
|
||||
237
source/jsffi.c
237
source/jsffi.c
@@ -69,6 +69,7 @@ static JSAtom num_indices_atom;
|
||||
static JSAtom transform_atom;
|
||||
static JSAtom image_atom;
|
||||
static JSAtom layer_atom;
|
||||
static JSAtom texture_atom;
|
||||
static JSAtom parent_atom;
|
||||
|
||||
// GPU ATOMS
|
||||
@@ -1108,16 +1109,41 @@ void SDL_GPU##NAME##_free(JSRuntime *rt, SDL_GPU##NAME *c) { \
|
||||
SDL_ReleaseGPU##NAME(global_gpu, c); } \
|
||||
QJSCLASS(SDL_GPU##NAME) \
|
||||
|
||||
QJSCLASS(transform)
|
||||
static JSClassID js_sprite_id;
|
||||
static void js_sprite_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) {
|
||||
sprite *sp = JS_GetOpaque(val, js_sprite_id);
|
||||
if (!sp) return;
|
||||
JS_MarkValue(rt, sp->image, mark_func);
|
||||
}
|
||||
QJSCLASSMARK(sprite)
|
||||
|
||||
static JSClassID js_transform_id;
|
||||
static void js_transform_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) {
|
||||
transform *t = JS_GetOpaque(val, js_transform_id);
|
||||
if (!t) return;
|
||||
// Mark the JSValue references stored in your struct
|
||||
JS_MarkValue(rt, t->change_hook, mark_func);
|
||||
JS_MarkValue(rt, t->jsparent, mark_func);
|
||||
// Mark the array elements
|
||||
for (int i = 0; i < arrlen(t->jschildren); i++)
|
||||
JS_MarkValue(rt, t->jschildren[i], mark_func);
|
||||
}
|
||||
|
||||
QJSCLASSMARK(transform)
|
||||
QJSCLASS(font)
|
||||
//QJSCLASS(warp_gravity)
|
||||
//QJSCLASS(warp_damp)
|
||||
QJSCLASS(datastream)
|
||||
QJSCLASS(timer)
|
||||
|
||||
static JSClassID js_timer_id;
|
||||
static void js_timer_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) {
|
||||
timer *t = JS_GetOpaque(val,js_timer_id);
|
||||
if (!t) return;
|
||||
JS_MarkValue(rt, t->fn, mark_func);
|
||||
}
|
||||
QJSCLASSMARK(timer)
|
||||
|
||||
QJSCLASS(skin)
|
||||
|
||||
QJSCLASS(jssprite)
|
||||
|
||||
QJSCLASS(SDL_Window)
|
||||
QJSCLASS(SDL_Renderer)
|
||||
QJSCLASS(SDL_Camera)
|
||||
@@ -3959,22 +3985,57 @@ typedef struct {
|
||||
text_vert vert[4];
|
||||
} quad;
|
||||
|
||||
typedef struct {
|
||||
quad quad;
|
||||
JSValue image;
|
||||
int layer;
|
||||
JSContext *js;
|
||||
JSValue sprite;
|
||||
} sprite;
|
||||
// Comparator inline for potential compiler inlining
|
||||
static inline int sprite_compare(const sprite *a, const sprite *b) {
|
||||
if (a->layer != b->layer) return a->layer - b->layer;
|
||||
|
||||
if (a->affine.y != b->affine.y)
|
||||
return (b->affine.y - a->affine.y);
|
||||
|
||||
if (a->tex != b->tex)
|
||||
return (a->tex < b->tex) ? -1 : 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Merge two sorted sub-ranges [left..mid] and [mid+1..right]
|
||||
static void merge_sprites(sprite *arr, sprite *temp, size_t left, size_t mid, size_t right) {
|
||||
size_t i = left, j = mid + 1, k = left;
|
||||
|
||||
while (i <= mid && j <= right)
|
||||
if (sprite_compare(&arr[i], &arr[j]) <= 0) temp[k++] = arr[i++];
|
||||
else temp[k++] = arr[j++];
|
||||
|
||||
while (i <= mid) temp[k++] = arr[i++];
|
||||
while (j <= right) temp[k++] = arr[j++];
|
||||
|
||||
for (size_t p = left; p <= right; p++)
|
||||
arr[p] = temp[p];
|
||||
}
|
||||
|
||||
// Recursive mergesort
|
||||
static void merge_sort_recursive(sprite *arr, sprite *temp, size_t left, size_t right) {
|
||||
if (left >= right) return;
|
||||
size_t mid = (left + right) / 2;
|
||||
merge_sort_recursive(arr, temp, left, mid);
|
||||
merge_sort_recursive(arr, temp, mid + 1, right);
|
||||
merge_sprites(arr, temp, left, mid, right);
|
||||
}
|
||||
|
||||
// Public function to sort the array of sprites with mergesort
|
||||
void better_sort_sprites(sprite *arr, size_t length) {
|
||||
if (length < 2) return;
|
||||
sprite *temp = malloc(length * sizeof(sprite));
|
||||
if (!temp) return; // fallback or handle error
|
||||
merge_sort_recursive(arr, temp, 0, length - 1);
|
||||
free(temp);
|
||||
}
|
||||
|
||||
int sort_sprite(const sprite *a, const sprite *b)
|
||||
{
|
||||
if (a->layer != b->layer) return a->layer - b->layer;
|
||||
|
||||
if (a->quad.vert[0].pos.y != b->quad.vert[0].pos.y) return b->quad.vert[0].pos.y - a->quad.vert[0].pos.y;
|
||||
|
||||
if (!JS_SameValue(a->js, a->image, b->image)) return JS_VALUE_GET_PTR(a->image) < JS_VALUE_GET_PTR(b->image) ? -1 : 1;
|
||||
|
||||
if (a->affine.y != b->affine.y) return b->affine.y - a->affine.y;
|
||||
if (a->tex != b->tex) return ((uintptr_t)a->tex < (uintptr_t)b->tex) ? -1 : 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4001,71 +4062,27 @@ JSC_CCALL(gpu_sort_sprite,
|
||||
return number2js(js,0);
|
||||
)
|
||||
|
||||
inline int sprite_in_view(HMM_Mat4 sprite, HMM_Mat4 camera)
|
||||
{
|
||||
HMM_Mat4 camsprite = HMM_MulM4(camera, sprite);
|
||||
int outside = 0;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
HMM_Vec4 clip = HMM_MulM4V4_P(&camsprite, &base_quad_4[j]);
|
||||
|
||||
if (clip.w <= 0.0) {
|
||||
outside++;
|
||||
continue;
|
||||
}
|
||||
|
||||
float nx = clip.x/clip.w;
|
||||
float ny = clip.y/clip.w;
|
||||
float nz = clip.z/clip.w;
|
||||
|
||||
if (nx < -1 || nx > 1) outside++;
|
||||
else if (ny < -1 || ny > 1) outside++;
|
||||
else if (nz < -1 || nz > 1) outside++;
|
||||
}
|
||||
|
||||
return outside != 4;
|
||||
}
|
||||
|
||||
JSC_CCALL(gpu_make_sprite_queue,
|
||||
size_t quads = js_arrlen(js, argv[0]);
|
||||
|
||||
sprite *sprites = NULL;
|
||||
arrsetcap(sprites, quads);
|
||||
|
||||
for (int i = 0; i < quads; i++) {
|
||||
JSValue sub = JS_GetPropertyUint32(js, argv[0], i);
|
||||
|
||||
rect src;
|
||||
HMM_Vec4 color;
|
||||
rect pr;
|
||||
|
||||
JS_GETATOM(js,pr,sub,rect_atom,rect);
|
||||
JS_GETATOM(js, src, sub, src_atom, rect)
|
||||
JS_GETATOM(js, color, sub, color_atom, color)
|
||||
|
||||
// Profile: build quad
|
||||
quad sprite_quad;
|
||||
sprite_quad.vert[0].pos = (HMM_Vec2){pr.x, pr.y};
|
||||
sprite_quad.vert[1].pos = (HMM_Vec2){pr.x+pr.w, pr.y};
|
||||
sprite_quad.vert[2].pos = (HMM_Vec2){pr.x, pr.y+pr.h};
|
||||
sprite_quad.vert[3].pos = (HMM_Vec2){pr.x+pr.w, pr.y+pr.h};
|
||||
|
||||
sprite_quad.vert[0].uv = (HMM_Vec2){ src.x, src.y + src.h };
|
||||
sprite_quad.vert[1].uv = (HMM_Vec2){ src.x+src.w, src.y + src.h };
|
||||
sprite_quad.vert[2].uv = (HMM_Vec2){ src.x, src.y };
|
||||
sprite_quad.vert[3].uv = (HMM_Vec2){ src.x+src.w, src.y };
|
||||
|
||||
sprite_quad.vert[0].color = color;
|
||||
sprite_quad.vert[1].color = color;
|
||||
sprite_quad.vert[2].color = color;
|
||||
sprite_quad.vert[3].color = color;
|
||||
|
||||
sprite sp;
|
||||
sp.quad = sprite_quad;
|
||||
sp.image = JS_GetProperty(js, sub, image_atom);
|
||||
sp.js = js;
|
||||
JS_GETATOM(js, sp.layer, sub, layer_atom, number)
|
||||
arrput(sprites, sp);
|
||||
|
||||
sprite *jsp = js2sprite(js, sub);
|
||||
if (jsp) {
|
||||
arrput(sprites, *jsp);
|
||||
JS_DupValue(js,jsp->image);
|
||||
}
|
||||
else {
|
||||
sprite sp = {0};
|
||||
JS_GETATOM(js,sp.affine, sub, rect_atom, rect)
|
||||
JS_GETATOM(js,sp.color,sub,color_atom,color)
|
||||
JS_GETATOM(js,sp.layer,sub,layer_atom,number)
|
||||
JS_GETATOM(js,sp.uv,sub,src_atom,rect)
|
||||
sp.image = JS_GetProperty(js,sub,image_atom);
|
||||
arrput(sprites,sp);
|
||||
}
|
||||
JS_FreeValue(js, sub);
|
||||
}
|
||||
|
||||
@@ -4073,9 +4090,33 @@ JSC_CCALL(gpu_make_sprite_queue,
|
||||
|
||||
text_vert *buffer = NULL;
|
||||
arrsetcap(buffer, arrlen(sprites)*4);
|
||||
for (int i = 0; i < arrlen(sprites); i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
arrput(buffer, sprites[i].quad.vert[j]);
|
||||
|
||||
for (int i = 0; i < arrlen(sprites); i++) {
|
||||
rect pr = sprites[i].affine;
|
||||
rect uv = sprites[i].uv;
|
||||
HMM_Vec4 c = sprites[i].color;
|
||||
|
||||
text_vert v[4];
|
||||
v[0].pos = (HMM_Vec2){ pr.x, pr.y };
|
||||
v[1].pos = (HMM_Vec2){ pr.x+pr.w, pr.y };
|
||||
v[2].pos = (HMM_Vec2){ pr.x, pr.y+pr.h };
|
||||
v[3].pos = (HMM_Vec2){ pr.x+pr.w, pr.y+pr.h };
|
||||
|
||||
v[0].uv = (HMM_Vec2){ uv.x, uv.y+uv.h };
|
||||
v[1].uv = (HMM_Vec2){ uv.x+uv.w, uv.y+uv.h };
|
||||
v[2].uv = (HMM_Vec2){ uv.x, uv.y };
|
||||
v[3].uv = (HMM_Vec2){ uv.x+uv.w, uv.y };
|
||||
|
||||
v[0].color = c;
|
||||
v[1].color = c;
|
||||
v[2].color = c;
|
||||
v[3].color = c;
|
||||
|
||||
arrput(buffer, v[0]);
|
||||
arrput(buffer, v[1]);
|
||||
arrput(buffer, v[2]);
|
||||
arrput(buffer, v[3]);
|
||||
}
|
||||
|
||||
JSValue mesh = quads_to_mesh(js, buffer);
|
||||
|
||||
@@ -4094,17 +4135,16 @@ JSC_CCALL(gpu_make_sprite_queue,
|
||||
JS_SetPropertyStr(js, q, "type", JS_NewString(js, "geometry"));
|
||||
JS_SetPropertyStr(js, q, "mesh", JS_DupValue(js, mesh));
|
||||
JS_SetPropertyStr(js, q, "pipeline", JS_DupValue(js, argv[2]));
|
||||
JS_SetPropertyStr(js, q, "image", JS_DupValue(js, img));
|
||||
JS_SetPropertyStr(js, q, "image", img);
|
||||
JS_SetPropertyStr(js, q, "first_index", number2js(js, first_index));
|
||||
JS_SetPropertyStr(js, q, "num_indices", number2js(js, count * 6));
|
||||
JS_SetPropertyUint32(js, ret, n++, q);
|
||||
}
|
||||
first_index = i*6;
|
||||
count = 1;
|
||||
JS_FreeValue(js, img);
|
||||
img = JS_DupValue(js, sprites[i].image);
|
||||
} else count++;
|
||||
JS_FreeValue(js, sprites[i].image);
|
||||
JS_FreeValue(js,sprites[i].image);
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
@@ -4112,7 +4152,7 @@ JSC_CCALL(gpu_make_sprite_queue,
|
||||
JS_SetPropertyStr(js, q, "type", JS_NewString(js, "geometry"));
|
||||
JS_SetPropertyStr(js, q, "mesh", JS_DupValue(js, mesh));
|
||||
JS_SetPropertyStr(js, q, "pipeline", JS_DupValue(js, argv[2]));
|
||||
JS_SetPropertyStr(js, q, "image", JS_DupValue(js, img));
|
||||
JS_SetPropertyStr(js, q, "image", img);
|
||||
JS_SetPropertyStr(js, q, "first_index", number2js(js, first_index));
|
||||
JS_SetPropertyStr(js, q, "num_indices", number2js(js, count * 6));
|
||||
JS_SetPropertyUint32(js, ret, n++, q);
|
||||
@@ -4122,7 +4162,6 @@ JSC_CCALL(gpu_make_sprite_queue,
|
||||
JS_FreeValue(js, mesh);
|
||||
)
|
||||
|
||||
|
||||
JSC_CCALL(gpu_make_sprite_mesh,
|
||||
size_t quads = js_arrlen(js, argv[0]);
|
||||
size_t verts = quads*4;
|
||||
@@ -6441,6 +6480,7 @@ JSC_CCALL(os_make_font,
|
||||
)
|
||||
|
||||
JSC_CCALL(os_make_transform, return transform2js(js,make_transform()))
|
||||
JSC_CCALL(os_make_sprite, return sprite2js(js,make_sprite()))
|
||||
|
||||
JSC_SCALL(os_system, return number2js(js,system(str)); )
|
||||
|
||||
@@ -7094,6 +7134,7 @@ static const JSCFunctionListEntry js_os_funcs[] = {
|
||||
MIST_FUNC_DEF(os, make_cursor, 1),
|
||||
MIST_FUNC_DEF(os, make_font, 2),
|
||||
MIST_FUNC_DEF(os, make_transform, 0),
|
||||
MIST_FUNC_DEF(os, make_sprite, 0),
|
||||
MIST_FUNC_DEF(os, make_line_prim, 5),
|
||||
MIST_FUNC_DEF(os, make_cylinder, 2),
|
||||
MIST_FUNC_DEF(os, make_cone, 2),
|
||||
@@ -7254,7 +7295,32 @@ static const JSCFunctionListEntry js_rtree_funcs[] = {
|
||||
MIST_FUNC_DEF(rtree, count, 0),
|
||||
};
|
||||
|
||||
static const JSCFunctionListEntry js_jssprite_funcs[] = {
|
||||
JSC_GETSET(sprite, layer, number)
|
||||
JSC_GETSET(sprite, color, color)
|
||||
|
||||
JSC_CCALL(sprite_set_affine,
|
||||
sprite *sp = js2sprite(js,self);
|
||||
transform *t = js2transform(js,argv[0]);
|
||||
// sp->affine = HMM_Mat4ToMat3(t->gcache);
|
||||
sp->affine = transform2rect(t);
|
||||
)
|
||||
|
||||
JSC_CCALL(sprite_set_image,
|
||||
sprite *sp = js2sprite(js,self);
|
||||
if (!JS_IsUndefined(sp->image))
|
||||
JS_FreeValue(js,sp->image);
|
||||
sp->image = JS_DupValue(js,argv[0]);
|
||||
if (JS_IsUndefined(sp->image)) return JS_UNDEFINED;
|
||||
JSValue img = sp->image;
|
||||
JS_GETATOM(js, sp->uv, img, rect_atom, rect)
|
||||
JS_GETATOM(js, sp->tex, img, texture_atom, SDL_GPUTexture)
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_sprite_funcs[] = {
|
||||
MIST_FUNC_DEF(sprite, set_affine, 1),
|
||||
MIST_FUNC_DEF(sprite, set_image, 1),
|
||||
CGETSET_ADD(sprite, layer),
|
||||
CGETSET_ADD(sprite, color),
|
||||
};
|
||||
|
||||
#define JSSTATIC(NAME, PARENT) \
|
||||
@@ -7336,7 +7402,7 @@ void ffi_load(JSContext *js) {
|
||||
QJSCLASSPREP_FUNCS(SDL_GPUSampler)
|
||||
QJSCLASSPREP_FUNCS(SDL_GPUGraphicsPipeline)
|
||||
QJSCLASSPREP_FUNCS(SDL_GPUComputePipeline)
|
||||
QJSCLASSPREP_FUNCS(jssprite)
|
||||
QJSCLASSPREP_FUNCS(sprite)
|
||||
// QJSCLASSPREP_FUNCS(SDL_GPUGraphicsPipeline)
|
||||
// QJSCLASSPREP_FUNCS(SDL_GPUSampler)
|
||||
// QJSCLASSPREP_FUNCS(SDL_GPUShader)
|
||||
@@ -7411,6 +7477,7 @@ void ffi_load(JSContext *js) {
|
||||
transform_atom = JS_NewAtom(js,"transform");
|
||||
image_atom = JS_NewAtom(js,"image");
|
||||
layer_atom = JS_NewAtom(js,"layer");
|
||||
texture_atom = JS_NewAtom(js, "texture");
|
||||
|
||||
cw_atom = JS_NewAtom(js,"cw");
|
||||
ccw_atom = JS_NewAtom(js,"ccw");
|
||||
|
||||
@@ -101,6 +101,27 @@ JSValue TYPE##2js(JSContext *js, TYPE *n) { \
|
||||
return j; }\
|
||||
\
|
||||
|
||||
#define QJSCLASSMARK(TYPE, ...)\
|
||||
static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val){\
|
||||
TYPE *n = JS_GetOpaque(val, js_##TYPE##_id);\
|
||||
TYPE##_free(rt,n);}\
|
||||
static JSClassDef js_##TYPE##_class = {\
|
||||
#TYPE,\
|
||||
.finalizer = js_##TYPE##_finalizer,\
|
||||
.gc_mark = js_##TYPE##_mark,\
|
||||
};\
|
||||
TYPE *js2##TYPE (JSContext *js, JSValue val) { \
|
||||
if (JS_GetClassID(val) != js_##TYPE##_id) return NULL; \
|
||||
return JS_GetOpaque(val,js_##TYPE##_id); \
|
||||
}\
|
||||
JSValue TYPE##2js(JSContext *js, TYPE *n) { \
|
||||
JSValue j = JS_NewObjectClass(js,js_##TYPE##_id);\
|
||||
JS_SetOpaque(j,n);\
|
||||
__VA_ARGS__ \
|
||||
return j; }\
|
||||
\
|
||||
|
||||
|
||||
#define QJSGLOBALCLASS(NAME) \
|
||||
JSValue NAME = JS_NewObject(js); \
|
||||
JS_SetPropertyFunctionList(js, NAME, js_##NAME##_funcs, countof(js_##NAME##_funcs)); \
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
#include "sprite.h"
|
||||
|
||||
void jssprite_free(JSRuntime *rt, jssprite *sprite)
|
||||
sprite *make_sprite()
|
||||
{
|
||||
sprite *sprite = calloc(sizeof(*sprite),1);
|
||||
return sprite;
|
||||
}
|
||||
|
||||
void sprite_free(JSRuntime *rt, sprite *sprite)
|
||||
{
|
||||
JS_FreeValueRT(rt,sprite->image);
|
||||
free(sprite);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,15 +3,20 @@
|
||||
|
||||
#include "HandmadeMath.h"
|
||||
#include "script.h"
|
||||
#include "render.h"
|
||||
|
||||
struct jssprite{
|
||||
HMM_Mat3 affine;
|
||||
struct sprite{
|
||||
rect affine;
|
||||
JSValue image;
|
||||
SDL_GPUTexture *tex;
|
||||
rect uv;
|
||||
int layer;
|
||||
HMM_Vec4 color;
|
||||
};
|
||||
|
||||
typedef struct jssprite jssprite;
|
||||
typedef struct sprite sprite;
|
||||
|
||||
void jssprite_free(JSRuntime *rt, jssprite *sprite);
|
||||
sprite *make_sprite();
|
||||
void sprite_free(JSRuntime *rt, sprite *sprite);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,17 @@ transform *make_transform()
|
||||
return t;
|
||||
}
|
||||
|
||||
void transform_free(JSRuntime *rt, transform *t) {
|
||||
JS_FreeValueRT(rt,t->change_hook);
|
||||
JS_FreeValueRT(rt,t->jsparent);
|
||||
for (int i = 0; i < arrlen(t->jschildren); i++)
|
||||
JS_FreeValueRT(rt,t->jschildren[i]);
|
||||
|
||||
arrfree(t->jschildren);
|
||||
arrfree(t->children);
|
||||
free(t);
|
||||
}
|
||||
|
||||
void transform_clean(transform *t)
|
||||
{
|
||||
if (!t->dirty) return;
|
||||
@@ -26,14 +37,6 @@ void transform_clean(transform *t)
|
||||
else
|
||||
t->gcache = t->cache;
|
||||
|
||||
HMM_Mat4 m = t->gcache;
|
||||
rect r = {0};
|
||||
r.x = m.Columns[3].x;
|
||||
r.y = m.Columns[3].y;
|
||||
r.w = m.Columns[0].x;
|
||||
r.h = m.Columns[1].y;
|
||||
t->rcache = r;
|
||||
|
||||
for (int i = 0; i < arrlen(t->children); i++) {
|
||||
t->children[i]->dirty = 1;
|
||||
transform_clean(t->children[i]);
|
||||
@@ -45,17 +48,6 @@ void transform_clean(transform *t)
|
||||
}
|
||||
}
|
||||
|
||||
void transform_free(JSRuntime *rt, transform *t) {
|
||||
JS_FreeValueRT(rt,t->change_hook);
|
||||
JS_FreeValueRT(rt,t->jsparent);
|
||||
for (int i = 0; i < arrlen(t->jschildren); i++)
|
||||
JS_FreeValueRT(rt,t->jschildren[i]);
|
||||
|
||||
arrfree(t->jschildren);
|
||||
arrfree(t->children);
|
||||
free(t);
|
||||
printf("FREED TRANSFORM!\n");
|
||||
}
|
||||
void transform_move(transform *t, HMM_Vec3 v)
|
||||
{
|
||||
t->pos = HMM_AddV3(t->pos, v);
|
||||
@@ -112,7 +104,13 @@ HMM_Mat4 transform2mat4_global(transform *t)
|
||||
|
||||
rect transform2rect(transform *t)
|
||||
{
|
||||
return t->rcache;
|
||||
HMM_Mat4 m = t->gcache;
|
||||
rect r = {0};
|
||||
r.x = m.Columns[3].x;
|
||||
r.y = m.Columns[3].y;
|
||||
r.w = m.Columns[0].x;
|
||||
r.h = m.Columns[1].y;
|
||||
return r;
|
||||
}
|
||||
|
||||
void transform_apply(transform *t)
|
||||
|
||||
@@ -11,7 +11,6 @@ typedef struct transform {
|
||||
HMM_Quat rotation;
|
||||
HMM_Mat4 cache;
|
||||
HMM_Mat4 gcache;
|
||||
rect rcache;
|
||||
int dirty;
|
||||
struct transform *parent;
|
||||
JSValue jsparent;
|
||||
|
||||
Reference in New Issue
Block a user