weapon animation wip
This commit is contained in:
parent
ecb115a540
commit
da643646a8
@ -389,6 +389,11 @@ Vec2 DivVec2Vec2(Vec2 a, Vec2 b)
|
||||
return VEC2(a.x * (1 / b.x), a.y * (1 / b.y));
|
||||
}
|
||||
|
||||
Vec2 RecipVec2(Vec2 a)
|
||||
{
|
||||
return VEC2(1.0 / a.x, 1.0 / a.y);
|
||||
};
|
||||
|
||||
//- Add
|
||||
|
||||
Vec2 AddVec2(Vec2 a, Vec2 b)
|
||||
@ -879,7 +884,7 @@ Affine TranslateAffine(Affine af, Vec2 v)
|
||||
return af;
|
||||
}
|
||||
|
||||
Affine WorldTranslateAffine(Affine af, Vec2 v)
|
||||
Affine PreTranslateAffine(Affine af, Vec2 v)
|
||||
{
|
||||
af.og = AddVec2(af.og, v);
|
||||
return af;
|
||||
@ -897,26 +902,16 @@ Affine RotateAffineAngle(Affine af, f32 r)
|
||||
return MulAffine(af, AffineFromAngle(r));
|
||||
}
|
||||
|
||||
Affine WorldRotateAffineAngle(Affine af, f32 r)
|
||||
Affine PreRotateAffine(Affine af, Vec2 r)
|
||||
{
|
||||
return MulAffine(AffineFromRot(r), af);
|
||||
}
|
||||
|
||||
Affine PreRotateAffineAngle(Affine af, f32 r)
|
||||
{
|
||||
return MulAffine(AffineFromAngle(r), af);
|
||||
}
|
||||
|
||||
Affine WorldRotateAffineBasisAngle(Affine af, f32 r)
|
||||
{
|
||||
f32 diff = r;
|
||||
f32 c = CosF32(diff);
|
||||
f32 s = SinF32(diff);
|
||||
af.bx = VEC2(af.bx.x * c - af.bx.y * s, af.bx.x * s + af.bx.y * c);
|
||||
af.by = VEC2(af.by.x * c - af.by.y * s, af.by.x * s + af.by.y * c);
|
||||
return af;
|
||||
}
|
||||
|
||||
Affine AffineWithWorldRotationAngle(Affine af, f32 r)
|
||||
{
|
||||
return WorldRotateAffineBasisAngle(af, r - AngleFromAffine(af));
|
||||
}
|
||||
|
||||
//- Scale
|
||||
|
||||
Affine ScaleAffine(Affine af, Vec2 scale)
|
||||
@ -926,7 +921,7 @@ Affine ScaleAffine(Affine af, Vec2 scale)
|
||||
return af;
|
||||
}
|
||||
|
||||
Affine WorldScaleAffine(Affine af, Vec2 scale)
|
||||
Affine PreScaleAffine(Affine af, Vec2 scale)
|
||||
{
|
||||
Affine result;
|
||||
result.bx = MulVec2Vec2(af.bx, scale);
|
||||
@ -993,21 +988,6 @@ Vec2 MulAffineVec2(Affine af, Vec2 v)
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Vec2 InvertAffineBasisMulVec2(Affine af, Vec2 v)
|
||||
{
|
||||
Affine inv = InvertAffine(af);
|
||||
Vec2 result = MulAffineBasisVec2(inv, v);
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO: Get rid of this? Just force caller to use invert manually since it's expensive.
|
||||
Vec2 InvertAffineMulVec2(Affine af, Vec2 v)
|
||||
{
|
||||
Affine inv = InvertAffine(af);
|
||||
return MulAffineVec2(inv, v);
|
||||
}
|
||||
|
||||
//- Helpers
|
||||
|
||||
Affine AffineFromXform(Xform xf)
|
||||
|
||||
@ -356,6 +356,7 @@ Vec2 NegVec2(Vec2 a);
|
||||
//- Div
|
||||
Vec2 DivVec2(Vec2 a, f32 s);
|
||||
Vec2 DivVec2Vec2(Vec2 a, Vec2 b);
|
||||
Vec2 RecipVec2(Vec2 a);
|
||||
|
||||
//- Add
|
||||
Vec2 AddVec2(Vec2 a, Vec2 b);
|
||||
@ -469,18 +470,17 @@ Affine AffineFromScale(Vec2 scale);
|
||||
|
||||
//- Translation
|
||||
Affine TranslateAffine(Affine af, Vec2 v);
|
||||
Affine WorldTranslateAffine(Affine af, Vec2 v);
|
||||
Affine PreTranslateAffine(Affine af, Vec2 v);
|
||||
|
||||
//- Rotation
|
||||
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);
|
||||
Affine PreRotateAffine(Affine af, Vec2 r);
|
||||
Affine PreRotateAffineAngle(Affine af, f32 r);
|
||||
|
||||
//- Scale
|
||||
Affine ScaleAffine(Affine af, Vec2 scale);
|
||||
Affine WorldScaleAffine(Affine af, Vec2 scale);
|
||||
Affine PreScaleAffine(Affine af, Vec2 scale);
|
||||
|
||||
//- Lerp
|
||||
Affine LerpAffine(Affine a, Affine b, f32 t);
|
||||
@ -492,8 +492,6 @@ Affine InvertAffine(Affine af);
|
||||
Vec2 MulAffineVec2(Affine af, Vec2 v);
|
||||
Affine MulAffine(Affine a, Affine b);
|
||||
Vec2 MulAffineBasisVec2(Affine af, Vec2 v);
|
||||
Vec2 InvertAffineMulVec2(Affine af, Vec2 v);
|
||||
Vec2 InvertAffineBasisMulVec2(Affine af, Vec2 v);
|
||||
|
||||
//- Helpers
|
||||
Affine AffineFromXform(Xform xf);
|
||||
|
||||
BIN
src/pp/pp_res/sprite/bla3.ase
(Stored with Git LFS)
BIN
src/pp/pp_res/sprite/bla3.ase
(Stored with Git LFS)
Binary file not shown.
BIN
src/pp/pp_res/sprite/raah.ase
(Stored with Git LFS)
BIN
src/pp/pp_res/sprite/raah.ase
(Stored with Git LFS)
Binary file not shown.
@ -827,17 +827,17 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
b32 should_zoom = prev_frame->zooms != 0 && (frame->edit_camera_zoom != prev_frame->edit_camera_zoom);
|
||||
if (prev_frame->is_editing && (should_zoom || (frame->is_panning && prev_frame->is_panning)))
|
||||
{
|
||||
Affine prev_frame_edit_to_screen_af = Zi;
|
||||
Affine edit_to_screen_af = Zi;
|
||||
Affine prev_frame_edit_to_screen_af = AffineIdentity;
|
||||
Affine edit_to_screen_af = AffineIdentity;
|
||||
{
|
||||
f32 prev_edit_camera_scale = (f32)prev_frame->screen_dims.x / (meters_per_camera_width * prev_frame->edit_camera_zoom);
|
||||
f32 edit_camera_scale = (f32)frame->screen_dims.x / (meters_per_camera_width * frame->edit_camera_zoom);
|
||||
prev_frame_edit_to_screen_af = AffineFromScale(VEC2(prev_edit_camera_scale, prev_edit_camera_scale));
|
||||
prev_frame_edit_to_screen_af = TranslateAffine(prev_frame_edit_to_screen_af, MulVec2(Vec2FromVec(frame->screen_dims), 0.5));
|
||||
prev_frame_edit_to_screen_af = ScaleAffine(prev_frame_edit_to_screen_af, VEC2(prev_edit_camera_scale, prev_edit_camera_scale));
|
||||
prev_frame_edit_to_screen_af = TranslateAffine(prev_frame_edit_to_screen_af, NegVec2(prev_frame->edit_camera_pos));
|
||||
prev_frame_edit_to_screen_af = WorldTranslateAffine(prev_frame_edit_to_screen_af, MulVec2(Vec2FromVec(frame->screen_dims), 0.5));
|
||||
edit_to_screen_af = AffineFromScale(VEC2(edit_camera_scale, edit_camera_scale));
|
||||
edit_to_screen_af = TranslateAffine(edit_to_screen_af, MulVec2(Vec2FromVec(frame->screen_dims), 0.5));
|
||||
edit_to_screen_af = ScaleAffine(edit_to_screen_af, VEC2(edit_camera_scale, edit_camera_scale));
|
||||
edit_to_screen_af = TranslateAffine(edit_to_screen_af, NegVec2(frame->edit_camera_pos));
|
||||
edit_to_screen_af = WorldTranslateAffine(edit_to_screen_af, MulVec2(Vec2FromVec(frame->screen_dims), 0.5));
|
||||
}
|
||||
Vec2 prev_target_cursor = MulAffineVec2(InvertAffine(prev_frame_edit_to_screen_af), prev_frame->screen_cursor);
|
||||
Vec2 target_cursor = MulAffineVec2(InvertAffine(edit_to_screen_af), ui_frame->cursor_pos);
|
||||
@ -905,9 +905,9 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
frame->af.screen_to_world = AffineIdentity;
|
||||
{
|
||||
f32 camera_scale = frame->screen_dims.x / (meters_per_camera_width * frame->camera_zoom);
|
||||
frame->af.world_to_screen = AffineFromScale(VEC2(camera_scale, camera_scale));
|
||||
frame->af.world_to_screen = TranslateAffine(frame->af.world_to_screen, MulVec2(frame->screen_dims, 0.5));
|
||||
frame->af.world_to_screen = ScaleAffine(frame->af.world_to_screen, VEC2(camera_scale, camera_scale));
|
||||
frame->af.world_to_screen = TranslateAffine(frame->af.world_to_screen, NegVec2(frame->camera_pos));
|
||||
frame->af.world_to_screen = WorldTranslateAffine(frame->af.world_to_screen, MulVec2(frame->screen_dims, 0.5));
|
||||
frame->af.world_to_screen.og = RoundVec2(frame->af.world_to_screen.og);
|
||||
frame->af.screen_to_world = InvertAffine(frame->af.world_to_screen);
|
||||
}
|
||||
@ -917,9 +917,9 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
frame->af.shade_to_world = AffineIdentity;
|
||||
{
|
||||
f32 camera_scale = (frame->shade_dims.x - shade_extra_dims.x) / (meters_per_camera_width * frame->camera_zoom);
|
||||
frame->af.world_to_shade = AffineFromScale(VEC2(camera_scale, camera_scale));
|
||||
frame->af.world_to_shade = TranslateAffine(frame->af.world_to_shade, MulVec2(frame->shade_dims, 0.5));
|
||||
frame->af.world_to_shade = ScaleAffine(frame->af.world_to_shade, VEC2(camera_scale, camera_scale));
|
||||
frame->af.world_to_shade = TranslateAffine(frame->af.world_to_shade, NegVec2(frame->camera_pos));
|
||||
frame->af.world_to_shade = WorldTranslateAffine(frame->af.world_to_shade, MulVec2(frame->shade_dims, 0.5));
|
||||
frame->af.world_to_shade.og = RoundVec2(frame->af.world_to_shade.og);
|
||||
frame->af.shade_to_world = InvertAffine(frame->af.world_to_shade);
|
||||
}
|
||||
@ -1836,6 +1836,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
|
||||
|
||||
|
||||
for (P_Ent *ent = P_FirstEnt(local_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
|
||||
{
|
||||
if (ent->is_guy)
|
||||
@ -1845,125 +1846,175 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
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;
|
||||
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;
|
||||
{
|
||||
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 anchor_to_body_xf = InvertXform(body.rays[SPR_RayKind_Anchor]);
|
||||
|
||||
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_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_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);
|
||||
}
|
||||
Affine body_origin_to_ent_af = AffineIdentity;
|
||||
|
||||
//- 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)
|
||||
if (body.ready)
|
||||
{
|
||||
Affine body_slice_to_world_af = MulAffine(AffineFromXform(ent_xf), body_slice_to_ent_af);
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//- 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);
|
||||
|
||||
// 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;
|
||||
// // }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
@ -4439,8 +4490,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
V_TileDesc tile_desc = Zi;
|
||||
{
|
||||
tile_desc.tex_slice_uv = tile_slice.tex_rect_uv;
|
||||
tile_desc.tex = tile_slice.tex;
|
||||
tile_desc.tex_slice_uv = DivRng2Vec2(tile_slice.tex_rect, tile_slice.tex_dims);
|
||||
}
|
||||
params.tile_descs[tile_kind] = tile_desc;
|
||||
}
|
||||
|
||||
@ -89,15 +89,15 @@ VertexShader(V_QuadVS, V_QuadPSInput)
|
||||
V_Quad quad = quads[SV_InstanceID];
|
||||
|
||||
Vec2 rect_uv = RectUvFromIdx(SV_VertexID);
|
||||
Vec2 shade_pos = mul(quad.to_shade_af, Vec3(rect_uv, 1));
|
||||
Vec2 shade_pos = mul(quad.quad_uv_to_shade_af, Vec3(rect_uv, 1));
|
||||
|
||||
Vec2 tex_uv = lerp(quad.tex_rect_uv.p0, quad.tex_rect_uv.p1, rect_uv);
|
||||
Vec2 tex_pos_uv = lerp(quad.tex_slice_uv.p0, quad.tex_slice_uv.p1, rect_uv);
|
||||
// Vec2 shade_pos = lerp(quad.p0, quad.p1, rect_uv);
|
||||
|
||||
V_QuadPSInput result;
|
||||
result.sv_position = Vec4(NdcFromPos(shade_pos, params.shade_dims).xy, 0, 1);
|
||||
result.quad_idx = SV_InstanceID;
|
||||
result.tex_uv = tex_uv;
|
||||
result.tex_pos_uv = tex_pos_uv;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input)
|
||||
V_Quad quad = quads[input.quad_idx];
|
||||
|
||||
Texture2D<Vec4> tex = G_Dereference<Vec4>(quad.tex);
|
||||
Vec4 albedo = tex.Sample(clamp_sampler, input.tex_uv);
|
||||
Vec4 albedo = tex.Sample(clamp_sampler, input.tex_pos_uv);
|
||||
|
||||
// Vec4 albedo = Color_Cyan;
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ Struct(V_QuadPSInput)
|
||||
{
|
||||
Semantic(Vec4, sv_position);
|
||||
Semantic(nointerpolation u32, quad_idx);
|
||||
Semantic(Vec2, tex_uv);
|
||||
Semantic(Vec2, tex_pos_uv);
|
||||
};
|
||||
|
||||
Struct(V_QuadPSOutput)
|
||||
|
||||
@ -48,8 +48,8 @@ Struct(V_Affines)
|
||||
|
||||
Struct(V_TileDesc)
|
||||
{
|
||||
Rng2 tex_slice_uv;
|
||||
G_Texture2DRef tex;
|
||||
Rng2 tex_slice_uv;
|
||||
};
|
||||
|
||||
Struct(V_GpuState)
|
||||
@ -183,9 +183,9 @@ Enum(V_QuadFlag)
|
||||
Struct(V_Quad)
|
||||
{
|
||||
V_QuadFlag flags;
|
||||
Affine to_shade_af;
|
||||
Affine quad_uv_to_shade_af;
|
||||
G_Texture2DRef tex;
|
||||
Rng2 tex_rect_uv;
|
||||
Rng2 tex_slice_uv;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@ -5,6 +5,8 @@ SPR_Ctx SPR = Zi;
|
||||
|
||||
void SPR_Bootstrap(void)
|
||||
{
|
||||
// FIXME: Initialize nil/unready sprite texture here
|
||||
|
||||
OnAsyncTick(SPR_TickAsync);
|
||||
}
|
||||
|
||||
@ -107,7 +109,7 @@ SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 f
|
||||
for (i64 slice_idx = 0; slice_idx < sheet->slices_count; ++slice_idx)
|
||||
{
|
||||
SPR_SliceEntry *slice = &sheet->slices[slice_idx];
|
||||
slice->bounds = Rng2Empty;
|
||||
slice->canvas_rect = Rng2Empty;
|
||||
Atomic64Set(&slice->atlas_copy_completion_target, I64Max);
|
||||
for (SPR_RayKind ray_kind = 0; ray_kind < SPR_RayKind_COUNT; ++ray_kind)
|
||||
{
|
||||
@ -115,7 +117,7 @@ SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 f
|
||||
}
|
||||
}
|
||||
|
||||
//- Compute slice bounds
|
||||
//- Compute slice rect
|
||||
for (ASE_Layer *ase_layer = sheet->meta.first_layer; ase_layer; ase_layer = ase_layer->next)
|
||||
{
|
||||
SPR_LayerKind kind = SPR_LayerKindFromName(ase_layer->name);
|
||||
@ -125,7 +127,7 @@ SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 f
|
||||
{
|
||||
ASE_Cel *cel = &ase_layer->cels[slice_idx];
|
||||
SPR_SliceEntry *slice = &sheet->slices[slice_idx];
|
||||
slice->bounds = UnionRng2(slice->bounds, cel->bounds);
|
||||
slice->canvas_rect = UnionRng2(slice->canvas_rect, cel->bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -139,7 +141,7 @@ SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 f
|
||||
for (i64 slice_idx = 0; slice_idx < sheet->meta.frames_count; ++slice_idx)
|
||||
{
|
||||
SPR_SliceEntry *slice = &sheet->slices[slice_idx];
|
||||
if (!IsRng2Empty(slice->bounds))
|
||||
if (!IsRng2Empty(slice->canvas_rect))
|
||||
{
|
||||
SPR_CmdNode *cmd_node = SPR.submit.first_free;
|
||||
if (cmd_node)
|
||||
@ -194,7 +196,7 @@ SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 f
|
||||
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 = ase_cel->bounds.p0;
|
||||
slice->rays[ray_kind].t = SubVec2(ase_cel->bounds.p0, slice->canvas_rect.p0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -310,15 +312,15 @@ SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 f
|
||||
// Fill tex info
|
||||
if (slice_ready)
|
||||
{
|
||||
result.tex_dims = Vec2FromVec(slice->atlas->dims);
|
||||
result.tex = slice->atlas->tex_ref;
|
||||
result.tex_rect_uv = slice->atlas_rect_uv;
|
||||
result.bounds = slice->bounds;
|
||||
result.tex_rect = RNG2(slice->atlas_pos, AddVec2(slice->atlas_pos, DimsFromRng2(slice->canvas_rect)));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.tex_dims = SPR.unready_tex_dims;
|
||||
result.tex = SPR.unready_tex;
|
||||
result.tex_rect_uv = RNG2(VEC2(0, 0), VEC2(1, 1));
|
||||
result.bounds = RNG2(VEC2(0, 0), SPR.unready_tex_dims);
|
||||
result.tex_rect = RNG2(VEC2(0, 0), SPR.unready_tex_dims);
|
||||
}
|
||||
|
||||
// Fill rays
|
||||
@ -382,12 +384,12 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
||||
// LogInfoF("Rasterizing sprite sheet %F \"%F\" (%F bytes)", FmtHandle(sheet->key.r), FmtString(name), FmtUint(encoded.len));
|
||||
|
||||
SPR_SliceEntry *slice = &sheet->slices[cmd->slice_idx];
|
||||
Vec2 slice_dims = DimsFromRng2(slice->bounds);
|
||||
Vec2 slice_dims = DimsFromRng2(slice->canvas_rect);
|
||||
|
||||
//////////////////////////////
|
||||
//- Composite
|
||||
|
||||
ASE_Image composite = ASE_PushBlankImage(frame_arena, slice->bounds);
|
||||
ASE_Image composite = ASE_PushBlankImage(frame_arena, slice->canvas_rect);
|
||||
for (ASE_Layer *ase_layer = sheet->meta.first_layer; ase_layer; ase_layer = ase_layer->next)
|
||||
{
|
||||
SPR_LayerKind kind = SPR_LayerKindFromName(ase_layer->name);
|
||||
@ -412,7 +414,7 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
||||
// TODO: Use a more efficient atlas packing algorithm for less wasted space
|
||||
SPR_Atlas *atlas = SPR.first_atlas;
|
||||
b32 can_use_atlas = 0;
|
||||
Vec2I32 pos_in_atlas = Zi;
|
||||
Vec2I32 atlas_pos = Zi;
|
||||
while (can_use_atlas == 0)
|
||||
{
|
||||
// Create atlas
|
||||
@ -435,9 +437,9 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
||||
++SPR.atlases_count;
|
||||
}
|
||||
// Determine pos in atlas
|
||||
pos_in_atlas = atlas->cur_pos;
|
||||
atlas_pos = atlas->cur_pos;
|
||||
atlas->cur_row_height = MaxI32(atlas->cur_row_height, slice_dims.y);
|
||||
if (pos_in_atlas.x + slice_dims.x > atlas->dims.x);
|
||||
if (atlas_pos.x + slice_dims.x > atlas->dims.x);
|
||||
{
|
||||
atlas->cur_pos.x = 0;
|
||||
atlas->cur_pos.y += atlas->cur_row_height;
|
||||
@ -456,18 +458,14 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
||||
|
||||
// Fill slice_entry atlas info
|
||||
{
|
||||
Rng2I32 atlas_rect = RNG2I32(pos_in_atlas, AddVec2I32(pos_in_atlas, Vec2I32FromVec(slice_dims)));
|
||||
slice->atlas = atlas;
|
||||
slice->atlas_rect_uv.p0.x = (f32)atlas_rect.p0.x / (f32)atlas->dims.x;
|
||||
slice->atlas_rect_uv.p0.y = (f32)atlas_rect.p0.y / (f32)atlas->dims.x;
|
||||
slice->atlas_rect_uv.p1.x = (f32)atlas_rect.p1.x / (f32)atlas->dims.x;
|
||||
slice->atlas_rect_uv.p1.y = (f32)atlas_rect.p1.y / (f32)atlas->dims.x;
|
||||
slice->atlas_pos = Vec2FromVec(atlas_pos);
|
||||
}
|
||||
|
||||
// Copy to atlas
|
||||
G_CopyCpuToTexture(
|
||||
cl,
|
||||
atlas->tex, VEC3I32(pos_in_atlas.x, pos_in_atlas.y, 0),
|
||||
atlas->tex, VEC3I32(atlas_pos.x, atlas_pos.y, 0),
|
||||
composite.pixels, VEC3I32(slice_dims.x, slice_dims.y, 1),
|
||||
RNG3I32(
|
||||
VEC3I32(0, 0, 0),
|
||||
|
||||
@ -25,7 +25,7 @@ Struct(SPR_Atlas)
|
||||
//~ Ray types
|
||||
|
||||
#define SPR_RayKindXMacro(X) \
|
||||
X(Origin, .origin) \
|
||||
X(Anchor, .anchor) \
|
||||
X(Ap, .ap) \
|
||||
/* ----------------------------- */
|
||||
|
||||
@ -53,9 +53,9 @@ Struct(SPR_Slice)
|
||||
{
|
||||
Xform rays[SPR_RayKind_COUNT];
|
||||
|
||||
Vec2 tex_dims;
|
||||
G_Texture2DRef tex;
|
||||
Rng2 tex_rect_uv;
|
||||
Rng2 bounds;
|
||||
Rng2 tex_rect;
|
||||
|
||||
b32 matched;
|
||||
b32 ready;
|
||||
@ -70,12 +70,12 @@ Struct(SPR_SliceEntry)
|
||||
{
|
||||
SPR_SliceEntry *next_in_bin;
|
||||
|
||||
Rng2 canvas_rect;
|
||||
Xform rays[SPR_RayKind_COUNT];
|
||||
|
||||
SPR_Atlas *atlas;
|
||||
Rng2 atlas_rect_uv;
|
||||
Rng2 bounds;
|
||||
Atomic64 atlas_copy_completion_target;
|
||||
SPR_Atlas *atlas;
|
||||
Vec2 atlas_pos;
|
||||
};
|
||||
|
||||
//- Span
|
||||
|
||||
Loading…
Reference in New Issue
Block a user