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);
i64 old_ent_bins_count = frame->ent_bins_count;
P_EntBin *old_ent_bins = frame->ent_bins;
i64 old_max_constraints = frame->max_constraints;
P_Constraint *old_constraints = frame->constraints;
{
ZeroStruct(frame);
}
frame->ent_bins_count = old_ent_bins_count;
frame->ent_bins = old_ent_bins;
frame->max_constraints = old_max_constraints;
frame->constraints = old_constraints;
ZeroStructs(frame->ent_bins, frame->ent_bins_count);
}
else
@ -1311,12 +1317,19 @@ P_Frame *P_PushFrame(P_World *world, P_Frame *src_frame, i64 tick)
frame->first_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 = 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);
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);
}
// Copy ents
for (P_Ent *src = P_FirstEnt(src_frame); !P_IsEntNil(src); src = P_NextEnt(src))
{
P_Ent *dst = world->first_free_ent;
@ -1474,17 +1488,10 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
// TODO: Not like this
// i64 max_constraints = 4096;
// i64 constraints_count = 0;
// P_Constraint *constraints = PushStructs(scratch.arena, P_Constraint, max_constraints);
frame->constraints_count = MinI64(prev_frame->constraints_count, frame->max_constraints);
CopyStructs(frame->constraints, prev_frame->constraints, frame->constraints_count);
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))
{
@ -1503,9 +1510,9 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
P_Constraint *constraint = 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))
{
match = 1;
@ -1514,10 +1521,10 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
}
if (!match)
{
if (constraints_count < max_constraints)
if (frame->constraints_count < frame->max_constraints)
{
constraint = &constraints[constraints_count];
constraints_count += 1;
constraint = &frame->constraints[frame->constraints_count];
frame->constraints_count += 1;
ZeroStruct(constraint);
}
}
@ -1626,9 +1633,9 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
{
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;
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
// 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;
constraints_count -= 1;
frame->constraints_count -= 1;
}
else
{
@ -1666,9 +1673,9 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
//////////////////////////////
//- 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 tangent = PerpVec2(normal);
f32 inv_m0 = constraint->inv_m0;
@ -1703,9 +1710,9 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
//////////////////////////////
//- 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 *ent1 = P_EntFromKey(frame, constraint->ent1);
@ -1747,9 +1754,9 @@ void P_StepFrame(P_Frame *frame, P_CmdList cmds)
//////////////////////////////
//- 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 *ent1 = P_EntFromKey(frame, constraint->ent1);

View File

@ -141,6 +141,43 @@ Struct(P_EntBin)
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
@ -169,6 +206,10 @@ Struct(P_Frame)
i64 ent_bins_count;
P_EntBin *ent_bins;
i64 max_constraints;
i64 constraints_count;
P_Constraint *constraints;
};
Struct(P_FrameBin)
@ -321,43 +362,6 @@ Struct(P_RaycastResult)
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

View File

@ -148,7 +148,7 @@ ComputeShader2D(V_BackdropCS, 8, 8)
if (tile == P_TileKind_Wall)
{
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.5));
}