diff --git a/res/graphics/tim.ase b/res/graphics/tim.ase index e767efc9..d7e4dba3 100644 --- a/res/graphics/tim.ase +++ b/res/graphics/tim.ase @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:424a19cf31766609c2e6daa5875990cfeb796c0d2206f0f089424899c5412d51 -size 3606 +oid sha256:4bfa00fad2ad3698b879bb93736d2085db53e75e53b69c4dd6a8e319e9361830 +size 5881 diff --git a/src/entity.h b/src/entity.h index ebc1ed22..e0e62c6d 100644 --- a/src/entity.h +++ b/src/entity.h @@ -63,10 +63,9 @@ struct entity { /* ====================================================================== */ /* Sprite */ + struct xform sprite_xform; struct string sprite_name; struct string sprite_tag_name; - struct trs sprite_trs; - struct v2 sprite_pivot_norm; /* Pivot x & y are each normalized about sprite dimensions. <0, 0> is center, <1, 1> is bottom right corner, etc. */ u32 sprite_tint; /* ====================================================================== */ @@ -81,8 +80,8 @@ struct entity { /* ENTITY_PROP_TEST */ b32 test_initialized; - struct trs test_start_rel_trs; - struct trs test_start_sprite_trs; + struct xform test_start_rel_xform; + struct xform test_start_sprite_xform; /* ENTITY_PROP_TEST_SOUND_EMITTER */ struct string sound_name; diff --git a/src/game.c b/src/game.c index 417f4222..2a45c667 100644 --- a/src/game.c +++ b/src/game.c @@ -169,23 +169,35 @@ INTERNAL void game_update(void) struct v2 size = V2(1, 1); f32 r = 0; - struct string sprite_name = STR("res/graphics/tim.ase"); - struct string sprite_tag_name = STR("UNARMED"); - - struct sheet *sheet = sheet_load(sprite_name); - f32 meters_width = sheet->frame_size.x / PIXELS_PER_UNIT; - f32 meters_height = sheet->frame_size.y / PIXELS_PER_UNIT; - struct v2 sprite_size = V2(meters_width, meters_height); - struct entity *e = entity_alloc(); e->valid = true; e->rel_xform = XFORM_TRS(.t = pos, .r = r, .s = size); + struct string sprite_name = STR("res/graphics/tim.ase"); + struct string sprite_tag_name = STR("UNARMED"); + struct sheet *sheet = sheet_load(sprite_name); + f32 meters_width = sheet->frame_size.x / PIXELS_PER_UNIT; + f32 meters_height = sheet->frame_size.y / PIXELS_PER_UNIT; + + struct v2 sprite_pos = V2(0, 0); + f32 sprite_rot = 0; + struct v2 sprite_size = V2(meters_width, meters_height); + + struct v2 sprite_pivot; + { + struct v2 sprite_pivot_norm = V2(0, 0.5); /* Pivot x & y are each normalized about sprite dimensions. <0, 0> is center, <1, 1> is bottom right corner, etc. */ + struct v2 half_size = v2_mul(sprite_size, 0.5f); + sprite_pivot = v2_mul_v2(sprite_pivot_norm, half_size); + } + + struct xform sprite_xf = XFORM_POS(sprite_pos); + sprite_xf = xform_rotate(sprite_xf, sprite_rot); + sprite_xf = xform_translate(sprite_xf, v2_neg(sprite_pivot)); + sprite_xf = xform_scale(sprite_xf, sprite_size); + e->sprite_xform = sprite_xf; + e->sprite_name = sprite_name; e->sprite_tag_name = sprite_tag_name; - e->sprite_trs = TRS(.s = sprite_size); - e->sprite_pivot_norm = V2(0, 0.65); - //e->sprite_pivot_norm = V2(0.4, 0.65); e->sprite_tint = COLOR_WHITE; entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); @@ -203,27 +215,40 @@ INTERNAL void game_update(void) /* Child ent */ { - struct v2 pos = V2(0.5, 0.5); + struct v2 pos = V2(0, 0.25); struct v2 size = V2(1, 1); - f32 r = PI / 2; - - struct string sprite_name = STR("res/graphics/tim.ase"); - struct string sprite_tag_name = STR("UNARMED"); - - struct sheet *sheet = sheet_load(sprite_name); - f32 meters_width = sheet->frame_size.x / PIXELS_PER_UNIT; - f32 meters_height = sheet->frame_size.y / PIXELS_PER_UNIT; - struct v2 sprite_size = V2(meters_width, meters_height); + f32 r = 0; struct entity *e = entity_alloc(); e->valid = true; e->rel_xform = XFORM_TRS(.t = pos, .r = r, .s = size); + struct string sprite_name = STR("res/graphics/tim.ase"); + struct string sprite_tag_name = STR("UNARMED"); + struct sheet *sheet = sheet_load(sprite_name); + f32 meters_width = sheet->frame_size.x / PIXELS_PER_UNIT; + f32 meters_height = sheet->frame_size.y / PIXELS_PER_UNIT; + + struct v2 sprite_pos = V2(0, 0); + f32 sprite_rot = 0; + struct v2 sprite_size = V2(meters_width, meters_height); + + struct v2 sprite_pivot; + { + struct v2 sprite_pivot_norm = V2(0, 0.5); /* Pivot x & y are each normalized about sprite dimensions. <0, 0> is center, <1, 1> is bottom right corner, etc. */ + struct v2 half_size = v2_mul(sprite_size, 0.5f); + sprite_pivot = v2_mul_v2(sprite_pivot_norm, half_size); + } + + struct xform sprite_xf = XFORM_POS(sprite_pos); + sprite_xf = xform_rotate(sprite_xf, sprite_rot); + sprite_xf = xform_translate(sprite_xf, v2_neg(sprite_pivot)); + sprite_xf = xform_scale(sprite_xf, sprite_size); + e->sprite_xform = sprite_xf; + e->sprite_name = sprite_name; e->sprite_tag_name = sprite_tag_name; - e->sprite_trs = TRS(.s = sprite_size); - e->sprite_pivot_norm = V2(0, 0.65); - e->sprite_tint = RGBA_F(0.5, 0.5, 0.3, 0.5); + e->sprite_tint = RGBA_F(0.3, 0.3, 0.3, 0.3); //entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); //e->player_max_speed = 5.f; @@ -302,8 +327,8 @@ INTERNAL void game_update(void) /* ENTITY_PROP_TEST */ if (entity_has_prop(ent, ENTITY_PROP_TEST) && !ent->test_initialized) { ent->test_initialized = true; - ent->test_start_rel_trs = trs_from_xform(ent->rel_xform); - ent->test_start_sprite_trs = ent->sprite_trs; + ent->test_start_rel_xform = ent->rel_xform; + ent->test_start_sprite_xform = ent->sprite_xform; } /* ENTITY_PROP_ANIMATING */ @@ -416,7 +441,7 @@ INTERNAL void game_update(void) /* ENTITY_PROP_TEST_FOLLOW_MOUSE */ if (entity_has_prop(ent, ENTITY_PROP_TEST_FOLLOW_MOUSE)) { ent->rel_xform.og = L.tick.player_focus; - ent->test_start_rel_trs.t = L.tick.player_focus; + ent->test_start_rel_xform.og = L.tick.player_focus; } /* ========================== * diff --git a/src/math.h b/src/math.h index 69c42b5c..7e577050 100644 --- a/src/math.h +++ b/src/math.h @@ -451,6 +451,8 @@ INLINE struct mat4x4 mat4x4_mul(struct mat4x4 m1, struct mat4x4 m2) /* Construct identity xform */ #define XFORM_IDENT ((struct xform) { .bx.x = 1, .by.y = 1 }) +#define XFORM_POS(p) ((struct xform) { .bx.x = 1, .by.y = 1, .og = p }) + /* Takes a translation, rotation, and scale as optional parameters for constructing an xform */ #define XFORM_TRS(...) xform_from_trs((struct trs) { .t = V2(0,0), .s = V2(1, 1), .r = 0, __VA_ARGS__ }) @@ -477,10 +479,10 @@ INLINE struct xform xform_from_pos(struct v2 v) INLINE struct xform xform_from_trs(struct trs trs) { - struct xform m = xform_from_pos(trs.t); - m = xform_rotate(m, trs.r); - m = xform_scale(m, trs.s); - return m; + struct xform xf = XFORM_POS(trs.t); + xf = xform_rotate(xf, trs.r); + xf = xform_scale(xf, trs.s); + return xf; } INLINE struct xform xform_translate(struct xform xf, struct v2 v) @@ -520,8 +522,9 @@ INLINE struct xform xform_with_rotation(struct xform xf, f32 r) struct v2 scale = xform_get_scale(xf); f32 c = math_cos(r); f32 s = math_sin(r); - xf.bx = V2(c * scale.x, s * scale.x); - xf.by = V2(-s * scale.y, c * scale.y); + xf.bx = V2(c, s); + xf.by = V2(-s, c); + xf = xform_with_scale(xf, scale); return xf; } diff --git a/src/user.c b/src/user.c index 28d34680..364d5946 100644 --- a/src/user.c +++ b/src/user.c @@ -510,8 +510,7 @@ INTERNAL void user_update(void) e->velocity = v2_lerp(e0->velocity, e1->velocity, tick_blend); e->player_acceleration = math_lerp_f32(e0->player_acceleration, e1->player_acceleration, tick_blend); - e->sprite_trs = trs_lerp(e0->sprite_trs, e1->sprite_trs, tick_blend); - e->sprite_pivot_norm = v2_lerp(e0->sprite_pivot_norm, e1->sprite_pivot_norm, tick_blend); + e->sprite_xform = xform_lerp(e0->sprite_xform, e1->sprite_xform, tick_blend); e->camera_zoom = math_lerp_f32(e0->camera_zoom, e1->camera_zoom, tick_blend); } @@ -598,19 +597,12 @@ INTERNAL void user_update(void) struct string tex_name = ent->sprite_name; /* Draw texture */ - struct quad quad = QUAD_UNIT_SQUARE_CENTERED; - - struct xform mtx; - { - struct v2 scale_div_2 = v2_mul(ent->sprite_trs.s, 0.5f); - struct v2 pivot = v2_mul_v2(ent->sprite_pivot_norm, scale_div_2); - mtx = xform_trs_pivot_r(ent->world_xform, ent->sprite_trs, pivot); - - quad = quad_mul_xform(quad, mtx); - } struct texture *texture = texture_load_async(tex_name); if (texture) { + struct xform xf = xform_mul(ent->world_xform, ent->sprite_xform); + struct quad quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, xf); + u32 tint = ent->sprite_tint; struct draw_texture_params params = DRAW_TEXTURE_PARAMS(.texture = texture, .tint = tint); @@ -641,33 +633,27 @@ INTERNAL void user_update(void) } draw_texture_quad(L.world_canvas, params, quad); - } - if (L.debug_draw && !is_camera) { + if (L.debug_draw && !is_camera) { #if 0 - /* Debug draw sprite quad */ - { - f32 thickness = 2.f; - u32 color = RGBA_F(1, 1, 0, 0.25); - draw_solid_quad_line(L.world_canvas, quad, (thickness / PIXELS_PER_UNIT / L.world_view.zoom), color); - } + /* Debug draw sprite quad */ + { + f32 thickness = 2.f; + u32 color = RGBA_F(1, 1, 0, 0.25); + draw_solid_quad_line(L.world_canvas, quad, (thickness / PIXELS_PER_UNIT / L.world_view.zoom), color); + } + + /* Debug draw sprite transform */ + { + debug_draw_xform(xf); + } + + /* Debug draw sprite pivot */ + { + u32 color = RGBA_F(1, 0, 0, 1); + draw_solid_circle(L.world_canvas, ent->world_xform.og, 0.02, color, 20); + } #endif - -#if 0 - /* Debug draw sprite transform */ - { - debug_draw_xform(mtx); - } -#endif - - /* Debug draw sprite pivot */ - { - u32 color = RGBA_F(1, 0, 0, 1); - - struct xform pre_pivot_xf = xform_trs(ent->world_xform, ent->sprite_trs); - struct v2 p = pre_pivot_xf.og; - - draw_solid_circle(L.world_canvas, p, 0.02, color, 20); } } }