diff --git a/src/ase/ase.c b/src/ase/ase.c index 5509092d..bb1578fd 100644 --- a/src/ase/ase.c +++ b/src/ase/ase.c @@ -463,7 +463,7 @@ ASE_Meta ASE_DecodeMeta(Arena *arena, String encoded) chunk->kind = ASE_ChunkKind_Tag; chunk->tag.from = BB_ReadUBits(&bbr, 16); - chunk->tag.to = BB_ReadUBits(&bbr, 16); + chunk->tag.to = BB_ReadUBits(&bbr, 16) + 1; BB_ReadSeekBytes(&bbr, 13); chunk->name.len = BB_ReadUBits(&bbr, 16); @@ -628,6 +628,7 @@ ASE_Meta ASE_DecodeMeta(Arena *arena, String encoded) span->name = chunk->name; span->from = chunk->tag.from; span->to = chunk->tag.to; + ++spans_count; } } } diff --git a/src/base/base_math.c b/src/base/base_math.c index 9beeb2dc..7ce519e6 100644 --- a/src/base/base_math.c +++ b/src/base/base_math.c @@ -526,14 +526,14 @@ i32 WindingFromVec2(Vec2 a, Vec2 b) return (w >= 0) - (w < 0); } -Vec2 RotateVec2(Vec2 v, f32 a) +Vec2 RotateVec2Angle(Vec2 v, f32 a) { f32 c = CosF32(a); f32 s = SinF32(a); return VEC2(v.x * c - v.y * s, v.x * s + v.y * c); } -Vec2 RotateVec2Vec2(Vec2 a, Vec2 b) +Vec2 RotateVec2(Vec2 a, Vec2 b) { return VEC2(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); } @@ -832,6 +832,7 @@ b32 MatchAffine(Affine af0, Affine af1) } //- Initialization + Affine AffineFromPos(Vec2 v) { Affine af; @@ -841,7 +842,16 @@ Affine AffineFromPos(Vec2 v) return af; } -Affine AffineFromRot(f32 r) +Affine AffineFromRot(Vec2 r) +{ + Affine result; + result.bx = VEC2(r.x, r.y); + result.by = VEC2(-r.y, r.x); + result.og = VEC2(0, 0); + return result; +} + +Affine AffineFromAngle(f32 r) { Affine result; f32 c = CosF32(r); @@ -862,6 +872,7 @@ Affine AffineFromScale(Vec2 scale) } //- Translation + Affine TranslateAffine(Affine af, Vec2 v) { af.og = VEC2(af.bx.x * v.x + af.by.x * v.y + af.og.x, af.bx.y * v.x + af.by.y * v.y + af.og.y); @@ -875,17 +886,23 @@ Affine WorldTranslateAffine(Affine af, Vec2 v) } //- Rotation -Affine RotateAffine(Affine af, f32 r) + +Affine RotateAffine(Affine af, Vec2 r) { return MulAffine(af, AffineFromRot(r)); } -Affine WorldRotateAffine(Affine af, f32 r) +Affine RotateAffineAngle(Affine af, f32 r) { - return MulAffine(AffineFromRot(r), af); + return MulAffine(af, AffineFromAngle(r)); } -Affine WorldRotateAffineBasis(Affine af, f32 r) +Affine WorldRotateAffineAngle(Affine af, f32 r) +{ + return MulAffine(AffineFromAngle(r), af); +} + +Affine WorldRotateAffineBasisAngle(Affine af, f32 r) { f32 diff = r; f32 c = CosF32(diff); @@ -895,12 +912,13 @@ Affine WorldRotateAffineBasis(Affine af, f32 r) return af; } -Affine AffineWithWorldRotation(Affine af, f32 r) +Affine AffineWithWorldRotationAngle(Affine af, f32 r) { - return WorldRotateAffineBasis(af, r - RotationFromAffine(af)); + return WorldRotateAffineBasisAngle(af, r - AngleFromAffine(af)); } //- Scale + Affine ScaleAffine(Affine af, Vec2 scale) { af.bx = MulVec2(af.bx, scale.x); @@ -918,6 +936,7 @@ Affine WorldScaleAffine(Affine af, Vec2 scale) } //- Lerp + Affine LerpAffine(Affine a, Affine b, f32 t) { Affine result; @@ -928,6 +947,7 @@ Affine LerpAffine(Affine a, Affine b, f32 t) } //- Invert + Affine InvertAffine(Affine af) { f32 det = DeterminantFromAffine(af); @@ -946,6 +966,7 @@ Affine InvertAffine(Affine af) } //- Mul + Affine MulAffine(Affine a, Affine b) { Affine result; @@ -988,6 +1009,25 @@ Vec2 InvertAffineMulVec2(Affine af, Vec2 v) } //- Helpers + +Affine AffineFromXform(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; +} + Affine BasisFromAffine(Affine af) { Affine result = Zi; @@ -1021,7 +1061,7 @@ Vec2 DownFromAffine(Affine af) return af.by; } -f32 RotationFromAffine(Affine af) +f32 AngleFromAffine(Affine af) { return AngleFromVec2(af.bx); } @@ -1036,18 +1076,38 @@ Vec2 ScaleFromAffine(Affine af) //////////////////////////////////////////////////////////// //~ Xform +Xform NormXform(Xform xf) +{ + if (xf.r.x == 0 && xf.r.y == 0) + { + xf.r.x = 1; + } + else + { + xf.r = NormVec2(xf.r); + } + return xf; +} + +Xform InvertXform(Xform xf) +{ + xf.t = NegVec2(xf.t); + xf.r = NegVec2(xf.r); + return xf; +} + Xform MulXform(Xform a, Xform b) { Xform result = Zi; - result.r = RotateVec2Vec2(a.r, b.r); - result.t = AddVec2(RotateVec2Vec2(a.r, b.t), a.t); + 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; - result = AddVec2(RotateVec2Vec2(v, xf.r), xf.t); + result = AddVec2(RotateVec2(v, xf.r), xf.t); return result; } diff --git a/src/base/base_math.h b/src/base/base_math.h index 4522129c..451d7301 100644 --- a/src/base/base_math.h +++ b/src/base/base_math.h @@ -387,8 +387,8 @@ Vec2 CeilVec2(Vec2 a); //- Angle i32 WindingFromVec2(Vec2 a, Vec2 b); -Vec2 RotateVec2(Vec2 v, f32 a); -Vec2 RotateVec2Vec2(Vec2 a, Vec2 b); +Vec2 RotateVec2Angle(Vec2 v, f32 a); +Vec2 RotateVec2(Vec2 a, Vec2 b); Vec2 Vec2FromAngle(f32 a); f32 AngleFromVec2(Vec2 v); @@ -463,7 +463,8 @@ b32 MatchAffine(Affine af0, Affine af1); //- Initialization Affine AffineFromPos(Vec2 v); -Affine AffineFromRot(f32 r); +Affine AffineFromRot(Vec2 r); +Affine AffineFromAngle(f32 r); Affine AffineFromScale(Vec2 scale); //- Translation @@ -471,10 +472,11 @@ Affine TranslateAffine(Affine af, Vec2 v); Affine WorldTranslateAffine(Affine af, Vec2 v); //- Rotation -Affine RotateAffine(Affine af, f32 r); -Affine WorldRotateAffine(Affine af, f32 r); -Affine WorldRotateAffineBasis(Affine af, f32 r); -Affine AffineWithWorldRotation(Affine af, f32 r); +Affine RotateAffine(Affine af, Vec2 r); +Affine RotateAffineAngle(Affine af, f32 r); +Affine WorldRotateAffineAngle(Affine af, f32 r); +Affine WorldRotateAffineBasisAngle(Affine af, f32 r); +Affine AffineWithWorldRotationAngle(Affine af, f32 r); //- Scale Affine ScaleAffine(Affine af, Vec2 scale); @@ -494,13 +496,14 @@ Vec2 InvertAffineMulVec2(Affine af, Vec2 v); Vec2 InvertAffineBasisMulVec2(Affine af, Vec2 v); //- Helpers +Affine AffineFromXform(Xform xf); Affine BasisFromAffine(Affine af); f32 DeterminantFromAffine(Affine af); Vec2 RightFromAffine(Affine af); Vec2 LeftFromAffine(Affine af); Vec2 UpFromAffine(Affine af); Vec2 DownFromAffine(Affine af); -f32 RotationFromAffine(Affine af); +f32 AngleFromAffine(Affine af); Vec2 ScaleFromAffine(Affine af); //////////////////////////////////////////////////////////// @@ -509,6 +512,8 @@ Vec2 ScaleFromAffine(Affine af); #define XformIdentity ((Xform) { .r = { 1, 0 } }) #define CompXformIdentity { .r = { 1, 0 } } +Xform NormXform(Xform xf); +Xform InvertXform(Xform xf); Vec2 MulXformVec2(Xform xf, Vec2 v); //////////////////////////////////////////////////////////// diff --git a/src/pp/pp.c b/src/pp/pp.c index 2c549619..0ff109e7 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -2,6 +2,7 @@ P_Ctx P = Zi; ThreadLocal P_ThreadLocalCtx P_tl = Zi; Readonly P_Ent P_NilEnt = { + .prev_xf = CompXformIdentity, .xf = CompXformIdentity, .control.look = { 1, 0 }, }; @@ -1455,6 +1456,8 @@ void P_SpawnEntsFromList(P_Frame *frame, P_EntList ents) P_Ent *old_prev_in_bin = dst->prev_in_bin; { *dst = *src; + dst->prev_xf = NormXform(dst->prev_xf); + dst->xf = NormXform(dst->xf); } dst->next = old_next; dst->prev = old_prev; @@ -2405,7 +2408,7 @@ void P_StepFrame(P_Frame *frame) { Xform xf = ent->xf; xf.t = AddVec2(xf.t, MulVec2(ent->solved_v, solver_dt)); - xf.r = RotateVec2(xf.r, ent->solved_w * solver_dt); + xf.r = RotateVec2Angle(xf.r, ent->solved_w * solver_dt); ent->xf = xf; } } diff --git a/src/pp/pp_res/sprite/bla3.ase b/src/pp/pp_res/sprite/bla3.ase index b2b983dd..57643010 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:cf51d5fb9a66ee01c0edcecf71b59285ad09c7bffdfe6d9cc1636e78e3afbac4 -size 3059 +oid sha256:cc11f5a97d6241a307d38f68b088ca5a68b44f0b597a7c7f92c1c9e0d2c66c3d +size 3058 diff --git a/src/pp/pp_sim/pp_sim_core.c b/src/pp/pp_sim/pp_sim_core.c index 0bdfd354..e36473f3 100644 --- a/src/pp/pp_sim/pp_sim_core.c +++ b/src/pp/pp_sim/pp_sim_core.c @@ -617,15 +617,6 @@ void S_TickForever(WaveLaneCtx *lane) dummy->exists = 1; dummy->guy = guy->key; P_SetEntString(dummy, Lit("Dummy")); - - // P_Ent *ent = P_PushTempEnt(frame_arena, &ents); - // *ent = P_NilEnt; - // ent->key = msg->key; - // ent->xf = msg->xf; - // ent->is_guy = 1; - // ent->is_dummy = 1; - // ent->has_weapon = 1; - // ent->exists = 1; } P_SpawnEntsFromList(world_frame, ents); } break; diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index aa28ba89..f7584cb9 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -959,7 +959,7 @@ void V_TickForever(WaveLaneCtx *lane) frame->shade_cursor = MulAffineVec2(frame->af.screen_to_shade, frame->screen_cursor); frame->world_cursor = MulAffineVec2(frame->af.screen_to_world, frame->screen_cursor); - b32 show_editor_ui = TweakBool("Show editor UI", 1); + b32 show_editor_ui = TweakBool("Show editor UI", 0); frame->world_selection_start = frame->world_cursor; if (frame->is_editing) @@ -1834,50 +1834,57 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Push guy quads - // 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); + 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); - // SPR_Slice body_slice = SPR_SliceFromSheet(anim.sheet, anim.span, anim.frame_seq); - - // if (body_slice.ready) - // { - // Affine body_to_world_af = AffineIdentity; - // { - // // FIXME: Use origin ray - // Vec2 world_dims = DivVec2(body_slice.dims, P_CellsPerMeter); - // body_to_world_af.og = ent->af.og; - // // body_to_world_af.og = SubVec2(body_to_world_af.og, MulVec2(world_dims, 0.25)); - // body_to_world_af = AffineWithWorldRotation(body_to_world_af, AngleFromVec2(ent->control.look)); - // body_to_world_af = TranslateAffine(body_to_world_af, MulVec2(world_dims, -0.5)); - // body_to_world_af = ScaleAffine(body_to_world_af, world_dims); - // } - - // // Push body quad - // { - // 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->uv_rect = body_slice.uv_rect; - // } - // } + SPR_Slice body_slice = SPR_SliceFromSheet(anim.sheet, anim.span, anim.frame_seq); - // // SPR_Slice wep_slice = SPR_FrameFromSheet(anim.weapon_sheet, anim.span, anim.frame_seq); - // // Affine wep_to_world_af = AffineIdentity; - // // { - // // } - // // // Push weapon quad - // // { - // // V_Quad *quad = PushStruct(frame->quads_arena, V_Quad); - // // quad->af = MulAffine(frame->af.world_to_shade, wep_to_world_af); - // // quad->slice = wep_sframe.slice; - // // } - // } - // } + + if (body_slice.ready) + { + 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); + } + + // Push body quad + { + 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; + } + } + } + } diff --git a/src/pp/pp_vis/pp_vis_gpu.g b/src/pp/pp_vis/pp_vis_gpu.g index b0e55b6b..28b91924 100644 --- a/src/pp/pp_vis/pp_vis_gpu.g +++ b/src/pp/pp_vis/pp_vis_gpu.g @@ -91,7 +91,7 @@ VertexShader(V_QuadVS, V_QuadPSInput) Vec2 rect_uv = RectUvFromIdx(SV_VertexID); Vec2 shade_pos = mul(quad.to_shade_af, Vec3(rect_uv, 1)); - Vec2 tex_uv = lerp(quad.uv_rect.p0, quad.uv_rect.p1, rect_uv); + Vec2 tex_uv = lerp(quad.tex_rect_uv.p0, quad.tex_rect_uv.p1, rect_uv); // Vec2 shade_pos = lerp(quad.p0, quad.p1, rect_uv); V_QuadPSInput result; @@ -112,10 +112,10 @@ PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input) V_Quad quad = quads[input.quad_idx]; - // Texture2D tex = G_Dereference(quad.tex); - // Vec4 albedo = tex.Sample(clamp_sampler, input.tex_uv); + Texture2D tex = G_Dereference(quad.tex); + Vec4 albedo = tex.Sample(clamp_sampler, input.tex_uv); - Vec4 albedo = Color_Cyan; + // Vec4 albedo = Color_Cyan; V_QuadPSOutput output; output.sv_target0 = albedo; diff --git a/src/pp/pp_vis/pp_vis_shared.cgh b/src/pp/pp_vis/pp_vis_shared.cgh index 84539167..efdc05ac 100644 --- a/src/pp/pp_vis/pp_vis_shared.cgh +++ b/src/pp/pp_vis/pp_vis_shared.cgh @@ -185,7 +185,7 @@ Struct(V_Quad) V_QuadFlag flags; Affine to_shade_af; G_Texture2DRef tex; - Rng2 uv_rect; + Rng2 tex_rect_uv; }; //////////////////////////////////////////////////////////// diff --git a/src/sprite/sprite.c b/src/sprite/sprite.c index d1dbd433..1c8a211e 100644 --- a/src/sprite/sprite.c +++ b/src/sprite/sprite.c @@ -383,7 +383,7 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame) //- Composite ASE_Image composite = ASE_PushBlankImage(frame_arena, slice->bounds); - for (ASE_Layer *ase_layer = sheet->meta.last_layer; ase_layer; ase_layer = ase_layer->prev) + for (ASE_Layer *ase_layer = sheet->meta.first_layer; ase_layer; ase_layer = ase_layer->next) { SPR_LayerKind kind = SPR_LayerKindFromName(ase_layer->name); if (kind == SPR_LayerKind_Visual)