power_play/src/sim/sim_space.h
2025-07-29 00:06:43 -05:00

145 lines
3.2 KiB
C

typedef struct SpaceEntryHandle SpaceEntryHandle;
struct SpaceEntryHandle {
u64 idx;
u64 gen;
};
typedef struct SpaceCellNode SpaceCellNode;
typedef struct SpaceEntry SpaceEntry;
struct SpaceEntry {
b32 valid;
SpaceEntryHandle handle;
SpaceCellNode *first_node;
SpaceCellNode *last_node;
Aabb aabb;
EntId ent;
SpaceEntry *next_free;
};
/* 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 {
SpaceEntry *entry;
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;
};
typedef struct SpaceCellBin SpaceCellBin;
typedef struct SpaceCell SpaceCell;
struct SpaceCell {
b32 valid;
V2i32 pos;
SpaceCellNode *first_node;
SpaceCellNode *last_node;
SpaceCellBin *bin;
SpaceCell *prev_in_bin;
SpaceCell *next_in_bin;
SpaceCell *next_free;
};
typedef struct SpaceCellBin SpaceCellBin;
struct SpaceCellBin {
SpaceCell *first_cell;
SpaceCell *last_cell;
};
typedef struct Space Space;
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;
};
typedef struct SpaceIter SpaceIter;
struct SpaceIter {
Aabb aabb;
Space *space;
V2i32 cell_start;
V2i32 cell_end;
V2i32 cell_cur;
SpaceCellNode *prev;
};
/* ========================== *
* Nil
* ========================== */
INLINE SpaceEntry *space_entry_nil(void)
{
extern READONLY SpaceEntry _g_space_entry_nil;
return &_g_space_entry_nil;
}
INLINE SpaceCell *space_cell_nil(void)
{
extern READONLY SpaceCell _g_space_cell_nil;
return &_g_space_cell_nil;
}
INLINE Space *space_nil(void)
{
extern READONLY Space _g_space_nil;
return &_g_space_nil;
}
/* ========================== *
* Space
* ========================== */
Space *space_alloc(f32 cell_size, u32 num_bins_sqrt);
void space_release(Space *space);
void space_reset(Space *space);
Space *space_from_entry(SpaceEntry *entry);
/* ========================== *
* Cell
* ========================== */
SpaceCell *space_get_cell(Space *space, V2i32 cell_pos);
/* ========================== *
* Entry
* ========================== */
SpaceEntry *space_entry_from_handle(Space *space, SpaceEntryHandle handle);
SpaceEntry *space_entry_alloc(Space *space, EntId entity);
void space_entry_release(SpaceEntry *entry);
void space_entry_update_aabb(SpaceEntry *entry, Aabb new_aabb);
/* ========================== *
* Iter
* ========================== */
SpaceIter space_iter_begin_aabb(Space *space, Aabb aabb);
SpaceEntry *space_iter_next(SpaceIter *iter);
#define space_iter_end(i)