//////////////////////////////////////////////////////////// //~ 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)