diff --git a/src/base/base_math.c b/src/base/base_math.c index 7f9fb216..55a835ec 100644 --- a/src/base/base_math.c +++ b/src/base/base_math.c @@ -543,6 +543,12 @@ Vec2 RotateVec2(Vec2 a, Vec2 b) return VEC2(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); } +Vec2 InvertRot(Vec2 r) +{ + r.y = -r.y; + return r; +} + Vec2 Vec2FromAngle(f32 a) { return VEC2(CosF32(a), SinF32(a)); @@ -897,21 +903,11 @@ Affine RotateAffine(Affine af, Vec2 r) return MulAffine(af, AffineFromRot(r)); } -Affine RotateAffineAngle(Affine af, f32 r) -{ - return MulAffine(af, AffineFromAngle(r)); -} - Affine PreRotateAffine(Affine af, Vec2 r) { return MulAffine(AffineFromRot(r), af); } -Affine PreRotateAffineAngle(Affine af, f32 r) -{ - return MulAffine(AffineFromAngle(r), af); -} - //- Scale Affine ScaleAffine(Affine af, Vec2 scale) @@ -988,18 +984,15 @@ Vec2 MulAffineVec2(Affine af, Vec2 v) return result; } -Affine MulAffineXformTR(Affine af, Xform xf) +Affine MulAffineXform(Affine af, Xform xf) { - 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; + Affine result; + result.bx.x = af.bx.x * xf.r.x + af.by.x * xf.r.y; + result.bx.y = af.bx.y * xf.r.x + af.by.y * xf.r.y; + result.by.x = af.bx.x * -xf.r.y + af.by.x * xf.r.x; + result.by.y = af.bx.y * -xf.r.y + af.by.y * xf.r.x; + result.og = MulAffineVec2(af, xf.t); + return result; } //- Helpers @@ -1060,9 +1053,26 @@ Xform MakeXform(Vec2 t, Vec2 r) return xf; } -Xform NormXform(Xform xf) +Xform MulXform(Xform a, Xform b) { - xf.r = NormRot(xf.r); + Xform result; + result.r.x = a.r.x * b.r.x + -a.r.y * b.r.y; + result.r.y = a.r.y * b.r.x + a.r.x * b.r.y; + result.t.x = a.r.x * b.t.x + -a.r.y * b.t.y; + result.t.y = a.r.y * b.t.x + a.r.x * b.t.y; + result.t = AddVec2(result.t, a.t); + return result; +} + +Xform TranslateXform(Xform xf, Vec2 t) +{ + xf.t = VEC2(xf.r.x * t.x + -xf.r.y * t.y + xf.t.x, xf.r.y * t.x + xf.r.x * t.y + xf.t.y); + return xf; +} + +Xform RotateXform(Xform xf, Vec2 r) +{ + xf.r = RotateVec2(xf.r, r); return xf; } @@ -1073,14 +1083,6 @@ Xform InvertXform(Xform xf) return xf; } -Xform MulXform(Xform a, Xform b) -{ - Xform result = Zi; - result.r = RotateVec2(a.r, b.r); - result.t = AddVec2(RotateVec2(a.r, b.t), a.t); - return result; -} - Vec2 MulXformVec2(Xform xf, Vec2 v) { Vec2 result = Zi; @@ -1088,6 +1090,12 @@ Vec2 MulXformVec2(Xform xf, Vec2 v) return result; } +Xform NormXform(Xform xf) +{ + xf.r = NormRot(xf.r); + return xf; +} + Vec2 NormRot(Vec2 r) { if (r.x == 0 && r.y == 0) diff --git a/src/base/base_math.h b/src/base/base_math.h index a719e1dc..eef0b641 100644 --- a/src/base/base_math.h +++ b/src/base/base_math.h @@ -390,6 +390,7 @@ Vec2 CeilVec2(Vec2 a); i32 WindingFromVec2(Vec2 a, Vec2 b); Vec2 RotateVec2Angle(Vec2 v, f32 a); Vec2 RotateVec2(Vec2 a, Vec2 b); +Vec2 InvertRot(Vec2 r); Vec2 Vec2FromAngle(f32 a); f32 AngleFromVec2(Vec2 v); @@ -474,9 +475,7 @@ Affine PreTranslateAffine(Affine af, Vec2 v); //- Rotation Affine RotateAffine(Affine af, Vec2 r); -Affine RotateAffineAngle(Affine af, f32 r); Affine PreRotateAffine(Affine af, Vec2 r); -Affine PreRotateAffineAngle(Affine af, f32 r); //- Scale Affine ScaleAffine(Affine af, Vec2 scale); @@ -492,8 +491,6 @@ Affine InvertAffine(Affine af); 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 BasisFromAffine(Affine af); @@ -513,10 +510,14 @@ Vec2 ScaleFromAffine(Affine af); Xform MakeXform(Vec2 t, Vec2 r); -Xform NormXform(Xform xf); +Xform MulXform(Xform a, Xform b); +Xform TranslateXform(Xform xf, Vec2 t); +Xform RotateXform(Xform xf, Vec2 r); + Xform InvertXform(Xform xf); Vec2 MulXformVec2(Xform xf, Vec2 v); +Xform NormXform(Xform xf); Vec2 NormRot(Vec2 r); //////////////////////////////////////////////////////////// diff --git a/src/pp/pp_res/sprite/bla3.ase b/src/pp/pp_res/sprite/bla3.ase index 84cc6b07..31463a27 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:888af3519ac240d0787b0719045f879ce7aacf56d4af0360a1c1a8b54b1e3fcf +oid sha256:aae562db3b8adf3af25dc82e69a7e4176162f137f1775aa69658aef8bd4cffda size 3071 diff --git a/src/pp/pp_res/sprite/palette.ase b/src/pp/pp_res/sprite/palette.ase index 41e4f1a9..78ddeabe 100644 --- a/src/pp/pp_res/sprite/palette.ase +++ b/src/pp/pp_res/sprite/palette.ase @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:63b837d60ca547c412f6f18352abd735776a0dc3802498098e715caa13ec3d52 -size 381 +oid sha256:c8b7f959717bf1a1597cdfc71c48ac85a5927ae1184d7edd3bc65687eada6136 +size 395 diff --git a/src/pp/pp_res/sprite/raah.ase b/src/pp/pp_res/sprite/raah.ase index 27e4f904..0bab1412 100644 --- a/src/pp/pp_res/sprite/raah.ase +++ b/src/pp/pp_res/sprite/raah.ase @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ea51a63c3a90e296c162b321287b4ac0048279d2efc5e1e683a90b60a62c98e7 -size 537 +oid sha256:a928f9225ff9a1d60b181f1ff331194f2da769b61cb43078f11bdd48fe96ad60 +size 549 diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 9baffdce..5f9e3232 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -1848,30 +1848,57 @@ void V_TickForever(WaveLaneCtx *lane) // 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); + Affine ent_to_world_af = MulAffineXform(AffineIdentity, ent_to_world_xf); - //- Compute body SPR_Slice body = SPR_SliceFromSheet(anim.sheet, anim.span, anim.frame_seq); - Affine body_to_world_af = ent_to_world_af; + SPR_Slice wep = SPR_SliceFromSheet(anim.wep_sheet, anim.span, anim.frame_seq); + + Affine body_pix_to_world_af = AffineIdentity; { - Xform anchor_to_body_xf = InvertXform(body.rays[SPR_RayKind_Anchor]); - 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); + body_pix_to_world_af = MulAffine(body_pix_to_world_af, ent_to_world_af); + body_pix_to_world_af = ScaleAffine(body_pix_to_world_af, pix_scale); + + SPR_Ray anchor_ray = body.rays[SPR_RayKind_Anchor]; + body_pix_to_world_af = RotateAffine(body_pix_to_world_af, InvertRot(anchor_ray.dir)); + body_pix_to_world_af = TranslateAffine(body_pix_to_world_af, NegVec2(anchor_ray.pos)); } + Affine wep_pix_to_world_af = AffineIdentity; { + wep_pix_to_world_af = MulAffine(wep_pix_to_world_af, ent_to_world_af); + wep_pix_to_world_af = ScaleAffine(wep_pix_to_world_af, pix_scale); - //- Push body quad - if (body.ready) - { - Affine body_uv_to_world_af = ScaleAffine(body_to_world_af, DimsFromRng2(body.tex_rect)); + SPR_Ray body_anchor_ray = body.rays[SPR_RayKind_Anchor]; + SPR_Ray body_ap_ray = body.rays[SPR_RayKind_Ap]; + wep_pix_to_world_af = RotateAffine(wep_pix_to_world_af, InvertRot(body_anchor_ray.dir)); + wep_pix_to_world_af = TranslateAffine(wep_pix_to_world_af, SubVec2(body_ap_ray.pos, body_anchor_ray.pos)); + wep_pix_to_world_af = RotateAffine(wep_pix_to_world_af, InvertRot(body_ap_ray.dir)); - V_Quad *quad = PushStruct(frame->quads_arena, V_Quad); - quad->quad_uv_to_shade_af = MulAffine(frame->af.world_to_shade, body_uv_to_world_af); - quad->tex = body.tex; - quad->tex_slice_uv = DivRng2Vec2(body.tex_rect, body.tex_dims); - } + SPR_Ray anchor_ray = wep.rays[SPR_RayKind_Anchor]; + wep_pix_to_world_af = RotateAffine(wep_pix_to_world_af, anchor_ray.dir); + wep_pix_to_world_af = TranslateAffine(wep_pix_to_world_af, NegVec2(anchor_ray.pos)); + } + + //- Push weapon quad + if (body.ready && wep.ready) + { + Affine wep_uv_to_world_af = ScaleAffine(wep_pix_to_world_af, DimsFromRng2(wep.tex_rect)); + + V_Quad *quad = PushStruct(frame->quads_arena, V_Quad); + quad->quad_uv_to_shade_af = MulAffine(frame->af.world_to_shade, wep_uv_to_world_af); + quad->tex = wep.tex; + quad->tex_slice_uv = DivRng2Vec2(wep.tex_rect, wep.tex_dims); + } + + //- Push body quad + if (body.ready) + { + Affine body_uv_to_world_af = ScaleAffine(body_pix_to_world_af, DimsFromRng2(body.tex_rect)); + + V_Quad *quad = PushStruct(frame->quads_arena, V_Quad); + quad->quad_uv_to_shade_af = MulAffine(frame->af.world_to_shade, body_uv_to_world_af); + quad->tex = body.tex; + quad->tex_slice_uv = DivRng2Vec2(body.tex_rect, body.tex_dims); } } } diff --git a/src/sprite/sprite.c b/src/sprite/sprite.c index 326ccbd4..f3f87949 100644 --- a/src/sprite/sprite.c +++ b/src/sprite/sprite.c @@ -113,7 +113,7 @@ SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 f Atomic64Set(&slice->atlas_copy_completion_target, I64Max); for (SPR_RayKind ray_kind = 0; ray_kind < SPR_RayKind_COUNT; ++ray_kind) { - slice->rays[ray_kind] = XformIdentity; + slice->rays[ray_kind].dir.x = 1; } } @@ -192,11 +192,11 @@ SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 f if (alpha > 0) { // TODO: Different quantization so that 128 equals 0, instead of approximately 0 - f32 rot_x = (((f32)((ray_pix >> 0) & 0xFF) / 255.0) * 2.0) - 1; - f32 rot_y = (((f32)((ray_pix >> 8) & 0xFF) / 255.0) * 2.0) - 1; - Vec2 rot = NormVec2(VEC2(rot_x, rot_y)); - slice->rays[ray_kind].r = rot; - slice->rays[ray_kind].t = SubVec2(ase_cel->bounds.p0, slice->canvas_rect.p0); + f32 dir_x = (((f32)((ray_pix >> 0) & 0xFF) / 255.0) * 2.0) - 1; + f32 dir_y = (((f32)((ray_pix >> 8) & 0xFF) / 255.0) * 2.0) - 1; + Vec2 dir = NormVec2(VEC2(dir_x, dir_y)); + slice->rays[ray_kind].pos = SubVec2(ase_cel->bounds.p0, slice->canvas_rect.p0); + slice->rays[ray_kind].dir = dir; } } } diff --git a/src/sprite/sprite.h b/src/sprite/sprite.h index a91ce96e..eae80998 100644 --- a/src/sprite/sprite.h +++ b/src/sprite/sprite.h @@ -49,9 +49,15 @@ Enum(SPR_LayerKind) //////////////////////////////////////////////////////////// //~ Lookup result types +Struct(SPR_Ray) +{ + Vec2 pos; + Vec2 dir; +}; + Struct(SPR_Slice) { - Xform rays[SPR_RayKind_COUNT]; + SPR_Ray rays[SPR_RayKind_COUNT]; Vec2 tex_dims; G_Texture2DRef tex; @@ -71,7 +77,7 @@ Struct(SPR_SliceEntry) SPR_SliceEntry *next_in_bin; Rng2 canvas_rect; - Xform rays[SPR_RayKind_COUNT]; + SPR_Ray rays[SPR_RayKind_COUNT]; Atomic64 atlas_copy_completion_target; SPR_Atlas *atlas;