diff --git a/src/pp/pp.c b/src/pp/pp.c index 0f39c6ca..abd804af 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -255,10 +255,9 @@ P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent) P_Ent *wep = P_EntFromKey(frame, ent->weapon); // TODO: Determine animation dynamically - i64 animation_rate_ns = NsFromSeconds(0.100); + i64 animation_rate_ns = NsFromSeconds(0.050); + i64 animation_time_ns = frame->time_ns; { - i64 walk_duration_ns = frame->time_ns; - result.frame_seq = walk_duration_ns / animation_rate_ns; // result.span = SPR_SpanKeyFromName(Lit("test")); if (P_IsEntRolling(frame, ent)) @@ -269,6 +268,11 @@ P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent) else if (Vec2LenSq(ent->control.move) > (0.01 * 0.01)) { result.span = SPR_SpanKeyFromName(Lit("walk")); + if (ent->is_guy) + { + result.legs_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("guy/legs.ase"))); + animation_time_ns = ent->walk_time_accum_ns; + } } else { @@ -276,6 +280,7 @@ P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent) } } + // TODO: Use prefab lookup if (ent->is_guy) @@ -299,6 +304,8 @@ P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent) result.wep_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("wep/launcher.ase"))); } + result.frame_seq = animation_time_ns / animation_rate_ns; + return result; } @@ -2317,6 +2324,15 @@ void P_StepFrame(P_Frame *frame) guy->last_roll_dir = NormVec2(guy->control.look); } } + + if (!P_IsEntRolling(frame, guy)) + { + b32 is_moving = Vec2LenSq(guy->control.move) > (0.001 * 0.001); + if (is_moving) + { + guy->walk_time_accum_ns += sim_dt_ns; + } + } } } diff --git a/src/pp/pp.h b/src/pp/pp.h index b0e61cb4..f2d09dd8 100644 --- a/src/pp/pp.h +++ b/src/pp/pp.h @@ -171,6 +171,7 @@ Struct(P_Ent) P_EntKey weapon; i64 last_roll_time_ns; Vec2 last_roll_dir; + i64 walk_time_accum_ns; //- Weapon @@ -217,6 +218,7 @@ Struct(P_Anim) i64 frame_seq; SPR_SpanKey span; SPR_SheetKey sheet; + SPR_SheetKey legs_sheet; SPR_SheetKey wep_sheet; b32 weapon_over; }; diff --git a/src/pp/pp_res/guy/guy.ase b/src/pp/pp_res/guy/guy.ase index 1048d65e..eaf23112 100644 --- a/src/pp/pp_res/guy/guy.ase +++ b/src/pp/pp_res/guy/guy.ase @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e0541266ade237e73791ae063d0a4aaad416cd8d7ad21e9cf9afcb31ce8ad38f -size 4080 +oid sha256:460192b81b4860758ce39630196e61006808cb8cb95508146cfd4e2fa1421e2a +size 9089 diff --git a/src/pp/pp_res/guy/legs.ase b/src/pp/pp_res/guy/legs.ase new file mode 100644 index 00000000..d9f06e03 --- /dev/null +++ b/src/pp/pp_res/guy/legs.ase @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ab70e7bccb51783818f3523b32b911d71ebedd9c711579084c9e4ef7540c174 +size 4716 diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index a2403499..9429664f 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -2170,6 +2170,23 @@ void V_TickForever(WaveLaneCtx *lane) body_pix_to_world_af = TranslateAffine(body_pix_to_world_af, NegVec2(anchor_ray.pos)); } + //- Compute legs sprite + SPR_Sprite legs = Zi; + Affine legs_pix_to_world_af = AffineIdentity; + { + Vec2 move_dir = NormVec2(ent->control.move); + + legs = SPR_SpriteFromSheet(anim.legs_sheet, anim.span, anim.frame_seq); + + legs_pix_to_world_af = TranslateAffine(legs_pix_to_world_af, ent_to_world_af.og); + legs_pix_to_world_af = ScaleAffine(legs_pix_to_world_af, pix_scale); + + SPR_Ray anchor_ray = legs.rays[SPR_RayKind_Anchor]; + legs_pix_to_world_af = RotateAffine(legs_pix_to_world_af, InvertRot(anchor_ray.dir)); + legs_pix_to_world_af = RotateAffine(legs_pix_to_world_af, move_dir); + legs_pix_to_world_af = TranslateAffine(legs_pix_to_world_af, NegVec2(anchor_ray.pos)); + } + //- Compute weapon sprite SPR_Sprite wep = Zi; Affine wep_pix_to_world_af = AffineIdentity; @@ -2206,6 +2223,15 @@ void V_TickForever(WaveLaneCtx *lane) if (body.ready) { + //- Legs quad + V_Quad legs_quad = Zi; + { + Affine legs_uv_to_world_af = ScaleAffine(legs_pix_to_world_af, DimsFromRng2(legs.tex_rect)); + legs_quad.quad_uv_to_world_af = legs_uv_to_world_af; + legs_quad.tex = legs.tex; + legs_quad.tex_slice_uv = DivRng2Vec2(legs.tex_rect, legs.tex_dims); + } + //- Body quad V_Quad body_quad = Zi; { @@ -2234,17 +2260,20 @@ void V_TickForever(WaveLaneCtx *lane) { if (anim.weapon_over) { + *PushStructNoZero(frame->quads_arena, V_Quad) = legs_quad; *PushStructNoZero(frame->quads_arena, V_Quad) = body_quad; *PushStructNoZero(frame->quads_arena, V_Quad) = wep_quad; } else { *PushStructNoZero(frame->quads_arena, V_Quad) = wep_quad; + *PushStructNoZero(frame->quads_arena, V_Quad) = legs_quad; *PushStructNoZero(frame->quads_arena, V_Quad) = body_quad; } } else { + *PushStructNoZero(frame->quads_arena, V_Quad) = legs_quad; *PushStructNoZero(frame->quads_arena, V_Quad) = body_quad; } }