From e7a3e1f662f83e259878ae60297f4326db4a06ce Mon Sep 17 00:00:00 2001 From: jacob Date: Thu, 13 Nov 2025 21:05:10 -0600 Subject: [PATCH] store body info in ent shape --- src/proto/pp_sim/pp_sim_core.c | 64 +++++++++++++++++++++++----------- src/proto/pp_sim/pp_sim_core.h | 37 ++++++++++++++++---- src/proto/pp_vis/pp_vis_core.c | 33 ++++++++++-------- src/proto/pp_vis/pp_vis_draw.c | 2 +- 4 files changed, 95 insertions(+), 41 deletions(-) diff --git a/src/proto/pp_sim/pp_sim_core.c b/src/proto/pp_sim/pp_sim_core.c index 42a1698d..bfec4f09 100644 --- a/src/proto/pp_sim/pp_sim_core.c +++ b/src/proto/pp_sim/pp_sim_core.c @@ -2,7 +2,7 @@ S_SharedState S_shared_state = ZI; Readonly S_Ent S_nil_ent = { .local_xf = CompXformIdentity, - .final_xf = CompXformIdentity, + .world_xf = CompXformIdentity, .tint = { 0.5, 0.5, 0.5, 1 }, }; @@ -72,6 +72,26 @@ S_Key S_RandKey(void) //////////////////////////////////////////////////////////// //~ Shape helpers +S_Shape S_ShapeFromDescEx(S_ShapeDesc desc) +{ + desc.count = MaxI32(desc.count, 1); + S_Shape result = ZI; + { + result.points_count = desc.count; + CopyStructs(result.points, desc.points, result.points_count); + Vec2 accum = ZI; + for (i32 p_idx = 0; p_idx < result.points_count; ++p_idx) + { + accum = AddVec2(accum, result.points[p_idx]); + } + result.centroid = DivVec2(accum, result.points_count); + result.center_of_mass = result.centroid; + result.radius = desc.radius; + result.mass = desc.mass; + } + return result; +} + S_Shape S_MulXformShape(Xform xf, S_Shape shape) { S_Shape result = shape; @@ -366,7 +386,7 @@ JobDef(S_SimWorker, _, __) ++world->ents_count; } *dst = *src; - dst->shape.points_count = MaxI32(dst->shape.points_count, 1); + dst->local_shape.points_count = MaxI32(dst->local_shape.points_count, 1); dst->active = 1; } @@ -455,9 +475,27 @@ JobDef(S_SimWorker, _, __) lookup = S_LookupFromWorld(frame_arena, world); ////////////////////////////// - //- Update entities from user control + //- Update ent controls - for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); !S_IsEntNil(ent); ent = S_NextEnt(frame_arena, &iter)) + for (S_CmdNode *cmd_node = input->first_cmd_node; cmd_node; cmd_node = cmd_node->next) + { + S_Cmd cmd = cmd_node->cmd; + if (cmd.kind == S_CmdKind_Control) + { + S_Ent *target = S_EntFromKey(&lookup, cmd.target); + if (target->active) + { + /* TODO: Clamp */ + target->move = cmd.move; + target->look = cmd.look; + } + } + } + + ////////////////////////////// + //- Apply control forces + + for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); ent->active; ent = S_NextEnt(frame_arena, &iter)) { if (!S_IsKeyNil(ent->camera)) { @@ -469,27 +507,13 @@ JobDef(S_SimWorker, _, __) } } - ////////////////////////////// - //- Compute shape centers - - for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); !S_IsEntNil(ent); ent = S_NextEnt(frame_arena, &iter)) - { - S_Shape shape = ent->shape; - Vec2 accum = ZI; - for (i32 p_idx = 0; p_idx < shape.points_count; ++p_idx) - { - accum = AddVec2(accum, shape.points[p_idx]); - } - ent->center = DivVec2(accum, shape.points_count); - } - ////////////////////////////// //- Compute final world transforms - for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); !S_IsEntNil(ent); ent = S_NextEnt(frame_arena, &iter)) + for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); ent->active; ent = S_NextEnt(frame_arena, &iter)) { S_Ent *parent = S_EntFromKey(&lookup, ent->parent); - ent->final_xf = MulXform(parent->final_xf, ent->local_xf); + ent->world_xf = MulXform(parent->world_xf, ent->local_xf); } ////////////////////////////// diff --git a/src/proto/pp_sim/pp_sim_core.h b/src/proto/pp_sim/pp_sim_core.h index 922a7688..d5abb4a1 100644 --- a/src/proto/pp_sim/pp_sim_core.h +++ b/src/proto/pp_sim/pp_sim_core.h @@ -12,8 +12,20 @@ Struct(S_Key) //////////////////////////////////////////////////////////// //~ Shape types +Struct(S_ShapeDesc) +{ + f32 radius; + f32 mass; + i32 count; + Vec2 points[8]; +}; + Struct(S_Shape) { + f32 mass; + Vec2 centroid; + Vec2 center_of_mass; + f32 radius; i32 points_count; Vec2 points[8]; @@ -45,23 +57,24 @@ Struct(S_Ent) ////////////////////////////// //- Build data + Xform local_xf; + Vec4 tint; S_Key follow; S_Key camera; - S_Shape shape; - Xform local_xf; + S_Shape local_shape; - ////////////////////////////// - //- Pre-solve data + f32 move_speed; - Vec2 center; + Vec2 move; + Vec2 look; ////////////////////////////// //- Post-solve data - Xform final_xf; + Xform world_xf; ////////////////////////////// //- Internal sim data @@ -161,12 +174,20 @@ Enum(S_CmdKind) { S_CmdKind_Nop, S_CmdKind_Spawn, + S_CmdKind_Control, }; Struct(S_Cmd) { S_CmdKind kind; + + /* Spawn */ S_EntList ents; + + /* Control */ + S_Key target; + Vec2 move; + Vec2 look; }; Struct(S_CmdNode) @@ -236,7 +257,11 @@ S_Key S_RandKey(void); //////////////////////////////////////////////////////////// //~ Shape helpers +#define S_ShapeFromDesc(...) S_ShapeFromDescEx((S_ShapeDesc) { __VA_ARGS__ }) +S_Shape S_ShapeFromDescEx(S_ShapeDesc desc); + S_Shape S_MulXformShape(Xform xf, S_Shape shape); + Vec2 S_SupportPointFromShape(S_Shape shape, Vec2 dir); //////////////////////////////////////////////////////////// diff --git a/src/proto/pp_vis/pp_vis_core.c b/src/proto/pp_vis/pp_vis_core.c index 05edfd41..9062df58 100644 --- a/src/proto/pp_vis/pp_vis_core.c +++ b/src/proto/pp_vis/pp_vis_core.c @@ -48,9 +48,11 @@ void V_PushTestEnts(Arena *arena, S_EntList *list) ent->key = player_key; ent->camera = camera_key; { - S_Shape *shape = &ent->shape; - shape->points_count = 1; - shape->radius = 50; + ent->local_shape = S_ShapeFromDesc( + .mass = 10, + .count = 1, + .radius = 50, + ); } } break; @@ -61,13 +63,15 @@ void V_PushTestEnts(Arena *arena, S_EntList *list) ent->key = child_key; ent->parent = player_key; { - S_Shape *shape = &ent->shape; - shape->points_count = 4; - shape->points[0] = VEC2(-15, -15); - shape->points[1] = VEC2(15, -15); - shape->points[2] = VEC2(15, 15); - shape->points[3] = VEC2(-15, 15); - shape->radius = 0; + ent->local_shape = S_ShapeFromDesc( + .count = 4, + .points = { + VEC2(-15, -15), + VEC2(15, -15), + VEC2(15, 15), + VEC2(-15, 15) + } + ); } } break; @@ -433,15 +437,16 @@ JobDef(V_VisWorker, _, __) //- Build render data /* Build shapes */ - for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); !S_IsEntNil(ent); ent = S_NextEnt(frame_arena, &iter)) + for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); ent->active; ent = S_NextEnt(frame_arena, &iter)) { b32 is_visible = ent->tint.w != 0; if (is_visible) { - Xform xf = ent->final_xf; - S_Shape shape = S_MulXformShape(ent->final_xf, ent->shape); + Xform xf = ent->world_xf; Vec4 color = ent->tint; - V_DrawShape(dverts_arena, dvert_idx_arena, shape, LinearFromSrgb(color), 32, V_DrawFlag_Line); + i32 detail = 32; + S_Shape shape = S_MulXformShape(ent->world_xf, ent->local_shape); + V_DrawShape(dverts_arena, dvert_idx_arena, shape, LinearFromSrgb(color), detail, V_DrawFlag_Line); } } diff --git a/src/proto/pp_vis/pp_vis_draw.c b/src/proto/pp_vis/pp_vis_draw.c index ae7e9321..414c1f31 100644 --- a/src/proto/pp_vis/pp_vis_draw.c +++ b/src/proto/pp_vis/pp_vis_draw.c @@ -10,7 +10,7 @@ void V_DrawPoly(Arena *verts_arena, Arena *idx_arena, Vec2Array points, Vec4 col { TempArena scratch = BeginScratchNoConflict(); { - f32 half_thickness = 1; + f32 half_thickness = 0.5; i32 lines_count = verts_count == 2 ? 1 : verts_count; i32 line_verts_count = lines_count * 4; i32 idx_count = lines_count * 6;