store constraints array in world frame

This commit is contained in:
jacob 2026-01-13 15:35:16 -06:00
parent 3ad4579bb9
commit 1ccaf37d3f
3 changed files with 76 additions and 65 deletions

View File

@ -1294,9 +1294,15 @@ P_Frame *P_PushFrame(P_World *world, P_Frame *src_frame, i64 tick)
SllStackPop(world->first_free_frame); SllStackPop(world->first_free_frame);
i64 old_ent_bins_count = frame->ent_bins_count; i64 old_ent_bins_count = frame->ent_bins_count;
P_EntBin *old_ent_bins = frame->ent_bins; P_EntBin *old_ent_bins = frame->ent_bins;
i64 old_max_constraints = frame->max_constraints;
P_Constraint *old_constraints = frame->constraints;
{
ZeroStruct(frame); ZeroStruct(frame);
}
frame->ent_bins_count = old_ent_bins_count; frame->ent_bins_count = old_ent_bins_count;
frame->ent_bins = old_ent_bins; frame->ent_bins = old_ent_bins;
frame->max_constraints = old_max_constraints;
frame->constraints = old_constraints;
ZeroStructs(frame->ent_bins, frame->ent_bins_count); ZeroStructs(frame->ent_bins, frame->ent_bins_count);
} }
else else
@ -1311,12 +1317,19 @@ P_Frame *P_PushFrame(P_World *world, P_Frame *src_frame, i64 tick)
frame->first_ent = &P_NilEnt; frame->first_ent = &P_NilEnt;
frame->last_ent = &P_NilEnt; frame->last_ent = &P_NilEnt;
if (frame->ent_bins_count == 0) if (!frame->ent_bins)
{ {
frame->ent_bins_count = Kibi(16); frame->ent_bins_count = Kibi(16);
frame->ent_bins = PushStructs(world->frames_arena, P_EntBin, frame->ent_bins_count); frame->ent_bins = PushStructs(world->frames_arena, P_EntBin, frame->ent_bins_count);
} }
if (!frame->constraints)
{
frame->max_constraints = Kibi(4);
frame->constraints_count = 0;
frame->constraints = PushStructsNoZero(world->frames_arena, P_Constraint, frame->max_constraints);
}
u64 hash = MixU64(tick); u64 hash = MixU64(tick);
P_FrameBin *bin = &world->frame_bins[hash % world->frame_bins_count]; P_FrameBin *bin = &world->frame_bins[hash % world->frame_bins_count];
@ -1324,6 +1337,7 @@ P_Frame *P_PushFrame(P_World *world, P_Frame *src_frame, i64 tick)
DllQueuePushNPZ(0, bin->first, bin->last, frame, next_in_bin, prev_in_bin); DllQueuePushNPZ(0, bin->first, bin->last, frame, next_in_bin, prev_in_bin);
} }
// Copy ents
for (P_Ent *src = P_FirstEnt(src_frame); !P_IsEntNil(src); src = P_NextEnt(src)) for (P_Ent *src = P_FirstEnt(src_frame); !P_IsEntNil(src); src = P_NextEnt(src))
{ {
P_Ent *dst = world->first_free_ent; P_Ent *dst = world->first_free_ent;
@ -1474,17 +1488,10 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
// TODO: Not like this // TODO: Not like this
// i64 max_constraints = 4096; frame->constraints_count = MinI64(prev_frame->constraints_count, frame->max_constraints);
// i64 constraints_count = 0; CopyStructs(frame->constraints, prev_frame->constraints, frame->constraints_count);
// P_Constraint *constraints = PushStructs(scratch.arena, P_Constraint, max_constraints);
PERSIST i64 max_constraints = 4096;
PERSIST i64 constraints_count = 0;
PERSIST P_Constraint *constraints = 0;
if (!constraints)
{
constraints = PushStructs(scratch.arena, P_Constraint, max_constraints);
}
for (P_Ent *ent0 = P_FirstEnt(frame); !P_IsEntNil(ent0); ent0 = P_NextEnt(ent0)) for (P_Ent *ent0 = P_FirstEnt(frame); !P_IsEntNil(ent0); ent0 = P_NextEnt(ent0))
{ {
@ -1503,9 +1510,9 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
P_Constraint *constraint = 0; P_Constraint *constraint = 0;
{ {
b32 match = 0; b32 match = 0;
for (i64 constraint_idx = 0; constraint_idx < constraints_count; ++constraint_idx) for (i64 constraint_idx = 0; constraint_idx < frame->constraints_count; ++constraint_idx)
{ {
constraint = &constraints[constraint_idx]; constraint = &frame->constraints[constraint_idx];
if (P_MatchKey(constraint->ent0, ent0->key) && P_MatchKey(constraint->ent1, ent1->key)) if (P_MatchKey(constraint->ent0, ent0->key) && P_MatchKey(constraint->ent1, ent1->key))
{ {
match = 1; match = 1;
@ -1514,10 +1521,10 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
} }
if (!match) if (!match)
{ {
if (constraints_count < max_constraints) if (frame->constraints_count < frame->max_constraints)
{ {
constraint = &constraints[constraints_count]; constraint = &frame->constraints[frame->constraints_count];
constraints_count += 1; frame->constraints_count += 1;
ZeroStruct(constraint); ZeroStruct(constraint);
} }
} }
@ -1626,9 +1633,9 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
{ {
i64 constraint_idx = 0; i64 constraint_idx = 0;
while (constraint_idx < constraints_count) while (constraint_idx < frame->constraints_count)
{ {
P_Constraint *constraint = &constraints[constraint_idx]; P_Constraint *constraint = &frame->constraints[constraint_idx];
b32 prune = 1; b32 prune = 1;
if (constraint->last_touched_tick == frame->tick) if (constraint->last_touched_tick == frame->tick)
{ {
@ -1643,9 +1650,9 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
{ {
// Prune by replacing with last constraint // Prune by replacing with last constraint
// TODO: Investigate whether the reordering here can degrade stability // TODO: Investigate whether the reordering here can degrade stability
P_Constraint *last_constraint = &constraints[constraints_count - 1]; P_Constraint *last_constraint = &frame->constraints[frame->constraints_count - 1];
*constraint = *last_constraint; *constraint = *last_constraint;
constraints_count -= 1; frame->constraints_count -= 1;
} }
else else
{ {
@ -1666,9 +1673,9 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
////////////////////////////// //////////////////////////////
//- Prepare constraints //- Prepare constraints
for (i64 constraint_idx = 0; constraint_idx < constraints_count; ++constraint_idx) for (i64 constraint_idx = 0; constraint_idx < frame->constraints_count; ++constraint_idx)
{ {
P_Constraint *constraint = &constraints[constraint_idx]; P_Constraint *constraint = &frame->constraints[constraint_idx];
Vec2 normal = constraint->normal; Vec2 normal = constraint->normal;
Vec2 tangent = PerpVec2(normal); Vec2 tangent = PerpVec2(normal);
f32 inv_m0 = constraint->inv_m0; f32 inv_m0 = constraint->inv_m0;
@ -1703,9 +1710,9 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
////////////////////////////// //////////////////////////////
//- Warm start constraints //- Warm start constraints
for (i64 constraint_idx = 0; constraint_idx < constraints_count; ++constraint_idx) for (i64 constraint_idx = 0; constraint_idx < frame->constraints_count; ++constraint_idx)
{ {
P_Constraint *constraint = &constraints[constraint_idx]; P_Constraint *constraint = &frame->constraints[constraint_idx];
P_Ent *ent0 = P_EntFromKey(frame, constraint->ent0); P_Ent *ent0 = P_EntFromKey(frame, constraint->ent0);
P_Ent *ent1 = P_EntFromKey(frame, constraint->ent1); P_Ent *ent1 = P_EntFromKey(frame, constraint->ent1);
@ -1747,9 +1754,9 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
////////////////////////////// //////////////////////////////
//- Solve constraints //- Solve constraints
for (i64 constraint_idx = 0; constraint_idx < constraints_count; ++constraint_idx) for (i64 constraint_idx = 0; constraint_idx < frame->constraints_count; ++constraint_idx)
{ {
P_Constraint *constraint = &constraints[constraint_idx]; P_Constraint *constraint = &frame->constraints[constraint_idx];
P_Ent *ent0 = P_EntFromKey(frame, constraint->ent0); P_Ent *ent0 = P_EntFromKey(frame, constraint->ent0);
P_Ent *ent1 = P_EntFromKey(frame, constraint->ent1); P_Ent *ent1 = P_EntFromKey(frame, constraint->ent1);

View File

@ -141,6 +141,43 @@ Struct(P_EntBin)
P_Ent *last; P_Ent *last;
}; };
////////////////////////////////////////////////////////////
//~ Constraint types
Struct(P_ContactPoint)
{
Vec2 vcp0;
Vec2 vcp1;
f32 starting_separation;
f32 inv_normal_mass;
f32 inv_tangent_mass;
u32 id;
f32 solved_normal_impulse;
f32 solved_tangent_impulse;
};
Struct(P_Constraint)
{
i64 last_touched_tick;
P_Key ent0;
P_Key ent1;
Vec2 static_center0;
Vec2 static_center1;
f32 inv_m0;
f32 inv_m1;
f32 inv_i0;
f32 inv_i1;
Vec2 normal;
f32 friction;
i32 points_count;
P_ContactPoint points[2];
};
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ World types //~ World types
@ -169,6 +206,10 @@ Struct(P_Frame)
i64 ent_bins_count; i64 ent_bins_count;
P_EntBin *ent_bins; P_EntBin *ent_bins;
i64 max_constraints;
i64 constraints_count;
P_Constraint *constraints;
}; };
Struct(P_FrameBin) Struct(P_FrameBin)
@ -321,43 +362,6 @@ Struct(P_RaycastResult)
Vec2 normal; Vec2 normal;
}; };
////////////////////////////////////////////////////////////
//~ Constraint types
Struct(P_ContactPoint)
{
Vec2 vcp0;
Vec2 vcp1;
f32 starting_separation;
f32 inv_normal_mass;
f32 inv_tangent_mass;
u32 id;
f32 solved_normal_impulse;
f32 solved_tangent_impulse;
};
Struct(P_Constraint)
{
i64 last_touched_tick;
P_Key ent0;
P_Key ent1;
Vec2 static_center0;
Vec2 static_center1;
f32 inv_m0;
f32 inv_m1;
f32 inv_i0;
f32 inv_i1;
Vec2 normal;
f32 friction;
i32 points_count;
P_ContactPoint points[2];
};
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Command types //~ Command types

View File

@ -148,7 +148,7 @@ ComputeShader2D(V_BackdropCS, 8, 8)
if (tile == P_TileKind_Wall) if (tile == P_TileKind_Wall)
{ {
Vec4 outer = LinearFromSrgb(Vec4(0.05, 0.05, 0.05, 1)); Vec4 outer = LinearFromSrgb(Vec4(0.05, 0.05, 0.05, 1));
Vec4 inner = LinearFromSrgb(Vec4(0.10, 0.10, 0.10, 1)); Vec4 inner = LinearFromSrgb(Vec4(0.15, 0.15, 0.15, 1));
result = lerp(outer, inner, smoothstep(0, 1, tile_edge_dist / 0.375)); result = lerp(outer, inner, smoothstep(0, 1, tile_edge_dist / 0.375));
// result = lerp(outer, inner, smoothstep(0, 1, tile_edge_dist / 0.5)); // result = lerp(outer, inner, smoothstep(0, 1, tile_edge_dist / 0.5));
} }