From 4e96e2f4d53f876f8a04826aeedfa41a8451d291 Mon Sep 17 00:00:00 2001 From: jacob Date: Sat, 31 Jan 2026 10:29:05 -0600 Subject: [PATCH] weapon animation wip --- src/base/base_math.c | 64 +++++---- src/base/base_math.h | 11 +- src/pp/pp_res/sprite/bla3.ase | 4 +- src/pp/pp_vis/pp_vis_core.c | 250 ++-------------------------------- 4 files changed, 57 insertions(+), 272 deletions(-) diff --git a/src/base/base_math.c b/src/base/base_math.c index cde789b9..7f9fb216 100644 --- a/src/base/base_math.c +++ b/src/base/base_math.c @@ -838,7 +838,7 @@ b32 MatchAffine(Affine af0, Affine af1) //- Initialization -Affine AffineFromPos(Vec2 v) +Affine AffineFromTranslation(Vec2 v) { Affine af; af.bx = VEC2(1, 0); @@ -988,26 +988,22 @@ Vec2 MulAffineVec2(Affine af, Vec2 v) return result; } -//- Helpers - -Affine AffineFromXform(Xform xf) +Affine MulAffineXformTR(Affine af, Xform xf) { - Affine result = Zi; - Vec2 rot = xf.r; - if (rot.x == 0 && rot.y == 0) - { - rot.x = 1; - } - else - { - rot = NormVec2(rot); - } - result.bx = rot; - result.by = PerpVec2(rot); - result.og = xf.t; - return result; + af = TranslateAffine(af, xf.t); + af = RotateAffine(af, xf.r); + return af; } +Affine MulAffineXformRT(Affine af, Xform xf) +{ + af = RotateAffine(af, xf.r); + af = TranslateAffine(af, xf.t); + return af; +} + +//- Helpers + Affine BasisFromAffine(Affine af) { Affine result = Zi; @@ -1056,23 +1052,24 @@ Vec2 ScaleFromAffine(Affine af) //////////////////////////////////////////////////////////// //~ Xform +Xform MakeXform(Vec2 t, Vec2 r) +{ + Xform xf; + xf.t = t; + xf.r = NormRot(r); + return xf; +} + Xform NormXform(Xform xf) { - if (xf.r.x == 0 && xf.r.y == 0) - { - xf.r.x = 1; - } - else - { - xf.r = NormVec2(xf.r); - } + xf.r = NormRot(xf.r); return xf; } Xform InvertXform(Xform xf) { xf.t = NegVec2(xf.t); - xf.r = NegVec2(xf.r); + xf.r.y = -xf.r.y; return xf; } @@ -1091,6 +1088,19 @@ Vec2 MulXformVec2(Xform xf, Vec2 v) return result; } +Vec2 NormRot(Vec2 r) +{ + if (r.x == 0 && r.y == 0) + { + r.x = 1; + } + else + { + r = Vec2WithLen(r, 1); + } + return r; +} + //////////////////////////////////////////////////////////// //~ Spring diff --git a/src/base/base_math.h b/src/base/base_math.h index 456fc2fe..a719e1dc 100644 --- a/src/base/base_math.h +++ b/src/base/base_math.h @@ -463,7 +463,7 @@ Rng2I32 DivRng2I32Vec2I32(Rng2I32 a, Vec2I32 v); b32 MatchAffine(Affine af0, Affine af1); //- Initialization -Affine AffineFromPos(Vec2 v); +Affine AffineFromTranslation(Vec2 v); Affine AffineFromRot(Vec2 r); Affine AffineFromAngle(f32 r); Affine AffineFromScale(Vec2 scale); @@ -489,12 +489,13 @@ Affine LerpAffine(Affine a, Affine b, f32 t); Affine InvertAffine(Affine af); //- Mul -Vec2 MulAffineVec2(Affine af, Vec2 v); Affine MulAffine(Affine a, Affine b); +Vec2 MulAffineVec2(Affine af, Vec2 v); Vec2 MulAffineBasisVec2(Affine af, Vec2 v); +Affine MulAffineXformTR(Affine af, Xform xf); +Affine MulAffineXformRT(Affine af, Xform xf); //- Helpers -Affine AffineFromXform(Xform xf); Affine BasisFromAffine(Affine af); f32 DeterminantFromAffine(Affine af); Vec2 RightFromAffine(Affine af); @@ -510,10 +511,14 @@ Vec2 ScaleFromAffine(Affine af); #define XformIdentity ((Xform) { .r = { 1, 0 } }) #define CompXformIdentity { .r = { 1, 0 } } +Xform MakeXform(Vec2 t, Vec2 r); + Xform NormXform(Xform xf); Xform InvertXform(Xform xf); Vec2 MulXformVec2(Xform xf, Vec2 v); +Vec2 NormRot(Vec2 r); + //////////////////////////////////////////////////////////// //~ Spring diff --git a/src/pp/pp_res/sprite/bla3.ase b/src/pp/pp_res/sprite/bla3.ase index 472a74b8..84cc6b07 100644 --- a/src/pp/pp_res/sprite/bla3.ase +++ b/src/pp/pp_res/sprite/bla3.ase @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5f149677408cff501a28a73dcea4cfa5ba0965e515757c2ebfb14123871d15c3 -size 3059 +oid sha256:888af3519ac240d0787b0719045f879ce7aacf56d4af0360a1c1a8b54b1e3fcf +size 3071 diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index b3163827..9baffdce 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -1845,30 +1845,26 @@ void V_TickForever(WaveLaneCtx *lane) Vec2 pix_scale = VEC2(1.0 / P_CellsPerMeter, 1.0 / P_CellsPerMeter); + // FIXME: Remove this + Xform ent_to_world_xf = ent->xf; + ent_to_world_xf = MakeXform(ent->xf.t, ent->control.look); + Affine ent_to_world_af = MulAffineXformTR(AffineIdentity, ent_to_world_xf); + //- Compute body SPR_Slice body = SPR_SliceFromSheet(anim.sheet, anim.span, anim.frame_seq); - Vec2 body_dims = DimsFromRng2(body.tex_rect); - Affine body_to_origin_af = AffineIdentity; + Affine body_to_world_af = ent_to_world_af; { - Xform anchor_to_body_xf = InvertXform(body.rays[SPR_RayKind_Anchor]); - - body_to_origin_af = ScaleAffine(body_to_origin_af, pix_scale); - body_to_origin_af = RotateAffine(body_to_origin_af, anchor_to_body_xf.r); - body_to_origin_af = TranslateAffine(body_to_origin_af, anchor_to_body_xf.t); + body_to_world_af = ScaleAffine(body_to_world_af, pix_scale); + body_to_world_af = RotateAffine(body_to_world_af, anchor_to_body_xf.r); + body_to_world_af = TranslateAffine(body_to_world_af, anchor_to_body_xf.t); } - Affine body_origin_to_ent_af = AffineIdentity; - { - // FIXME: Remove this - Xform ent_xf = ent->xf; - ent_xf.r = ent->control.look; //- Push body quad if (body.ready) { - Affine body_to_world_af = MulAffine(AffineFromXform(ent_xf), MulAffine(body_origin_to_ent_af, body_to_origin_af)); Affine body_uv_to_world_af = ScaleAffine(body_to_world_af, DimsFromRng2(body.tex_rect)); V_Quad *quad = PushStruct(frame->quads_arena, V_Quad); @@ -1882,232 +1878,6 @@ void V_TickForever(WaveLaneCtx *lane) - - - - - - // for (P_Ent *ent = P_FirstEnt(local_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) - // { - // if (ent->is_guy) - // { - // P_Anim anim = P_AnimFromEnt(ent, local_frame->time_ns); - - // Vec2 pix_scale = VEC2(1.0 / P_CellsPerMeter, 1.0 / P_CellsPerMeter); - - // //- Compute body - // SPR_Slice body_slice = SPR_SliceFromSheet(anim.sheet, anim.span, anim.frame_seq); - // Affine body_slice_to_origin_af = AffineIdentity; - // Xform body_ap_to_origin_xf = XformIdentity; - // { - // Vec2 body_slice_dims = DimsFromRng2(body_slice.bounds); - - // Xform origin_to_slice_corner_xf = body_slice.rays[SPR_RayKind_Origin]; - // origin_to_slice_corner_xf.t = SubVec2(origin_to_slice_corner_xf.t, body_slice.bounds.p0); - // origin_to_slice_corner_xf = InvertXform(origin_to_slice_corner_xf); - - // Xform ap_to_slice_corner_xf = body_slice.rays[SPR_RayKind_Ap]; - // ap_to_slice_corner_xf.t = SubVec2(ap_to_slice_corner_xf.t, body_slice.bounds.p0); - // ap_to_slice_corner_xf = InvertXform(ap_to_slice_corner_xf); - - // // body_ap_to_origin_xf = MulXform(InvertXform(origin_to_slice_corner_xf), ap_to_slice_corner_xf); - - // // FIXME: Remove this - // { - // Xform a = InvertXform(origin_to_slice_corner_xf); - // Xform b = ap_to_slice_corner_xf; - - // body_ap_to_origin_xf.r = RotateVec2(a.r, b.r); - - // body_ap_to_origin_xf.t = AddVec2(b.t, a.t); - // } - - // body_slice_to_origin_af = ScaleAffine(body_slice_to_origin_af, pix_scale); - // body_slice_to_origin_af = RotateAffine(body_slice_to_origin_af, origin_to_slice_corner_xf.r); - // body_slice_to_origin_af = TranslateAffine(body_slice_to_origin_af, origin_to_slice_corner_xf.t); - // body_slice_to_origin_af = ScaleAffine(body_slice_to_origin_af, body_slice_dims); - // } - - // //- Compute weapon - // // SPR_Slice wep_slice = SPR_SliceFromSheet(anim.wep_sheet, anim.span, anim.frame_seq); - // // Affine wep_slice_to_origin_af = AffineIdentity; - // // { - // // Vec2 wep_slice_dims = DimsFromRng2(wep_slice.bounds); - - // // Xform origin_ray = wep_slice.rays[SPR_RayKind_Origin]; - // // origin_ray.t = SubVec2(origin_ray.t, wep_slice.bounds.p0); - // // origin_ray = InvertXform(origin_ray); - - // // wep_slice_to_origin_af = ScaleAffine(wep_slice_to_origin_af, pix_scale); - // // wep_slice_to_origin_af = RotateAffine(wep_slice_to_origin_af, origin_ray.r); - // // wep_slice_to_origin_af = TranslateAffine(wep_slice_to_origin_af, origin_ray.t); - // // wep_slice_to_origin_af = ScaleAffine(wep_slice_to_origin_af, wep_slice_dims); - // // } - - // //- Compute weapon - // // SPR_Slice wep_slice = SPR_SliceFromSheet(anim.wep_sheet, anim.span, anim.frame_seq); - // // Affine wep_to_world_af = AffineIdentity; - // // { - // // Vec2 pix_dims = DimsFromRng2(wep_slice.bounds); - // // Vec2 world_dims = DivVec2(pix_dims, P_CellsPerMeter); - - // // Xform origin_ray = wep_slice.rays[SPR_RayKind_Origin]; - // // origin_ray.t = SubVec2(origin_ray.t, wep_slice.bounds.p0); - // // origin_ray = InvertXform(origin_ray); - - // // Affine origin_to_wep_af = AffineIdentity; - // // origin_to_wep_af = ScaleAffine(origin_to_wep_af, DivVec2Vec2(VEC2(1.0, 1.0), pix_dims)); - // // origin_to_wep_af = RotateAffine(origin_to_wep_af, origin_ray.r); - // // origin_to_wep_af = TranslateAffine(origin_to_wep_af, origin_ray.t); - // // origin_to_wep_af = ScaleAffine(origin_to_wep_af, pix_dims); - - // // Affine wep_to_ap_af = AffineIdentity; - // // wep_to_ap_af = ScaleAffine(wep_to_ap_af, world_dims); - // // wep_to_ap_af = MulAffine(wep_to_ap_af, origin_to_wep_af); - - // // Affine ap_to_ent_af = AffineIdentity; - - // // Xform ent_xf = ent->xf; - // // // FIXME: Remove this - // // ent_xf.r = ent->control.look; - - // // wep_to_world_af = MulAffine(AffineFromXform(ent_xf), wep_to_ent_af); - // // } - - - - - // Affine body_slice_to_ent_af = AffineIdentity; - // body_slice_to_ent_af = MulAffine(body_slice_to_ent_af, body_slice_to_origin_af); - - // // Affine body_ap_to_ent_af = AffineIdentity; - // // body_ap_to_ent_af = MulAffine(body_ap_to_ent_af, AffineFromXform(body_ap_to_origin_xf)); - - // // Affine wep_slice_to_ent_af = AffineIdentity; - // // wep_slice_to_ent_af = MulAffine(body_ap_to_ent_af, wep_slice_to_origin_af); - - - - // // FIXME: Remove this - // Xform ent_xf = ent->xf; - // ent_xf.r = ent->control.look; - - // //- Push body quad - // if (body_slice.ready) - // { - // Affine body_slice_to_world_af = MulAffine(AffineFromXform(ent_xf), body_slice_to_ent_af); - - // V_Quad *quad = PushStruct(frame->quads_arena, V_Quad); - // quad->to_shade_af = MulAffine(frame->af.world_to_shade, body_slice_to_world_af); - // quad->tex = body_slice.tex; - // quad->tex_rect_uv = body_slice.tex_rect_uv; - // } - - // //- Push weapon quad - // // if (body_slice.ready && wep_slice.ready) - // // { - // // Affine wep_slice_to_world_af = MulAffine(AffineFromXform(ent_xf), wep_slice_to_ent_af); - - // // V_Quad *quad = PushStruct(frame->quads_arena, V_Quad); - // // quad->to_shade_af = MulAffine(frame->af.world_to_shade, wep_slice_to_world_af); - // // quad->tex = wep_slice.tex; - // // quad->tex_rect_uv = wep_slice.tex_rect_uv; - // // } - // } - // } - - - - - - // for (P_Ent *ent = P_FirstEnt(local_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) - // { - // if (ent->is_guy) - // { - // P_Anim anim = P_AnimFromEnt(ent, local_frame->time_ns); - - // //- Compute body - // SPR_Slice body_slice = SPR_SliceFromSheet(anim.sheet, anim.span, anim.frame_seq); - // Affine body_to_world_af = AffineIdentity; - // { - // Vec2 pix_dims = DimsFromRng2(body_slice.bounds); - // Vec2 world_dims = DivVec2(pix_dims, P_CellsPerMeter); - - // Xform origin_ray = body_slice.rays[SPR_RayKind_Origin]; - // origin_ray.t = SubVec2(origin_ray.t, body_slice.bounds.p0); - // origin_ray = InvertXform(origin_ray); - - // Affine origin_to_body_af = AffineIdentity; - // origin_to_body_af = ScaleAffine(origin_to_body_af, DivVec2Vec2(VEC2(1.0, 1.0), pix_dims)); - // origin_to_body_af = RotateAffine(origin_to_body_af, origin_ray.r); - // origin_to_body_af = TranslateAffine(origin_to_body_af, origin_ray.t); - // origin_to_body_af = ScaleAffine(origin_to_body_af, pix_dims); - - // Affine body_to_ent_af = AffineIdentity; - // body_to_ent_af = ScaleAffine(body_to_ent_af, world_dims); - // body_to_ent_af = MulAffine(body_to_ent_af, origin_to_body_af); - - // Xform ent_xf = ent->xf; - // // FIXME: Remove this - // ent_xf.r = ent->control.look; - - // body_to_world_af = MulAffine(AffineFromXform(ent_xf), body_to_ent_af); - // } - - // //- Compute weapon - // SPR_Slice wep_slice = SPR_SliceFromSheet(anim.wep_sheet, anim.span, anim.frame_seq); - // Affine wep_to_world_af = AffineIdentity; - // { - // Vec2 pix_dims = DimsFromRng2(wep_slice.bounds); - // Vec2 world_dims = DivVec2(pix_dims, P_CellsPerMeter); - - // Xform origin_ray = wep_slice.rays[SPR_RayKind_Origin]; - // origin_ray.t = SubVec2(origin_ray.t, wep_slice.bounds.p0); - // origin_ray = InvertXform(origin_ray); - - // Affine origin_to_wep_af = AffineIdentity; - // origin_to_wep_af = ScaleAffine(origin_to_wep_af, DivVec2Vec2(VEC2(1.0, 1.0), pix_dims)); - // origin_to_wep_af = RotateAffine(origin_to_wep_af, origin_ray.r); - // origin_to_wep_af = TranslateAffine(origin_to_wep_af, origin_ray.t); - // origin_to_wep_af = ScaleAffine(origin_to_wep_af, pix_dims); - - // Affine wep_to_ap_af = AffineIdentity; - // wep_to_ap_af = ScaleAffine(wep_to_ap_af, world_dims); - // wep_to_ap_af = MulAffine(wep_to_ap_af, origin_to_wep_af); - - // Affine ap_to_ent_af = AffineIdentity; - - // Xform ent_xf = ent->xf; - // // FIXME: Remove this - // ent_xf.r = ent->control.look; - - // wep_to_world_af = MulAffine(AffineFromXform(ent_xf), wep_to_ent_af); - // } - - // //- Push weapon quad - // if (body_slice.ready && wep_slice.ready) - // { - // V_Quad *quad = PushStruct(frame->quads_arena, V_Quad); - // quad->to_shade_af = MulAffine(frame->af.world_to_shade, wep_to_world_af); - // quad->tex = wep_slice.tex; - // quad->tex_rect_uv = wep_slice.tex_rect_uv; - // } - - // //- Push body quad - // // if (body_slice.ready) - // // { - // // V_Quad *quad = PushStruct(frame->quads_arena, V_Quad); - // // quad->to_shade_af = MulAffine(frame->af.world_to_shade, body_to_world_af); - // // quad->tex = body_slice.tex; - // // quad->tex_rect_uv = body_slice.tex_rect_uv; - // // } - // } - // } - - - - - ////////////////////////////// //- Push test bullet particles @@ -4294,7 +4064,7 @@ void V_TickForever(WaveLaneCtx *lane) // P_Ent *ent = &cmd->ent; // *ent = P_NilEnt; // ent->key = V.guy_key; - // ent->af = AffineFromPos(guy_pos); + // ent->af = AffineFromTranslation(guy_pos); // ent->is_guy = 1; // ent->has_weapon = 1; // ent->exists = 1;