pp refactor
This commit is contained in:
parent
03d4386cdc
commit
a39c649dc3
@ -33,9 +33,9 @@ void CreateAndUpdateContacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_iteratio
|
||||
CLD_Shape check0_collider = check0->local_collider;
|
||||
Aabb aabb = CLD_AabbFromShape(&check0_collider, check0_xf);
|
||||
|
||||
SpaceIter iter = space_iter_begin_aabb(space, aabb);
|
||||
SpaceIter iter = BeginSpaceIterAabb(space, aabb);
|
||||
SpaceEntry *space_entry;
|
||||
while ((space_entry = space_iter_next(&iter)) != 0)
|
||||
while ((space_entry = NextSpaceIterAabb(&iter)) != 0)
|
||||
{
|
||||
Entity *check1 = EntityFromId(ss, space_entry->ent);
|
||||
if (!IsValidAndActive(check1)) continue;
|
||||
@ -287,7 +287,7 @@ void CreateAndUpdateContacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_iteratio
|
||||
}
|
||||
#endif
|
||||
}
|
||||
space_iter_end(&iter);
|
||||
EndSpaceIter(&iter);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1249,9 +1249,9 @@ f32 DetermineEarliestToi(PhysStepCtx *ctx, f32 step_dt, f32 tolerance, u32 max_i
|
||||
Aabb aabb_t1 = CLD_AabbFromShape(&e0_collider, e0_xf_t1);
|
||||
Aabb combined_aabb = CLD_CombineAabb(aabb_t0, aabb_t1);
|
||||
|
||||
SpaceIter iter = space_iter_begin_aabb(space, combined_aabb);
|
||||
SpaceIter iter = BeginSpaceIterAabb(space, combined_aabb);
|
||||
SpaceEntry *entry;
|
||||
while ((entry = space_iter_next(&iter)) != 0)
|
||||
while ((entry = NextSpaceIterAabb(&iter)) != 0)
|
||||
{
|
||||
Entity *e1 = EntityFromId(ss, entry->ent);
|
||||
if (!ShouldSimulate(e1)) continue;
|
||||
@ -1269,7 +1269,7 @@ f32 DetermineEarliestToi(PhysStepCtx *ctx, f32 step_dt, f32 tolerance, u32 max_i
|
||||
smallest_t = t;
|
||||
}
|
||||
}
|
||||
space_iter_end(&iter);
|
||||
EndSpaceIter(&iter);
|
||||
}
|
||||
|
||||
return smallest_t;
|
||||
@ -1290,14 +1290,14 @@ void UpdateAabbs(PhysStepCtx *ctx)
|
||||
if (ent->local_collider.count > 0)
|
||||
{
|
||||
Xform xf = XformFromEntity(ent);
|
||||
SpaceEntry *space_entry = space_entry_from_handle(space, ent->space_handle);
|
||||
SpaceEntry *space_entry = SpaceEntryFromHandle(space, ent->space_handle);
|
||||
if (!space_entry->valid)
|
||||
{
|
||||
space_entry = space_entry_acquire(space, ent->id);
|
||||
space_entry = AcquireSpaceEntry(space, ent->id);
|
||||
ent->space_handle = space_entry->handle;
|
||||
}
|
||||
Aabb aabb = CLD_AabbFromShape(&ent->local_collider, xf);
|
||||
space_entry_update_aabb(space_entry, aabb);
|
||||
UpdateSpaceEntryAabb(space_entry, aabb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,21 +1,16 @@
|
||||
/* FIXME: Default space entry & cell pointers to nil */
|
||||
|
||||
/* Offset in bytes from start of space struct to start of entry array (assume adjacently allocated) */
|
||||
#define SPACE_ENTRIES_OFFSET (sizeof(Space) + (sizeof(Space) % alignof(SpaceEntry)))
|
||||
Readonly SpaceEntry _g_space_entry_nil = ZI;
|
||||
Readonly SpaceCell _g_space_cell_nil = ZI;
|
||||
Readonly Space _g_space_nil = ZI;
|
||||
|
||||
/* Accessed via NilEntity() */
|
||||
Readonly SpaceEntry _g_space_entry_nil = { .valid = 0 };
|
||||
Readonly SpaceCell _g_space_cell_nil = { .valid = 0 };
|
||||
Readonly Space _g_space_nil = { .valid = 0 };
|
||||
|
||||
/* ========================== *
|
||||
* Space alloc
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Space
|
||||
|
||||
/* NOTE:
|
||||
* The number of bins determines how often tiles will collide in the spatial hash.
|
||||
* For example, at `num_bins_sqrt` = 256 (65536 bins), tiles <1, 1>, <1, 257>, and <257, 257> will collide. */
|
||||
Space *space_acquire(f32 cell_size, u32 num_bins_sqrt)
|
||||
Space *AcquireSpace(f32 cell_size, u32 num_bins_sqrt)
|
||||
{
|
||||
Space *space;
|
||||
{
|
||||
@ -36,13 +31,13 @@ Space *space_acquire(f32 cell_size, u32 num_bins_sqrt)
|
||||
return space;
|
||||
}
|
||||
|
||||
void space_release(Space *space)
|
||||
void ReleaseSpace(Space *space)
|
||||
{
|
||||
ReleaseArena(space->cell_arena);
|
||||
ReleaseArena(space->entry_arena);
|
||||
}
|
||||
|
||||
void space_reset(Space *space)
|
||||
void ResetSpace(Space *space)
|
||||
{
|
||||
PopTo(space->entry_arena, (u64)space->entries - (u64)ArenaBase(space->entry_arena));
|
||||
ResetArena(space->cell_arena);
|
||||
@ -53,23 +48,25 @@ void space_reset(Space *space)
|
||||
space->first_free_entry = 0;
|
||||
}
|
||||
|
||||
Space *space_from_entry(SpaceEntry *entry)
|
||||
Space *SpaceFromEntry(SpaceEntry *entry)
|
||||
{
|
||||
if (entry->valid) {
|
||||
if (entry->valid)
|
||||
{
|
||||
u64 first_entry_addr = (u64)(entry - entry->handle.idx);
|
||||
Space *space = (Space *)(first_entry_addr - SPACE_ENTRIES_OFFSET);
|
||||
Space *space = (Space *)(first_entry_addr - SpaceEntriesOffset);
|
||||
Assert(space->entries == (SpaceEntry *)first_entry_addr);
|
||||
return space;
|
||||
} else {
|
||||
return space_nil();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NilSpace();
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Cell
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Cell
|
||||
|
||||
internal Vec2I32 world_to_cell_coords(f32 cell_size, Vec2 world_pos)
|
||||
Vec2I32 SpaceCellCoordsFromWorldCoords(f32 cell_size, Vec2 world_pos)
|
||||
{
|
||||
f32 x = world_pos.x;
|
||||
f32 y = world_pos.y;
|
||||
@ -78,7 +75,7 @@ internal Vec2I32 world_to_cell_coords(f32 cell_size, Vec2 world_pos)
|
||||
return VEC2I32((i32)x, (i32)y);
|
||||
}
|
||||
|
||||
internal i32 cell_coords_to_bin_index(Space *space, Vec2I32 cell_pos)
|
||||
i32 SpaceBinIndexFromCellCoords(Space *space, Vec2I32 cell_pos)
|
||||
{
|
||||
i32 num_bins_sqrt = space->num_bins_sqrt;
|
||||
|
||||
@ -100,13 +97,15 @@ internal i32 cell_coords_to_bin_index(Space *space, Vec2I32 cell_pos)
|
||||
return bin_index;
|
||||
}
|
||||
|
||||
SpaceCell *space_get_cell(Space *space, Vec2I32 cell_pos)
|
||||
SpaceCell *SpaceCellFromCellPos(Space *space, Vec2I32 cell_pos)
|
||||
{
|
||||
i32 bin_index = cell_coords_to_bin_index(space, cell_pos);
|
||||
i32 bin_index = SpaceBinIndexFromCellCoords(space, cell_pos);
|
||||
SpaceCellBin *bin = &space->bins[bin_index];
|
||||
SpaceCell *result = space_cell_nil();
|
||||
for (SpaceCell *n = bin->first_cell; n; n = n->next_in_bin) {
|
||||
if (EqVec2I32(n->pos, cell_pos)) {
|
||||
SpaceCell *result = NilSpaceCell();
|
||||
for (SpaceCell *n = bin->first_cell; n; n = n->next_in_bin)
|
||||
{
|
||||
if (EqVec2I32(n->pos, cell_pos))
|
||||
{
|
||||
result = n;
|
||||
break;
|
||||
}
|
||||
@ -114,34 +113,43 @@ SpaceCell *space_get_cell(Space *space, Vec2I32 cell_pos)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void space_cell_node_alloc(Vec2I32 cell_pos, SpaceEntry *entry)
|
||||
void AcquireSpaceCellNode(Vec2I32 cell_pos, SpaceEntry *entry)
|
||||
{
|
||||
Space *space = space_from_entry(entry);
|
||||
i32 bin_index = cell_coords_to_bin_index(space, cell_pos);
|
||||
Space *space = SpaceFromEntry(entry);
|
||||
i32 bin_index = SpaceBinIndexFromCellCoords(space, cell_pos);
|
||||
SpaceCellBin *bin = &space->bins[bin_index];
|
||||
|
||||
/* Find existing cell */
|
||||
SpaceCell *cell = 0;
|
||||
for (SpaceCell *n = bin->first_cell; n; n = n->next_in_bin) {
|
||||
if (EqVec2I32(n->pos, cell_pos)) {
|
||||
for (SpaceCell *n = bin->first_cell; n; n = n->next_in_bin)
|
||||
{
|
||||
if (EqVec2I32(n->pos, cell_pos))
|
||||
{
|
||||
cell = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Acquire new cell if necessary */
|
||||
if (!cell) {
|
||||
if (space->first_free_cell) {
|
||||
if (!cell)
|
||||
{
|
||||
if (space->first_free_cell)
|
||||
{
|
||||
cell = space->first_free_cell;
|
||||
space->first_free_cell = cell->next_free;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
cell = PushStructNoZero(space->cell_arena, SpaceCell);
|
||||
}
|
||||
ZeroStruct(cell);
|
||||
if (bin->last_cell) {
|
||||
if (bin->last_cell)
|
||||
{
|
||||
bin->last_cell->next_in_bin = cell;
|
||||
cell->prev_in_bin = bin->last_cell;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
bin->first_cell = cell;
|
||||
}
|
||||
bin->last_cell = cell;
|
||||
@ -153,10 +161,13 @@ internal void space_cell_node_alloc(Vec2I32 cell_pos, SpaceEntry *entry)
|
||||
/* Acquire node */
|
||||
SpaceCellNode *node;
|
||||
{
|
||||
if (space->first_free_cell_node) {
|
||||
if (space->first_free_cell_node)
|
||||
{
|
||||
node = space->first_free_cell_node;
|
||||
space->first_free_cell_node = node->next_free;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
node = PushStructNoZero(space->cell_arena, SpaceCellNode);
|
||||
}
|
||||
ZeroStruct(node);
|
||||
@ -164,44 +175,56 @@ internal void space_cell_node_alloc(Vec2I32 cell_pos, SpaceEntry *entry)
|
||||
|
||||
/* Insert into cell list */
|
||||
node->cell = cell;
|
||||
if (cell->last_node) {
|
||||
if (cell->last_node)
|
||||
{
|
||||
cell->last_node->next_in_cell = node;
|
||||
node->prev_in_cell = cell->last_node;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
cell->first_node = node;
|
||||
}
|
||||
cell->last_node = node;
|
||||
|
||||
/* Insert into entry list */
|
||||
node->entry = entry;
|
||||
if (entry->last_node) {
|
||||
if (entry->last_node)
|
||||
{
|
||||
entry->last_node->next_in_entry = node;
|
||||
node->prev_in_entry = entry->last_node;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->first_node = node;
|
||||
}
|
||||
entry->last_node = node;
|
||||
}
|
||||
|
||||
internal void space_cell_node_release(SpaceCellNode *n)
|
||||
void ReleaseSpaceCellNode(SpaceCellNode *n)
|
||||
{
|
||||
SpaceCell *cell = n->cell;
|
||||
SpaceEntry *entry = n->entry;
|
||||
Space *space = space_from_entry(entry);
|
||||
Space *space = SpaceFromEntry(entry);
|
||||
SpaceCellBin *bin = cell->bin;
|
||||
|
||||
/* Remove from entry list */
|
||||
{
|
||||
SpaceCellNode *prev = n->prev_in_entry;
|
||||
SpaceCellNode *next = n->next_in_entry;
|
||||
if (prev) {
|
||||
if (prev)
|
||||
{
|
||||
prev->next_in_entry = next;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->first_node = next;
|
||||
}
|
||||
if (next) {
|
||||
if (next)
|
||||
{
|
||||
next->prev_in_entry = prev;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->last_node = prev;
|
||||
}
|
||||
}
|
||||
@ -210,31 +233,44 @@ internal void space_cell_node_release(SpaceCellNode *n)
|
||||
{
|
||||
SpaceCellNode *prev = n->prev_in_cell;
|
||||
SpaceCellNode *next = n->next_in_cell;
|
||||
if (prev) {
|
||||
if (prev)
|
||||
{
|
||||
prev->next_in_cell = next;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
cell->first_node = next;
|
||||
}
|
||||
if (next) {
|
||||
if (next)
|
||||
{
|
||||
next->prev_in_cell = prev;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
cell->last_node = prev;
|
||||
}
|
||||
}
|
||||
|
||||
/* If cell is now empty, release it */
|
||||
if (!cell->first_node && !cell->last_node) {
|
||||
if (!cell->first_node && !cell->last_node)
|
||||
{
|
||||
/* Remove from bin */
|
||||
SpaceCell *prev = cell->prev_in_bin;
|
||||
SpaceCell *next = cell->next_in_bin;
|
||||
if (prev) {
|
||||
if (prev)
|
||||
{
|
||||
prev->next_in_bin = next;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
bin->first_cell = next;
|
||||
}
|
||||
if (next) {
|
||||
if (next)
|
||||
{
|
||||
next->prev_in_bin = prev;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
bin->last_cell = prev;
|
||||
}
|
||||
cell->valid = 0;
|
||||
@ -249,17 +285,18 @@ internal void space_cell_node_release(SpaceCellNode *n)
|
||||
space->first_free_cell_node = n;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Entry
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Entry
|
||||
|
||||
SpaceEntry *space_entry_from_handle(Space *space, SpaceEntryHandle handle)
|
||||
SpaceEntry *SpaceEntryFromHandle(Space *space, SpaceEntryHandle handle)
|
||||
{
|
||||
SpaceEntry *entry = space_entry_nil();
|
||||
SpaceEntry *entry = NilSpaceEntry();
|
||||
|
||||
if (handle.gen > 0 && handle.idx < space->num_entries_reserved) {
|
||||
if (handle.gen > 0 && handle.idx < space->num_entries_reserved)
|
||||
{
|
||||
SpaceEntry *tmp = &space->entries[handle.idx];
|
||||
if (tmp->handle.gen == handle.gen) {
|
||||
if (tmp->handle.gen == handle.gen)
|
||||
{
|
||||
entry = tmp;
|
||||
}
|
||||
}
|
||||
@ -267,15 +304,18 @@ SpaceEntry *space_entry_from_handle(Space *space, SpaceEntryHandle handle)
|
||||
return entry;
|
||||
}
|
||||
|
||||
SpaceEntry *space_entry_acquire(Space *space, EntityId ent)
|
||||
SpaceEntry *AcquireSpaceEntry(Space *space, EntityId ent)
|
||||
{
|
||||
SpaceEntry *entry = 0;
|
||||
SpaceEntryHandle handle = ZI;
|
||||
if (space->first_free_entry) {
|
||||
if (space->first_free_entry)
|
||||
{
|
||||
entry = space->first_free_entry;
|
||||
space->first_free_entry = entry->next_free;
|
||||
handle = entry->handle;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = PushStructNoZero(space->entry_arena, SpaceEntry);
|
||||
handle.idx = space->num_entries_reserved;
|
||||
handle.gen = 1;
|
||||
@ -288,61 +328,70 @@ SpaceEntry *space_entry_acquire(Space *space, EntityId ent)
|
||||
return entry;
|
||||
}
|
||||
|
||||
void space_entry_release(SpaceEntry *entry)
|
||||
void ReleaseSpaceEntry(SpaceEntry *entry)
|
||||
{
|
||||
/* Release nodes */
|
||||
SpaceCellNode *n = entry->first_node;
|
||||
while (n) {
|
||||
while (n)
|
||||
{
|
||||
SpaceCellNode *next = n->next_in_entry;
|
||||
/* TODO: More efficient batch release that doesn't care about maintaining entry list */
|
||||
space_cell_node_release(n);
|
||||
ReleaseSpaceCellNode(n);
|
||||
n = next;
|
||||
}
|
||||
|
||||
Space *space = space_from_entry(entry);
|
||||
Space *space = SpaceFromEntry(entry);
|
||||
entry->next_free = space->first_free_entry;
|
||||
entry->valid = 0;
|
||||
++entry->handle.gen;
|
||||
space->first_free_entry = entry;
|
||||
}
|
||||
|
||||
void space_entry_update_aabb(SpaceEntry *entry, Aabb new_aabb)
|
||||
void UpdateSpaceEntryAabb(SpaceEntry *entry, Aabb new_aabb)
|
||||
{
|
||||
Space *space = space_from_entry(entry);
|
||||
Space *space = SpaceFromEntry(entry);
|
||||
f32 cell_size = space->cell_size;
|
||||
|
||||
Vec2I32 old_cell_p0 = VEC2I32(0, 0);
|
||||
Vec2I32 old_cell_p1 = VEC2I32(0, 0);
|
||||
if (entry->first_node) {
|
||||
if (entry->first_node)
|
||||
{
|
||||
Aabb old_aabb = entry->aabb;
|
||||
old_cell_p0 = world_to_cell_coords(cell_size, old_aabb.p0);
|
||||
old_cell_p1 = world_to_cell_coords(cell_size, old_aabb.p1);
|
||||
old_cell_p0 = SpaceCellCoordsFromWorldCoords(cell_size, old_aabb.p0);
|
||||
old_cell_p1 = SpaceCellCoordsFromWorldCoords(cell_size, old_aabb.p1);
|
||||
}
|
||||
|
||||
Vec2I32 new_cell_p0 = world_to_cell_coords(cell_size, new_aabb.p0);
|
||||
Vec2I32 new_cell_p1 = world_to_cell_coords(cell_size, new_aabb.p1);
|
||||
Vec2I32 new_cell_p0 = SpaceCellCoordsFromWorldCoords(cell_size, new_aabb.p0);
|
||||
Vec2I32 new_cell_p1 = SpaceCellCoordsFromWorldCoords(cell_size, new_aabb.p1);
|
||||
|
||||
/* Release outdated nodes */
|
||||
SpaceCellNode *n = entry->first_node;
|
||||
while (n) {
|
||||
while (n)
|
||||
{
|
||||
SpaceCell *cell = n->cell;
|
||||
Vec2I32 cell_pos = cell->pos;
|
||||
if (cell_pos.x < new_cell_p0.x || cell_pos.x > new_cell_p1.x || cell_pos.y < new_cell_p0.y || cell_pos.y > new_cell_p1.y) {
|
||||
if (cell_pos.x < new_cell_p0.x || cell_pos.x > new_cell_p1.x || cell_pos.y < new_cell_p0.y || cell_pos.y > new_cell_p1.y)
|
||||
{
|
||||
/* Cell is outside of new AABB */
|
||||
SpaceCellNode *next = n->next_in_entry;
|
||||
space_cell_node_release(n);
|
||||
ReleaseSpaceCellNode(n);
|
||||
n = next;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
n = n->next_in_entry;
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert new nodes */
|
||||
for (i32 y = new_cell_p0.y; y <= new_cell_p1.y; ++y) {
|
||||
for (i32 x = new_cell_p0.x; x <= new_cell_p1.x; ++x) {
|
||||
if (x != 0 && y != 0 && (x < old_cell_p0.x || x > old_cell_p1.x || y < old_cell_p0.y || y > old_cell_p1.y)) {
|
||||
for (i32 y = new_cell_p0.y; y <= new_cell_p1.y; ++y)
|
||||
{
|
||||
for (i32 x = new_cell_p0.x; x <= new_cell_p1.x; ++x)
|
||||
{
|
||||
if (x != 0 && y != 0 && (x < old_cell_p0.x || x > old_cell_p1.x || y < old_cell_p0.y || y > old_cell_p1.y))
|
||||
{
|
||||
/* Cell is outside of old AABB */
|
||||
space_cell_node_alloc(VEC2I32(x, y), entry);
|
||||
AcquireSpaceCellNode(VEC2I32(x, y), entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -350,19 +399,19 @@ void space_entry_update_aabb(SpaceEntry *entry, Aabb new_aabb)
|
||||
entry->aabb = new_aabb;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Iter
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Iter
|
||||
|
||||
SpaceIter space_iter_begin_aabb(Space *space, Aabb aabb)
|
||||
SpaceIter BeginSpaceIterAabb(Space *space, Aabb aabb)
|
||||
{
|
||||
SpaceIter iter = ZI;
|
||||
f32 cell_size = space->cell_size;
|
||||
|
||||
iter.space = space;
|
||||
iter.cell_start = world_to_cell_coords(cell_size, aabb.p0);
|
||||
iter.cell_end = world_to_cell_coords(cell_size, aabb.p1);
|
||||
if (iter.cell_start.x > iter.cell_end.x || iter.cell_start.y > iter.cell_end.y) {
|
||||
iter.cell_start = SpaceCellCoordsFromWorldCoords(cell_size, aabb.p0);
|
||||
iter.cell_end = SpaceCellCoordsFromWorldCoords(cell_size, aabb.p1);
|
||||
if (iter.cell_start.x > iter.cell_end.x || iter.cell_start.y > iter.cell_end.y)
|
||||
{
|
||||
/* Swap cell_start & cell_end */
|
||||
Vec2I32 tmp = iter.cell_start;
|
||||
iter.cell_start = iter.cell_end;
|
||||
@ -377,7 +426,7 @@ SpaceIter space_iter_begin_aabb(Space *space, Aabb aabb)
|
||||
return iter;
|
||||
}
|
||||
|
||||
SpaceEntry *space_iter_next(SpaceIter *iter)
|
||||
SpaceEntry *NextSpaceIterAabb(SpaceIter *iter)
|
||||
{
|
||||
Space *space = iter->space;
|
||||
Aabb iter_aabb = iter->aabb;
|
||||
@ -387,36 +436,49 @@ SpaceEntry *space_iter_next(SpaceIter *iter)
|
||||
i32 span = cell_end.x - cell_start.x;
|
||||
|
||||
SpaceCellNode *next_node = 0;
|
||||
if (cell_cur.x >= cell_start.x && cell_cur.x <= cell_end.x && cell_cur.y >= cell_start.y && cell_cur.y <= cell_end.y) {
|
||||
if (cell_cur.x >= cell_start.x && cell_cur.x <= cell_end.x && cell_cur.y >= cell_start.y && cell_cur.y <= cell_end.y)
|
||||
{
|
||||
/* Started */
|
||||
Assert(iter->prev != 0);
|
||||
next_node = iter->prev->next_in_cell;
|
||||
} else if (cell_cur.x > cell_end.x || cell_cur.y > cell_end.y) {
|
||||
}
|
||||
else if (cell_cur.x > cell_end.x || cell_cur.y > cell_end.y)
|
||||
{
|
||||
/* Ended */
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (next_node) {
|
||||
for (;;)
|
||||
{
|
||||
if (next_node)
|
||||
{
|
||||
SpaceEntry *entry = next_node->entry;
|
||||
Aabb entry_aabb = entry->aabb;
|
||||
if (CLD_TestAabb(entry_aabb, iter_aabb)) {
|
||||
if (CLD_TestAabb(entry_aabb, iter_aabb))
|
||||
{
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
next_node = next_node->next_in_cell;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reached end of cell, find next cell */
|
||||
b32 nextx = (cell_cur.x + 1) <= cell_end.x;
|
||||
b32 nexty = (nextx == 0) && ((cell_cur.y + 1) <= cell_end.y);
|
||||
if (nextx || nexty) {
|
||||
if (nextx || nexty)
|
||||
{
|
||||
cell_cur.x += nextx - (span * nexty);
|
||||
cell_cur.y += nexty;
|
||||
cell_cur.x += (cell_cur.x == 0);
|
||||
cell_cur.y += (cell_cur.y == 0);
|
||||
SpaceCell *cell = space_get_cell(space, cell_cur);
|
||||
SpaceCell *cell = SpaceCellFromCellPos(space, cell_cur);
|
||||
next_node = cell->first_node;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reached end of iter */
|
||||
cell_cur.x += 1;
|
||||
cell_cur.y += 1;
|
||||
|
||||
@ -1,17 +1,19 @@
|
||||
typedef struct SpaceEntryHandle SpaceEntryHandle;
|
||||
struct SpaceEntryHandle {
|
||||
////////////////////////////////
|
||||
//~ Space entry types
|
||||
|
||||
Struct(SpaceEntryHandle)
|
||||
{
|
||||
u64 idx;
|
||||
u64 gen;
|
||||
};
|
||||
|
||||
typedef struct SpaceCellNode SpaceCellNode;
|
||||
typedef struct SpaceEntry SpaceEntry;
|
||||
struct SpaceEntry {
|
||||
Struct(SpaceEntry)
|
||||
{
|
||||
b32 valid;
|
||||
SpaceEntryHandle handle;
|
||||
|
||||
SpaceCellNode *first_node;
|
||||
SpaceCellNode *last_node;
|
||||
struct SpaceCellNode *first_node;
|
||||
struct SpaceCellNode *last_node;
|
||||
|
||||
Aabb aabb;
|
||||
EntityId ent;
|
||||
@ -19,13 +21,15 @@ struct SpaceEntry {
|
||||
SpaceEntry *next_free;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ Space cell types
|
||||
|
||||
/* Links a cell to a entry.
|
||||
* Acts as both a node in the list of entries contained by the cell, and a node in the list of cells containing the entry. */
|
||||
typedef struct SpaceCell SpaceCell;
|
||||
typedef struct SpaceCellNode SpaceCellNode;
|
||||
struct SpaceCellNode {
|
||||
Struct(SpaceCellNode)
|
||||
{
|
||||
SpaceEntry *entry;
|
||||
SpaceCell *cell;
|
||||
struct SpaceCell *cell;
|
||||
|
||||
/* For list of all entries contained by cell */
|
||||
SpaceCellNode *prev_in_cell;
|
||||
@ -38,30 +42,32 @@ struct SpaceCellNode {
|
||||
SpaceCellNode *next_free;
|
||||
};
|
||||
|
||||
typedef struct SpaceCellBin SpaceCellBin;
|
||||
typedef struct SpaceCell SpaceCell;
|
||||
struct SpaceCell {
|
||||
Struct(SpaceCell)
|
||||
{
|
||||
b32 valid;
|
||||
Vec2I32 pos;
|
||||
|
||||
SpaceCellNode *first_node;
|
||||
SpaceCellNode *last_node;
|
||||
|
||||
SpaceCellBin *bin;
|
||||
struct SpaceCellBin *bin;
|
||||
SpaceCell *prev_in_bin;
|
||||
SpaceCell *next_in_bin;
|
||||
|
||||
SpaceCell *next_free;
|
||||
};
|
||||
|
||||
typedef struct SpaceCellBin SpaceCellBin;
|
||||
struct SpaceCellBin {
|
||||
Struct(SpaceCellBin)
|
||||
{
|
||||
SpaceCell *first_cell;
|
||||
SpaceCell *last_cell;
|
||||
};
|
||||
|
||||
typedef struct Space Space;
|
||||
struct Space {
|
||||
////////////////////////////////
|
||||
//~ Space types
|
||||
|
||||
Struct(Space)
|
||||
{
|
||||
b32 valid;
|
||||
f32 cell_size;
|
||||
|
||||
@ -78,8 +84,8 @@ struct Space {
|
||||
SpaceEntry *first_free_entry;
|
||||
};
|
||||
|
||||
typedef struct SpaceIter SpaceIter;
|
||||
struct SpaceIter {
|
||||
Struct(SpaceIter)
|
||||
{
|
||||
Aabb aabb;
|
||||
Space *space;
|
||||
Vec2I32 cell_start;
|
||||
@ -88,57 +94,66 @@ struct SpaceIter {
|
||||
SpaceCellNode *prev;
|
||||
};
|
||||
|
||||
/* ========================== *
|
||||
* Nil
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Nil types
|
||||
|
||||
Inline SpaceEntry *space_entry_nil(void)
|
||||
/* Offset in bytes from start of space struct to start of entry array (assume adjacently allocated) */
|
||||
#define SpaceEntriesOffset (sizeof(Space) + (sizeof(Space) % alignof(SpaceEntry)))
|
||||
|
||||
/* Accessed via NilEntity() */
|
||||
extern Readonly SpaceEntry _g_space_entry_nil;
|
||||
extern Readonly SpaceCell _g_space_cell_nil;
|
||||
extern Readonly Space _g_space_nil;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Nil helpers
|
||||
|
||||
Inline SpaceEntry *NilSpaceEntry(void)
|
||||
{
|
||||
extern Readonly SpaceEntry _g_space_entry_nil;
|
||||
return &_g_space_entry_nil;
|
||||
}
|
||||
|
||||
Inline SpaceCell *space_cell_nil(void)
|
||||
Inline SpaceCell *NilSpaceCell(void)
|
||||
{
|
||||
extern Readonly SpaceCell _g_space_cell_nil;
|
||||
return &_g_space_cell_nil;
|
||||
}
|
||||
|
||||
Inline Space *space_nil(void)
|
||||
Inline Space *NilSpace(void)
|
||||
{
|
||||
extern Readonly Space _g_space_nil;
|
||||
return &_g_space_nil;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Space
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Space
|
||||
|
||||
Space *space_acquire(f32 cell_size, u32 num_bins_sqrt);
|
||||
void space_release(Space *space);
|
||||
void space_reset(Space *space);
|
||||
Space *AcquireSpace(f32 cell_size, u32 num_bins_sqrt);
|
||||
void ReleaseSpace(Space *space);
|
||||
void ResetSpace(Space *space);
|
||||
Space *SpaceFromEntry(SpaceEntry *entry);
|
||||
|
||||
Space *space_from_entry(SpaceEntry *entry);
|
||||
////////////////////////////////
|
||||
//~ Cell
|
||||
|
||||
/* ========================== *
|
||||
* Cell
|
||||
* ========================== */
|
||||
Vec2I32 SpaceCellCoordsFromWorldCoords(f32 cell_size, Vec2 world_pos);
|
||||
i32 SpaceBinIndexFromCellCoords(Space *space, Vec2I32 cell_pos);
|
||||
SpaceCell *SpaceCellFromCellPos(Space *space, Vec2I32 cell_pos);
|
||||
void AcquireSpaceCellNode(Vec2I32 cell_pos, SpaceEntry *entry);
|
||||
void ReleaseSpaceCellNode(SpaceCellNode *n);
|
||||
|
||||
SpaceCell *space_get_cell(Space *space, Vec2I32 cell_pos);
|
||||
////////////////////////////////
|
||||
//~ Entry
|
||||
|
||||
/* ========================== *
|
||||
* Entry
|
||||
* ========================== */
|
||||
SpaceEntry *SpaceEntryFromHandle(Space *space, SpaceEntryHandle handle);
|
||||
SpaceEntry *AcquireSpaceEntry(Space *space, EntityId ent);
|
||||
void ReleaseSpaceEntry(SpaceEntry *entry);
|
||||
void UpdateSpaceEntryAabb(SpaceEntry *entry, Aabb new_aabb);
|
||||
|
||||
SpaceEntry *space_entry_from_handle(Space *space, SpaceEntryHandle handle);
|
||||
SpaceEntry *space_entry_acquire(Space *space, EntityId entity);
|
||||
void space_entry_release(SpaceEntry *entry);
|
||||
void space_entry_update_aabb(SpaceEntry *entry, Aabb new_aabb);
|
||||
////////////////////////////////
|
||||
//~ Iter
|
||||
|
||||
/* ========================== *
|
||||
* Iter
|
||||
* ========================== */
|
||||
|
||||
SpaceIter space_iter_begin_aabb(Space *space, Aabb aabb);
|
||||
SpaceEntry *space_iter_next(SpaceIter *iter);
|
||||
#define space_iter_end(i)
|
||||
SpaceIter BeginSpaceIterAabb(Space *space, Aabb aabb);
|
||||
SpaceEntry *NextSpaceIterAabb(SpaceIter *iter);
|
||||
#define EndSpaceIter(i)
|
||||
|
||||
@ -4,18 +4,18 @@
|
||||
SimAccel AcquireSimAccel(void)
|
||||
{
|
||||
SimAccel accel = ZI;
|
||||
accel.space = space_acquire(SPACE_CELL_SIZE, SPACE_CELL_BINS_SQRT);
|
||||
accel.space = AcquireSpace(SPACE_CELL_SIZE, SPACE_CELL_BINS_SQRT);
|
||||
return accel;
|
||||
}
|
||||
|
||||
void ReleaseSimAccel(SimAccel *accel)
|
||||
{
|
||||
space_release(accel->space);
|
||||
ReleaseSpace(accel->space);
|
||||
}
|
||||
|
||||
void ResetSimAccel(Snapshot *ss, SimAccel *accel)
|
||||
{
|
||||
space_reset(accel->space);
|
||||
ResetSpace(accel->space);
|
||||
|
||||
/* Reset ent space handles */
|
||||
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index)
|
||||
|
||||
@ -12,8 +12,7 @@ Struct(SimAccel)
|
||||
////////////////////////////////
|
||||
//~ Step ctx
|
||||
|
||||
typedef struct SimStepCtx SimStepCtx;
|
||||
struct SimStepCtx
|
||||
Struct(SimStepCtx)
|
||||
{
|
||||
b32 is_master;
|
||||
SimAccel *accel;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user