Initial add of proper transforms

This commit is contained in:
John Alanbrook 2023-11-09 22:44:33 +00:00
parent 8bef401be4
commit 8265eb658f
4 changed files with 100 additions and 18 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -12,6 +12,7 @@
#include <string.h>
#include <ctype.h>
#include <limits.h>
#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)