#ifndef SPACE_H #define SPACE_H struct space_cell_bucket; struct space_client { b32 valid; struct space_client_handle handle; struct space_cell_node *first_node; struct space_cell_node *last_node; struct aabb aabb; struct entity_handle ent; struct space_client *next_free; }; /* Links a cell to a client. * Acts as both a list of clients contained by cell & a list of cells containing client. */ struct space_cell_node { struct space_client *client; struct space_cell *cell; /* For list of all clients contained by cell */ struct space_cell_node *prev_in_cell; struct space_cell_node *next_in_cell; /* For list of all cells containing client */ struct space_cell_node *prev_in_client; struct space_cell_node *next_in_client; struct space_cell_node *next_free; }; struct space_cell { b32 valid; struct v2i32 pos; struct space_cell_node *first_node; struct space_cell_node *last_node; struct space_cell_bucket *bucket; struct space_cell *prev_in_bucket; struct space_cell *next_in_bucket; struct space_cell *next_free; }; struct space_cell_bucket { struct space_cell *first_cell; struct space_cell *last_cell; }; struct space { b32 valid; f32 cell_size; struct arena cell_arena; struct space_cell_bucket *buckets; u64 num_buckets; u64 num_buckets_sqrt; struct space_cell *first_free_cell; struct space_cell_node *first_free_cell_node; struct arena client_arena; u64 num_clients_reserved; struct space_client *clients; struct space_client *first_free_client; }; struct space_iter { struct aabb aabb; struct space *space; struct v2i32 cell_start; struct v2i32 cell_end; struct v2i32 cell_cur; struct space_cell_node *prev; }; /* ========================== * * Nil * ========================== */ INLINE struct space_client *space_client_nil(void) { extern READONLY struct space_client _g_space_client_nil; return &_g_space_client_nil; } INLINE struct space_cell *space_cell_nil(void) { extern READONLY struct space_cell _g_space_cell_nil; return &_g_space_cell_nil; } INLINE struct space *space_nil(void) { extern READONLY struct space _g_space_nil; return &_g_space_nil; } /* ========================== * * Space * ========================== */ struct space *space_alloc(f32 cell_size, u32 num_buckets_sqrt); void space_release(struct space *space); struct space *space_from_client(struct space_client *client); /* ========================== * * Cell * ========================== */ struct space_cell *space_get_cell(struct space *space, struct v2i32 cell_pos); /* ========================== * * Client * ========================== */ struct space_client *space_client_from_handle(struct space *space, struct space_client_handle handle); struct space_client *space_client_alloc(struct space *space, struct entity_handle entity); void space_client_release(struct space_client *client); void space_client_update_aabb(struct space_client *client, struct aabb new_aabb); /* ========================== * * Iter * ========================== */ struct space_iter space_iter_begin_aabb(struct space *space, struct aabb aabb); struct space_client *space_iter_next(struct space_iter *iter); #define space_iter_end(i) #endif