weapon animation wip

This commit is contained in:
jacob 2026-01-31 07:06:05 -06:00
parent 253670856a
commit ecb115a540
6 changed files with 214 additions and 42 deletions

View File

@ -592,10 +592,10 @@ ASE_Meta ASE_DecodeMeta(Arena *arena, String encoded)
if (allowed) if (allowed)
{ {
ASE_Cel *cel = &layer->cels[chunk->cel.frame_idx]; ASE_Cel *cel = &layer->cels[chunk->cel.frame_idx];
// Original cel properties // Original cel chunk properties
cel->frame_idx = chunk->cel.frame_idx; cel->frame_idx = chunk->cel.frame_idx;
cel->linked_frame_idx = linked_chunk->cel.frame_idx; cel->linked_frame_idx = linked_chunk->cel.frame_idx;
// Linked cel properties // Linked cel chunk properties
cel->opacity = linked_chunk->opacity; cel->opacity = linked_chunk->opacity;
cel->frame_idx = linked_chunk->cel.frame_idx; cel->frame_idx = linked_chunk->cel.frame_idx;
cel->encoded = linked_chunk->cel.encoded; cel->encoded = linked_chunk->cel.encoded;

BIN
src/pp/pp_res/sprite/bla3.ase (Stored with Git LFS)

Binary file not shown.

View File

@ -447,7 +447,7 @@ void S_TickForever(WaveLaneCtx *lane)
{ {
i64 alive_time_ns = time_ns - dummy->created_at_ns; i64 alive_time_ns = time_ns - dummy->created_at_ns;
i64 frequency_ns = NsFromSeconds(0.1); i64 frequency_ns = NsFromSeconds(0.1);
dummy->control.move.x = SinF32((f64)alive_time_ns / (f64)frequency_ns); dummy->control.move.y = SinF32((f64)alive_time_ns / (f64)frequency_ns);
} }
else else
{ {

View File

@ -1834,54 +1834,133 @@ void V_TickForever(WaveLaneCtx *lane)
////////////////////////////// //////////////////////////////
//- Push guy quads //- Push guy quads
for (P_Ent *ent = P_FirstEnt(local_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) for (P_Ent *ent = P_FirstEnt(local_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
{ {
if (ent->is_guy) if (ent->is_guy)
{ {
P_Anim anim = P_AnimFromEnt(ent, local_frame->time_ns); 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); 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;
if (body_slice.ready)
{ {
Affine body_to_world_af = AffineIdentity; Vec2 body_slice_dims = DimsFromRng2(body_slice.bounds);
{
Vec2 pix_dims = DimsFromRng2(body_slice.bounds);
Vec2 world_dims = DivVec2(pix_dims, P_CellsPerMeter);
Xform origin_ray = body_slice.rays[SPR_RayKind_Origin]; Xform origin_to_slice_corner_xf = body_slice.rays[SPR_RayKind_Origin];
origin_ray.t = SubVec2(origin_ray.t, body_slice.bounds.p0); origin_to_slice_corner_xf.t = SubVec2(origin_to_slice_corner_xf.t, body_slice.bounds.p0);
origin_ray = InvertXform(origin_ray); origin_to_slice_corner_xf = InvertXform(origin_to_slice_corner_xf);
Affine origin_to_body_af = AffineIdentity; Xform ap_to_slice_corner_xf = body_slice.rays[SPR_RayKind_Ap];
origin_to_body_af = ScaleAffine(origin_to_body_af, DivVec2Vec2(VEC2(1.0, 1.0), pix_dims)); ap_to_slice_corner_xf.t = SubVec2(ap_to_slice_corner_xf.t, body_slice.bounds.p0);
origin_to_body_af = RotateAffine(origin_to_body_af, origin_ray.r); ap_to_slice_corner_xf = InvertXform(ap_to_slice_corner_xf);
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_ap_to_origin_xf = MulXform(InvertXform(origin_to_slice_corner_xf), ap_to_slice_corner_xf);
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 // FIXME: Remove this
ent_xf.r = ent->control.look; {
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_to_world_af = MulAffine(AffineFromXform(ent_xf), body_to_ent_af); body_ap_to_origin_xf.t = AddVec2(b.t, a.t);
} }
// Push body quad 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); V_Quad *quad = PushStruct(frame->quads_arena, V_Quad);
quad->to_shade_af = MulAffine(frame->af.world_to_shade, body_to_world_af); quad->to_shade_af = MulAffine(frame->af.world_to_shade, body_slice_to_world_af);
quad->tex = body_slice.tex; quad->tex = body_slice.tex;
quad->tex_rect_uv = body_slice.tex_rect_uv; 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;
} }
} }
} }
@ -1890,6 +1969,94 @@ 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);
// //- 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 //- Push test bullet particles

View File

@ -297,17 +297,18 @@ SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 f
SPR_Slice result = Zi; SPR_Slice result = Zi;
{ {
result.exists = span_matched; b32 slice_ready = 0;
if (result.exists) if (sheet->ok)
{ {
i64 completion = G_CompletionValueFromQueue(G_QueueKind_AsyncCopy); i64 completion = G_CompletionValueFromQueue(G_QueueKind_AsyncCopy);
if (completion >= Atomic64Fetch(&slice->atlas_copy_completion_target)) if (completion >= Atomic64Fetch(&slice->atlas_copy_completion_target))
{ {
result.ready = 1; slice_ready = 1;
} }
} }
// Fill tex info // Fill tex info
if (result.ready) if (slice_ready)
{ {
result.tex = slice->atlas->tex_ref; result.tex = slice->atlas->tex_ref;
result.tex_rect_uv = slice->atlas_rect_uv; result.tex_rect_uv = slice->atlas_rect_uv;
@ -319,9 +320,13 @@ SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 f
result.tex_rect_uv = RNG2(VEC2(0, 0), VEC2(1, 1)); result.tex_rect_uv = RNG2(VEC2(0, 0), VEC2(1, 1));
result.bounds = RNG2(VEC2(0, 0), SPR.unready_tex_dims); result.bounds = RNG2(VEC2(0, 0), SPR.unready_tex_dims);
} }
// Fill rays // Fill rays
StaticAssert(countof(result.rays) == countof(slice->rays)); StaticAssert(countof(result.rays) == countof(slice->rays));
CopyStructs(result.rays, slice->rays, countof(result.rays)); CopyStructs(result.rays, slice->rays, countof(result.rays));
result.matched = span_matched;
result.ready = slice_ready;
} }
return result; return result;

View File

@ -57,7 +57,7 @@ Struct(SPR_Slice)
Rng2 tex_rect_uv; Rng2 tex_rect_uv;
Rng2 bounds; Rng2 bounds;
b32 exists; b32 matched;
b32 ready; b32 ready;
}; };