implement partially broken slice based aiming
This commit is contained in:
parent
91d7812f8a
commit
c25afa72b9
191
src/game.c
191
src/game.c
@ -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
|
||||
* ========================== */
|
||||
|
||||
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 */
|
||||
/* ========================== *
|
||||
* Update entity 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) {
|
||||
@ -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");
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
|
||||
Loading…
Reference in New Issue
Block a user