//////////////////////////////////////////////////////////// //~ Space entry types Struct(PP_SpaceEntryKey) { u64 idx; u64 gen; }; Struct(PP_SpaceEntry) { b32 valid; PP_SpaceEntryKey key; struct PP_SpaceCellNode *first_node; struct PP_SpaceCellNode *last_node; Aabb aabb; PP_EntKey ent; PP_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(PP_SpaceCellNode) { PP_SpaceEntry *entry; struct PP_SpaceCell *cell; /* For list of all entries contained by cell */ PP_SpaceCellNode *prev_in_cell; PP_SpaceCellNode *next_in_cell; /* For list of all cells containing entry */ PP_SpaceCellNode *prev_in_entry; PP_SpaceCellNode *next_in_entry; PP_SpaceCellNode *next_free; }; Struct(PP_SpaceCell) { b32 valid; Vec2I32 pos; PP_SpaceCellNode *first_node; PP_SpaceCellNode *last_node; struct PP_SpaceCellBin *bin; PP_SpaceCell *prev_in_bin; PP_SpaceCell *next_in_bin; PP_SpaceCell *next_free; }; Struct(PP_SpaceCellBin) { PP_SpaceCell *first_cell; PP_SpaceCell *last_cell; }; //////////////////////////////////////////////////////////// //~ Space types Struct(PP_Space) { b32 valid; f32 cell_size; Arena *cell_arena; PP_SpaceCellBin *bins; i32 num_bins; i32 num_bins_sqrt; PP_SpaceCell *first_free_cell; PP_SpaceCellNode *first_free_cell_node; Arena *entry_arena; u64 num_entries_reserved; PP_SpaceEntry *entries; PP_SpaceEntry *first_free_entry; }; Struct(PP_SpaceIter) { Aabb aabb; PP_Space *space; Vec2I32 cell_start; Vec2I32 cell_end; Vec2I32 cell_cur; PP_SpaceCellNode *prev; }; //////////////////////////////////////////////////////////// //~ Nil types /* Offset in bytes from start of space struct to start of entry array (assume adjacently allocated) */ #define PP_SpaceEntriesOffset (sizeof(PP_Space) + (sizeof(PP_Space) % alignof(PP_SpaceEntry))) /* Accessed via NilEnt() */ extern Readonly PP_SpaceEntry PP_nil_space_entry; extern Readonly PP_SpaceCell PP_nil_space_cell; extern Readonly PP_Space PP_nil_space; //////////////////////////////////////////////////////////// //~ Nil helpers Inline PP_SpaceEntry *PP_NilSpaceEntry(void) { extern Readonly PP_SpaceEntry PP_nil_space_entry; return &PP_nil_space_entry; } Inline PP_SpaceCell *PP_NilSpaceCell(void) { extern Readonly PP_SpaceCell PP_nil_space_cell; return &PP_nil_space_cell; } Inline PP_Space *PP_NilSpace(void) { extern Readonly PP_Space PP_nil_space; return &PP_nil_space; } //////////////////////////////////////////////////////////// //~ Space PP_Space *PP_AcquireSpace(f32 cell_size, u32 num_bins_sqrt); void PP_ReleaseSpace(PP_Space *space); void PP_ResetSpace(PP_Space *space); PP_Space *PP_SpaceFromEntry(PP_SpaceEntry *entry); //////////////////////////////////////////////////////////// //~ Cell Vec2I32 PP_SpaceCellCoordsFromWorldCoords(f32 cell_size, Vec2 world_pos); i32 PP_SpaceBinIndexFromCellCoords(PP_Space *space, Vec2I32 cell_pos); PP_SpaceCell *PP_SpaceCellFromCellPos(PP_Space *space, Vec2I32 cell_pos); void PP_AcquireSpaceCellNode(Vec2I32 cell_pos, PP_SpaceEntry *entry); void PP_ReleaseSpaceCellNode(PP_SpaceCellNode *n); //////////////////////////////////////////////////////////// //~ Entry PP_SpaceEntry *PP_SpaceEntryFromKey(PP_Space *space, PP_SpaceEntryKey key); PP_SpaceEntry *PP_AcquireSpaceEntry(PP_Space *space, PP_EntKey ent); void PP_ReleaseSpaceEntry(PP_SpaceEntry *entry); void PP_UpdateSpaceEntryAabb(PP_SpaceEntry *entry, Aabb new_aabb); //////////////////////////////////////////////////////////// //~ Iter PP_SpaceIter PP_BeginSpaceIterAabb(PP_Space *space, Aabb aabb); PP_SpaceEntry *PP_NextSpaceIterAabb(PP_SpaceIter *iter); #define PP_EndSpaceIter(i)