diff --git a/src/base/base_math.c b/src/base/base_math.c index d821022a..d7096c75 100644 --- a/src/base/base_math.c +++ b/src/base/base_math.c @@ -535,6 +535,11 @@ Vec2 RotateVec2(Vec2 v, f32 a) return VEC2(v.x * c - v.y * s, v.x * s + v.y * c); } +Vec2 RotateVec2Vec2(Vec2 a, Vec2 b) +{ + return VEC2(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); +} + Vec2 Vec2FromAngle(f32 a) { return VEC2(CosF32(a), SinF32(a)); @@ -837,14 +842,6 @@ Affine AffineFromScale(Vec2 scale) return result; } -Affine AffineFromTrs(Trs trs) -{ - Affine af = AffineFromPos(trs.t); - af = RotateAffine(af, trs.r); - af = ScaleAffine(af, trs.s); - return af; -} - //- Translation Affine TranslateAffine(Affine af, Vec2 v) { @@ -924,7 +921,7 @@ Affine InvertAffine(Affine af) af.bx = MulVec2Vec2(af.bx, VEC2(inv_det, -inv_det)); af.by = MulVec2Vec2(af.by, VEC2(-inv_det, inv_det)); - af.og = MulAffineBasisV2(af, NegVec2(af.og)); + af.og = MulAffineBasisVec2(af, NegVec2(af.og)); return af; } @@ -937,11 +934,11 @@ Affine MulAffine(Affine a, Affine b) result.bx.y = a.bx.y * b.bx.x + a.by.y * b.bx.y; result.by.x = a.bx.x * b.by.x + a.by.x * b.by.y; result.by.y = a.bx.y * b.by.x + a.by.y * b.by.y; - result.og = MulAffineV2(a, b.og); + result.og = MulAffineVec2(a, b.og); return result; } -Vec2 MulAffineBasisV2(Affine af, Vec2 v) +Vec2 MulAffineBasisVec2(Affine af, Vec2 v) { return VEC2( af.bx.x * v.x + af.by.x * v.y, @@ -949,26 +946,26 @@ Vec2 MulAffineBasisV2(Affine af, Vec2 v) ); } -Vec2 MulAffineV2(Affine af, Vec2 v) +Vec2 MulAffineVec2(Affine af, Vec2 v) { - Vec2 result = MulAffineBasisV2(af, v); + Vec2 result = MulAffineBasisVec2(af, v); result = AddVec2(result, af.og); return result; } -Vec2 InvertAffineBasisMulV2(Affine af, Vec2 v) +Vec2 InvertAffineBasisMulVec2(Affine af, Vec2 v) { Affine inv = InvertAffine(af); - Vec2 result = MulAffineBasisV2(inv, v); + Vec2 result = MulAffineBasisVec2(inv, v); return result; } // TODO: Get rid of this? Just force caller to use invert manually since it's expensive. -Vec2 InvertAffineMulV2(Affine af, Vec2 v) +Vec2 InvertAffineMulVec2(Affine af, Vec2 v) { Affine inv = InvertAffine(af); - return MulAffineV2(inv, v); + return MulAffineVec2(inv, v); } //- Helpers @@ -1017,6 +1014,24 @@ Vec2 ScaleFromAffine(Affine af) return VEC2(Vec2Len(af.bx), det_sign * Vec2Len(af.by)); } +//////////////////////////////////////////////////////////// +//~ Xform + +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); + return result; +} + +Vec2 MulXformVec2(Xform xf, Vec2 v) +{ + Vec2 result = Zi; + result = AddVec2(RotateVec2Vec2(v, xf.r), xf.t); + return result; +} + //////////////////////////////////////////////////////////// //~ Spring diff --git a/src/base/base_math.h b/src/base/base_math.h index 5c71fea2..71573665 100644 --- a/src/base/base_math.h +++ b/src/base/base_math.h @@ -151,9 +151,9 @@ Struct(Rng3U64) { Vec3U64 p0, p1; }; Struct(Affine) { - Vec2 bx; // X basis vector (x axis) - Vec2 by; // Y basis vector (y axis) - Vec2 og; // Translation vector (origin) + Vec2 bx; // X basis + Vec2 by; // Y basis + Vec2 og; // Origin }; // (T)ranslation, (R)otation, (S)cale @@ -164,6 +164,15 @@ Struct(Trs) f32 r; }; +//////////////////////////////////////////////////////////// +//~ Xform types + +Struct(Xform) +{ + Vec2 t; // Translation + Vec2 r; // Rotation +}; + //////////////////////////////////////////////////////////// //~ Spring types @@ -375,6 +384,7 @@ Vec2 CeilVec2(Vec2 a); //- Angle i32 WindingFromVec2(Vec2 a, Vec2 b); Vec2 RotateVec2(Vec2 v, f32 a); +Vec2 RotateVec2Vec2(Vec2 a, Vec2 b); Vec2 Vec2FromAngle(f32 a); f32 AngleFromVec2(Vec2 v); f32 AngleFromVec2Dirs(Vec2 dir1, Vec2 dir2); @@ -438,15 +448,15 @@ Rng2I32 DivRng2I32Vec2I32(Rng2I32 a, Vec2I32 v); //////////////////////////////////////////////////////////// //~ Affine +#define AffineIdentity ((Affine) { .bx = { .x = 1 }, .by = { .y = 1 } }) +#define CompAffineIdentity { .bx = { .x = 1 }, .by = { .y = 1 } } + b32 MatchAffine(Affine af1, Affine af2); //- Initialization -#define AffineIdentity (Affine) { .bx = { .x = 1 }, .by = { .y = 1 } } -#define CompAffineIdentity { .bx = { .x = 1 }, .by = { .y = 1 } } Affine AffineFromPos(Vec2 v); Affine AffineFromRot(f32 r); Affine AffineFromScale(Vec2 scale); -Affine AffineFromTrs(Trs trs); //- Translation Affine TranslateAffine(Affine af, Vec2 v); @@ -469,11 +479,11 @@ Affine LerpAffine(Affine a, Affine b, f32 t); Affine InvertAffine(Affine af); //- Mul -Vec2 MulAffineV2(Affine af, Vec2 v); +Vec2 MulAffineVec2(Affine af, Vec2 v); Affine MulAffine(Affine a, Affine b); -Vec2 MulAffineBasisV2(Affine af, Vec2 v); -Vec2 InvertAffineMulV2(Affine af, Vec2 v); -Vec2 InvertAffineBasisMulV2(Affine af, Vec2 v); +Vec2 MulAffineBasisVec2(Affine af, Vec2 v); +Vec2 InvertAffineMulVec2(Affine af, Vec2 v); +Vec2 InvertAffineBasisMulVec2(Affine af, Vec2 v); //- Helpers Affine BasisFromAffine(Affine af); @@ -485,8 +495,13 @@ Vec2 DownFromAffine(Affine af); f32 RotationFromAffine(Affine af); Vec2 ScaleFromAffine(Affine af); -//- Trs -#define TRS(...) ((Trs) { .t = VEC2(0,0), .s = VEC2(1, 1), .r = 0, __VA_ARGS__ }) +//////////////////////////////////////////////////////////// +//~ Xform + +#define XformIdentity ((Xform) { .r = { 1, 0 } }) +#define CompXformIdentity { .r = { 1, 0 } } + +Vec2 MulXformVec2(Xform xf, Vec2 v); //////////////////////////////////////////////////////////// //~ Spring diff --git a/src/collider/collider.c b/src/collider/collider.c index b2085c6d..284722e5 100644 --- a/src/collider/collider.c +++ b/src/collider/collider.c @@ -69,7 +69,7 @@ CLD_SupportPoint CLD_SupportPointFromDirEx(CLD_Shape *shape, Affine af, Vec2 dir furthest = AddVec2(furthest, dir); } - furthest = MulAffineV2(af, furthest); + furthest = MulAffineVec2(af, furthest); CLD_SupportPoint result; result.p = furthest; @@ -919,7 +919,7 @@ CLD_ClosestPointData CLD_ClosestPointDataFromShapes(CLD_Shape *shape0, CLD_Shape //////////////////////////////////////////////////////////// //~ Time of impact -// Takes 2 shapes and their Affines at t=0 and t=1. +// Takes 2 shapes and their affines at t=0 and t=1. // Returns time of impact in range [0, 1]. f32 CLD_TimeOfImpact(CLD_Shape *c0, CLD_Shape *c1, Affine af0_t0, Affine af1_t0, Affine af0_t1, Affine af1_t1, f32 tolerance, u32 max_iterations) { @@ -1031,10 +1031,10 @@ Vec2Array CLD_PointCloud(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Aff u32 count1 = shape1->count; for (u64 i = 0; i < count0; ++i) { - Vec2 p0 = MulAffineV2(af0, points0[i]); + Vec2 p0 = MulAffineVec2(af0, points0[i]); for (u64 j = 0; j < count1; ++j) { - Vec2 p1 = MulAffineV2(af1, points1[j]); + Vec2 p1 = MulAffineVec2(af1, points1[j]); *PushStructNoZero(arena, Vec2) = SubVec2(p0, p1); ++result.count; } diff --git a/src/draw/draw.c b/src/draw/draw.c index a263b446..8d282442 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -226,7 +226,7 @@ void D_DrawColliderLine(GPU_RenderSig *sig, CLD_Shape shape, Affine shape_af, f3 poly.points = PushStructsNoZero(scratch.arena, Vec2, shape.count); for (u32 i = 0; i < shape.count; ++i) { - Vec2 p = MulAffineV2(shape_af, shape.points[i]); + Vec2 p = MulAffineVec2(shape_af, shape.points[i]); poly.points[i] = p; } } diff --git a/src/pp/pp.c b/src/pp/pp.c index e4e9ee04..2c549619 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -2,8 +2,8 @@ P_Ctx P = Zi; ThreadLocal P_ThreadLocalCtx P_tl = Zi; Readonly P_Ent P_NilEnt = { - .af = CompAffineIdentity, - .control.look = { 0, -1 }, + .xf = CompXformIdentity, + .control.look = { 1, 0 }, }; Readonly P_Frame P_NilFrame = { @@ -124,17 +124,15 @@ P_Shape P_ShapeFromDescEx(P_ShapeDesc desc) return result; } -P_Shape P_MulAffineShape(Affine af, P_Shape shape) +P_Shape P_MulXformShape(Xform xf, P_Shape shape) { P_Shape result = shape; for (i32 i = 0; i < shape.points_count; ++i) { - result.points[i] = MulAffineV2(af, shape.points[i]); + result.points[i] = MulXformVec2(xf, shape.points[i]); } - Vec2 scale = ScaleFromAffine(af); - result.radius *= MaxF32(scale.x, scale.y); - result.centroid = MulAffineV2(af, shape.centroid); - result.center_of_mass = MulAffineV2(af, shape.center_of_mass); + result.centroid = MulXformVec2(xf, shape.centroid); + result.center_of_mass = MulXformVec2(xf, shape.center_of_mass); return result; } @@ -193,7 +191,7 @@ P_Shape P_LocalShapeFromEnt(P_Ent *ent) P_Shape P_WorldShapeFromEnt(P_Ent *ent) { P_Shape local = P_LocalShapeFromEnt(ent); - P_Shape world = P_MulAffineShape(ent->af, local); + P_Shape world = P_MulXformShape(ent->xf, local); return world; } @@ -1363,7 +1361,7 @@ void P_DebugDrawFrame(P_Frame *frame) { Vec4 color = VEC4(0.8, 0.8, 0.8, 1); Vec2 p0 = world_shape.centroid; - Vec2 p1 = P_EdgePointFromShape(world_shape, UpFromAffine(ent->af)); + Vec2 p1 = P_EdgePointFromShape(world_shape, ent->xf.r); P_DebugDrawLine(p0, p1, color); } @@ -1647,7 +1645,7 @@ void P_StepFrame(P_Frame *frame) for (P_Ent *ent = P_FirstEnt(frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) { - ent->prev_af = ent->af; + ent->prev_xf = ent->xf; } ////////////////////////////// @@ -2405,10 +2403,10 @@ void P_StepFrame(P_Frame *frame) { if (!is_predicting || ent == local_guy) { - Affine af = ent->af; - af.og = AddVec2(af.og, MulVec2(ent->solved_v, solver_dt)); - af = RotateAffine(af, ent->solved_w * solver_dt); - ent->af = af; + 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); + ent->xf = xf; } } } @@ -2463,25 +2461,27 @@ void P_StepFrame(P_Frame *frame) Vec2 base_pos = P_EdgePointFromShape(firer_world_shape, firer->control.look); Vec2 base_dir = firer->control.look; - // Vec2 base_pos = Zi; - // Vec2 base_dir = Zi; + // Xform base_xf = Zi; // { - // P_Anim anim = P_AnimFromEnt(firer); + // P_Anim anim = P_AnimFromEnt(firer, frame->time_ns); // SPR_LayerKey origin_layer = SPR_LayerKeyFromName(Lit(".origin")); // SPR_LayerKey ap_layer = SPR_LayerKeyFromName(Lit(".ap")); - // Vec2 firer_origin_ray = SPR_RayFromSheet(anim.sheet, anim.span, anim.frame_seq, origin_layer); - // Vec2 firer_ap_ray = SPR_RayFromSheet(anim.sheet, anim.span, anim.frame_seq, ap_layer); + // Xform firer_to_body_origin_xf = SPR_XformFromSheet(anim.sheet, origin_layer, anim.span, anim.frame_seq); + // Xform firer_to_body_ap_xf = SPR_XformFromSheet(anim.sheet, ap_layer, anim.span, anim.frame_seq); - // Vec2 wep_origin_ray = SPR_RayFromSheet(anim.wep_sheet, anim.span, anim.frame_seq, origin_layer); - // Vec2 wep_ap_ray = SPR_RayFromSheet(anim.wep_sheet, anim.span, anim.frame_seq, ap_layer); + // Xform body_ap_to_wep_origin_xf = SPR_XformFromSheet(anim.wep_sheet, origin_layer, anim.span, anim.frame_seq); + // Xform body_ap_to_wep_ap_xf = SPR_XformFromSheet(anim.wep_sheet, ap_layer, anim.span, anim.frame_seq); - // Vec2 fo2w = SubVec2(firer_ - // base_pos = + // // Xform fo2w = SubVec2(firer_ + // Xform firer_to_world_xf = firer->xf; + // Xform bullet_xf = MulXform(firer_to_world_xf, firer_to_body_ap_xf); + // base_pos = bullet_xf.t; // // FIXME: Real dir - // base_dir = firer->control.look; + // // base_dir = firer->control.look; + // base_dir = bullet_xf.r; // } diff --git a/src/pp/pp.h b/src/pp/pp.h index 1890a1a8..31dd663f 100644 --- a/src/pp/pp.h +++ b/src/pp/pp.h @@ -112,8 +112,8 @@ Struct(P_Ent) b32 is_dummy; f32 health; - Affine prev_af; - Affine af; + Xform prev_xf; + Xform xf; // TODO: Remove this (weapon testing) i64 last_fire_ns; @@ -328,7 +328,7 @@ Struct(P_Msg) u64 tiles_hash; P_Key key; - Vec2 pos; + Xform xf; String data; }; @@ -481,7 +481,7 @@ String P_NameFromTileKind(P_TileKind kind); P_Shape P_ShapeFromDescEx(P_ShapeDesc desc); #define P_ShapeFromDesc(...) P_ShapeFromDescEx((P_ShapeDesc) { __VA_ARGS__ }) -P_Shape P_MulAffineShape(Affine af, P_Shape shape); +P_Shape P_MulXformShape(Xform xf, P_Shape shape); Rng2 P_BoundingBoxFromShape(P_Shape shape); P_Shape P_LocalShapeFromEnt(P_Ent *ent); diff --git a/src/pp/pp_sim/pp_sim_core.c b/src/pp/pp_sim/pp_sim_core.c index dc3c7766..0bdfd354 100644 --- a/src/pp/pp_sim/pp_sim_core.c +++ b/src/pp/pp_sim/pp_sim_core.c @@ -594,7 +594,7 @@ void S_TickForever(WaveLaneCtx *lane) P_Ent *guy = P_PushTempEnt(frame_arena, &ents); *guy = P_NilEnt; guy->key = msg->key; - guy->af = AffineFromPos(msg->pos); + guy->xf = msg->xf; guy->is_guy = 1; guy->has_weapon = 1; guy->exists = 1; @@ -604,7 +604,7 @@ void S_TickForever(WaveLaneCtx *lane) P_Ent *guy = P_PushTempEnt(frame_arena, &ents); *guy = P_NilEnt; guy->key = P_RandKey(); - guy->af = AffineFromPos(msg->pos); + guy->xf = msg->xf; guy->is_guy = 1; guy->has_weapon = 1; guy->exists = 1; @@ -621,7 +621,7 @@ void S_TickForever(WaveLaneCtx *lane) // P_Ent *ent = P_PushTempEnt(frame_arena, &ents); // *ent = P_NilEnt; // ent->key = msg->key; - // ent->af = AffineFromPos(msg->pos); + // ent->xf = msg->xf; // ent->is_guy = 1; // ent->is_dummy = 1; // ent->has_weapon = 1; @@ -710,6 +710,7 @@ void S_TickForever(WaveLaneCtx *lane) msg->tile_range = RNG2I32(VEC2I32(0, 0), VEC2I32(P_TilesPitch, P_TilesPitch)); msg->dst = client->net_key; msg->data = STRING(P_TilesCount, world->tiles); + msg->xf = XformIdentity; client->remote_tiles_hash = world->tiles_hash; } } diff --git a/src/pp/pp_transcode.c b/src/pp/pp_transcode.c index 9b92586f..7b3010fc 100644 --- a/src/pp/pp_transcode.c +++ b/src/pp/pp_transcode.c @@ -60,8 +60,8 @@ String P_PackWorld(Arena *arena, P_World *src_world) } } result.len += StringF(arena, " }\n").len; - result.len += StringF(arena, " pos: \"%F\"\n", FmtFloat2(ent->af.og)).len; - result.len += StringF(arena, " rot: \"%F\"\n", FmtFloat2(RightFromAffine(ent->af))).len; + result.len += StringF(arena, " pos: \"%F\"\n", FmtFloat2(ent->xf.t)).len; + result.len += StringF(arena, " angle: \"%F\"\n", FmtFloat(AngleFromVec2(ent->xf.r))).len; result.len += StringF(arena, " exists: \"%F\"\n", FmtFloat(ent->exists)).len; result.len += StringF(arena, " look: \"%F\"\n", FmtFloat2(ent->control.look)).len; } @@ -163,12 +163,11 @@ P_UnpackedWorld P_UnpackWorld(Arena *arena, String packed) if (MatchString(attr->name, Lit("pos"))) { Vec2 pos = CR_Vec2FromString(attr->value); - ent->af.og = pos; + ent->xf.t = pos; } - if (MatchString(attr->name, Lit("rot"))) + if (MatchString(attr->name, Lit("angle"))) { - Vec2 rot = CR_Vec2FromString(attr->value); - ent->af = AffineWithWorldRotation(ent->af, AngleFromVec2(rot)); + ent->xf.r = Vec2FromAngle(CR_FloatFromString(attr->value)); } if (MatchString(attr->name, Lit("exists"))) { diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index c2c16fc5..fb6f2c6a 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -184,33 +184,36 @@ void V_DrawPoly(Vec2Array points, Vec4 srgb, V_DrawFlag flags) } } -void V_DrawShape(P_Shape shape, Vec4 srgb, i32 detail, V_DrawFlag flags) +void V_DrawShape(P_Shape shape, Affine af, Vec4 srgb, i32 detail, V_DrawFlag flags) { - if (shape.radius == 0) + TempArena scratch = BeginScratchNoConflict(); + Vec2Array draw_points = Zi; { - Vec2Array draw_points = Zi; - draw_points.points = shape.points; - draw_points.count = shape.points_count; - V_DrawPoly(draw_points, srgb, flags); - } - else - { - TempArena scratch = BeginScratchNoConflict(); + if (shape.radius == 0) { - Vec2Array draw_points = Zi; - draw_points.points = PushStructsNoZero(scratch.arena, Vec2, detail); - draw_points.count = detail; - for (i32 i = 0; i < detail; ++i) + draw_points.count = shape.points_count; + draw_points.points = PushStructsNoZero(scratch.arena, Vec2, draw_points.count); + for (i32 point_idx = 0; point_idx < draw_points.count; ++point_idx) { - f32 rad = ((f32)i / (f32)detail) * Tau; - Vec2 dir = Vec2FromAngle(rad); - Vec2 sp = P_SupportPointFromShape(shape, dir).p; - draw_points.points[i] = sp; + draw_points.points[point_idx] = MulAffineVec2(af, shape.points[point_idx]); } V_DrawPoly(draw_points, srgb, flags); } - EndScratch(scratch); + else + { + draw_points.count = detail; + draw_points.points = PushStructsNoZero(scratch.arena, Vec2, draw_points.count); + for (i32 point_idx = 0; point_idx < detail; ++point_idx) + { + f32 rad = ((f32)point_idx / (f32)detail) * Tau; + Vec2 dir = Vec2FromAngle(rad); + Vec2 sp = P_SupportPointFromShape(shape, dir).p; + draw_points.points[point_idx] = MulAffineVec2(af, sp); + } + } } + V_DrawPoly(draw_points, srgb, flags); + EndScratch(scratch); } void V_DrawLine(Vec2 p0, Vec2 p1, Vec4 srgb) @@ -246,7 +249,7 @@ void V_DrawPoint(Vec2 p, Vec4 srgb) .points = { p }, .radius = 5 ); - V_DrawShape(ui_shape, srgb, 24, V_DrawFlag_None); + V_DrawShape(ui_shape, AffineIdentity, srgb, 24, V_DrawFlag_None); } //////////////////////////////////////////////////////////// @@ -836,8 +839,8 @@ void V_TickForever(WaveLaneCtx *lane) 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 = MulAffineV2(InvertAffine(prev_frame_edit_to_screen_af), prev_frame->screen_cursor); - Vec2 target_cursor = MulAffineV2(InvertAffine(edit_to_screen_af), ui_frame->cursor_pos); + 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); Vec2 diff = SubVec2(prev_target_cursor, target_cursor); frame->edit_camera_pos = AddVec2(frame->edit_camera_pos, diff); } @@ -855,7 +858,7 @@ void V_TickForever(WaveLaneCtx *lane) P_Ent *guy = P_EntFromKey(local_world->last_frame, player->guy); Vec2 guy_center = P_WorldShapeFromEnt(guy).centroid; Vec2 screen_center = MulVec2(frame->screen_dims, 0.5); - Vec2 look = MulAffineBasisV2(prev_frame->af.screen_to_world, SubVec2(ui_frame->cursor_pos, screen_center)); + Vec2 look = MulAffineBasisVec2(prev_frame->af.screen_to_world, SubVec2(ui_frame->cursor_pos, screen_center)); target_camera_pos = guy_center; target_camera_pos = AddVec2(target_camera_pos, MulVec2Vec2(look, look_ratio)); target_camera_zoom = 1; @@ -895,7 +898,7 @@ void V_TickForever(WaveLaneCtx *lane) } ////////////////////////////// - //- Compute frame Affines + //- Compute frame affines // World <-> screen frame->af.world_to_screen = AffineIdentity; @@ -953,8 +956,8 @@ void V_TickForever(WaveLaneCtx *lane) //- Update cursors / selection frame->screen_cursor = ui_frame->cursor_pos; - frame->shade_cursor = MulAffineV2(frame->af.screen_to_shade, frame->screen_cursor); - frame->world_cursor = MulAffineV2(frame->af.screen_to_world, frame->screen_cursor); + 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); @@ -984,11 +987,11 @@ void V_TickForever(WaveLaneCtx *lane) frame->world_selection.p1.x = MaxF32(frame->world_cursor.x, frame->world_selection_start.x); frame->world_selection.p1.y = MaxF32(frame->world_cursor.y, frame->world_selection_start.y); - frame->screen_selection.p0 = MulAffineV2(frame->af.world_to_screen, frame->world_selection.p0); - frame->screen_selection.p1 = MulAffineV2(frame->af.world_to_screen, frame->world_selection.p1); + frame->screen_selection.p0 = MulAffineVec2(frame->af.world_to_screen, frame->world_selection.p0); + frame->screen_selection.p1 = MulAffineVec2(frame->af.world_to_screen, frame->world_selection.p1); - frame->shade_selection.p0 = MulAffineV2(frame->af.world_to_shade, frame->world_selection.p0); - frame->shade_selection.p1 = MulAffineV2(frame->af.world_to_shade, frame->world_selection.p1); + frame->shade_selection.p0 = MulAffineVec2(frame->af.world_to_shade, frame->world_selection.p0); + frame->shade_selection.p1 = MulAffineVec2(frame->af.world_to_shade, frame->world_selection.p1); ////////////////////////////// //- Place tiles @@ -1001,8 +1004,8 @@ void V_TickForever(WaveLaneCtx *lane) { // TODO: Fix clamp when both start & end are outside of world Rng2I32 tile_range = Zi; - tile_range.p0 = Vec2I32FromVec(FloorVec2(MulAffineV2(frame->af.world_to_tile, prev_frame->world_selection.p0))); - tile_range.p1 = Vec2I32FromVec(CeilVec2(MulAffineV2(frame->af.world_to_tile, prev_frame->world_selection.p1))); + tile_range.p0 = Vec2I32FromVec(FloorVec2(MulAffineVec2(frame->af.world_to_tile, prev_frame->world_selection.p0))); + tile_range.p1 = Vec2I32FromVec(CeilVec2(MulAffineVec2(frame->af.world_to_tile, prev_frame->world_selection.p1))); P_Msg *msg = P_PushMsg(P_MsgKind_TileEdit, Zstr); msg->tile_kind = prev_frame->equipped_tile; @@ -1831,50 +1834,50 @@ 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); + // 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); - } + // 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; - } - } + // // 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 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; - // } - } - } + // // 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; + // // } + // } + // } @@ -1904,8 +1907,8 @@ void V_TickForever(WaveLaneCtx *lane) { skip = 1; } - // V_DrawPoint(MulAffineV2(frame->af.world_to_screen, start), Color_Red); - // V_DrawPoint(MulAffineV2(frame->af.world_to_screen, end), Color_Purple); + // V_DrawPoint(MulAffineVec2(frame->af.world_to_screen, start), Color_Red); + // V_DrawPoint(MulAffineVec2(frame->af.world_to_screen, end), Color_Purple); end = hit_pos; } @@ -2295,29 +2298,28 @@ void V_TickForever(WaveLaneCtx *lane) { case P_DebugDrawKind_Point: { - Vec2 ui_p = MulAffineV2(frame->af.world_to_screen, n->point.p); + Vec2 ui_p = MulAffineVec2(frame->af.world_to_screen, n->point.p); V_DrawPoint(ui_p, color); } break; case P_DebugDrawKind_Line: { - Vec2 ui_p0 = MulAffineV2(frame->af.world_to_screen, n->line.p0); - Vec2 ui_p1 = MulAffineV2(frame->af.world_to_screen, n->line.p1); + Vec2 ui_p0 = MulAffineVec2(frame->af.world_to_screen, n->line.p0); + Vec2 ui_p1 = MulAffineVec2(frame->af.world_to_screen, n->line.p1); V_DrawLine(ui_p0, ui_p1, color); } break; case P_DebugDrawKind_Rect: { Rng2 ui_rect = Zi; - ui_rect.p0 = MulAffineV2(frame->af.world_to_screen, n->rect.p0); - ui_rect.p1 = MulAffineV2(frame->af.world_to_screen, n->rect.p1); + ui_rect.p0 = MulAffineVec2(frame->af.world_to_screen, n->rect.p0); + ui_rect.p1 = MulAffineVec2(frame->af.world_to_screen, n->rect.p1); V_DrawRect(ui_rect, color, V_DrawFlag_Line); } break; case P_DebugDrawKind_Shape: { - P_Shape ui_shape = P_MulAffineShape(frame->af.world_to_screen, n->shape); - V_DrawShape(ui_shape, color, detail, V_DrawFlag_Line); + V_DrawShape(n->shape, frame->af.world_to_screen, color, detail, V_DrawFlag_Line); } break; } } @@ -3663,8 +3665,8 @@ void V_TickForever(WaveLaneCtx *lane) } UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y); { - Vec2 tile_pos = MulAffineV2(frame->af.world_to_tile, frame->world_cursor); - Vec2 cell_pos = MulAffineV2(frame->af.world_to_cell, frame->world_cursor); + Vec2 tile_pos = MulAffineVec2(frame->af.world_to_tile, frame->world_cursor); + Vec2 cell_pos = MulAffineVec2(frame->af.world_to_cell, frame->world_cursor); i32 tile_idx = P_TileIdxFromTilePos(tile_pos); UI_BuildLabelF("Camera pos: %F", FmtFloat2(frame->camera_pos)); UI_BuildLabelF("Cursor world pos: %F", FmtFloat2(frame->world_cursor)); @@ -4092,7 +4094,7 @@ void V_TickForever(WaveLaneCtx *lane) { P_Msg *msg = P_PushMsg(P_MsgKind_EntEdit, Lit("guy")); msg->key = local_guy->key; - msg->pos = guy_pos; + msg->xf.t = guy_pos; } } break; @@ -4100,7 +4102,7 @@ void V_TickForever(WaveLaneCtx *lane) { P_Msg *msg = P_PushMsg(P_MsgKind_EntEdit, Lit("dummy")); msg->key = P_RandKey(); - msg->pos = frame->world_cursor; + msg->xf.t = frame->world_cursor; } break; case V_CmdKind_delete: diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index 9f7de71a..4a98741d 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -270,7 +270,7 @@ Struct(V_Frame) Vec2 camera_pos; f32 camera_zoom; - // Affines; + // affines; V_Affines af; // Cursors @@ -346,7 +346,7 @@ void V_PushParticles(V_Emitter src); //~ Draw helpers void V_DrawPoly(Vec2Array points, Vec4 srgb, V_DrawFlag flags); -void V_DrawShape(P_Shape shape, Vec4 srgb, i32 detail, V_DrawFlag flags); +void V_DrawShape(P_Shape shape, Affine af, Vec4 srgb, i32 detail, V_DrawFlag flags); void V_DrawLine(Vec2 p0, Vec2 p1, Vec4 srgb); void V_DrawRect(Rng2 rect, Vec4 srgb, V_DrawFlag flags); void V_DrawPoint(Vec2 p, Vec4 srgb); diff --git a/src/sprite/sprite.c b/src/sprite/sprite.c index aeaf0d75..b3a2c3a7 100644 --- a/src/sprite/sprite.c +++ b/src/sprite/sprite.c @@ -21,14 +21,14 @@ SPR_SheetKey SPR_SheetKeyFromResource(ResourceKey resource) SPR_SpanKey SPR_SpanKeyFromName(String name) { SPR_SpanKey result = Zi; - // TODO + result.v = HashString(name); return result; } SPR_LayerKey SPR_LayerKeyFromName(String name) { SPR_LayerKey result = Zi; - // TODO + result.v = HashString(name); return result; } @@ -38,12 +38,19 @@ SPR_LayerKey SPR_LayerKeyFromName(String name) SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet, SPR_SpanKey span, i64 frame_seq) { SPR_Slice result = Zi; - - // TODO - return result; } +Xform SPR_XformFromSheet(SPR_SheetKey sheet, SPR_LayerKey layer, SPR_SpanKey span, i64 frame_seq) +{ + Xform result = Zi; + return result; +} + + + + + // SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet, SPR_SpanKey span, i64 frame_seq) // { // // TODO: Ability to specify desired alpha modes (Straight, Premultiplied, Opaque) diff --git a/src/sprite/sprite.h b/src/sprite/sprite.h index c693d010..aeead3fd 100644 --- a/src/sprite/sprite.h +++ b/src/sprite/sprite.h @@ -113,6 +113,7 @@ SPR_LayerKey SPR_LayerKeyFromName(String name); //~ Lookup SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet, SPR_SpanKey span, i64 frame_seq); +Xform SPR_XformFromSheet(SPR_SheetKey sheet, SPR_LayerKey layer, SPR_SpanKey span, i64 frame_seq); //////////////////////////////////////////////////////////// //~ Async