diff --git a/source/engine/HandmadeMath.h b/source/engine/HandmadeMath.h index d31586c..c0adb96 100644 --- a/source/engine/HandmadeMath.h +++ b/source/engine/HandmadeMath.h @@ -1197,6 +1197,15 @@ static inline HMM_Mat3 HMM_DivM3F(HMM_Mat3 Matrix, float Scalar) { return Result; } +static inline HMM_Mat3 HMM_ScaleM3(HMM_Vec2 Scale) { + + HMM_Mat3 Result = HMM_M3D(1.0f); + Result.Elements[0][0] = Scale.X; + Result.Elements[1][1] = Scale.Y; + + return Result; +} + static inline float HMM_DeterminantM3(HMM_Mat3 Matrix) { HMM_Mat3 Cross; diff --git a/source/engine/gameobject.c b/source/engine/gameobject.c index affe6f6..3adeb3a 100644 --- a/source/engine/gameobject.c +++ b/source/engine/gameobject.c @@ -55,6 +55,42 @@ struct gameobject *shape2go(cpShape *shape) return id2go(shape2gameobject(shape)); } +HMM_Vec2 go2pos(struct gameobject *go) +{ + cpVect p = cpBodyGetPosition(go->body); + return (HMM_Vec2){p.x, p.y}; +} + +float go2angle(struct gameobject *go) +{ + return cpBodyGetAngle(go->body); +} + +transform2d mat2transform2d(HMM_Mat3 mat) +{ +} + +HMM_Mat3 transform2d2mat(transform2d t) +{ + HMM_Mat3 m = HMM_M3D(1); + HMM_Mat3 p = HMM_M3D(1); + p.Columns[2].X = t.pos.X; + p.Columns[2].Y = t.pos.Y; + + HMM_Mat3 s = HMM_M3D(1); + s.Columns[0].X = t.scale.X; + s.Columns[1].Y = t.scale.Y; + + HMM_Mat3 r = HMM_M3D(1); + r.Columns[0] = (HMM_Vec3){cos(t.angle), sin(t.angle), 0}; + r.Columns[1] = (HMM_Vec3){-sin(t.angle), cos(t.angle), 0}; + + m = HMM_MulM3(s, r); + m = HMM_MulM3(m, p); + return m; +} + + int pos2gameobject(cpVect pos) { cpShape *hit = phys2d_query_pos(pos); @@ -85,6 +121,16 @@ void gameobject_set_sensor(int id, int sensor) { gameobject_apply(id2go(id)); } +transform2d go2t(gameobject *go) +{ + transform2d t; + cpVect p = cpBodyGetPosition(go->body); + t.pos.X = p.x; t.pos.Y = p.y; + t.angle = cpBodyGetAngle(go->body); + t.scale = (HMM_Vec2){go->scale, go->scale}; + return t; +} + int go2id(struct gameobject *go) { return id_from_gameobject(go); } @@ -158,7 +204,7 @@ static void gameobject_setpickcolor(struct gameobject *go) { static void velocityFn(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt) { - struct gameobject *go = id2go(cpBodyGetUserData(body)); + struct gameobject *go = id2go((int)cpBodyGetUserData(body)); if (!go) cpBodyUpdateVelocity(body,gravity,damping,dt); diff --git a/source/engine/gameobject.h b/source/engine/gameobject.h index b2a5982..789e39a 100644 --- a/source/engine/gameobject.h +++ b/source/engine/gameobject.h @@ -13,7 +13,16 @@ struct shader; struct sprite; struct component; -struct gameobject { +typedef struct transform2d { + HMM_Vec2 pos; + HMM_Vec2 scale; + double angle; +} transform2d; + +transform2d mat2transform2d(HMM_Mat3 mat); +HMM_Mat3 transform2d2mat(transform2d t); + +typedef struct gameobject { cpBodyType bodytype; int next; float scale; @@ -35,7 +44,10 @@ struct gameobject { struct phys_cbs cbs; struct shape_cb *shape_cbs; JSValue ref; -}; + HMM_Mat3 transform; + struct gameobject *master; + transform2d t; /* The local transformation of this object */ +} gameobject; extern struct gameobject *gameobjects; @@ -46,6 +58,10 @@ void gameobjects_cleanup(); void gameobject_set_sensor(int id, int sensor); +HMM_Vec2 go2pos(struct gameobject *go); +float go2angle(struct gameobject *go); +transform2d go2t(gameobject *go); + struct gameobject *get_gameobject_from_id(int id); struct gameobject *id2go(int id); int id_from_gameobject(struct gameobject *go); diff --git a/source/engine/sprite.c b/source/engine/sprite.c index c23ed34..4490d06 100644 --- a/source/engine/sprite.c +++ b/source/engine/sprite.c @@ -12,6 +12,7 @@ #include #include #include +#include "HandmadeMath.h" #include "sprite.sglsl.h" #include "9slice.sglsl.h" @@ -191,7 +192,7 @@ void sprite_initialize() { } /* offset given in texture offset, so -0.5,-0.5 results in it being centered */ -void tex_draw(struct Texture *tex, HMM_Vec2 pos, float angle, HMM_Vec2 size, HMM_Vec2 offset, struct glrect r, struct rgba color, int wrap, HMM_Vec2 wrapoffset, float wrapscale) { +void tex_draw(struct Texture *tex, HMM_Mat3 m, struct glrect r, struct rgba color, int wrap, HMM_Vec2 wrapoffset, float wrapscale) { struct sprite_vert verts[4]; HMM_Vec2 sposes[4] = { @@ -200,20 +201,23 @@ void tex_draw(struct Texture *tex, HMM_Vec2 pos, float angle, HMM_Vec2 size, HMM {0.0,1.0}, {1.0,1.0}, }; - - HMM_Mat2 rot = HMM_RotateM2(angle); + HMM_Vec2 t_scale = { - tex->width * st_s_w(r) * size.X, - tex->height * st_s_h(r) * size.Y + tex->width * st_s_w(r), //*size.X; + tex->height * st_s_h(r) // * size.Y }; + m = HMM_MulM3(m, HMM_ScaleM3(t_scale)); for (int i = 0; i < 4; i++) { - sposes[i] = HMM_AddV2(sposes[i], offset); +/* sposes[i] = HMM_AddV2(sposes[i], offset); sposes[i] = HMM_MulV2(sposes[i], t_scale); sposes[i] = HMM_MulM2V2(rot, sposes[i]); sposes[i] = HMM_AddV2(sposes[i], pos); verts[i].pos = sposes[i]; +*/ + HMM_Vec3 v = HMM_MulM3V3(m, (HMM_Vec3){sposes[i].X, sposes[i].Y, 1.0}); + verts[i].pos = (HMM_Vec2){v.X, v.Y}; verts[i].color = color; } if (!wrap) { @@ -226,10 +230,10 @@ void tex_draw(struct Texture *tex, HMM_Vec2 pos, float angle, HMM_Vec2 size, HMM verts[3].uv.X = r.s1; verts[3].uv.Y = r.t0; } else { - verts[0].uv = HMM_MulV2((HMM_Vec2){0,0}, size); - verts[1].uv = HMM_MulV2((HMM_Vec2){1,0}, size); - verts[2].uv = HMM_MulV2((HMM_Vec2){0,1}, size); - verts[3].uv = HMM_MulV2((HMM_Vec2){1,1}, size); +// verts[0].uv = HMM_MulV2((HMM_Vec2){0,0}, size); +// verts[1].uv = HMM_MulV2((HMM_Vec2){1,0}, size); +// verts[2].uv = HMM_MulV2((HMM_Vec2){0,1}, size); +// verts[3].uv = HMM_MulV2((HMM_Vec2){1,1}, size); for (int i = 0; i < 4; i++) verts[i].uv = HMM_AddV2(verts[i].uv, wrapoffset); @@ -250,9 +254,13 @@ void sprite_draw(struct sprite *sprite) { if (sprite->tex) { cpVect cpos = cpBodyGetPosition(go->body); - HMM_Vec2 pos = {cpos.x, cpos.y}; - HMM_Vec2 size = {sprite->size.X * go->scale * go->flipx, sprite->size.Y * go->scale * go->flipy}; - tex_draw(sprite->tex, pos, cpBodyGetAngle(go->body), size, sprite->pos, sprite->frame, sprite->color, 0, pos, 0); + HMM_Vec2 pos = (HMM_Vec2){cpos.x, cpos.y}; + HMM_Vec2 size = (HMM_Vec2){sprite->size.X * go->scale * go->flipx, sprite->size.Y * go->scale * go->flipy}; + transform2d t = go2t(id2go(sprite->go)); + HMM_Mat3 m = transform2d2mat(t); + m.Columns[2].X += sprite->pos.X; + m.Columns[2].Y += sprite->pos.Y; + tex_draw(sprite->tex, transform2d2mat(t), sprite->frame, sprite->color, 0, pos, 0); } } @@ -266,8 +274,11 @@ void gui_draw_img(const char *img, HMM_Vec2 pos, HMM_Vec2 scale, float angle, in sg_apply_pipeline(pip_sprite); sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(hudproj)); struct Texture *tex = texture_loadfromfile(img); - HMM_Vec2 offset = {0.f, 0.f}; - tex_draw(tex, pos, angle, scale, offset, tex_get_rect(tex), color, wrap, wrapoffset, wrapscale); + transform2d t; + t.pos = pos; + t.angle = angle; + t.scale = scale; + tex_draw(tex, transform2d2mat(t), tex_get_rect(tex), color, wrap, wrapoffset, wrapscale); } void slice9_draw(const char *img, HMM_Vec2 pos, HMM_Vec2 dimensions, struct rgba color)