#include "pxl8_world.h" #include #include "pxl8_log.h" #include "pxl8_mem.h" #define PXL8_WORLD_ENTITY_CAPACITY 256 struct pxl8_world { pxl8_chunk* active_chunk; pxl8_block_registry* block_registry; pxl8_chunk_cache* chunk_cache; pxl8_entity_pool* entities; }; pxl8_world* pxl8_world_create(void) { pxl8_world* world = pxl8_calloc(1, sizeof(pxl8_world)); if (!world) return NULL; world->block_registry = pxl8_block_registry_create(); world->chunk_cache = pxl8_chunk_cache_create(); world->entities = pxl8_entity_pool_create(PXL8_WORLD_ENTITY_CAPACITY); if (!world->block_registry || !world->chunk_cache || !world->entities) { pxl8_world_destroy(world); return NULL; } return world; } void pxl8_world_destroy(pxl8_world* world) { if (!world) return; pxl8_block_registry_destroy(world->block_registry); pxl8_chunk_cache_destroy(world->chunk_cache); pxl8_entity_pool_destroy(world->entities); pxl8_free(world); } pxl8_chunk_cache* pxl8_world_chunk_cache(pxl8_world* world) { if (!world) return NULL; return world->chunk_cache; } pxl8_chunk* pxl8_world_active_chunk(pxl8_world* world) { if (!world) return NULL; return world->active_chunk; } void pxl8_world_set_active_chunk(pxl8_world* world, pxl8_chunk* chunk) { if (!world) return; world->active_chunk = chunk; } pxl8_block_registry* pxl8_world_block_registry(pxl8_world* world) { if (!world) return NULL; return world->block_registry; } pxl8_entity_pool* pxl8_world_entities(pxl8_world* world) { if (!world) return NULL; return world->entities; } pxl8_entity pxl8_world_spawn(pxl8_world* world) { if (!world || !world->entities) return PXL8_ENTITY_INVALID; return pxl8_entity_spawn(world->entities); } bool pxl8_world_check_collision(const pxl8_world* world, pxl8_vec3 pos, f32 radius) { (void)radius; if (!world || !world->active_chunk) return false; if (world->active_chunk->type == PXL8_CHUNK_BSP && world->active_chunk->bsp) { return pxl8_bsp_point_solid(world->active_chunk->bsp, pos); } return false; } pxl8_vec3 pxl8_world_resolve_collision(const pxl8_world* world, pxl8_vec3 from, pxl8_vec3 to, f32 radius) { if (!world || !world->active_chunk) return to; if (world->active_chunk->type == PXL8_CHUNK_BSP && world->active_chunk->bsp) { return pxl8_bsp_trace(world->active_chunk->bsp, from, to, radius); } return to; } void pxl8_world_update(pxl8_world* world, f32 dt) { (void)dt; if (!world) return; pxl8_chunk_cache_tick(world->chunk_cache); } void pxl8_world_render(pxl8_world* world, pxl8_gfx* gfx, pxl8_vec3 camera_pos) { if (!world || !gfx || !world->active_chunk) return; if (world->active_chunk->type == PXL8_CHUNK_BSP && world->active_chunk->bsp) { pxl8_bsp_render(gfx, world->active_chunk->bsp, camera_pos); } } void pxl8_world_sync(pxl8_world* world, pxl8_net* net) { if (!world || !net) return; u8 chunk_type = pxl8_net_chunk_type(net); u32 chunk_id = pxl8_net_chunk_id(net); if (chunk_type == PXL8_CHUNK_TYPE_BSP && chunk_id != 0) { pxl8_chunk* chunk = pxl8_chunk_cache_get_bsp(world->chunk_cache, chunk_id); if (chunk && chunk->bsp) { if (world->active_chunk != chunk) { world->active_chunk = chunk; pxl8_debug("[CLIENT] Synced BSP chunk id=%u as active (verts=%u faces=%u)", chunk_id, chunk->bsp->num_vertices, chunk->bsp->num_faces); } } } }