power_play/src/pp/pp_space.h
2025-10-22 03:22:23 -05:00

160 lines
3.7 KiB
C

////////////////////////////////////////////////////////////
//~ Space entry types
Struct(SpaceEntryHandle)
{
u64 idx;
u64 gen;
};
Struct(SpaceEntry)
{
b32 valid;
SpaceEntryHandle handle;
struct SpaceCellNode *first_node;
struct SpaceCellNode *last_node;
Aabb aabb;
EntityId ent;
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. */
Struct(SpaceCellNode)
{
SpaceEntry *entry;
struct SpaceCell *cell;
/* For list of all entries contained by cell */
SpaceCellNode *prev_in_cell;
SpaceCellNode *next_in_cell;
/* For list of all cells containing entry */
SpaceCellNode *prev_in_entry;
SpaceCellNode *next_in_entry;
SpaceCellNode *next_free;
};
Struct(SpaceCell)
{
b32 valid;
Vec2I32 pos;
SpaceCellNode *first_node;
SpaceCellNode *last_node;
struct SpaceCellBin *bin;
SpaceCell *prev_in_bin;
SpaceCell *next_in_bin;
SpaceCell *next_free;
};
Struct(SpaceCellBin)
{
SpaceCell *first_cell;
SpaceCell *last_cell;
};
////////////////////////////////////////////////////////////
//~ Space types
Struct(Space)
{
b32 valid;
f32 cell_size;
Arena *cell_arena;
SpaceCellBin *bins;
i32 num_bins;
i32 num_bins_sqrt;
SpaceCell *first_free_cell;
SpaceCellNode *first_free_cell_node;
Arena *entry_arena;
u64 num_entries_reserved;
SpaceEntry *entries;
SpaceEntry *first_free_entry;
};
Struct(SpaceIter)
{
Aabb aabb;
Space *space;
Vec2I32 cell_start;
Vec2I32 cell_end;
Vec2I32 cell_cur;
SpaceCellNode *prev;
};
////////////////////////////////////////////////////////////
//~ Nil types
/* 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 *NilSpaceCell(void)
{
extern Readonly SpaceCell _g_space_cell_nil;
return &_g_space_cell_nil;
}
Inline Space *NilSpace(void)
{
extern Readonly Space _g_space_nil;
return &_g_space_nil;
}
////////////////////////////////////////////////////////////
//~ Space
Space *AcquireSpace(f32 cell_size, u32 num_bins_sqrt);
void ReleaseSpace(Space *space);
void ResetSpace(Space *space);
Space *SpaceFromEntry(SpaceEntry *entry);
////////////////////////////////////////////////////////////
//~ 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);
////////////////////////////////////////////////////////////
//~ Entry
SpaceEntry *SpaceEntryFromHandle(Space *space, SpaceEntryHandle handle);
SpaceEntry *AcquireSpaceEntry(Space *space, EntityId ent);
void ReleaseSpaceEntry(SpaceEntry *entry);
void UpdateSpaceEntryAabb(SpaceEntry *entry, Aabb new_aabb);
////////////////////////////////////////////////////////////
//~ Iter
SpaceIter BeginSpaceIterAabb(Space *space, Aabb aabb);
SpaceEntry *NextSpaceIterAabb(SpaceIter *iter);
#define EndSpaceIter(i)