#include "blocks.h" #include "world.h" #include "assets.h" #include #include bool tc_block_is_opaque_by_id(uint32_t id) { return !!(id & TC_BLOCK_OPAQUE_BIT); } uint32_t tc_count_vertices_of_block(tc_chunk_s *chunk, uint8_t x, uint8_t y, uint8_t z) { uint32_t num_vertices = 0; uint32_t top_neighbour = 0; uint32_t bottom_neighbour = 0; uint32_t north_neighbour = 0; uint32_t south_neighbour = 0; uint32_t east_neighbour = 0; uint32_t west_neighbour = 0; if(x < 31) east_neighbour = chunk->blocks[x+1] [y] [z]; if(x > 0) west_neighbour = chunk->blocks[x-1] [y] [z]; if(y < 31) top_neighbour = chunk->blocks[x] [y+1] [z]; if(y > 0) bottom_neighbour = chunk->blocks[x] [y-1] [z]; if(z < 31) north_neighbour = chunk->blocks[x] [y] [z+1]; if(z > 0) south_neighbour = chunk->blocks[x] [y] [z-1]; if(!tc_block_is_opaque_by_id(top_neighbour)) num_vertices += 6; if(!tc_block_is_opaque_by_id(bottom_neighbour)) num_vertices += 6; if(!tc_block_is_opaque_by_id(north_neighbour)) num_vertices += 6; if(!tc_block_is_opaque_by_id(south_neighbour)) num_vertices += 6; if(!tc_block_is_opaque_by_id(east_neighbour)) num_vertices += 6; if(!tc_block_is_opaque_by_id(west_neighbour)) num_vertices += 6; return num_vertices; } uint32_t tc_count_chunk_vertices(tc_chunk_s *chunk) { uint32_t num_vertices = 0; uint32_t x_in_chunk = 0; uint32_t y_in_chunk = 0; uint32_t z_in_chunk = 0; while(x_in_chunk < 32) { y_in_chunk = 0; while(y_in_chunk < 32) { z_in_chunk = 0; while(z_in_chunk < 32) { if(chunk->blocks[x_in_chunk][y_in_chunk][z_in_chunk] != 0) { num_vertices += tc_count_vertices_of_block(chunk, x_in_chunk, y_in_chunk, z_in_chunk); } ++z_in_chunk; } ++y_in_chunk; } ++x_in_chunk; } return num_vertices; } void printfloatarr(float *arr, uint32_t num) { for(int i = 0; i < num; ++i) printf("%f ", arr[i]); } uint32_t tc_meshize_block(tc_chunk_s *chunk, uint8_t x, uint8_t y, uint8_t z, float *xyz, float *uv) { tc_block_entry_s *entry = tc_resolve_id_to_block_entry( chunk->blocks[x][y][z] ); if(entry == NULL) { return 0; } uint32_t num_vertices = 0; uint32_t top_neighbour = 0; uint32_t bottom_neighbour = 0; uint32_t north_neighbour = 0; uint32_t south_neighbour = 0; uint32_t east_neighbour = 0; uint32_t west_neighbour = 0; if(x < 31) east_neighbour = chunk->blocks[x+1] [y] [z]; if(x > 0) west_neighbour = chunk->blocks[x-1] [y] [z]; if(y < 31) top_neighbour = chunk->blocks[x] [y+1] [z]; if(y > 0) bottom_neighbour = chunk->blocks[x] [y-1] [z]; if(z < 31) north_neighbour = chunk->blocks[x] [y] [z+1]; if(z > 0) south_neighbour = chunk->blocks[x] [y] [z-1]; if(!tc_block_is_opaque_by_id(top_neighbour)) { tc_cube_side_mesh_s *side_mesh = tc_block_resolve_name_to_attribute(entry, "top_mesh")->value.pointer; memcpy(&xyz[num_vertices*3], side_mesh->xyz, sizeof(float) * side_mesh->num_vertices * 3); memcpy(&uv[num_vertices*2], side_mesh->uv, sizeof(float) * side_mesh->num_vertices * 2); num_vertices += side_mesh->num_vertices; } if(!tc_block_is_opaque_by_id(bottom_neighbour)) { tc_cube_side_mesh_s *side_mesh = tc_block_resolve_name_to_attribute(entry, "bottom_mesh")->value.pointer; memcpy(&xyz[num_vertices*3], side_mesh->xyz, sizeof(float) * side_mesh->num_vertices * 3); memcpy(&uv[num_vertices*2], side_mesh->uv, sizeof(float) * side_mesh->num_vertices * 2); num_vertices += side_mesh->num_vertices; } if(!tc_block_is_opaque_by_id(south_neighbour)) { tc_cube_side_mesh_s *side_mesh = tc_block_resolve_name_to_attribute(entry, "south_mesh")->value.pointer; memcpy(&xyz[num_vertices*3], side_mesh->xyz, sizeof(float) * side_mesh->num_vertices * 3); memcpy(&uv[num_vertices*2], side_mesh->uv, sizeof(float) * side_mesh->num_vertices * 2); num_vertices += side_mesh->num_vertices; } if(!tc_block_is_opaque_by_id(north_neighbour)) { tc_cube_side_mesh_s *side_mesh = tc_block_resolve_name_to_attribute(entry, "north_mesh")->value.pointer; memcpy(&xyz[num_vertices*3], side_mesh->xyz, sizeof(float) * side_mesh->num_vertices * 3); memcpy(&uv[num_vertices*2], side_mesh->uv, sizeof(float) * side_mesh->num_vertices * 2); num_vertices += side_mesh->num_vertices; } if(!tc_block_is_opaque_by_id(east_neighbour)) { tc_cube_side_mesh_s *side_mesh = tc_block_resolve_name_to_attribute(entry, "east_mesh")->value.pointer; memcpy(&xyz[num_vertices*3], side_mesh->xyz, sizeof(float) * side_mesh->num_vertices * 3); memcpy(&uv[num_vertices*2], side_mesh->uv, sizeof(float) * side_mesh->num_vertices * 2); num_vertices += side_mesh->num_vertices; } if(!tc_block_is_opaque_by_id(west_neighbour)) { tc_cube_side_mesh_s *side_mesh = tc_block_resolve_name_to_attribute(entry, "west_mesh")->value.pointer; memcpy(&xyz[num_vertices*3], side_mesh->xyz, sizeof(float) * side_mesh->num_vertices * 3); memcpy(&uv[num_vertices*2], side_mesh->uv, sizeof(float) * side_mesh->num_vertices * 2); num_vertices += side_mesh->num_vertices; } uint32_t vertex_of_block = 0; vertex_of_block = 0; while(vertex_of_block < num_vertices) { xyz[vertex_of_block*3 + 0] += (float) x; xyz[vertex_of_block*3 + 1] += (float) y; xyz[vertex_of_block*3 + 2] += (float) z; ++vertex_of_block; } return num_vertices; } void tc_meshize_chunk(tc_chunk_s *chunk, void *userdata) { chunk->num_vertices = tc_count_chunk_vertices(chunk); chunk->vertex_positions = calloc(sizeof(float), 3 * chunk->num_vertices); chunk->vertex_uvs = calloc(sizeof(float), 2 * chunk->num_vertices); uint32_t vertex_index = 0; float block_positions[1024]; float block_uvs[1024]; uint32_t x_in_chunk = 0; uint32_t y_in_chunk = 0; uint32_t z_in_chunk = 0; while(x_in_chunk < 32) { y_in_chunk = 0; while(y_in_chunk < 32) { z_in_chunk = 0; while(z_in_chunk < 32) { tc_block_entry_s *entry = tc_resolve_id_to_block_entry( chunk->blocks[x_in_chunk][y_in_chunk][z_in_chunk] ); if(entry == NULL) { ++z_in_chunk; continue; } tc_block_attribute_s *block = tc_block_resolve_name_to_attribute(entry, "block_type"); if(block == NULL) { ++z_in_chunk; continue; } if(!strcmp(block->value.string, "basic_cube")) { memset(block_positions, 0x00, sizeof(float) * 1024); memset(block_uvs, 0x00, sizeof(float) * 1024); uint32_t made_vertices = tc_meshize_block(chunk, x_in_chunk, y_in_chunk, z_in_chunk, block_positions, block_uvs); memcpy( &chunk->vertex_positions[vertex_index*3], block_positions, sizeof(float) * made_vertices * 3 ); memcpy( &chunk->vertex_uvs[vertex_index*2], block_uvs, sizeof(float) * made_vertices * 2 ); vertex_index += made_vertices; } ++z_in_chunk; } ++y_in_chunk; } ++x_in_chunk; } }