store body info in ent shape

This commit is contained in:
jacob 2025-11-13 21:05:10 -06:00
parent eb1a4cd646
commit e7a3e1f662
4 changed files with 95 additions and 41 deletions

View File

@ -2,7 +2,7 @@ S_SharedState S_shared_state = ZI;
Readonly S_Ent S_nil_ent = { Readonly S_Ent S_nil_ent = {
.local_xf = CompXformIdentity, .local_xf = CompXformIdentity,
.final_xf = CompXformIdentity, .world_xf = CompXformIdentity,
.tint = { 0.5, 0.5, 0.5, 1 }, .tint = { 0.5, 0.5, 0.5, 1 },
}; };
@ -72,6 +72,26 @@ S_Key S_RandKey(void)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Shape helpers //~ 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 S_MulXformShape(Xform xf, S_Shape shape)
{ {
S_Shape result = shape; S_Shape result = shape;
@ -366,7 +386,7 @@ JobDef(S_SimWorker, _, __)
++world->ents_count; ++world->ents_count;
} }
*dst = *src; *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; dst->active = 1;
} }
@ -455,9 +475,27 @@ JobDef(S_SimWorker, _, __)
lookup = S_LookupFromWorld(frame_arena, world); 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)) 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 //- 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); 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);
} }
////////////////////////////// //////////////////////////////

View File

@ -12,8 +12,20 @@ Struct(S_Key)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Shape types //~ Shape types
Struct(S_ShapeDesc)
{
f32 radius;
f32 mass;
i32 count;
Vec2 points[8];
};
Struct(S_Shape) Struct(S_Shape)
{ {
f32 mass;
Vec2 centroid;
Vec2 center_of_mass;
f32 radius; f32 radius;
i32 points_count; i32 points_count;
Vec2 points[8]; Vec2 points[8];
@ -45,23 +57,24 @@ Struct(S_Ent)
////////////////////////////// //////////////////////////////
//- Build data //- Build data
Xform local_xf;
Vec4 tint; Vec4 tint;
S_Key follow; S_Key follow;
S_Key camera; S_Key camera;
S_Shape shape; S_Shape local_shape;
Xform local_xf;
////////////////////////////// f32 move_speed;
//- Pre-solve data
Vec2 center; Vec2 move;
Vec2 look;
////////////////////////////// //////////////////////////////
//- Post-solve data //- Post-solve data
Xform final_xf; Xform world_xf;
////////////////////////////// //////////////////////////////
//- Internal sim data //- Internal sim data
@ -161,12 +174,20 @@ Enum(S_CmdKind)
{ {
S_CmdKind_Nop, S_CmdKind_Nop,
S_CmdKind_Spawn, S_CmdKind_Spawn,
S_CmdKind_Control,
}; };
Struct(S_Cmd) Struct(S_Cmd)
{ {
S_CmdKind kind; S_CmdKind kind;
/* Spawn */
S_EntList ents; S_EntList ents;
/* Control */
S_Key target;
Vec2 move;
Vec2 look;
}; };
Struct(S_CmdNode) Struct(S_CmdNode)
@ -236,7 +257,11 @@ S_Key S_RandKey(void);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Shape helpers //~ 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); S_Shape S_MulXformShape(Xform xf, S_Shape shape);
Vec2 S_SupportPointFromShape(S_Shape shape, Vec2 dir); Vec2 S_SupportPointFromShape(S_Shape shape, Vec2 dir);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -48,9 +48,11 @@ void V_PushTestEnts(Arena *arena, S_EntList *list)
ent->key = player_key; ent->key = player_key;
ent->camera = camera_key; ent->camera = camera_key;
{ {
S_Shape *shape = &ent->shape; ent->local_shape = S_ShapeFromDesc(
shape->points_count = 1; .mass = 10,
shape->radius = 50; .count = 1,
.radius = 50,
);
} }
} break; } break;
@ -61,13 +63,15 @@ void V_PushTestEnts(Arena *arena, S_EntList *list)
ent->key = child_key; ent->key = child_key;
ent->parent = player_key; ent->parent = player_key;
{ {
S_Shape *shape = &ent->shape; ent->local_shape = S_ShapeFromDesc(
shape->points_count = 4; .count = 4,
shape->points[0] = VEC2(-15, -15); .points = {
shape->points[1] = VEC2(15, -15); VEC2(-15, -15),
shape->points[2] = VEC2(15, 15); VEC2(15, -15),
shape->points[3] = VEC2(-15, 15); VEC2(15, 15),
shape->radius = 0; VEC2(-15, 15)
}
);
} }
} break; } break;
@ -433,15 +437,16 @@ JobDef(V_VisWorker, _, __)
//- Build render data //- Build render data
/* Build shapes */ /* 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; b32 is_visible = ent->tint.w != 0;
if (is_visible) if (is_visible)
{ {
Xform xf = ent->final_xf; Xform xf = ent->world_xf;
S_Shape shape = S_MulXformShape(ent->final_xf, ent->shape);
Vec4 color = ent->tint; 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);
} }
} }

View File

@ -10,7 +10,7 @@ void V_DrawPoly(Arena *verts_arena, Arena *idx_arena, Vec2Array points, Vec4 col
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
{ {
f32 half_thickness = 1; f32 half_thickness = 0.5;
i32 lines_count = verts_count == 2 ? 1 : verts_count; i32 lines_count = verts_count == 2 ? 1 : verts_count;
i32 line_verts_count = lines_count * 4; i32 line_verts_count = lines_count * 4;
i32 idx_count = lines_count * 6; i32 idx_count = lines_count * 6;