Techneck/code/source-c/chunk_loader.c

172 lines
5.3 KiB
C
Raw Normal View History

2023-10-13 06:00:53 +00:00
#include "world.h"
2023-10-14 19:17:30 +00:00
#include "entity.h"
2023-10-13 06:00:53 +00:00
#include <stdlib.h>
#include <stdio.h>
2023-10-15 09:51:45 +00:00
void tc_add_chunk_to_loader(tc_chunkloader_s *chunkloader, tc_entity_s *entity)
2023-10-13 06:00:53 +00:00
{
2023-10-14 14:48:09 +00:00
if(chunkloader->num_chunks >= chunkloader->chunks_capacity)
2023-10-13 06:00:53 +00:00
{
2023-10-14 14:48:09 +00:00
chunkloader->chunks_capacity *= 2;
2023-10-15 09:51:45 +00:00
chunkloader->chunks = realloc(chunkloader->chunks, sizeof(tc_entity_s *) * chunkloader->chunks_capacity);
2023-10-13 06:00:53 +00:00
}
2023-10-15 09:51:45 +00:00
chunkloader->chunks[chunkloader->num_chunks] = entity;
2023-10-14 14:48:09 +00:00
++chunkloader->num_chunks;
2023-10-13 06:00:53 +00:00
}
bool tc_coord_is_within_loaders_range(tc_chunkloader_s *loader, tc_vec3i_s coord)
{
if(coord.x < (loader->center.x - loader->extent.x / 2)) return false;
if(coord.y < (loader->center.y - loader->extent.y / 2)) return false;
if(coord.z < (loader->center.z - loader->extent.z / 2)) return false;
if(coord.x > (loader->center.x + loader->extent.x / 2)) return false;
if(coord.y > (loader->center.y + loader->extent.y / 2)) return false;
if(coord.z > (loader->center.z + loader->extent.z / 2)) return false;
return true;
}
tc_chunkloader_s * tc_get_corresponding_loader(tc_world_s *world, tc_vec3i_s coord)
{
for(uint32_t loader_index = 0; loader_index < world->num_loaders; ++loader_index)
if(tc_coord_is_within_loaders_range(&world->loaders[loader_index], coord))
return &world->loaders[loader_index];
return NULL;
}
2023-10-15 09:51:45 +00:00
tc_entity_s * tc_get_chunk_of_loader(tc_chunkloader_s *loader, tc_vec3i_s coord)
2023-10-13 06:00:53 +00:00
{
for(uint32_t chunk_index = 0; chunk_index < loader->num_chunks; ++chunk_index)
2023-10-15 09:51:45 +00:00
{
tc_chunk_s *chunk = loader->chunks[chunk_index]->specific;
if(tc_vec3i_equ(chunk->position, coord))
2023-10-13 06:00:53 +00:00
return loader->chunks[chunk_index];
2023-10-15 09:51:45 +00:00
}
2023-10-13 06:00:53 +00:00
return NULL;
}
2023-10-15 09:51:45 +00:00
tc_entity_s * tc_get_loaded_chunk(tc_world_s *world, tc_vec3i_s coord)
2023-10-13 06:00:53 +00:00
{
tc_chunkloader_s *loader = tc_get_corresponding_loader(world, coord);
if(loader == NULL) return NULL;
return tc_get_chunk_of_loader(loader, coord);
}
2023-10-15 09:51:45 +00:00
tc_entity_s * tc_load_chunk_of_loader(tc_chunkloader_s *loader, tc_vec3i_s coord)
2023-10-13 06:00:53 +00:00
{
2023-10-15 09:51:45 +00:00
tc_entity_s *entity = tc_get_chunk_of_loader(loader, coord);
2023-10-13 06:00:53 +00:00
2023-10-15 09:51:45 +00:00
if(entity == NULL)
2023-10-13 06:00:53 +00:00
{
2023-10-15 12:41:53 +00:00
tc_entity_s *entity = tc_create_entity("chunk", loader->world);
2023-10-15 09:51:45 +00:00
tc_chunk_s *chunk = entity->specific;
2023-10-14 19:17:30 +00:00
chunk = entity->specific;
2023-10-13 06:00:53 +00:00
chunk->position = coord;
loader->world->worldgen->fn_generate_chunk(loader->world->worldgen, chunk);
2023-10-15 12:41:53 +00:00
tc_run_hooklist(&loader->world->after_chunk_generate, chunk);
2023-10-13 06:00:53 +00:00
tc_upload_chunk(chunk);
2023-10-15 09:51:45 +00:00
tc_add_chunk_to_loader(loader, entity);
2023-10-13 06:00:53 +00:00
}
2023-10-15 09:51:45 +00:00
return entity;
2023-10-13 06:00:53 +00:00
}
void tc_reload_chunk_of_loader(tc_chunkloader_s *loader, tc_vec3i_s coord)
{
2023-10-15 09:51:45 +00:00
tc_entity_s *entity = tc_get_chunk_of_loader(loader, coord);
tc_chunk_s *chunk = entity->specific;
2023-10-13 06:00:53 +00:00
if(chunk == NULL) return;
2023-10-15 12:41:53 +00:00
tc_meshize_chunk(chunk, NULL);
2023-10-13 06:00:53 +00:00
tc_upload_chunk(chunk);
}
void tc_reload_chunk(tc_world_s *world, tc_vec3i_s coord)
{
tc_chunkloader_s *loader = tc_get_corresponding_loader(world, coord);
if(loader == NULL) return;
tc_reload_chunk_of_loader(loader, coord);
}
void tc_remove_loaders_chunk(tc_chunkloader_s *loader, uint32_t index)
{
2023-10-15 09:51:45 +00:00
tc_delete_entity(loader->chunks[index]);
2023-10-13 06:00:53 +00:00
2023-10-14 08:47:21 +00:00
if(loader->num_chunks != 0)
2023-10-13 06:00:53 +00:00
{
2023-10-14 08:47:21 +00:00
// This is is NOT last element
if((index+1) < loader->num_chunks)
{
loader->chunks[index] = loader->chunks[loader->num_chunks-1]; // move last chunk into gap
}
--loader->num_chunks;
2023-10-13 06:00:53 +00:00
}
}
void tc_remove_unnecessary_chunks_of_loader(tc_chunkloader_s *loader)
{
for(uint32_t chunk_index = 0; chunk_index < loader->num_chunks; ++chunk_index)
{
2023-10-15 09:51:45 +00:00
tc_entity_s *entity = loader->chunks[chunk_index];
tc_chunk_s *chunk = entity->specific;
2023-10-13 06:00:53 +00:00
if(!tc_coord_is_within_loaders_range(loader, chunk->position))
{
tc_remove_loaders_chunk(loader, chunk_index);
}
}
}
void tc_load_all_chunks_of_chunkloader(tc_chunkloader_s *loader)
{
2023-10-14 08:47:21 +00:00
for(int32_t x = 0; x < loader->extent.x; ++x)
2023-10-13 06:00:53 +00:00
{
2023-10-14 08:47:21 +00:00
for(int32_t y = 0; y < loader->extent.y; ++y)
2023-10-13 06:00:53 +00:00
{
2023-10-14 08:47:21 +00:00
for(int32_t z = 0; z < loader->extent.z; ++z)
2023-10-13 06:00:53 +00:00
{
tc_vec3i_s coords;
2023-10-14 08:47:21 +00:00
coords.x = (loader->center.x - (x - ((int32_t) loader->extent.x)))-1;
coords.y = (loader->center.y - (y - ((int32_t) loader->extent.y)))-1;
coords.z = (loader->center.z - (z - ((int32_t) loader->extent.z)))-1;
2023-10-13 06:00:53 +00:00
tc_load_chunk_of_loader(loader, coords);
}
}
}
}
void tc_reload_chunkloader_zone(tc_chunkloader_s *loader)
{
tc_remove_unnecessary_chunks_of_loader(loader);
tc_load_all_chunks_of_chunkloader(loader);
}
2023-10-13 10:23:26 +00:00
uint64_t world_update_tick = 0;
2023-10-13 06:00:53 +00:00
void tc_update_world(tc_world_s *world)
2023-10-13 10:23:26 +00:00
{
2023-10-14 08:47:21 +00:00
if((world_update_tick % 512) == 0)
2023-10-13 06:00:53 +00:00
{
2023-10-13 10:23:26 +00:00
uint32_t chunkloader_index = 0;
while(chunkloader_index < world->num_loaders)
2023-10-13 06:00:53 +00:00
{
2023-10-13 10:23:26 +00:00
if(world->loaders[chunkloader_index].needs_reload)
{
tc_reload_chunkloader_zone(&world->loaders[chunkloader_index]);
}
++chunkloader_index;
2023-10-13 06:00:53 +00:00
}
}
2023-10-13 10:23:26 +00:00
++world_update_tick;
2023-10-13 06:00:53 +00:00
}