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);
|
struct xform xform_world = xform_mul(node.parent_xform_world, child->xform);
|
||||||
child->xform_world = xform_world;
|
child->xform_world = xform_world;
|
||||||
|
|
||||||
/* Calculate sprite xform */
|
/* Calculate sprite world xform */
|
||||||
struct xform sprite_xform_world = xform_mul(xform_world, child->sprite_xform);
|
struct xform sprite_xform_world = xform_mul(xform_world, child->sprite_xform);
|
||||||
child->sprite_xform_world = sprite_xform_world;
|
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->xform = XFORM_TRS(.t = pos, .r = r, .s = size);
|
||||||
|
|
||||||
e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase"));
|
e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase"));
|
||||||
e->sprite_span_name = STR("idle.unarmed");
|
//e->sprite_span_name = STR("idle.unarmed");
|
||||||
//e->sprite_span_name = STR("idle.two_handed");
|
e->sprite_span_name = STR("idle.two_handed");
|
||||||
|
|
||||||
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
||||||
e->player_max_speed = 4.f;
|
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
|
* 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) {
|
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
|
||||||
struct entity *ent = &entities_array.entities[entity_index];
|
struct entity *ent = &entities_array.entities[entity_index];
|
||||||
if (!ent->valid) continue;
|
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)) {
|
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||||
f64 time_in_frame = ent->animation_time_in_frame + G.world.dt;
|
/* Update focus */
|
||||||
u64 span_frame_offset = ent->animation_frame;
|
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 *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 sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("hold"), 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);
|
struct v2 hold_pos = xform_mul_v2(ent->xform_world, xform_mul_v2(ent->sprite_xform, slice.center_norm));
|
||||||
ent->sprite_xform = xform_with_scale(XFORM_POS(v2_neg(pivot_pos)), sprite_size);
|
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)) {
|
if (entity_has_prop(ent, ENTITY_PROP_TEST)) {
|
||||||
f32 t = ((f32)G.world.time);
|
f32 t = ((f32)G.world.time);
|
||||||
struct v2 og = v2_mul(V2(math_cos(t), math_sin(t)), 3);
|
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);
|
struct v2 s = V2(1 + (math_fabs(math_sin(t * 5)) * 3), 1);
|
||||||
(UNUSED)og;
|
(UNUSED)og;
|
||||||
(UNUSED)r;
|
(UNUSED)r;
|
||||||
@ -338,43 +389,13 @@ INTERNAL void game_update(void)
|
|||||||
ent->xform = xform_with_rotation(ent->xform, r);
|
ent->xform = xform_with_rotation(ent->xform, r);
|
||||||
ent->xform = xform_with_scale(ent->xform, s);
|
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) {
|
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
|
||||||
struct entity *ent = &entities_array.entities[entity_index];
|
struct entity *ent = &entities_array.entities[entity_index];
|
||||||
if (ent->valid && !ent->parent.gen) {
|
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) {
|
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
|
||||||
struct entity *ent = &entities_array.entities[entity_index];
|
struct entity *ent = &entities_array.entities[entity_index];
|
||||||
if (!ent->valid) continue;
|
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) {
|
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
|
||||||
struct entity *ent = &entities_array.entities[entity_index];
|
struct entity *ent = &entities_array.entities[entity_index];
|
||||||
if (ent->valid && !ent->parent.gen) {
|
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) {
|
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
|
||||||
struct entity *ent = &entities_array.entities[entity_index];
|
struct entity *ent = &entities_array.entities[entity_index];
|
||||||
if (!ent->valid) continue;
|
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) {
|
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
|
||||||
struct entity *ent = &entities_array.entities[entity_index];
|
struct entity *ent = &entities_array.entities[entity_index];
|
||||||
if (ent->valid && !ent->parent.gen) {
|
if (ent->valid && !ent->parent.gen) {
|
||||||
@ -500,9 +524,6 @@ INTERNAL void game_update(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* Publish tick */
|
/* Publish tick */
|
||||||
publish_game_tick();
|
publish_game_tick();
|
||||||
__profframe("Game");
|
__profframe("Game");
|
||||||
|
|||||||
@ -631,14 +631,14 @@ INLINE f32 v2_angle(struct v2 v)
|
|||||||
return math_atan2(v.y, v.x);
|
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