fix sprite slice size off-by-one. dont calculate entity animation in user thread. debug draw slices
This commit is contained in:
parent
fd3ab6146b
commit
5c51b555b2
@ -954,8 +954,8 @@ struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct buff
|
||||
slice->start = start;
|
||||
slice->x1 = x;
|
||||
slice->y1 = y;
|
||||
slice->x2 = max_u32((x + width) - 1, 0);
|
||||
slice->y2 = max_u32((y + height) - 1, 0);
|
||||
slice->x2 = x + width;
|
||||
slice->y2 = y + height;
|
||||
}
|
||||
|
||||
++num_slice_keys;
|
||||
|
||||
43
src/game.c
43
src/game.c
@ -175,7 +175,6 @@ INTERNAL void game_update(void)
|
||||
e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase"));
|
||||
e->sprite_span_name = STR("idle.unarmed");
|
||||
//e->sprite_span_name = STR("idle.two_handed");
|
||||
e->sprite_quad_xform = XFORM_TRS(.s = size);
|
||||
|
||||
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
||||
e->player_max_speed = 4.f;
|
||||
@ -187,7 +186,6 @@ INTERNAL void game_update(void)
|
||||
player_ent = e;
|
||||
|
||||
//entity_enable_prop(e, ENTITY_PROP_TEST);
|
||||
//entity_enable_prop(e, ENTITY_PROP_TEST_FOLLOW_MOUSE);
|
||||
}
|
||||
|
||||
/* Camera ent */
|
||||
@ -300,6 +298,18 @@ INTERNAL void game_update(void)
|
||||
ent->animation_frame = span_frame_offset;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Calculate sprite xform
|
||||
* ========================== */
|
||||
|
||||
if (!sprite_tag_is_nil(ent->sprite)) {
|
||||
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
|
||||
struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT);
|
||||
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("pivot"), ent->animation_frame);
|
||||
struct v2 pivot_pos = v2_mul_v2(slice.center_norm, sprite_size);
|
||||
ent->sprite_quad_xform = xform_with_scale(XFORM_POS(v2_neg(pivot_pos)), sprite_size);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Test
|
||||
* ========================== */
|
||||
@ -324,29 +334,12 @@ INTERNAL void game_update(void)
|
||||
ent->rel_xform = xform_with_scale(ent->rel_xform, s);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Calculate sprite xform
|
||||
* ========================== */
|
||||
|
||||
if (ent->sprite.hash != 0) {
|
||||
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
|
||||
struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT);
|
||||
|
||||
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("pivot"), ent->animation_frame);
|
||||
struct v2 pivot_pos = v2_mul_v2(slice.center_norm, sprite_size);
|
||||
|
||||
/* Apply Pivot */
|
||||
struct xform sprite_xf = XFORM_POS(v2_neg(pivot_pos));
|
||||
sprite_xf = xform_scale(sprite_xf, sprite_size);
|
||||
|
||||
ent->sprite_quad_xform = sprite_xf;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Calculate player aim angle
|
||||
* ========================== */
|
||||
|
||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||
#if 1
|
||||
/* Update focus */
|
||||
ent->focus = G.world.player_aim;
|
||||
|
||||
@ -355,6 +348,16 @@ INTERNAL void game_update(void)
|
||||
struct v2 look_pos = v2_add(ent_pos, ent->focus);
|
||||
f32 r = v2_angle_to_point(ent_pos, look_pos) + PI / 2;
|
||||
ent->rel_xform = xform_with_rotation(ent->rel_xform, r);
|
||||
#else
|
||||
/* Update focus */
|
||||
ent->focus = G.world.player_aim;
|
||||
|
||||
/* Update view angle */
|
||||
struct v2 ent_pos = ent->rel_xform.og;
|
||||
struct v2 look_pos = v2_add(ent_pos, ent->focus);
|
||||
f32 r = v2_angle_to_point(ent_pos, look_pos) + PI / 2;
|
||||
ent->rel_xform = xform_with_rotation(ent->rel_xform, r);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -650,7 +650,7 @@ INTERNAL void cache_node_load_sheet(struct cache_node *n, struct sprite_tag tag)
|
||||
logf_info("Loading sprite sheet \"%F\"", FMT_STR(path));
|
||||
sys_timestamp_t start_ts = sys_timestamp();
|
||||
|
||||
ASSERT(string_ends_with(path, STR(".ase")));
|
||||
//ASSERT(string_ends_with(path, STR(".ase")));
|
||||
ASSERT(n->kind == CACHE_NODE_KIND_SHEET);
|
||||
|
||||
n->arena = arena_alloc(SHEET_ARENA_RESERVE);
|
||||
@ -671,7 +671,7 @@ INTERNAL void cache_node_load_sheet(struct cache_node *n, struct sprite_tag tag)
|
||||
n->sheet->loaded = true;
|
||||
n->sheet->valid = true;
|
||||
} else {
|
||||
logf_error("Sprite \"%F\" not found", path);
|
||||
logf_error("Sprite \"%F\" not found", FMT_STR(path));
|
||||
}
|
||||
}
|
||||
#if RESOURCE_RELOADING
|
||||
@ -899,7 +899,6 @@ INTERNAL void *data_from_tag_internal(struct sprite_scope *scope, struct sprite_
|
||||
|
||||
sys_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
35
src/user.c
35
src/user.c
@ -457,6 +457,7 @@ INTERNAL void user_update(void)
|
||||
|
||||
e->sprite_quad_xform = xform_lerp(e0->sprite_quad_xform, e1->sprite_quad_xform, tick_blend);
|
||||
e->animation_time_in_frame = math_lerp64(e0->animation_time_in_frame, e1->animation_time_in_frame, (f64)tick_blend);
|
||||
e->animation_frame = (u32)math_round_to_int(math_lerp(e0->animation_frame, e1->animation_frame, tick_blend));
|
||||
|
||||
e->camera_quad_xform = xform_lerp(e0->camera_quad_xform, e1->camera_quad_xform, tick_blend);
|
||||
e->camera_rel_xform_target = xform_lerp(e0->camera_rel_xform_target, e1->camera_rel_xform_target, tick_blend);
|
||||
@ -765,29 +766,10 @@ INTERNAL void user_update(void)
|
||||
struct sprite_texture *texture = sprite_texture_from_tag_async(sprite_frame_scope, sprite);
|
||||
(UNUSED)texture;
|
||||
|
||||
/* TODO: Fade in placeholder if texture isn't loaded */
|
||||
if (sheet->loaded) {
|
||||
struct sprite_sheet_frame frame;
|
||||
{
|
||||
struct sprite_sheet_span span = sprite_sheet_get_span(sheet, ent->sprite_span_name);
|
||||
u32 frame_index = span.start + ent->animation_frame;
|
||||
frame = sprite_sheet_get_frame(sheet, frame_index);
|
||||
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) {
|
||||
f64 time_in_frame = ent->animation_time_in_frame;
|
||||
while (time_in_frame > frame.duration) {
|
||||
time_in_frame -= frame.duration;
|
||||
++frame_index;
|
||||
if (frame_index > span.end) {
|
||||
/* Loop animation */
|
||||
frame_index = span.start;
|
||||
}
|
||||
frame = sprite_sheet_get_frame(sheet, frame_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct sprite_sheet_frame frame = sprite_sheet_get_frame(sheet, ent->animation_frame);
|
||||
struct quad quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, xform_mul(ent->world_xform, ent->sprite_quad_xform));
|
||||
|
||||
/* TODO: Fade in placeholder if texture isn't loaded */
|
||||
struct draw_sprite_params params = DRAW_SPRITE_PARAMS(.sprite = sprite, .tint = ent->sprite_tint, .clip = frame.clip);
|
||||
draw_sprite_quad(G.world_canvas, params, quad);
|
||||
}
|
||||
@ -840,9 +822,8 @@ INTERNAL void user_update(void)
|
||||
debug_draw_xform(ent->world_xform);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Draw slices */
|
||||
{
|
||||
if (!sprite_tag_is_nil(ent->sprite)) {
|
||||
struct sprite_tag sprite = ent->sprite;
|
||||
struct sprite_sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, sprite);
|
||||
|
||||
@ -850,12 +831,14 @@ INTERNAL void user_update(void)
|
||||
struct sprite_sheet_slice_group *group = &sheet->slice_groups[i];
|
||||
|
||||
for (u32 j = 0; j < group->per_frame_count; ++j) {
|
||||
group->frame_slices[(j * group->per_frame_count) + k];
|
||||
struct sprite_sheet_slice slice = group->frame_slices[(ent->animation_frame * group->per_frame_count) + j];
|
||||
struct quad quad = quad_from_rect(slice.rect_norm);
|
||||
quad = quad_mul_xform(quad, xform_mul(ent->world_xform, ent->sprite_quad_xform));
|
||||
draw_solid_quad_line(G.viewport_canvas, quad_mul_xform(quad, G.world_view), 3, COLOR_RED);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Draw hierarchy */
|
||||
struct entity *parent = entity_from_handle(&G.world.entity_store, ent->parent);
|
||||
if (parent->valid) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user