implement partially broken slice based aiming

This commit is contained in:
jacob 2024-08-01 14:47:37 -05:00
parent 91d7812f8a
commit c25afa72b9
2 changed files with 110 additions and 89 deletions

View File

@ -132,7 +132,7 @@ INTERNAL void recalculate_world_xforms_recurse(struct entity *parent)
struct xform xform_world = xform_mul(node.parent_xform_world, child->xform);
child->xform_world = xform_world;
/* Calculate sprite xform */
/* Calculate sprite world xform */
struct xform sprite_xform_world = xform_mul(xform_world, child->sprite_xform);
child->sprite_xform_world = sprite_xform_world;
@ -178,8 +178,8 @@ INTERNAL void game_update(void)
e->xform = XFORM_TRS(.t = pos, .r = r, .s = size);
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_span_name = STR("idle.unarmed");
e->sprite_span_name = STR("idle.two_handed");
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
e->player_max_speed = 4.f;
@ -256,10 +256,76 @@ INTERNAL void game_update(void)
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* ========================== *
* Update sprite
* ========================== */
/* Recalculate world xforms */
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
struct entity *ent = &entities_array.entities[entity_index];
if (ent->valid && !ent->parent.gen) {
recalculate_world_xforms_recurse(ent);
}
}
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
struct entity *ent = &entities_array.entities[entity_index];
if (!ent->valid) continue;
if (sprite_tag_is_nil(ent->sprite)) continue;
/* ========================== *
* Update animation
* ========================== */
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) {
struct sprite_sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, ent->sprite);
struct sprite_sheet_span span = sprite_sheet_get_span(sheet, ent->sprite_span_name);
f64 time_in_frame = ent->animation_time_in_frame + G.world.dt;
u64 frame_index = ent->animation_frame;
if (frame_index < span.start || frame_index > span.end) {
frame_index = span.start;
}
struct sprite_sheet_frame frame = sprite_sheet_get_frame(sheet, frame_index);
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);
}
ent->animation_time_in_frame = time_in_frame;
ent->animation_frame = frame_index;
}
/* ========================== *
* Update sprite xform
* ========================== */
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("pivot"), ent->animation_frame);
struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT);
struct v2 pivot_pos = v2_mul_v2(slice.center_norm, sprite_size);
ent->sprite_xform = xform_with_scale(XFORM_POS(v2_neg(pivot_pos)), sprite_size);
}
/* ========================== *
* Update entities pre-physics
* ========================== */
/* Recalculate world xforms */
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
struct entity *ent = &entities_array.entities[entity_index];
if (ent->valid && !ent->parent.gen) {
recalculate_world_xforms_recurse(ent);
}
}
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
struct entity *ent = &entities_array.entities[entity_index];
if (!ent->valid) continue;
@ -276,43 +342,28 @@ INTERNAL void game_update(void)
}
/* ========================== *
* Update animation
* Calculate player aim angle
* ========================== */
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) {
f64 time_in_frame = ent->animation_time_in_frame + G.world.dt;
u64 span_frame_offset = ent->animation_frame;
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
/* Update focus */
ent->focus = G.world.player_aim;
struct sprite_sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, ent->sprite);
struct sprite_sheet_span span = sprite_sheet_get_span(sheet, ent->sprite_span_name);
u64 frame_index = span.start + span_frame_offset;
struct sprite_sheet_frame frame = sprite_sheet_get_frame(sheet, frame_index);
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);
}
span_frame_offset = frame_index - span.start;
ent->animation_time_in_frame = time_in_frame;
ent->animation_frame = span_frame_offset;
}
/* ========================== *
* Update sprite xform
* ========================== */
if (!sprite_tag_is_nil(ent->sprite)) {
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("pivot"), ent->animation_frame);
struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT);
struct v2 pivot_pos = v2_mul_v2(slice.center_norm, sprite_size);
ent->sprite_xform = xform_with_scale(XFORM_POS(v2_neg(pivot_pos)), sprite_size);
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("hold"), ent->animation_frame);
struct v2 hold_pos = xform_mul_v2(ent->xform_world, xform_mul_v2(ent->sprite_xform, slice.center_norm));
struct v2 hold_dir = xform_basis_mul_v2(ent->xform_world, xform_basis_mul_v2(ent->sprite_xform, slice.dir_norm));
struct v2 focus_pos = v2_add(ent->xform_world.og, ent->focus);
struct v2 hold_focus_dir = v2_sub(focus_pos, hold_pos);
/* Only rotate if rotation to focus around origin is possible */
f32 ent_hold_len = v2_len(v2_sub(hold_pos, ent->xform_world.og));
f32 ent_focus_len = v2_len(v2_sub(focus_pos, ent->xform_world.og));
if (ent_focus_len > ent_hold_len) {
ent->xform = xform_rotate(ent->xform, v2_angle_from_dirs(hold_dir, hold_focus_dir));
}
}
/* ========================== *
@ -323,7 +374,7 @@ INTERNAL void game_update(void)
if (entity_has_prop(ent, ENTITY_PROP_TEST)) {
f32 t = ((f32)G.world.time);
struct v2 og = v2_mul(V2(math_cos(t), math_sin(t)), 3);
f32 r = t + PI / 2;
f32 r = t * 3;
struct v2 s = V2(1 + (math_fabs(math_sin(t * 5)) * 3), 1);
(UNUSED)og;
(UNUSED)r;
@ -338,43 +389,13 @@ INTERNAL void game_update(void)
ent->xform = xform_with_rotation(ent->xform, r);
ent->xform = xform_with_scale(ent->xform, s);
}
}
/* ========================== *
* Calculate player aim angle
* Update entity physics
* ========================== */
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
#if 0
/* Update focus */
ent->focus = G.world.player_aim;
/* Update view angle */
struct v2 ent_pos = ent->xform.og;
struct v2 look_pos = v2_add(ent_pos, ent->focus);
float r;
{
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_scope, ent->sprite);
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("hold"), ent->animation_frame);
struct v2 dir = slice.dir_norm;
}
ent->xform = xform_with_rotation(ent->xform, r);
#else
/* Update focus */
ent->focus = G.world.player_aim;
/* Update view angle */
struct v2 ent_pos = ent->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->xform = xform_with_rotation(ent->xform, r);
#endif
}
}
/* Recalculate xforms */
/* Recalculate world xforms */
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
struct entity *ent = &entities_array.entities[entity_index];
if (ent->valid && !ent->parent.gen) {
@ -382,10 +403,6 @@ INTERNAL void game_update(void)
}
}
/* ========================== *
* Update entity physics
* ========================== */
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
struct entity *ent = &entities_array.entities[entity_index];
if (!ent->valid) continue;
@ -419,7 +436,11 @@ INTERNAL void game_update(void)
}
}
/* Recalculate xforms */
/* ========================== *
* Update entities post-physics
* ========================== */
/* Recalculate world xforms */
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
struct entity *ent = &entities_array.entities[entity_index];
if (ent->valid && !ent->parent.gen) {
@ -427,10 +448,6 @@ INTERNAL void game_update(void)
}
}
/* ========================== *
* Update entities post-physics
* ========================== */
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
struct entity *ent = &entities_array.entities[entity_index];
if (!ent->valid) continue;
@ -492,7 +509,14 @@ INTERNAL void game_update(void)
}
}
/* Recalculate xforms */
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* ========================== *
* Publish tick
* ========================== */
/* Recalculate world xforms */
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
struct entity *ent = &entities_array.entities[entity_index];
if (ent->valid && !ent->parent.gen) {
@ -500,9 +524,6 @@ INTERNAL void game_update(void)
}
}
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* Publish tick */
publish_game_tick();
__profframe("Game");

View File

@ -631,14 +631,14 @@ INLINE f32 v2_angle(struct v2 v)
return math_atan2(v.y, v.x);
}
INLINE f32 v2_angle_to_dir(struct v2 a, struct v2 b)
INLINE f32 v2_angle_from_dirs(struct v2 dir1, struct v2 dir2)
{
return math_atan2(v2_wedge(a, b), v2_dot(a, b));
return math_atan2(v2_wedge(dir1, dir2), v2_dot(dir1, dir2));
}
INLINE f32 v2_angle_to_point(struct v2 a, struct v2 b)
INLINE f32 v2_angle_from_points(struct v2 pt1, struct v2 pt2)
{
return v2_angle(v2_sub(b, a));
return v2_angle(v2_sub(pt2, pt1));
}
/* ========================== *