From 080e8f2437f8cdfdd49ca9dacb705de2b4bbe538 Mon Sep 17 00:00:00 2001 From: Relintai Date: Thu, 12 Mar 2020 23:23:38 +0100 Subject: [PATCH] Broke up VoxelChunk into VoxelChunk and VoxelChunkDefault. --- SCsub | 1 + meshers/cubic_mesher/voxel_cube_points.cpp | 178 +-- meshers/cubic_mesher/voxel_cube_points.h | 3 +- meshers/cubic_mesher/voxel_mesher_cubic.cpp | 4 +- .../voxel_mesher_transvoxel.cpp | 57 +- meshers/voxel_mesher.cpp | 31 +- register_types.cpp | 2 + world/voxel_chunk.cpp | 1230 +--------------- world/voxel_chunk.h | 208 +-- world/voxel_chunk_default.cpp | 1251 +++++++++++++++++ world/voxel_chunk_default.h | 281 ++++ world/voxel_structure.cpp | 2 +- world/voxel_world.cpp | 8 +- 13 files changed, 1725 insertions(+), 1531 deletions(-) create mode 100644 world/voxel_chunk_default.cpp create mode 100644 world/voxel_chunk_default.h diff --git a/SCsub b/SCsub index 444da9f..8986136 100644 --- a/SCsub +++ b/SCsub @@ -34,6 +34,7 @@ sources = [ "world/voxel_world.cpp", "world/voxel_chunk.cpp", + "world/voxel_chunk_default.cpp", "world/voxel_structure.cpp", "world/environment_data.cpp", "world/voxel_chunk_prop_data.cpp", diff --git a/meshers/cubic_mesher/voxel_cube_points.cpp b/meshers/cubic_mesher/voxel_cube_points.cpp index 5524667..bb210d0 100644 --- a/meshers/cubic_mesher/voxel_cube_points.cpp +++ b/meshers/cubic_mesher/voxel_cube_points.cpp @@ -21,6 +21,8 @@ SOFTWARE. */ #include "voxel_cube_points.h" +#include "../../world/voxel_chunk.h" +#include "../../world/voxel_chunk_default.h" const unsigned int VoxelCubePoints::index_table[6][4] = { { P000, P010, P110, P100 }, //VOXEL_FACE_FRONT 0 @@ -200,25 +202,25 @@ void VoxelCubePoints::refresh_neighbours(VoxelChunk *chunk) { int z = _z; //000 - if (chunk->get_voxel(x - 1, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT; - if (chunk->get_voxel(x, y - 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y - 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM; - if (chunk->get_voxel(x, y, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_FRONT; /* - if (chunk->get_voxel(x - 1, y, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT_FRONT; - if (chunk->get_voxel(x - 1, y - 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y - 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_LEFT; - if (chunk->get_voxel(x, y - 1, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y - 1, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_FRONT; - if (chunk->get_voxel(x - 1, y - 1, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y - 1, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_LEFT_FRONT;*/ _point_neighbours[P000] = neighbours; @@ -229,25 +231,25 @@ void VoxelCubePoints::refresh_neighbours(VoxelChunk *chunk) { z = _z; //100 - if (chunk->get_voxel(x + 1, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT; - if (chunk->get_voxel(x, y - 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y - 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM; - if (chunk->get_voxel(x, y, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_FRONT; /* - if (chunk->get_voxel(x + 1, y, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT_FRONT; - if (chunk->get_voxel(x + 1, y - 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y - 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_RIGHT; - if (chunk->get_voxel(x, y - 1, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y - 1, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_FRONT; - if (chunk->get_voxel(x + 1, y - 1, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y - 1, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_RIGHT_FRONT;*/ _point_neighbours[P100] = neighbours; @@ -258,25 +260,25 @@ void VoxelCubePoints::refresh_neighbours(VoxelChunk *chunk) { z = _z; //010 - if (chunk->get_voxel(x - 1, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT; - if (chunk->get_voxel(x, y + 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y + 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP; - if (chunk->get_voxel(x, y, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_FRONT; /* - if (chunk->get_voxel(x - 1, y, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT_FRONT; - if (chunk->get_voxel(x - 1, y + 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y + 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_LEFT; - if (chunk->get_voxel(x, y + 1, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y + 1, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_FRONT; - if (chunk->get_voxel(x - 1, y + 1, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y + 1, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_LEFT_FRONT;*/ _point_neighbours[P010] = neighbours; @@ -287,25 +289,25 @@ void VoxelCubePoints::refresh_neighbours(VoxelChunk *chunk) { z = _z; //110 - if (chunk->get_voxel(x + 1, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT; - if (chunk->get_voxel(x, y + 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y + 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP; - if (chunk->get_voxel(x, y, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_FRONT; /* - if (chunk->get_voxel(x + 1, y, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT_FRONT; - if (chunk->get_voxel(x + 1, y + 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y + 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_RIGHT; - if (chunk->get_voxel(x, y + 1, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y + 1, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_FRONT; - if (chunk->get_voxel(x + 1, y + 1, z - 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y + 1, z - 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_RIGHT_FRONT;*/ _point_neighbours[P110] = neighbours; @@ -316,25 +318,25 @@ void VoxelCubePoints::refresh_neighbours(VoxelChunk *chunk) { z = _z + 1; //001 - if (chunk->get_voxel(x - 1, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT; - if (chunk->get_voxel(x, y - 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y - 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM; - if (chunk->get_voxel(x, y, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BACK; /* - if (chunk->get_voxel(x - 1, y, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT_BACK; - if (chunk->get_voxel(x - 1, y - 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y - 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_LEFT; - if (chunk->get_voxel(x, y - 1, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y - 1, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_BACK; - if (chunk->get_voxel(x - 1, y - 1, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y - 1, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_LEFT_BACK;*/ _point_neighbours[P001] = neighbours; @@ -345,25 +347,25 @@ void VoxelCubePoints::refresh_neighbours(VoxelChunk *chunk) { z = _z + 1; //101 - if (chunk->get_voxel(x + 1, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT; - if (chunk->get_voxel(x, y - 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y - 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM; - if (chunk->get_voxel(x, y, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BACK; /* - if (chunk->get_voxel(x + 1, y, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT_BACK; - if (chunk->get_voxel(x + 1, y - 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y - 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_RIGHT; - if (chunk->get_voxel(x, y - 1, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y - 1, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_BACK; - if (chunk->get_voxel(x + 1, y - 1, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y - 1, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_RIGHT_BACK;*/ _point_neighbours[P101] = neighbours; @@ -374,25 +376,25 @@ void VoxelCubePoints::refresh_neighbours(VoxelChunk *chunk) { z = _z + 1; //011 - if (chunk->get_voxel(x - 1, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT; - if (chunk->get_voxel(x, y + 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y + 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP; - if (chunk->get_voxel(x, y, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BACK; /* - if (chunk->get_voxel(x - 1, y, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT_BACK; - if (chunk->get_voxel(x - 1, y + 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y + 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_LEFT; - if (chunk->get_voxel(x, y + 1, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y + 1, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_BACK; - if (chunk->get_voxel(x - 1, y + 1, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x - 1, y + 1, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_LEFT_BACK;*/ _point_neighbours[P011] = neighbours; @@ -403,25 +405,25 @@ void VoxelCubePoints::refresh_neighbours(VoxelChunk *chunk) { z = _z + 1; //111 - if (chunk->get_voxel(x + 1, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT; - if (chunk->get_voxel(x, y + 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y + 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP; - if (chunk->get_voxel(x, y, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_BACK; /* - if (chunk->get_voxel(x + 1, y, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT_BACK; - if (chunk->get_voxel(x + 1, y + 1, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y + 1, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_RIGHT; - if (chunk->get_voxel(x, y + 1, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y + 1, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_BACK; - if (chunk->get_voxel(x + 1, y + 1, z + 1, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + 1, y + 1, z + 1, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_RIGHT_BACK;*/ _point_neighbours[P111] = neighbours; @@ -443,44 +445,44 @@ void VoxelCubePoints::setup(VoxelChunk *chunk, int x, int y, int z, int size) { _z = z; _size = size; - _point_types[P000] = chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE); - _point_types[P100] = chunk->get_voxel(x + size, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE); - _point_types[P010] = chunk->get_voxel(x, y + size, z, VoxelChunk::DEFAULT_CHANNEL_TYPE); - _point_types[P001] = chunk->get_voxel(x, y, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE); - _point_types[P110] = chunk->get_voxel(x + size, y + size, z, VoxelChunk::DEFAULT_CHANNEL_TYPE); - _point_types[P011] = chunk->get_voxel(x, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE); - _point_types[P101] = chunk->get_voxel(x + size, y, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE); - _point_types[P111] = chunk->get_voxel(x + size, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE); + _point_types[P000] = chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + _point_types[P100] = chunk->get_voxel(x + size, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + _point_types[P010] = chunk->get_voxel(x, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + _point_types[P001] = chunk->get_voxel(x, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + _point_types[P110] = chunk->get_voxel(x + size, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + _point_types[P011] = chunk->get_voxel(x, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + _point_types[P101] = chunk->get_voxel(x + size, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + _point_types[P111] = chunk->get_voxel(x + size, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); if (!has_points()) return; - _point_fills[P000] = chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_ISOLEVEL); - _point_fills[P100] = chunk->get_voxel(x + size, y, z, VoxelChunk::DEFAULT_CHANNEL_ISOLEVEL); - _point_fills[P010] = chunk->get_voxel(x, y + size, z, VoxelChunk::DEFAULT_CHANNEL_ISOLEVEL); - _point_fills[P001] = chunk->get_voxel(x, y, z + size, VoxelChunk::DEFAULT_CHANNEL_ISOLEVEL); - _point_fills[P110] = chunk->get_voxel(x + size, y + size, z, VoxelChunk::DEFAULT_CHANNEL_ISOLEVEL); - _point_fills[P011] = chunk->get_voxel(x, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_ISOLEVEL); - _point_fills[P101] = chunk->get_voxel(x + size, y, z + size, VoxelChunk::DEFAULT_CHANNEL_ISOLEVEL); - _point_fills[P111] = chunk->get_voxel(x + size, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_ISOLEVEL); + _point_fills[P000] = chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL); + _point_fills[P100] = chunk->get_voxel(x + size, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL); + _point_fills[P010] = chunk->get_voxel(x, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL); + _point_fills[P001] = chunk->get_voxel(x, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL); + _point_fills[P110] = chunk->get_voxel(x + size, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL); + _point_fills[P011] = chunk->get_voxel(x, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL); + _point_fills[P101] = chunk->get_voxel(x + size, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL); + _point_fills[P111] = chunk->get_voxel(x + size, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL); - _point_aos[P000] = chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_AO); - _point_aos[P100] = chunk->get_voxel(x + size, y, z, VoxelChunk::DEFAULT_CHANNEL_AO); - _point_aos[P010] = chunk->get_voxel(x, y + size, z, VoxelChunk::DEFAULT_CHANNEL_AO); - _point_aos[P001] = chunk->get_voxel(x, y, z + size, VoxelChunk::DEFAULT_CHANNEL_AO); - _point_aos[P110] = chunk->get_voxel(x + size, y + size, z, VoxelChunk::DEFAULT_CHANNEL_AO); - _point_aos[P011] = chunk->get_voxel(x, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_AO); - _point_aos[P101] = chunk->get_voxel(x + size, y, z + size, VoxelChunk::DEFAULT_CHANNEL_AO); - _point_aos[P111] = chunk->get_voxel(x + size, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_AO); + _point_aos[P000] = chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_AO); + _point_aos[P100] = chunk->get_voxel(x + size, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_AO); + _point_aos[P010] = chunk->get_voxel(x, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_AO); + _point_aos[P001] = chunk->get_voxel(x, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_AO); + _point_aos[P110] = chunk->get_voxel(x + size, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_AO); + _point_aos[P011] = chunk->get_voxel(x, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_AO); + _point_aos[P101] = chunk->get_voxel(x + size, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_AO); + _point_aos[P111] = chunk->get_voxel(x + size, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_AO); - _point_colors[P000] = Color(chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); - _point_colors[P100] = Color(chunk->get_voxel(x + size, y, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x + size, y, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x + size, y, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); - _point_colors[P010] = Color(chunk->get_voxel(x, y + size, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x, y + size, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x, y + size, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); - _point_colors[P001] = Color(chunk->get_voxel(x, y, z + size, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x, y, z + size, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x, y, z + size, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); - _point_colors[P110] = Color(chunk->get_voxel(x + size, y + size, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x + size, y + size, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x + size, y + size, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); - _point_colors[P011] = Color(chunk->get_voxel(x, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); - _point_colors[P101] = Color(chunk->get_voxel(x + size, y, z + size, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x + size, y, z + size, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x + size, y, z + size, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); - _point_colors[P111] = Color(chunk->get_voxel(x + size, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x + size, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x + size, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P000] = Color(chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P100] = Color(chunk->get_voxel(x + size, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x + size, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x + size, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P010] = Color(chunk->get_voxel(x, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P001] = Color(chunk->get_voxel(x, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P110] = Color(chunk->get_voxel(x + size, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x + size, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x + size, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P011] = Color(chunk->get_voxel(x, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P101] = Color(chunk->get_voxel(x + size, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x + size, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x + size, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); + _point_colors[P111] = Color(chunk->get_voxel(x + size, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, chunk->get_voxel(x + size, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, chunk->get_voxel(x + size, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); refresh_neighbours(chunk); diff --git a/meshers/cubic_mesher/voxel_cube_points.h b/meshers/cubic_mesher/voxel_cube_points.h index bc7ff7d..947f0d4 100644 --- a/meshers/cubic_mesher/voxel_cube_points.h +++ b/meshers/cubic_mesher/voxel_cube_points.h @@ -26,8 +26,7 @@ SOFTWARE. #include "core/reference.h" #include "core/vector.h" -#include "../../world/voxel_chunk.h" - +class VoxelChunk; class SubVoxelFacePointsHelper; class VoxelCubePoints : public Reference { diff --git a/meshers/cubic_mesher/voxel_mesher_cubic.cpp b/meshers/cubic_mesher/voxel_mesher_cubic.cpp index 0e2fae3..52c50fc 100644 --- a/meshers/cubic_mesher/voxel_mesher_cubic.cpp +++ b/meshers/cubic_mesher/voxel_mesher_cubic.cpp @@ -22,8 +22,10 @@ SOFTWARE. #include "voxel_mesher_cubic.h" +#include "../../world/voxel_chunk_default.h" + void VoxelMesherCubic::_add_chunk(Node *p_chunk) { - VoxelChunk *chunk = Object::cast_to(p_chunk); + VoxelChunkDefault *chunk = Object::cast_to(p_chunk); ERR_FAIL_COND(!ObjectDB::instance_validate(chunk)); diff --git a/meshers/transvoxel_uv_mesher/voxel_mesher_transvoxel.cpp b/meshers/transvoxel_uv_mesher/voxel_mesher_transvoxel.cpp index d710697..49cacf5 100644 --- a/meshers/transvoxel_uv_mesher/voxel_mesher_transvoxel.cpp +++ b/meshers/transvoxel_uv_mesher/voxel_mesher_transvoxel.cpp @@ -23,6 +23,7 @@ SOFTWARE. #include "voxel_mesher_transvoxel.h" #include "../../world/voxel_chunk.h" +#include "../../world/voxel_chunk_default.h" #include "core/array.h" #include "core/dictionary.h" #include "servers/visual_server.h" @@ -35,14 +36,14 @@ void VoxelMesherTransvoxel::set_texture_scale(const int value) { } void VoxelMesherTransvoxel::get_voxel_type_array(int *arr, VoxelChunk *chunk, const int x, const int y, const int z, const int size) { - arr[0] = chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE); - arr[1] = chunk->get_voxel(x, y + size, z, VoxelChunk::DEFAULT_CHANNEL_TYPE); - arr[2] = chunk->get_voxel(x, y, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE); - arr[3] = chunk->get_voxel(x, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE); - arr[4] = chunk->get_voxel(x + size, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE); - arr[5] = chunk->get_voxel(x + size, y + size, z, VoxelChunk::DEFAULT_CHANNEL_TYPE); - arr[6] = chunk->get_voxel(x + size, y, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE); - arr[7] = chunk->get_voxel(x + size, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE); + arr[0] = chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + arr[1] = chunk->get_voxel(x, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + arr[2] = chunk->get_voxel(x, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + arr[3] = chunk->get_voxel(x, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + arr[4] = chunk->get_voxel(x + size, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + arr[5] = chunk->get_voxel(x + size, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + arr[6] = chunk->get_voxel(x + size, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + arr[7] = chunk->get_voxel(x + size, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); } int VoxelMesherTransvoxel::get_case_code_from_arr(const int *data) { int case_code = 0; @@ -76,28 +77,28 @@ int VoxelMesherTransvoxel::get_case_code_from_arr(const int *data) { int VoxelMesherTransvoxel::get_case_code(VoxelChunk *chunk, const int x, const int y, const int z, const int size) { int case_code = 0; - if (chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) case_code = case_code | VOXEL_ENTRY_MASK_000; - if (chunk->get_voxel(x, y + size, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) case_code = case_code | VOXEL_ENTRY_MASK_010; - if (chunk->get_voxel(x, y, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) case_code = case_code | VOXEL_ENTRY_MASK_001; - if (chunk->get_voxel(x, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) case_code = case_code | VOXEL_ENTRY_MASK_011; - if (chunk->get_voxel(x + size, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + size, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) case_code = case_code | VOXEL_ENTRY_MASK_100; - if (chunk->get_voxel(x + size, y + size, z, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + size, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) case_code = case_code | VOXEL_ENTRY_MASK_110; - if (chunk->get_voxel(x + size, y, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + size, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) case_code = case_code | VOXEL_ENTRY_MASK_101; - if (chunk->get_voxel(x + size, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE) != 0) + if (chunk->get_voxel(x + size, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE) != 0) case_code = case_code | VOXEL_ENTRY_MASK_111; return case_code; @@ -106,48 +107,48 @@ int VoxelMesherTransvoxel::get_case_code(VoxelChunk *chunk, const int x, const i int VoxelMesherTransvoxel::get_voxel_type(VoxelChunk *chunk, const int x, const int y, const int z, const int size) { int type = 0; - type = chunk->get_voxel(x, y + size, z, VoxelChunk::DEFAULT_CHANNEL_TYPE); + type = chunk->get_voxel(x, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); if (type != 0) return type; - type = chunk->get_voxel(x, y, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE); + type = chunk->get_voxel(x, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); if (type != 0) return type; - type = chunk->get_voxel(x, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE); + type = chunk->get_voxel(x, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); if (type != 0) return type; - type = chunk->get_voxel(x + size, y + size, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE); + type = chunk->get_voxel(x + size, y + size, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); if (type != 0) return type; - type = chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE); + type = chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); if (type != 0) return type; - type = chunk->get_voxel(x + size, y + size, z, VoxelChunk::DEFAULT_CHANNEL_TYPE); + type = chunk->get_voxel(x + size, y + size, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); if (type != 0) return type; - type = chunk->get_voxel(x + size, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE); + type = chunk->get_voxel(x + size, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); if (type != 0) return type; - type = chunk->get_voxel(x + size, y, z + size, VoxelChunk::DEFAULT_CHANNEL_TYPE); + type = chunk->get_voxel(x + size, y, z + size, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); return type; } void VoxelMesherTransvoxel::_add_chunk(Node *p_chunk) { - VoxelChunk *chunk = Object::cast_to(p_chunk); + VoxelChunkDefault *chunk = Object::cast_to(p_chunk); ERR_FAIL_COND(!ObjectDB::instance_validate(chunk)); @@ -259,7 +260,7 @@ void VoxelMesherTransvoxel::_add_chunk(Node *p_chunk) { Vector3 offs0 = corner_id_to_vertex(fv) * lod_size; Vector3 offs1 = corner_id_to_vertex(sv) * lod_size; - int type = chunk->get_voxel(int(x + offs0.x), int(y + offs0.y), int(z + offs0.z), VoxelChunk::DEFAULT_CHANNEL_TYPE); + int type = chunk->get_voxel(int(x + offs0.x), int(y + offs0.y), int(z + offs0.z), VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); int fill = 0; @@ -267,12 +268,12 @@ void VoxelMesherTransvoxel::_add_chunk(Node *p_chunk) { Vector3 vert_dir; if (type == 0) { - fill = chunk->get_voxel(int(x + offs1.x), int(y + offs1.y), int(z + offs1.z), VoxelChunk::DEFAULT_CHANNEL_ISOLEVEL); + fill = chunk->get_voxel(int(x + offs1.x), int(y + offs1.y), int(z + offs1.z), VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL); vert_pos = get_regular_vertex_second_position(case_code, i); vert_dir = get_regular_vertex_first_position(case_code, i); } else { - fill = chunk->get_voxel(int(x + offs0.x), int(y + offs0.y), int(z + offs0.z), VoxelChunk::DEFAULT_CHANNEL_ISOLEVEL); + fill = chunk->get_voxel(int(x + offs0.x), int(y + offs0.y), int(z + offs0.z), VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL); vert_pos = get_regular_vertex_first_position(case_code, i); vert_dir = get_regular_vertex_second_position(case_code, i); diff --git a/meshers/voxel_mesher.cpp b/meshers/voxel_mesher.cpp index 05bb862..2055173 100644 --- a/meshers/voxel_mesher.cpp +++ b/meshers/voxel_mesher.cpp @@ -23,6 +23,7 @@ SOFTWARE. #include "voxel_mesher.h" #include "../world/voxel_chunk.h" +#include "../world/voxel_chunk_default.h" bool VoxelMesher::Vertex::operator==(const Vertex &p_vertex) const { @@ -603,12 +604,12 @@ void VoxelMesher::_bake_colors(Node *p_chunk) { if (chunk->validate_channel_data_position(x, y, z)) { Color light = Color( - chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, - chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, - chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); + chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, + chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, + chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); - float ao = (chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_AO) / 255.0) * _ao_strength; - float rao = chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_RANDOM_AO) / 255.0; + float ao = (chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_AO) / 255.0) * _ao_strength; + float rao = chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_RANDOM_AO) / 255.0; ao += rao; @@ -672,12 +673,12 @@ void VoxelMesher::_bake_liquid_colors(Node *p_chunk) { if (chunk->validate_channel_data_position(x, y, z)) { Color light = Color( - chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, - chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, - chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); + chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, + chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, + chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0); - float ao = (chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_AO) / 255.0) * _ao_strength; - float rao = chunk->get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_RANDOM_AO) / 255.0; + float ao = (chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_AO) / 255.0) * _ao_strength; + float rao = chunk->get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_RANDOM_AO) / 255.0; ao += rao; @@ -858,11 +859,11 @@ void VoxelMesher::add_vertex(const Vector3 &vertex) { vtx.normal = _last_normal; vtx.uv = _last_uv; vtx.uv2 = _last_uv2; -// Todo? -// vtx.weights = _last_weights; -// vtx.bones = _last_bones; -// vtx.tangent = _last_tangent.normal; -// vtx.binormal = _last_normal.cross(_last_tangent.normal).normalized() * _last_tangent.d; + // Todo? + // vtx.weights = _last_weights; + // vtx.bones = _last_bones; + // vtx.tangent = _last_tangent.normal; + // vtx.binormal = _last_normal.cross(_last_tangent.normal).normalized() * _last_tangent.d; _vertices.push_back(vtx); } diff --git a/register_types.cpp b/register_types.cpp index 61ec490..2b14f32 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -40,6 +40,7 @@ SOFTWARE. #include "world/environment_data.h" #include "world/voxel_chunk.h" +#include "world/voxel_chunk_default.h" #include "world/voxel_chunk_prop_data.h" #include "world/voxel_structure.h" #include "world/voxel_world.h" @@ -92,6 +93,7 @@ void register_voxelman_types() { ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); diff --git a/world/voxel_chunk.cpp b/world/voxel_chunk.cpp index 5d12c98..ded1433 100644 --- a/world/voxel_chunk.cpp +++ b/world/voxel_chunk.cpp @@ -24,8 +24,6 @@ SOFTWARE. #include "voxel_world.h" -const String VoxelChunk::BINDING_STRING_ACTIVE_BUILD_PHASE_TYPE = "Normal,Process,Physics Process"; - _FORCE_INLINE_ bool VoxelChunk::get_is_generating() const { return _is_generating; } @@ -33,39 +31,6 @@ _FORCE_INLINE_ void VoxelChunk::set_is_generating(bool value) { _is_generating = value; } -_FORCE_INLINE_ bool VoxelChunk::get_is_build_threaded() const { - return _is_build_threaded; -} -_FORCE_INLINE_ void VoxelChunk::set_is_build_threaded(bool value) { - _is_build_threaded = value; -} - -_FORCE_INLINE_ VoxelChunk::ActiveBuildPhaseType VoxelChunk::get_active_build_phase_type() const { - return _active_build_phase_type; -} -_FORCE_INLINE_ void VoxelChunk::set_active_build_phase_type(const VoxelChunk::ActiveBuildPhaseType value) { - _active_build_phase_type = value; - - if (_active_build_phase_type == VoxelChunk::BUILD_PHASE_TYPE_PHYSICS_PROCESS) { - set_physics_process_internal(true); - } else { - set_physics_process_internal(false); - } -} - -bool VoxelChunk::get_build_phase_done() const { - _build_phase_done_mutex->lock(); - bool v = _build_phase_done; - _build_phase_done_mutex->unlock(); - - return v; -} -void VoxelChunk::set_build_phase_done(bool value) { - _build_phase_done_mutex->lock(); - _build_phase_done = value; - _build_phase_done_mutex->unlock(); -} - _FORCE_INLINE_ bool VoxelChunk::get_dirty() const { return _dirty; } @@ -170,25 +135,10 @@ _FORCE_INLINE_ void VoxelChunk::set_margin_end(int value) { Ref VoxelChunk::get_library() { return _library; } -void VoxelChunk::set_library(Ref value) { +void VoxelChunk::set_library(const Ref &value) { _library = value; } -int VoxelChunk::get_lod_size() const { - return _lod_size; -} -void VoxelChunk::set_lod_size(const int lod_size) { - _lod_size = lod_size; - - for (int i = 0; i < _meshers.size(); ++i) { - Ref mesher = _meshers.get(i); - - ERR_CONTINUE(!mesher.is_valid()); - - mesher->set_lod_size(_lod_size); - } -} - float VoxelChunk::get_voxel_scale() const { return _voxel_scale; } @@ -204,18 +154,19 @@ void VoxelChunk::set_voxel_scale(float value) { } } -int VoxelChunk::get_current_build_phase() { - return _current_build_phase; +VoxelWorld *VoxelChunk::get_voxel_world() const { + return _voxel_world; } -void VoxelChunk::set_current_build_phase(int value) { - _current_build_phase = value; +void VoxelChunk::set_voxel_world(VoxelWorld *world) { + _voxel_world = world; } +void VoxelChunk::set_voxel_world_bind(Node *world) { + if (world == NULL) { + _voxel_world = NULL; + return; + } -int VoxelChunk::get_max_build_phase() { - return _max_build_phases; -} -void VoxelChunk::set_max_build_phase(int value) { - _max_build_phases = value; + _voxel_world = Object::cast_to(world); } Ref VoxelChunk::get_mesher(int index) const { @@ -240,82 +191,12 @@ int VoxelChunk::get_mesher_count() { return _meshers.size(); } -VoxelWorld *VoxelChunk::get_voxel_world() const { - return _voxel_world; -} -void VoxelChunk::set_voxel_world(VoxelWorld *world) { - _voxel_world = world; -} -void VoxelChunk::set_voxel_world_bind(Node *world) { - if (world == NULL) { - _voxel_world = NULL; - return; - } - - _voxel_world = Object::cast_to(world); -} - -bool VoxelChunk::get_create_collider() const { - return _create_collider; -} -void VoxelChunk::set_create_collider(bool value) { - _create_collider = value; -} - -bool VoxelChunk::get_bake_lights() const { - return _bake_lights; -} -void VoxelChunk::set_bake_lights(bool value) { - _bake_lights = value; -} - -RID VoxelChunk::get_mesh_rid() { - return _mesh_rid; -} -RID VoxelChunk::get_mesh_instance_rid() { - return _mesh_instance_rid; -} -RID VoxelChunk::get_shape_rid() { - return _shape_rid; -} -RID VoxelChunk::get_body_rid() { - return _body_rid; -} - -RID VoxelChunk::get_prop_mesh_rid() { - return _prop_mesh_rid; -} -RID VoxelChunk::get_prop_mesh_instance_rid() { - return _prop_mesh_instance_rid; -} -RID VoxelChunk::get_prop_shape_rid() { - return _prop_shape_rid; -} -RID VoxelChunk::get_prop_body_rid() { - return _prop_body_rid; -} - -RID VoxelChunk::get_liquid_mesh_rid() { - return _liquid_mesh_rid; -} -RID VoxelChunk::get_liquid_mesh_instance_rid() { - return _liquid_mesh_instance_rid; -} - -RID VoxelChunk::get_clutter_mesh_rid() { - return _clutter_mesh_rid; -} -RID VoxelChunk::get_clutter_mesh_instance_rid() { - return _clutter_mesh_instance_rid; -} - //Voxel Data void VoxelChunk::setup_channels() { + ERR_FAIL_COND_MSG(!has_method("_setup_channels"), "VoxelChunk: _setup_channels() is missing! Please implement it!"); + call("_setup_channels"); } -void VoxelChunk::_setup_channels() { - set_channel_count(MAX_DEFAULT_CHANNELS); -} void VoxelChunk::set_size(uint32_t size_x, uint32_t size_y, uint32_t size_z, uint32_t margin_start, uint32_t margin_end) { if (_size_x == size_x && _size_y == size_y && _size_z == size_z && _margin_start == margin_start && _margin_end == margin_end) { @@ -515,563 +396,22 @@ _FORCE_INLINE_ uint32_t VoxelChunk::get_data_size() const { return _data_size_x * _data_size_y * _data_size_z; } -//Data Management functions -void VoxelChunk::generate_ao() { - ERR_FAIL_COND(_data_size_x == 0 || _data_size_y == 0 || _data_size_z == 0); - - int size_x = get_size_x() + get_margin_end(); - int size_y = get_size_y() + get_margin_end(); - int size_z = get_size_z() + get_margin_end(); - - for (int y = get_margin_start() - 1; y < size_y - 1; ++y) { - for (int z = get_margin_start() - 1; z < size_z - 1; ++z) { - for (int x = get_margin_start() - 1; x < size_x - 1; ++x) { - int current = get_voxel(x, y, z, DEFAULT_CHANNEL_ISOLEVEL); - - int sum = get_voxel(x + 1, y, z, DEFAULT_CHANNEL_ISOLEVEL); - sum += get_voxel(x - 1, y, z, DEFAULT_CHANNEL_ISOLEVEL); - sum += get_voxel(x, y + 1, z, DEFAULT_CHANNEL_ISOLEVEL); - sum += get_voxel(x, y - 1, z, DEFAULT_CHANNEL_ISOLEVEL); - sum += get_voxel(x, y, z + 1, DEFAULT_CHANNEL_ISOLEVEL); - sum += get_voxel(x, y, z - 1, DEFAULT_CHANNEL_ISOLEVEL); - - sum /= 6; - - sum -= current; - - if (sum < 0) - sum = 0; - - set_voxel(sum, x, y, z, DEFAULT_CHANNEL_AO); - } - } - } -} - -void VoxelChunk::add_light(int local_x, int local_y, int local_z, int size, Color color) { - ERR_FAIL_COND(size < 0); - - //float sizef = static_cast(size); - //float rf = (color.r / sizef); - //float gf = (color.g / sizef); - //float bf = (color.b / sizef); - - int64_t dsx = static_cast(_data_size_x); - int64_t dsy = static_cast(_data_size_y); - int64_t dsz = static_cast(_data_size_z); - - for (int y = local_y - size; y <= local_y + size; ++y) { - if (y < 0 || y >= dsy) - continue; - - for (int z = local_z - size; z <= local_z + size; ++z) { - if (z < 0 || z >= dsz) - continue; - - for (int x = local_x - size; x <= local_x + size; ++x) { - if (x < 0 || x >= dsx) - continue; - - int lx = x - local_x; - int ly = y - local_y; - int lz = z - local_z; - - float str = size - (((float)lx * lx + ly * ly + lz * lz)); - str /= size; - - if (str < 0) - continue; - - int r = color.r * str * 255.0; - int g = color.g * str * 255.0; - int b = color.b * str * 255.0; - - r += get_voxel(x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_R); - g += get_voxel(x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_G); - b += get_voxel(x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_B); - - if (r > 255) - r = 255; - - if (g > 255) - g = 255; - - if (b > 255) - b = 255; - - set_voxel(r, x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_R); - set_voxel(g, x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_G); - set_voxel(b, x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_B); - } - } - } -} -void VoxelChunk::clear_baked_lights() { - fill_channel(0, DEFAULT_CHANNEL_LIGHT_COLOR_R); - fill_channel(0, DEFAULT_CHANNEL_LIGHT_COLOR_G); - fill_channel(0, DEFAULT_CHANNEL_LIGHT_COLOR_B); -} - void VoxelChunk::create_meshers() { + ERR_FAIL_COND_MSG(!has_method("_create_meshers"), "VoxelChunk: _create_meshers() is missing! Please implement it!"); + call("_create_meshers"); - - for (int i = 0; i < _meshers.size(); ++i) { - Ref mesher = _meshers.get(i); - - ERR_CONTINUE(!mesher.is_valid()); - - mesher->set_lod_size(get_lod_size()); - mesher->set_voxel_scale(get_voxel_scale()); - } } -void VoxelChunk::_create_meshers() { - add_mesher(Ref(memnew(VoxelMesherCubic()))); -} +void VoxelChunk::build(const bool immediate) { + ERR_FAIL_COND_MSG(!has_method("_build"), "VoxelChunk: _build(immediate : bool) is missing! Please implement it!"); -void VoxelChunk::build_deferred() { - if (_current_build_phase == BUILD_PHASE_DONE) { - _build_prioritized = true; - - wait_and_finish_thread(); - - set_process_internal(true); - - _is_generating = true; - - next_phase(); - - if (!_voxel_world->can_chunk_do_build_step()) - return; - - build_step(); - } -} - -void VoxelChunk::build_prioritized() { - if (_current_build_phase == BUILD_PHASE_DONE) { - _build_prioritized = true; - - wait_and_finish_thread(); - - set_process_internal(true); - - _is_generating = true; - - next_phase(); - - if (!_voxel_world->can_chunk_do_build_step()) - return; - - build_step(); - } -} - -void VoxelChunk::build_step() { - ERR_FAIL_COND(!has_next_phase()); - ERR_FAIL_COND(_build_step_in_progress); - - _build_step_in_progress = true; - - if (get_is_build_threaded()) { - if (_build_thread) { - wait_and_finish_thread(); - } - - _build_thread = Thread::create(_build_step_threaded, this); - return; - } - - while (has_next_phase() && _active_build_phase_type == BUILD_PHASE_TYPE_NORMAL) { - build_phase(); - - if (!get_build_phase_done()) - break; - } - - _build_step_in_progress = false; -} - -void VoxelChunk::_build_step_threaded(void *_userdata) { - VoxelChunk *vc = (VoxelChunk *)_userdata; - - while (vc->has_next_phase() && vc->_active_build_phase_type == BUILD_PHASE_TYPE_NORMAL) { - vc->build_phase(); - - if (!vc->get_build_phase_done()) - break; - } - - vc->_build_step_in_progress = false; -} - -void VoxelChunk::build_phase() { - - _THREAD_SAFE_METHOD_ - - if (_abort_build) - return; - - set_build_phase_done(false); - - call("_build_phase", _current_build_phase); -} - -void VoxelChunk::_build_phase(int phase) { - ERR_FAIL_COND(!_library.is_valid()); - - switch (phase) { - case BUILD_PHASE_DONE: - return; - case BUILD_PHASE_SETUP: { - if (_meshers.size() == 0) { - create_meshers(); - } - - for (int i = 0; i < _meshers.size(); ++i) { - Ref mesher = _meshers.get(i); - - ERR_CONTINUE(!mesher.is_valid()); - - mesher->set_library(_library); - mesher->reset(); - } - - next_phase(); - - return; - } - case BUILD_PHASE_TERRARIN_MESH_SETUP: { - for (int i = 0; i < _meshers.size(); ++i) { - Ref mesher = _meshers.get(i); - - ERR_CONTINUE(!mesher.is_valid()); - - mesher->add_chunk(this); - } - - next_phase(); - - return; - } - case BUILD_PHASE_TERRARIN_MESH_COLLIDER: { - if (!get_create_collider()) { - next_phase(); - return; - } - - for (int i = 0; i < _meshers.size(); ++i) { - Ref mesher = _meshers.get(i); - - ERR_CONTINUE(!mesher.is_valid()); - - temp_arr_collider.append_array(mesher->build_collider()); - } - - if (temp_arr_collider.size() == 0) { - next_phase(); - return; - } - - if (_is_build_threaded) { - set_active_build_phase_type(BUILD_PHASE_TYPE_PHYSICS_PROCESS); - return; - } - - if (_body_rid == RID()) { - create_colliders(); - } - - PhysicsServer::get_singleton()->shape_set_data(_shape_rid, temp_arr_collider); - - //temp_arr_collider.resize(0); - - next_phase(); - - return; - } - case BUILD_PHASE_TERRARIN_MESH: { - for (int i = 0; i < _meshers.size(); ++i) { - Ref mesher = _meshers.get(i); - - ERR_CONTINUE(!mesher.is_valid()); - - mesher->bake_colors(this); - } - - for (int i = 0; i < _meshers.size(); ++i) { - Ref mesher = _meshers.get(i); - - ERR_CONTINUE(!mesher.is_valid()); - - mesher->set_library(_library); - } - - Ref mesher; - for (int i = 0; i < _meshers.size(); ++i) { - Ref m = _meshers.get(i); - - ERR_CONTINUE(!m.is_valid()); - - if (!mesher.is_valid()) { - mesher = m; - mesher->set_material(get_library()->get_material()); - continue; - } - - mesher->set_material(get_library()->get_material()); - mesher->add_mesher(m); - } - - ERR_FAIL_COND(!mesher.is_valid()); - - if (mesher->get_vertex_count() == 0) { - next_phase(); - return; - } - - if (_mesh_rid != RID()) - VS::get_singleton()->mesh_clear(_mesh_rid); - - Array temp_mesh_arr = mesher->build_mesh(); - - if (_mesh_rid == RID()) { - allocate_main_mesh(); - } - - VS::get_singleton()->mesh_add_surface_from_arrays(_mesh_rid, VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr); - - if (_library->get_material().is_valid()) - VS::get_singleton()->mesh_surface_set_material(_mesh_rid, 0, _library->get_material()->get_rid()); - - next_phase(); - - return; - } - case BUILD_PHASE_PROP_MESH: { - for (int i = 0; i < _meshers.size(); ++i) { - Ref mesher = _meshers.get(i); - - ERR_CONTINUE(!mesher.is_valid()); - - mesher->reset(); - } - - if (_props.size() > 0) { - if (_prop_mesh_rid == RID()) { - allocate_prop_mesh(); - } - - for (int i = 0; i < _meshers.size(); ++i) { - Ref mesher = _meshers.get(i); - - ERR_CONTINUE(!mesher.is_valid()); - - mesher->bake_colors(this); - mesher->set_material(get_library()->get_material()); - - ERR_FAIL_COND(_prop_mesh_rid == RID()); - - VS::get_singleton()->mesh_clear(_prop_mesh_rid); - - if (mesher->get_vertex_count() == 0) { - next_phase(); - return; - } - - Array arr = mesher->build_mesh(); - - VS::get_singleton()->mesh_add_surface_from_arrays(_prop_mesh_rid, VisualServer::PRIMITIVE_TRIANGLES, arr); - - if (_library->get_material().is_valid()) - VS::get_singleton()->mesh_surface_set_material(_prop_mesh_rid, 0, _library->get_material()->get_rid()); - } - } - - next_phase(); - - return; - } - case BUILD_PHASE_PROP_COLLIDER: { - if (!get_create_collider()) { - next_phase(); - return; - } - - for (int i = 0; i < _meshers.size(); ++i) { - Ref mesher = _meshers.get(i); - - ERR_CONTINUE(!mesher.is_valid()); - - temp_arr_collider.append_array(mesher->build_collider()); - } - - for (int i = 0; i < _meshers.size(); ++i) { - Ref mesher = _meshers.get(i); - - ERR_CONTINUE(!mesher.is_valid()); - - mesher->reset(); - } - - if (temp_arr_collider.size() == 0) { - next_phase(); - return; - } - - if (_is_build_threaded) { - set_active_build_phase_type(BUILD_PHASE_TYPE_PHYSICS_PROCESS); - return; - } - - if (_prop_body_rid == RID()) { - allocate_prop_colliders(); - } - - PhysicsServer::get_singleton()->shape_set_data(_shape_rid, temp_arr_collider); - - //temp_arr_collider.resize(0); - - next_phase(); - - return; - } - /* - case BUILD_PHASE_LIQUID: { - next_phase(); - return; - } - case BUILD_PHASE_CLUTTER: { - next_phase(); - return; - } - */ - case BUILD_PHASE_FINALIZE: { - if (_mesh_instance_rid != RID()) - VS::get_singleton()->instance_set_visible(_mesh_instance_rid, is_visible()); - - if (_prop_mesh_instance_rid != RID()) - VS::get_singleton()->instance_set_visible(_prop_mesh_instance_rid, is_visible()); - - if (_liquid_mesh_instance_rid != RID()) - VS::get_singleton()->instance_set_visible(_liquid_mesh_instance_rid, is_visible()); - - if (_clutter_mesh_instance_rid != RID()) - VS::get_singleton()->instance_set_visible(_clutter_mesh_instance_rid, is_visible()); - - next_phase(); - - return; - } - } -} - -void VoxelChunk::build_phase_process() { - if (_abort_build) - return; - - set_build_phase_done(false); - - call("_build_phase_process", _current_build_phase); -} -void VoxelChunk::_build_phase_process(int phase) { -} - -void VoxelChunk::build_phase_physics_process() { - if (_abort_build) - return; - - set_build_phase_done(false); - - call("_build_phase_physics_process", _current_build_phase); -} -void VoxelChunk::_build_phase_physics_process(int phase) { - if (phase == BUILD_PHASE_TERRARIN_MESH_COLLIDER) { - - if (_body_rid == RID()) { - create_colliders(); - } - - PhysicsServer::get_singleton()->shape_set_data(_shape_rid, temp_arr_collider); - //temp_arr_collider.resize(0); - - set_active_build_phase_type(BUILD_PHASE_TYPE_NORMAL); - next_phase(); - - } else if (phase == BUILD_PHASE_PROP_COLLIDER) { - - if (_prop_body_rid == RID()) { - allocate_prop_colliders(); - } - - PhysicsServer::get_singleton()->shape_set_data(_prop_shape_rid, temp_arr_collider); - //temp_arr_collider.resize(0); - - set_active_build_phase_type(BUILD_PHASE_TYPE_NORMAL); - next_phase(); - } -} - -bool VoxelChunk::has_next_phase() { - if (_current_build_phase == BUILD_PHASE_DONE) - return false; - - return true; -} - -void VoxelChunk::next_phase() { - set_build_phase_done(true); - - if (_abort_build) { - _current_build_phase = BUILD_PHASE_DONE; - _is_generating = false; - set_process_internal(false); - - return; - } - - ++_current_build_phase; - - if (_current_build_phase >= _max_build_phases) { - _current_build_phase = BUILD_PHASE_DONE; - _is_generating = false; - set_process_internal(false); - - emit_signal("mesh_generation_finished", this); - - if (_voxel_world != NULL) { - _voxel_world->on_chunk_mesh_generation_finished(this); - } - } + call("_build", immediate); } void VoxelChunk::clear() { - _voxel_lights.clear(); -} + ERR_FAIL_COND_MSG(!has_method("_clear"), "VoxelChunk: _clear() is missing! Please implement it!"); -void VoxelChunk::create_colliders() { - ERR_FAIL_COND(_voxel_world == NULL); - - _shape_rid = PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON); - _body_rid = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC); - - PhysicsServer::get_singleton()->body_set_collision_layer(_body_rid, 1); - PhysicsServer::get_singleton()->body_set_collision_mask(_body_rid, 1); - - PhysicsServer::get_singleton()->body_add_shape(_body_rid, _shape_rid); - - PhysicsServer::get_singleton()->body_set_state(_body_rid, PhysicsServer::BODY_STATE_TRANSFORM, Transform(Basis(), Vector3(_position_x * _size_x * _voxel_scale, _position_y * _size_y * _voxel_scale, _position_z * _size_z * _voxel_scale))); - PhysicsServer::get_singleton()->body_set_space(_body_rid, get_voxel_world()->get_world()->get_space()); -} - -void VoxelChunk::remove_colliders() { - if (_body_rid != RID()) { - PhysicsServer::get_singleton()->free(_body_rid); - PhysicsServer::get_singleton()->free(_shape_rid); - - _body_rid = RID(); - _shape_rid = RID(); - } + call("_clear"); } void VoxelChunk::add_lights(Array lights) { @@ -1162,13 +502,21 @@ void VoxelChunk::bake_light(Ref light) { int wpy = light->get_world_position_y() - (_position_y * _size_y); int wpz = light->get_world_position_z() - (_position_z * _size_z); - //int wpx = (int)(wp.x / _size.x) - _position.x; - //int wpy = (int)(wp.y / _size.y) - _position.y; - //int wpz = (int)(wp.z / _size.z) - _position.z; - add_light(wpx, wpy, wpz, light->get_size(), light->get_color()); } +void VoxelChunk::clear_baked_lights() { + ERR_FAIL_COND_MSG(!has_method("_clear_baked_lights"), "VoxelChunk: _clear_baked_lights() is missing! Please implement it!"); + + call("_clear_baked_lights"); +} + +void VoxelChunk::add_light(int local_x, int local_y, int local_z, int size, Color color) { + ERR_FAIL_COND_MSG(!has_method("_add_light"), "VoxelChunk: _add_light() is missing! Please implement it!"); + + call("_add_light", local_x, local_y, local_z, size, color); +} + void VoxelChunk::add_prop_light(Ref light) { bake_light(light); } @@ -1192,139 +540,6 @@ void VoxelChunk::clear_props() { _props.clear(); } -void VoxelChunk::allocate_main_mesh() { - ERR_FAIL_COND(_voxel_world == NULL); - - ERR_FAIL_COND(!get_library().is_valid()); - - _mesh_instance_rid = VS::get_singleton()->instance_create(); - - if (get_voxel_world()->get_world().is_valid()) - VS::get_singleton()->instance_set_scenario(_mesh_instance_rid, get_voxel_world()->get_world()->get_scenario()); - - _mesh_rid = VS::get_singleton()->mesh_create(); - - VS::get_singleton()->instance_set_base(_mesh_instance_rid, _mesh_rid); - - VS::get_singleton()->instance_set_transform(_mesh_instance_rid, Transform(Basis(), Vector3(_position_x * _size_x * _voxel_scale, _position_y * _size_y * _voxel_scale, _position_z * _size_z * _voxel_scale))); -} - -void VoxelChunk::free_main_mesh() { - if (_mesh_instance_rid != RID()) { - VS::get_singleton()->free(_mesh_instance_rid); - VS::get_singleton()->free(_mesh_rid); - - _mesh_instance_rid = RID(); - _mesh_rid = RID(); - } -} - -void VoxelChunk::allocate_prop_mesh() { - ERR_FAIL_COND(_voxel_world == NULL); - ERR_FAIL_COND(!get_library().is_valid()); - - _prop_mesh_instance_rid = VS::get_singleton()->instance_create(); - - if (get_voxel_world()->get_world().is_valid()) - VS::get_singleton()->instance_set_scenario(_prop_mesh_instance_rid, get_voxel_world()->get_world()->get_scenario()); - - _prop_mesh_rid = VS::get_singleton()->mesh_create(); - - VS::get_singleton()->instance_set_base(_prop_mesh_instance_rid, _prop_mesh_rid); - - VS::get_singleton()->instance_set_transform(_prop_mesh_instance_rid, Transform(Basis(), Vector3(_position_x * _size_x * _voxel_scale, _position_y * _size_y * _voxel_scale, _position_z * _size_z * _voxel_scale))); -} - -void VoxelChunk::free_prop_mesh() { - if (_prop_mesh_instance_rid != RID()) { - VS::get_singleton()->free(_prop_mesh_instance_rid); - VS::get_singleton()->free(_prop_mesh_rid); - - _prop_mesh_instance_rid = RID(); - _prop_mesh_rid = RID(); - } -} - -void VoxelChunk::allocate_prop_colliders() { - ERR_FAIL_COND(_voxel_world == NULL); - - _prop_shape_rid = PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON); - _prop_body_rid = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC); - - PhysicsServer::get_singleton()->body_set_collision_layer(_prop_body_rid, 1); - PhysicsServer::get_singleton()->body_set_collision_mask(_prop_body_rid, 1); - - PhysicsServer::get_singleton()->body_add_shape(_prop_body_rid, _prop_shape_rid); - - PhysicsServer::get_singleton()->body_set_state(_prop_body_rid, PhysicsServer::BODY_STATE_TRANSFORM, Transform(Basis(), Vector3(_position_x * _size_x * _voxel_scale, _position_y * _size_y * _voxel_scale, _position_z * _size_z * _voxel_scale))); - PhysicsServer::get_singleton()->body_set_space(_prop_body_rid, get_voxel_world()->get_world()->get_space()); -} -void VoxelChunk::free_prop_colliders() { - if (_prop_body_rid != RID()) { - PhysicsServer::get_singleton()->free(_prop_body_rid); - PhysicsServer::get_singleton()->free(_prop_shape_rid); - - _prop_body_rid = RID(); - _prop_shape_rid = RID(); - } -} - -//Liquid mesh -void VoxelChunk::allocate_liquid_mesh() { - ERR_FAIL_COND(_voxel_world == NULL); - - ERR_FAIL_COND(!get_library().is_valid()); - - _liquid_mesh_instance_rid = VS::get_singleton()->instance_create(); - - if (get_voxel_world()->get_world().is_valid()) - VS::get_singleton()->instance_set_scenario(_liquid_mesh_instance_rid, get_voxel_world()->get_world()->get_scenario()); - - _liquid_mesh_rid = VS::get_singleton()->mesh_create(); - - VS::get_singleton()->instance_set_base(_liquid_mesh_instance_rid, _liquid_mesh_rid); - - VS::get_singleton()->instance_set_transform(_liquid_mesh_instance_rid, Transform(Basis(), Vector3(_position_x * _size_x * _voxel_scale, _position_y * _size_y * _voxel_scale, _position_z * _size_z * _voxel_scale))); -} - -void VoxelChunk::free_liquid_mesh() { - if (_liquid_mesh_instance_rid != RID()) { - VS::get_singleton()->free(_liquid_mesh_instance_rid); - VS::get_singleton()->free(_liquid_mesh_rid); - - _liquid_mesh_instance_rid = RID(); - _liquid_mesh_rid = RID(); - } -} - -//Clutter mesh -void VoxelChunk::allocate_clutter_mesh() { - ERR_FAIL_COND(_voxel_world == NULL); - - ERR_FAIL_COND(!get_library().is_valid()); - - _clutter_mesh_instance_rid = VS::get_singleton()->instance_create(); - - if (get_voxel_world()->get_world().is_valid()) - VS::get_singleton()->instance_set_scenario(_clutter_mesh_instance_rid, get_voxel_world()->get_world()->get_scenario()); - - _clutter_mesh_rid = VS::get_singleton()->mesh_create(); - - VS::get_singleton()->instance_set_base(_clutter_mesh_instance_rid, _clutter_mesh_rid); - - VS::get_singleton()->instance_set_transform(_clutter_mesh_instance_rid, Transform(Basis(), Vector3(_position_x * _size_x * _voxel_scale, _position_y * _size_y * _voxel_scale, _position_z * _size_z * _voxel_scale))); -} - -void VoxelChunk::free_clutter_mesh() { - if (_clutter_mesh_instance_rid != RID()) { - VS::get_singleton()->free(_clutter_mesh_instance_rid); - VS::get_singleton()->free(_clutter_mesh_rid); - - _clutter_mesh_instance_rid = RID(); - _clutter_mesh_rid = RID(); - } -} - void VoxelChunk::free_spawn_props() { for (int i = 0; i < _spawned_props.size(); ++i) { _spawned_props[i]->queue_delete(); @@ -1333,151 +548,13 @@ void VoxelChunk::free_spawn_props() { _spawned_props.clear(); } -void VoxelChunk::create_debug_immediate_geometry() { - ERR_FAIL_COND(_voxel_world == NULL); - ERR_FAIL_COND(_debug_drawer != NULL); - - _debug_drawer = memnew(ImmediateGeometry()); - - add_child(_debug_drawer); - - if (Engine::get_singleton()->is_editor_hint()) - _debug_drawer->set_owner(get_tree()->get_edited_scene_root()); - - //_debug_drawer->set_transform(Transform(Basis(), Vector3(_position.x * _size.x * _voxel_scale, _position.y * _size.y * _voxel_scale, _position.z * _size.z * _voxel_scale))); - //_debug_drawer->set_transform(Transform(Basis(), Vector3(_position.x * _size.x * _voxel_scale, _position.y * _size.y * _voxel_scale, _position.z * _size.z * _voxel_scale))); -} - -void VoxelChunk::free_debug_immediate_geometry() { - if (ObjectDB::instance_validate(_debug_drawer)) { - _debug_drawer->queue_delete(); - - _debug_drawer = NULL; - } -} - -void VoxelChunk::draw_cross_voxels(Vector3 pos) { - pos *= _voxel_scale; - - _debug_drawer->add_vertex(pos + Vector3(0, 0, -0.2)); - _debug_drawer->add_vertex(pos + Vector3(0, 0, 0.2)); - - _debug_drawer->add_vertex(pos + Vector3(0, -0.2, 0)); - _debug_drawer->add_vertex(pos + Vector3(0, 0.2, 0)); - - _debug_drawer->add_vertex(pos + Vector3(-0.2, 0, 0)); - _debug_drawer->add_vertex(pos + Vector3(0.2, 0, 0)); -} - -void VoxelChunk::draw_cross_voxels_fill(Vector3 pos, float fill) { - pos *= _voxel_scale; - - _debug_drawer->add_vertex(pos + Vector3(0, 0, -0.5 * fill)); - _debug_drawer->add_vertex(pos + Vector3(0, 0, 0.5 * fill)); - - _debug_drawer->add_vertex(pos + Vector3(0, -0.5 * fill, 0)); - _debug_drawer->add_vertex(pos + Vector3(0, 0.5 * fill, 0)); - - _debug_drawer->add_vertex(pos + Vector3(-0.5 * fill, 0, 0)); - _debug_drawer->add_vertex(pos + Vector3(0.5 * fill, 0, 0)); -} - -void VoxelChunk::draw_debug_voxels(int max, Color color) { - if (_debug_drawer == NULL) { - create_debug_immediate_geometry(); - } - - ERR_FAIL_COND(_debug_drawer == NULL); - - _debug_drawer->clear(); - _debug_drawer->begin(Mesh::PRIMITIVE_LINES); - _debug_drawer->set_color(color); - - int a = 0; - - int64_t sx = static_cast(_size_x); - int64_t sy = static_cast(_size_y); - int64_t sz = static_cast(_size_y); - - for (int y = 0; y < sy; ++y) { - for (int z = 0; z < sz; ++z) { - for (int x = 0; x < sx; ++x) { - - int type = get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_TYPE); - - if (type == 0) { - continue; - } - - draw_cross_voxels_fill(Vector3(x, y, z), get_voxel(x, y, z, VoxelChunk::DEFAULT_CHANNEL_ISOLEVEL) / 255.0 * get_voxel_scale() * 2.0); - - ++a; - - if (a > max) { - break; - } - } - } - } - - _debug_drawer->end(); -} - -void VoxelChunk::draw_debug_voxel_lights() { - if (_debug_drawer == NULL) { - create_debug_immediate_geometry(); - } - - ERR_FAIL_COND(_debug_drawer == NULL); - - _debug_drawer->clear(); - _debug_drawer->begin(Mesh::PrimitiveType::PRIMITIVE_LINES); - _debug_drawer->set_color(Color(1, 1, 1)); - - for (int i = 0; i < _voxel_lights.size(); ++i) { - Ref v = _voxel_lights[i]; - - int pos_x = v->get_world_position_x() - (_size_x * _position_x); - int pos_y = v->get_world_position_y() - (_size_y * _position_y); - int pos_z = v->get_world_position_z() - (_size_z * _position_z); - - draw_cross_voxels_fill(Vector3(pos_x, pos_y, pos_z), 1.0); - } - - if (has_method("_draw_debug_voxel_lights")) - call("_draw_debug_voxel_lights", _debug_drawer); - - _debug_drawer->end(); -} - -void VoxelChunk::free_chunk() { - free_main_mesh(); - remove_colliders(); - free_prop_mesh(); - free_prop_colliders(); - free_spawn_props(); - free_liquid_mesh(); - free_clutter_mesh(); -} - VoxelChunk::VoxelChunk() { _is_generating = false; - _is_build_threaded = false; - _abort_build = false; _dirty = false; _state = VOXEL_CHUNK_STATE_OK; - _enabled = true; - _build_mesh = true; - _create_collider = true; - _bake_lights = true; - _current_build_phase = BUILD_PHASE_DONE; - _max_build_phases = BUILD_PHASE_MAX; - _voxel_scale = 1; - _lod_size = 1; - _debug_drawer = NULL; _voxel_world = NULL; _position_x = 0; @@ -1494,25 +571,9 @@ VoxelChunk::VoxelChunk() { _margin_start = 0; _margin_end = 0; - - _build_prioritized = false; - _build_phase_done_mutex = Mutex::create(); - _build_phase_done = false; - _build_thread = NULL; - _build_step_in_progress = false; - - _active_build_phase_type = BUILD_PHASE_TYPE_NORMAL; } VoxelChunk::~VoxelChunk() { - free_main_mesh(); - remove_colliders(); - free_prop_mesh(); - free_prop_colliders(); - free_liquid_mesh(); - free_clutter_mesh(); - //do not call free here, the app will crash on exit, if you try to free nodes too. - _voxel_lights.clear(); _meshers.clear(); @@ -1530,88 +591,6 @@ VoxelChunk::~VoxelChunk() { memdelete_arr(ch); } } - - memdelete(_build_phase_done_mutex); -} - -void VoxelChunk::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_EXIT_TREE: { - if (_build_thread) { - _abort_build = true; - - wait_and_finish_thread(); - } - } - case NOTIFICATION_INTERNAL_PROCESS: { - if (!get_is_generating() || !has_next_phase() || _build_step_in_progress) { - return; - } - - switch (_active_build_phase_type) { - case BUILD_PHASE_TYPE_PROCESS: { - if (!_voxel_world->can_chunk_do_build_step()) - return; - - _build_step_in_progress = true; - - while (has_next_phase() && _active_build_phase_type == BUILD_PHASE_TYPE_PROCESS) { - build_phase_process(); - - if (!get_build_phase_done()) - break; - } - - _build_step_in_progress = false; - return; - } - case BUILD_PHASE_TYPE_NORMAL: { - //normal mode -> build step is not in progress -> need to restart building - - if (!_voxel_world->can_chunk_do_build_step()) - return; - - build_step(); - - return; - } - case BUILD_PHASE_TYPE_PHYSICS_PROCESS: - return; - } - case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - if (!get_is_generating() || !has_next_phase() || _build_step_in_progress) { - return; - } - - if (_active_build_phase_type == BUILD_PHASE_TYPE_PHYSICS_PROCESS) { - - if (!_voxel_world->can_chunk_do_build_step()) - return; - - _build_step_in_progress = true; - - while (has_next_phase() && _active_build_phase_type == BUILD_PHASE_TYPE_PHYSICS_PROCESS) { - build_phase_physics_process(); - - if (!get_build_phase_done()) - break; - } - - _build_step_in_progress = false; - - return; - } - } - } - } -} - -void VoxelChunk::wait_and_finish_thread() { - if (_build_thread) { - Thread::wait_to_finish(_build_thread); - memdelete(_build_thread); - _build_thread = NULL; - } } bool VoxelChunk::_set(const StringName &p_name, const Variant &p_value) { @@ -1661,22 +640,14 @@ void VoxelChunk::_bind_methods() { ADD_SIGNAL(MethodInfo("mesh_generation_finished", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk"))); BIND_VMETHOD(MethodInfo("_prop_added", PropertyInfo(Variant::OBJECT, "prop", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunkPropData"))); - BIND_VMETHOD(MethodInfo("_create_meshers")); - ClassDB::bind_method(D_METHOD("_create_meshers"), &VoxelChunk::_create_meshers); + BIND_VMETHOD(MethodInfo("_setup_channels")); + BIND_VMETHOD(MethodInfo("_add_light", PropertyInfo(Variant::INT, "local_x"), PropertyInfo(Variant::INT, "local_y"), PropertyInfo(Variant::INT, "local_z"), PropertyInfo(Variant::INT, "size"), PropertyInfo(Variant::COLOR, "color"))); ClassDB::bind_method(D_METHOD("get_is_generating"), &VoxelChunk::get_is_generating); ClassDB::bind_method(D_METHOD("set_is_generating", "value"), &VoxelChunk::set_is_generating); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_generating"), "set_is_generating", "get_is_generating"); - ClassDB::bind_method(D_METHOD("get_is_build_threaded"), &VoxelChunk::get_is_build_threaded); - ClassDB::bind_method(D_METHOD("set_is_build_threaded", "value"), &VoxelChunk::set_is_build_threaded); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_build_threaded"), "set_is_build_threaded", "get_is_build_threaded"); - - ClassDB::bind_method(D_METHOD("get_active_build_phase_type"), &VoxelChunk::get_active_build_phase_type); - ClassDB::bind_method(D_METHOD("set_active_build_phase_type", "value"), &VoxelChunk::set_active_build_phase_type); - ADD_PROPERTY(PropertyInfo(Variant::INT, "active_build_phase_type", PROPERTY_HINT_ENUM, BINDING_STRING_ACTIVE_BUILD_PHASE_TYPE), "set_active_build_phase_type", "get_active_build_phase_type"); - ClassDB::bind_method(D_METHOD("get_dirty"), &VoxelChunk::get_dirty); ClassDB::bind_method(D_METHOD("set_dirty", "value"), &VoxelChunk::set_dirty); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dirty"), "set_dirty", "get_dirty"); @@ -1736,34 +707,10 @@ void VoxelChunk::_bind_methods() { ClassDB::bind_method(D_METHOD("set_library", "value"), &VoxelChunk::set_library); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "library", PROPERTY_HINT_RESOURCE_TYPE, "VoxelmanLibrary"), "set_library", "get_library"); - ClassDB::bind_method(D_METHOD("get_lod_size"), &VoxelChunk::get_lod_size); - ClassDB::bind_method(D_METHOD("set_lod_size", "value"), &VoxelChunk::set_lod_size); - ADD_PROPERTY(PropertyInfo(Variant::INT, "lod_size"), "set_lod_size", "get_lod_size"); - ClassDB::bind_method(D_METHOD("get_voxel_scale"), &VoxelChunk::get_voxel_scale); ClassDB::bind_method(D_METHOD("set_voxel_scale", "value"), &VoxelChunk::set_voxel_scale); ADD_PROPERTY(PropertyInfo(Variant::REAL, "voxel_scale"), "set_voxel_scale", "get_voxel_scale"); - ClassDB::bind_method(D_METHOD("get_current_build_phase"), &VoxelChunk::get_current_build_phase); - ClassDB::bind_method(D_METHOD("set_current_build_phase", "value"), &VoxelChunk::set_current_build_phase); - ADD_PROPERTY(PropertyInfo(Variant::INT, "current_build_phase"), "set_current_build_phase", "get_current_build_phase"); - - ClassDB::bind_method(D_METHOD("get_max_build_phase"), &VoxelChunk::get_max_build_phase); - ClassDB::bind_method(D_METHOD("set_max_build_phase", "value"), &VoxelChunk::set_max_build_phase); - ADD_PROPERTY(PropertyInfo(Variant::INT, "max_build_phase"), "set_max_build_phase", "get_max_build_phase"); - - ADD_GROUP("Meshing", "meshing"); - - ClassDB::bind_method(D_METHOD("meshing_get_create_collider"), &VoxelChunk::get_create_collider); - ClassDB::bind_method(D_METHOD("meshing_set_create_collider", "value"), &VoxelChunk::set_create_collider); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meshing_create_collider"), "meshing_set_create_collider", "meshing_get_create_collider"); - - ClassDB::bind_method(D_METHOD("meshing_get_bake_lights"), &VoxelChunk::get_bake_lights); - ClassDB::bind_method(D_METHOD("meshing_set_bake_lights", "value"), &VoxelChunk::set_bake_lights); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meshing_bake_lights"), "meshing_set_bake_lights", "meshing_get_bake_lights"); - - ADD_GROUP("Settings", "setting"); - ClassDB::bind_method(D_METHOD("get_mesher", "index"), &VoxelChunk::get_mesher); ClassDB::bind_method(D_METHOD("set_mesher", "index", "mesher"), &VoxelChunk::set_mesher); ClassDB::bind_method(D_METHOD("remove_mesher", "index"), &VoxelChunk::remove_mesher); @@ -1774,27 +721,8 @@ void VoxelChunk::_bind_methods() { ClassDB::bind_method(D_METHOD("set_voxel_world", "world"), &VoxelChunk::set_voxel_world_bind); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "voxel_world", PROPERTY_HINT_RESOURCE_TYPE, "VoxelWorld"), "set_voxel_world", "get_voxel_world"); - ClassDB::bind_method(D_METHOD("get_mesh_rid"), &VoxelChunk::get_mesh_rid); - ClassDB::bind_method(D_METHOD("get_mesh_instance_rid"), &VoxelChunk::get_mesh_instance_rid); - ClassDB::bind_method(D_METHOD("get_shape_rid"), &VoxelChunk::get_shape_rid); - ClassDB::bind_method(D_METHOD("get_body_rid"), &VoxelChunk::get_body_rid); - - ClassDB::bind_method(D_METHOD("get_prop_mesh_rid"), &VoxelChunk::get_prop_mesh_rid); - ClassDB::bind_method(D_METHOD("get_prop_mesh_instance_rid"), &VoxelChunk::get_prop_mesh_instance_rid); - ClassDB::bind_method(D_METHOD("get_prop_shape_rid"), &VoxelChunk::get_prop_shape_rid); - ClassDB::bind_method(D_METHOD("get_prop_body_rid"), &VoxelChunk::get_prop_body_rid); - - ClassDB::bind_method(D_METHOD("get_liquid_mesh_rid"), &VoxelChunk::get_liquid_mesh_rid); - ClassDB::bind_method(D_METHOD("get_liquid_mesh_instance_rid"), &VoxelChunk::get_liquid_mesh_instance_rid); - - ClassDB::bind_method(D_METHOD("get_clutter_mesh_rid"), &VoxelChunk::get_clutter_mesh_rid); - ClassDB::bind_method(D_METHOD("get_clutter_mesh_instance_rid"), &VoxelChunk::get_clutter_mesh_instance_rid); - //Voxel Data - BIND_VMETHOD(MethodInfo("_setup_channels")); - ClassDB::bind_method(D_METHOD("setup_channels"), &VoxelChunk::setup_channels); - ClassDB::bind_method(D_METHOD("_setup_channels"), &VoxelChunk::_setup_channels); ClassDB::bind_method(D_METHOD("set_size", "size_x", "size_y", "size_z", "margin_start", "margin_end"), &VoxelChunk::set_size, DEFVAL(0), DEFVAL(0)); @@ -1817,35 +745,7 @@ void VoxelChunk::_bind_methods() { ClassDB::bind_method(D_METHOD("get_data_index", "x", "y", "z"), &VoxelChunk::get_data_index); ClassDB::bind_method(D_METHOD("get_data_size"), &VoxelChunk::get_data_size); - //Data Management functions - ClassDB::bind_method(D_METHOD("generate_ao"), &VoxelChunk::generate_ao); - ClassDB::bind_method(D_METHOD("add_light", "local_x", "local_y", "local_z", "size", "color"), &VoxelChunk::add_light); - ClassDB::bind_method(D_METHOD("clear_baked_lights"), &VoxelChunk::clear_baked_lights); - //Meshes - BIND_VMETHOD(MethodInfo("_build_phase", PropertyInfo(Variant::INT, "phase"))); - BIND_VMETHOD(MethodInfo("_build_phase_process", PropertyInfo(Variant::INT, "phase"))); - BIND_VMETHOD(MethodInfo("_build_phase_physics_process", PropertyInfo(Variant::INT, "phase"))); - - ClassDB::bind_method(D_METHOD("build_deferred"), &VoxelChunk::build_deferred); - ClassDB::bind_method(D_METHOD("build_prioritized"), &VoxelChunk::build_prioritized); - - ClassDB::bind_method(D_METHOD("build_phase"), &VoxelChunk::build_phase); - ClassDB::bind_method(D_METHOD("_build_phase", "phase"), &VoxelChunk::_build_phase); - - ClassDB::bind_method(D_METHOD("build_phase_process"), &VoxelChunk::build_phase_process); - ClassDB::bind_method(D_METHOD("_build_phase_process", "phase"), &VoxelChunk::_build_phase_process); - - ClassDB::bind_method(D_METHOD("build_phase_physics_process"), &VoxelChunk::build_phase_physics_process); - ClassDB::bind_method(D_METHOD("_build_phase_physics_process", "phase"), &VoxelChunk::_build_phase_physics_process); - - ClassDB::bind_method(D_METHOD("next_phase"), &VoxelChunk::next_phase); - ClassDB::bind_method(D_METHOD("has_next_phase"), &VoxelChunk::has_next_phase); - ClassDB::bind_method(D_METHOD("clear"), &VoxelChunk::clear); - - ClassDB::bind_method(D_METHOD("create_colliders"), &VoxelChunk::create_colliders); - ClassDB::bind_method(D_METHOD("remove_colliders"), &VoxelChunk::remove_colliders); - ClassDB::bind_method(D_METHOD("add_lights", "lights"), &VoxelChunk::add_lights); ClassDB::bind_method(D_METHOD("add_voxel_light", "light"), &VoxelChunk::add_voxel_light); ClassDB::bind_method(D_METHOD("create_voxel_light", "color", "size", "x", "y", "z"), &VoxelChunk::create_voxel_light); @@ -1869,67 +769,5 @@ void VoxelChunk::_bind_methods() { ClassDB::bind_method(D_METHOD("free_spawn_props"), &VoxelChunk::free_spawn_props); - ClassDB::bind_method(D_METHOD("allocate_main_mesh"), &VoxelChunk::allocate_main_mesh); - ClassDB::bind_method(D_METHOD("free_main_mesh"), &VoxelChunk::free_main_mesh); - - ClassDB::bind_method(D_METHOD("allocate_prop_mesh"), &VoxelChunk::allocate_prop_mesh); - ClassDB::bind_method(D_METHOD("free_prop_mesh"), &VoxelChunk::free_prop_mesh); - - ClassDB::bind_method(D_METHOD("allocate_prop_colliders"), &VoxelChunk::allocate_prop_colliders); - ClassDB::bind_method(D_METHOD("free_prop_colliders"), &VoxelChunk::free_prop_colliders); - - ClassDB::bind_method(D_METHOD("allocate_liquid_mesh"), &VoxelChunk::allocate_liquid_mesh); - ClassDB::bind_method(D_METHOD("free_liquid_mesh"), &VoxelChunk::free_liquid_mesh); - - ClassDB::bind_method(D_METHOD("allocate_clutter_mesh"), &VoxelChunk::allocate_clutter_mesh); - ClassDB::bind_method(D_METHOD("free_clutter_mesh"), &VoxelChunk::free_clutter_mesh); - ClassDB::bind_method(D_METHOD("create_meshers"), &VoxelChunk::create_meshers); - - ClassDB::bind_method(D_METHOD("create_debug_immediate_geometry"), &VoxelChunk::create_debug_immediate_geometry); - ClassDB::bind_method(D_METHOD("free_debug_immediate_geometry"), &VoxelChunk::free_debug_immediate_geometry); - - ClassDB::bind_method(D_METHOD("free_chunk"), &VoxelChunk::free_chunk); - - BIND_VMETHOD(MethodInfo("_draw_debug_voxel_lights", PropertyInfo(Variant::OBJECT, "debug_drawer", PROPERTY_HINT_RESOURCE_TYPE, "ImmediateGeometry"))); - - ClassDB::bind_method(D_METHOD("draw_cross_voxels", "max"), &VoxelChunk::draw_cross_voxels); - ClassDB::bind_method(D_METHOD("draw_cross_voxels_fill", "max", "fill"), &VoxelChunk::draw_cross_voxels_fill); - ClassDB::bind_method(D_METHOD("draw_debug_voxels", "max", "color"), &VoxelChunk::draw_debug_voxels, DEFVAL(Color(1, 1, 1))); - - ClassDB::bind_method(D_METHOD("draw_debug_voxel_lights"), &VoxelChunk::draw_debug_voxel_lights); - - BIND_CONSTANT(BUILD_PHASE_DONE); - BIND_CONSTANT(BUILD_PHASE_SETUP); - BIND_CONSTANT(BUILD_PHASE_TERRARIN_MESH_SETUP); - BIND_CONSTANT(BUILD_PHASE_TERRARIN_MESH_COLLIDER); - BIND_CONSTANT(BUILD_PHASE_TERRARIN_MESH); - BIND_CONSTANT(BUILD_PHASE_LIGHTS); - BIND_CONSTANT(BUILD_PHASE_PROP_MESH); - BIND_CONSTANT(BUILD_PHASE_PROP_COLLIDER); - BIND_CONSTANT(BUILD_PHASE_FINALIZE); - BIND_CONSTANT(BUILD_PHASE_MAX); - - BIND_CONSTANT(VOXEL_CHUNK_STATE_OK); - BIND_CONSTANT(VOXEL_CHUNK_STATE_GENERATION_QUEUED); - BIND_CONSTANT(VOXEL_CHUNK_STATE_GENERATION); - BIND_CONSTANT(VOXEL_CHUNK_STATE_MESH_GENERATION_QUEUED); - BIND_CONSTANT(VOXEL_CHUNK_STATE_MESH_GENERATION); - BIND_CONSTANT(VOXEL_CHUNK_STATE_MAX); - - BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_TYPE); - BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_ISOLEVEL); - BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_LIGHT_COLOR_R); - BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_LIGHT_COLOR_G); - BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_LIGHT_COLOR_B); - BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_AO); - BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_RANDOM_AO); - BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_LIQUID_TYPES); - BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_LIQUID_FILL); - BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_LIQUID_FLOW); - BIND_ENUM_CONSTANT(MAX_DEFAULT_CHANNELS); - - BIND_ENUM_CONSTANT(BUILD_PHASE_TYPE_NORMAL); - BIND_ENUM_CONSTANT(BUILD_PHASE_TYPE_PROCESS); - BIND_ENUM_CONSTANT(BUILD_PHASE_TYPE_PHYSICS_PROCESS); } diff --git a/world/voxel_chunk.h b/world/voxel_chunk.h index bcd8f1e..fa70057 100644 --- a/world/voxel_chunk.h +++ b/world/voxel_chunk.h @@ -66,65 +66,14 @@ class VoxelChunk : public Spatial { _THREAD_SAFE_CLASS_ public: - static const String BINDING_STRING_ACTIVE_BUILD_PHASE_TYPE; - enum { VOXEL_CHUNK_STATE_OK = 0, - VOXEL_CHUNK_STATE_GENERATION_QUEUED, - VOXEL_CHUNK_STATE_GENERATION, - VOXEL_CHUNK_STATE_MESH_GENERATION_QUEUED, - VOXEL_CHUNK_STATE_MESH_GENERATION, - VOXEL_CHUNK_STATE_MAX, - }; - - enum { - BUILD_PHASE_DONE = 0, - BUILD_PHASE_SETUP, - BUILD_PHASE_TERRARIN_MESH_SETUP, - BUILD_PHASE_TERRARIN_MESH_COLLIDER, - BUILD_PHASE_LIGHTS, - BUILD_PHASE_TERRARIN_MESH, - BUILD_PHASE_PROP_MESH, - BUILD_PHASE_PROP_COLLIDER, - //BUILD_PHASE_LIQUID, - //BUILD_PHASE_CLUTTER, - BUILD_PHASE_FINALIZE, - BUILD_PHASE_MAX - }; - - enum DefaultChannels { - DEFAULT_CHANNEL_TYPE = 0, - DEFAULT_CHANNEL_ISOLEVEL, - DEFAULT_CHANNEL_LIGHT_COLOR_R, - DEFAULT_CHANNEL_LIGHT_COLOR_G, - DEFAULT_CHANNEL_LIGHT_COLOR_B, - DEFAULT_CHANNEL_AO, - DEFAULT_CHANNEL_RANDOM_AO, - DEFAULT_CHANNEL_LIQUID_TYPES, - DEFAULT_CHANNEL_LIQUID_FILL, - DEFAULT_CHANNEL_LIQUID_FLOW, - MAX_DEFAULT_CHANNELS - }; - - enum ActiveBuildPhaseType { - BUILD_PHASE_TYPE_NORMAL = 0, - BUILD_PHASE_TYPE_PROCESS, - BUILD_PHASE_TYPE_PHYSICS_PROCESS, }; public: bool get_is_generating() const; void set_is_generating(bool value); - bool get_is_build_threaded() const; - void set_is_build_threaded(bool value); - - ActiveBuildPhaseType get_active_build_phase_type() const; - void set_active_build_phase_type(const ActiveBuildPhaseType value); - - bool get_build_phase_done() const; - void set_build_phase_done(bool value); - bool get_dirty() const; void set_dirty(bool value); @@ -162,55 +111,24 @@ public: void set_margin_end(int value); Ref get_library(); - void set_library(Ref value); - - int get_lod_size() const; - void set_lod_size(int lod_size); + void set_library(const Ref &value); float get_voxel_scale() const; void set_voxel_scale(float value); - int get_current_build_phase(); - void set_current_build_phase(int value); - - int get_max_build_phase(); - void set_max_build_phase(int value); + VoxelWorld *get_voxel_world() const; + void set_voxel_world(VoxelWorld *world); + void set_voxel_world_bind(Node *world); + //Meshers Ref get_mesher(int index) const; void set_mesher(int index, Ref mesher); void remove_mesher(int index); void add_mesher(Ref mesher); int get_mesher_count(); - VoxelWorld *get_voxel_world() const; - void set_voxel_world(VoxelWorld *world); - void set_voxel_world_bind(Node *world); - - bool get_create_collider() const; - void set_create_collider(bool value); - - bool get_bake_lights() const; - void set_bake_lights(bool value); - - RID get_mesh_rid(); - RID get_mesh_instance_rid(); - RID get_shape_rid(); - RID get_body_rid(); - - RID get_prop_mesh_rid(); - RID get_prop_mesh_instance_rid(); - RID get_prop_shape_rid(); - RID get_prop_body_rid(); - - RID get_liquid_mesh_rid(); - RID get_liquid_mesh_instance_rid(); - - RID get_clutter_mesh_rid(); - RID get_clutter_mesh_instance_rid(); - - //Voxel Data + //Channels void setup_channels(); - void _setup_channels(); void set_size(uint32_t size_x, uint32_t size_y, uint32_t size_z, uint32_t margin_start = 0, uint32_t margin_end = 0); @@ -235,40 +153,13 @@ public: uint32_t get_data_index(uint32_t x, uint32_t y, uint32_t z) const; uint32_t get_data_size() const; - //Data Management functions - void generate_ao(); - - void add_light(int local_x, int local_y, int local_z, int size, Color color); - void clear_baked_lights(); - //Meshing void create_meshers(); - void _create_meshers(); - void build_deferred(); - void build_prioritized(); - static void _build_step_threaded(void *_userdata); - - void build_step(); - - void build_phase(); - void _build_phase(int phase); - - void build_phase_process(); - void _build_phase_process(int phase); - - void build_phase_physics_process(); - void _build_phase_physics_process(int phase); - - bool has_next_phase(); - void next_phase(); + void build(bool immediate = false); void clear(); - //Colliders - void create_colliders(); - void remove_colliders(); - //lights void add_lights(Array lights); void add_voxel_light(Ref light); @@ -282,6 +173,9 @@ public: void bake_lights(); void bake_light(Ref light); + void clear_baked_lights(); + + void add_light(int local_x, int local_y, int local_z, int size, Color color); void add_prop_light(Ref light); @@ -294,56 +188,19 @@ public: void free_spawn_props(); - //Meshes - void allocate_main_mesh(); - void free_main_mesh(); - - void allocate_prop_mesh(); - void free_prop_mesh(); - - void allocate_prop_colliders(); - void free_prop_colliders(); - - void allocate_liquid_mesh(); - void free_liquid_mesh(); - - void allocate_clutter_mesh(); - void free_clutter_mesh(); - - //Debug - void create_debug_immediate_geometry(); - void free_debug_immediate_geometry(); - - void draw_cross_voxels(Vector3 pos); - void draw_cross_voxels_fill(Vector3 pos, float fill); - void draw_debug_voxels(int max, Color color = Color(1, 1, 1)); - void draw_debug_voxel_lights(); - - //free - void free_chunk(); - VoxelChunk(); ~VoxelChunk(); protected: - void wait_and_finish_thread(); - - void _notification(int p_what); bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List *p_list) const; static void _bind_methods(); bool _is_generating; - bool _is_build_threaded; - bool _abort_build; bool _dirty; int _state; - int _current_build_phase; - int _max_build_phases; - bool _enabled; - VoxelWorld *_voxel_world; int _position_x; @@ -365,61 +222,16 @@ protected: Vector > _voxel_lights; - int _lod_size; float _voxel_scale; - NodePath _library_path; Ref _library; Vector > _meshers; - //voxel mesh - RID _mesh_rid; - RID _mesh_instance_rid; - - RID _shape_rid; - RID _body_rid; - //mergeable props Vector > _props; - RID _prop_mesh_rid; - RID _prop_mesh_instance_rid; - - RID _prop_shape_rid; - RID _prop_body_rid; - - //liquids - RID _liquid_mesh_rid; - RID _liquid_mesh_instance_rid; - - //clutter - RID _clutter_mesh_rid; - RID _clutter_mesh_instance_rid; - //spawned props Vector _spawned_props; - - //debug - ImmediateGeometry *_debug_drawer; - - bool _build_mesh; - bool _create_collider; - - bool _bake_lights; - - bool _build_prioritized; - Mutex *_build_phase_done_mutex; - bool _build_phase_done; - Thread *_build_thread; - bool _build_step_in_progress; - - Array temp_array; - PoolVector temp_arr_collider; - - ActiveBuildPhaseType _active_build_phase_type; }; -VARIANT_ENUM_CAST(VoxelChunk::DefaultChannels); -VARIANT_ENUM_CAST(VoxelChunk::ActiveBuildPhaseType); - #endif diff --git a/world/voxel_chunk_default.cpp b/world/voxel_chunk_default.cpp new file mode 100644 index 0000000..e65ef5e --- /dev/null +++ b/world/voxel_chunk_default.cpp @@ -0,0 +1,1251 @@ +/* +Copyright (c) 2019-2020 Péter Magyar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "voxel_chunk_default.h" + +#include "voxel_world.h" + +const String VoxelChunkDefault::BINDING_STRING_ACTIVE_BUILD_PHASE_TYPE = "Normal,Process,Physics Process"; + +_FORCE_INLINE_ bool VoxelChunkDefault::get_is_build_threaded() const { + return _is_build_threaded; +} +_FORCE_INLINE_ void VoxelChunkDefault::set_is_build_threaded(bool value) { + _is_build_threaded = value; +} + +_FORCE_INLINE_ VoxelChunkDefault::ActiveBuildPhaseType VoxelChunkDefault::get_active_build_phase_type() const { + return _active_build_phase_type; +} +_FORCE_INLINE_ void VoxelChunkDefault::set_active_build_phase_type(const VoxelChunkDefault::ActiveBuildPhaseType value) { + _active_build_phase_type = value; + + if (_active_build_phase_type == VoxelChunkDefault::BUILD_PHASE_TYPE_PHYSICS_PROCESS) { + set_physics_process_internal(true); + } else { + set_physics_process_internal(false); + } +} + +bool VoxelChunkDefault::get_build_phase_done() const { + _build_phase_done_mutex->lock(); + bool v = _build_phase_done; + _build_phase_done_mutex->unlock(); + + return v; +} +void VoxelChunkDefault::set_build_phase_done(bool value) { + _build_phase_done_mutex->lock(); + _build_phase_done = value; + _build_phase_done_mutex->unlock(); +} + +int VoxelChunkDefault::get_lod_size() const { + return _lod_size; +} +void VoxelChunkDefault::set_lod_size(const int lod_size) { + _lod_size = lod_size; + + for (int i = 0; i < _meshers.size(); ++i) { + Ref mesher = _meshers.get(i); + + ERR_CONTINUE(!mesher.is_valid()); + + mesher->set_lod_size(_lod_size); + } +} + +int VoxelChunkDefault::get_current_build_phase() { + return _current_build_phase; +} +void VoxelChunkDefault::set_current_build_phase(int value) { + _current_build_phase = value; +} + +int VoxelChunkDefault::get_max_build_phase() { + return _max_build_phases; +} +void VoxelChunkDefault::set_max_build_phase(int value) { + _max_build_phases = value; +} +bool VoxelChunkDefault::get_create_collider() const { + return _create_collider; +} +void VoxelChunkDefault::set_create_collider(bool value) { + _create_collider = value; +} + +bool VoxelChunkDefault::get_bake_lights() const { + return _bake_lights; +} +void VoxelChunkDefault::set_bake_lights(bool value) { + _bake_lights = value; +} + +RID VoxelChunkDefault::get_mesh_rid() { + return _mesh_rid; +} +RID VoxelChunkDefault::get_mesh_instance_rid() { + return _mesh_instance_rid; +} +RID VoxelChunkDefault::get_shape_rid() { + return _shape_rid; +} +RID VoxelChunkDefault::get_body_rid() { + return _body_rid; +} + +RID VoxelChunkDefault::get_prop_mesh_rid() { + return _prop_mesh_rid; +} +RID VoxelChunkDefault::get_prop_mesh_instance_rid() { + return _prop_mesh_instance_rid; +} +RID VoxelChunkDefault::get_prop_shape_rid() { + return _prop_shape_rid; +} +RID VoxelChunkDefault::get_prop_body_rid() { + return _prop_body_rid; +} + +RID VoxelChunkDefault::get_liquid_mesh_rid() { + return _liquid_mesh_rid; +} +RID VoxelChunkDefault::get_liquid_mesh_instance_rid() { + return _liquid_mesh_instance_rid; +} + +RID VoxelChunkDefault::get_clutter_mesh_rid() { + return _clutter_mesh_rid; +} +RID VoxelChunkDefault::get_clutter_mesh_instance_rid() { + return _clutter_mesh_instance_rid; +} + +//Data Management functions +void VoxelChunkDefault::generate_ao() { + ERR_FAIL_COND(_data_size_x == 0 || _data_size_y == 0 || _data_size_z == 0); + + int size_x = get_size_x() + get_margin_end(); + int size_y = get_size_y() + get_margin_end(); + int size_z = get_size_z() + get_margin_end(); + + for (int y = get_margin_start() - 1; y < size_y - 1; ++y) { + for (int z = get_margin_start() - 1; z < size_z - 1; ++z) { + for (int x = get_margin_start() - 1; x < size_x - 1; ++x) { + int current = get_voxel(x, y, z, DEFAULT_CHANNEL_ISOLEVEL); + + int sum = get_voxel(x + 1, y, z, DEFAULT_CHANNEL_ISOLEVEL); + sum += get_voxel(x - 1, y, z, DEFAULT_CHANNEL_ISOLEVEL); + sum += get_voxel(x, y + 1, z, DEFAULT_CHANNEL_ISOLEVEL); + sum += get_voxel(x, y - 1, z, DEFAULT_CHANNEL_ISOLEVEL); + sum += get_voxel(x, y, z + 1, DEFAULT_CHANNEL_ISOLEVEL); + sum += get_voxel(x, y, z - 1, DEFAULT_CHANNEL_ISOLEVEL); + + sum /= 6; + + sum -= current; + + if (sum < 0) + sum = 0; + + set_voxel(sum, x, y, z, DEFAULT_CHANNEL_AO); + } + } + } +} + +void VoxelChunkDefault::build_deferred() { + if (_current_build_phase == BUILD_PHASE_DONE) { + _build_prioritized = true; + + wait_and_finish_thread(); + + set_process_internal(true); + + _is_generating = true; + + next_phase(); + + if (!_voxel_world->can_chunk_do_build_step()) + return; + + build_step(); + } +} + +void VoxelChunkDefault::build_prioritized() { + if (_current_build_phase == BUILD_PHASE_DONE) { + _build_prioritized = true; + + wait_and_finish_thread(); + + set_process_internal(true); + + _is_generating = true; + + next_phase(); + + if (!_voxel_world->can_chunk_do_build_step()) + return; + + build_step(); + } +} + +void VoxelChunkDefault::build_step() { + ERR_FAIL_COND(!has_next_phase()); + ERR_FAIL_COND(_build_step_in_progress); + + _build_step_in_progress = true; + + if (get_is_build_threaded()) { + if (_build_thread) { + wait_and_finish_thread(); + } + + _build_thread = Thread::create(_build_step_threaded, this); + return; + } + + while (has_next_phase() && _active_build_phase_type == BUILD_PHASE_TYPE_NORMAL) { + build_phase(); + + if (!get_build_phase_done()) + break; + } + + _build_step_in_progress = false; +} + +void VoxelChunkDefault::_build_step_threaded(void *_userdata) { + VoxelChunkDefault *vc = (VoxelChunkDefault *)_userdata; + + while (vc->has_next_phase() && vc->_active_build_phase_type == BUILD_PHASE_TYPE_NORMAL) { + vc->build_phase(); + + if (!vc->get_build_phase_done()) + break; + } + + vc->_build_step_in_progress = false; +} + +void VoxelChunkDefault::build_phase() { + + _THREAD_SAFE_METHOD_ + + if (_abort_build) + return; + + set_build_phase_done(false); + + call("_build_phase", _current_build_phase); +} + +void VoxelChunkDefault::build_phase_process() { + if (_abort_build) + return; + + set_build_phase_done(false); + + call("_build_phase_process", _current_build_phase); +} + +void VoxelChunkDefault::build_phase_physics_process() { + if (_abort_build) + return; + + set_build_phase_done(false); + + call("_build_phase_physics_process", _current_build_phase); +} + +bool VoxelChunkDefault::has_next_phase() { + if (_current_build_phase == BUILD_PHASE_DONE) + return false; + + return true; +} + +void VoxelChunkDefault::next_phase() { + set_build_phase_done(true); + + if (_abort_build) { + _current_build_phase = BUILD_PHASE_DONE; + _is_generating = false; + set_process_internal(false); + + return; + } + + ++_current_build_phase; + + if (_current_build_phase >= _max_build_phases) { + _current_build_phase = BUILD_PHASE_DONE; + _is_generating = false; + set_process_internal(false); + + emit_signal("mesh_generation_finished", this); + + if (_voxel_world != NULL) { + _voxel_world->on_chunk_mesh_generation_finished(this); + } + } +} + +void VoxelChunkDefault::clear() { + _voxel_lights.clear(); +} + +void VoxelChunkDefault::create_colliders() { + ERR_FAIL_COND(_voxel_world == NULL); + + _shape_rid = PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON); + _body_rid = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC); + + PhysicsServer::get_singleton()->body_set_collision_layer(_body_rid, 1); + PhysicsServer::get_singleton()->body_set_collision_mask(_body_rid, 1); + + PhysicsServer::get_singleton()->body_add_shape(_body_rid, _shape_rid); + + PhysicsServer::get_singleton()->body_set_state(_body_rid, PhysicsServer::BODY_STATE_TRANSFORM, Transform(Basis(), Vector3(_position_x * _size_x * _voxel_scale, _position_y * _size_y * _voxel_scale, _position_z * _size_z * _voxel_scale))); + PhysicsServer::get_singleton()->body_set_space(_body_rid, get_voxel_world()->get_world()->get_space()); +} + +void VoxelChunkDefault::remove_colliders() { + if (_body_rid != RID()) { + PhysicsServer::get_singleton()->free(_body_rid); + PhysicsServer::get_singleton()->free(_shape_rid); + + _body_rid = RID(); + _shape_rid = RID(); + } +} + +void VoxelChunkDefault::allocate_main_mesh() { + ERR_FAIL_COND(_voxel_world == NULL); + + ERR_FAIL_COND(!get_library().is_valid()); + + _mesh_instance_rid = VS::get_singleton()->instance_create(); + + if (get_voxel_world()->get_world().is_valid()) + VS::get_singleton()->instance_set_scenario(_mesh_instance_rid, get_voxel_world()->get_world()->get_scenario()); + + _mesh_rid = VS::get_singleton()->mesh_create(); + + VS::get_singleton()->instance_set_base(_mesh_instance_rid, _mesh_rid); + + VS::get_singleton()->instance_set_transform(_mesh_instance_rid, Transform(Basis(), Vector3(_position_x * _size_x * _voxel_scale, _position_y * _size_y * _voxel_scale, _position_z * _size_z * _voxel_scale))); +} + +void VoxelChunkDefault::free_main_mesh() { + if (_mesh_instance_rid != RID()) { + VS::get_singleton()->free(_mesh_instance_rid); + VS::get_singleton()->free(_mesh_rid); + + _mesh_instance_rid = RID(); + _mesh_rid = RID(); + } +} + +void VoxelChunkDefault::allocate_prop_mesh() { + ERR_FAIL_COND(_voxel_world == NULL); + ERR_FAIL_COND(!get_library().is_valid()); + + _prop_mesh_instance_rid = VS::get_singleton()->instance_create(); + + if (get_voxel_world()->get_world().is_valid()) + VS::get_singleton()->instance_set_scenario(_prop_mesh_instance_rid, get_voxel_world()->get_world()->get_scenario()); + + _prop_mesh_rid = VS::get_singleton()->mesh_create(); + + VS::get_singleton()->instance_set_base(_prop_mesh_instance_rid, _prop_mesh_rid); + + VS::get_singleton()->instance_set_transform(_prop_mesh_instance_rid, Transform(Basis(), Vector3(_position_x * _size_x * _voxel_scale, _position_y * _size_y * _voxel_scale, _position_z * _size_z * _voxel_scale))); +} + +void VoxelChunkDefault::free_prop_mesh() { + if (_prop_mesh_instance_rid != RID()) { + VS::get_singleton()->free(_prop_mesh_instance_rid); + VS::get_singleton()->free(_prop_mesh_rid); + + _prop_mesh_instance_rid = RID(); + _prop_mesh_rid = RID(); + } +} + +void VoxelChunkDefault::allocate_prop_colliders() { + ERR_FAIL_COND(_voxel_world == NULL); + + _prop_shape_rid = PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON); + _prop_body_rid = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC); + + PhysicsServer::get_singleton()->body_set_collision_layer(_prop_body_rid, 1); + PhysicsServer::get_singleton()->body_set_collision_mask(_prop_body_rid, 1); + + PhysicsServer::get_singleton()->body_add_shape(_prop_body_rid, _prop_shape_rid); + + PhysicsServer::get_singleton()->body_set_state(_prop_body_rid, PhysicsServer::BODY_STATE_TRANSFORM, Transform(Basis(), Vector3(_position_x * _size_x * _voxel_scale, _position_y * _size_y * _voxel_scale, _position_z * _size_z * _voxel_scale))); + PhysicsServer::get_singleton()->body_set_space(_prop_body_rid, get_voxel_world()->get_world()->get_space()); +} +void VoxelChunkDefault::free_prop_colliders() { + if (_prop_body_rid != RID()) { + PhysicsServer::get_singleton()->free(_prop_body_rid); + PhysicsServer::get_singleton()->free(_prop_shape_rid); + + _prop_body_rid = RID(); + _prop_shape_rid = RID(); + } +} + +//Liquid mesh +void VoxelChunkDefault::allocate_liquid_mesh() { + ERR_FAIL_COND(_voxel_world == NULL); + + ERR_FAIL_COND(!get_library().is_valid()); + + _liquid_mesh_instance_rid = VS::get_singleton()->instance_create(); + + if (get_voxel_world()->get_world().is_valid()) + VS::get_singleton()->instance_set_scenario(_liquid_mesh_instance_rid, get_voxel_world()->get_world()->get_scenario()); + + _liquid_mesh_rid = VS::get_singleton()->mesh_create(); + + VS::get_singleton()->instance_set_base(_liquid_mesh_instance_rid, _liquid_mesh_rid); + + VS::get_singleton()->instance_set_transform(_liquid_mesh_instance_rid, Transform(Basis(), Vector3(_position_x * _size_x * _voxel_scale, _position_y * _size_y * _voxel_scale, _position_z * _size_z * _voxel_scale))); +} + +void VoxelChunkDefault::free_liquid_mesh() { + if (_liquid_mesh_instance_rid != RID()) { + VS::get_singleton()->free(_liquid_mesh_instance_rid); + VS::get_singleton()->free(_liquid_mesh_rid); + + _liquid_mesh_instance_rid = RID(); + _liquid_mesh_rid = RID(); + } +} + +//Clutter mesh +void VoxelChunkDefault::allocate_clutter_mesh() { + ERR_FAIL_COND(_voxel_world == NULL); + + ERR_FAIL_COND(!get_library().is_valid()); + + _clutter_mesh_instance_rid = VS::get_singleton()->instance_create(); + + if (get_voxel_world()->get_world().is_valid()) + VS::get_singleton()->instance_set_scenario(_clutter_mesh_instance_rid, get_voxel_world()->get_world()->get_scenario()); + + _clutter_mesh_rid = VS::get_singleton()->mesh_create(); + + VS::get_singleton()->instance_set_base(_clutter_mesh_instance_rid, _clutter_mesh_rid); + + VS::get_singleton()->instance_set_transform(_clutter_mesh_instance_rid, Transform(Basis(), Vector3(_position_x * _size_x * _voxel_scale, _position_y * _size_y * _voxel_scale, _position_z * _size_z * _voxel_scale))); +} + +void VoxelChunkDefault::free_clutter_mesh() { + if (_clutter_mesh_instance_rid != RID()) { + VS::get_singleton()->free(_clutter_mesh_instance_rid); + VS::get_singleton()->free(_clutter_mesh_rid); + + _clutter_mesh_instance_rid = RID(); + _clutter_mesh_rid = RID(); + } +} + +void VoxelChunkDefault::create_debug_immediate_geometry() { + ERR_FAIL_COND(_voxel_world == NULL); + ERR_FAIL_COND(_debug_drawer != NULL); + + _debug_drawer = memnew(ImmediateGeometry()); + + add_child(_debug_drawer); + + if (Engine::get_singleton()->is_editor_hint()) + _debug_drawer->set_owner(get_tree()->get_edited_scene_root()); + + //_debug_drawer->set_transform(Transform(Basis(), Vector3(_position.x * _size.x * _voxel_scale, _position.y * _size.y * _voxel_scale, _position.z * _size.z * _voxel_scale))); + //_debug_drawer->set_transform(Transform(Basis(), Vector3(_position.x * _size.x * _voxel_scale, _position.y * _size.y * _voxel_scale, _position.z * _size.z * _voxel_scale))); +} + +void VoxelChunkDefault::free_debug_immediate_geometry() { + if (ObjectDB::instance_validate(_debug_drawer)) { + _debug_drawer->queue_delete(); + + _debug_drawer = NULL; + } +} + +void VoxelChunkDefault::draw_cross_voxels(Vector3 pos) { + pos *= _voxel_scale; + + _debug_drawer->add_vertex(pos + Vector3(0, 0, -0.2)); + _debug_drawer->add_vertex(pos + Vector3(0, 0, 0.2)); + + _debug_drawer->add_vertex(pos + Vector3(0, -0.2, 0)); + _debug_drawer->add_vertex(pos + Vector3(0, 0.2, 0)); + + _debug_drawer->add_vertex(pos + Vector3(-0.2, 0, 0)); + _debug_drawer->add_vertex(pos + Vector3(0.2, 0, 0)); +} + +void VoxelChunkDefault::draw_cross_voxels_fill(Vector3 pos, float fill) { + pos *= _voxel_scale; + + _debug_drawer->add_vertex(pos + Vector3(0, 0, -0.5 * fill)); + _debug_drawer->add_vertex(pos + Vector3(0, 0, 0.5 * fill)); + + _debug_drawer->add_vertex(pos + Vector3(0, -0.5 * fill, 0)); + _debug_drawer->add_vertex(pos + Vector3(0, 0.5 * fill, 0)); + + _debug_drawer->add_vertex(pos + Vector3(-0.5 * fill, 0, 0)); + _debug_drawer->add_vertex(pos + Vector3(0.5 * fill, 0, 0)); +} + +void VoxelChunkDefault::draw_debug_voxels(int max, Color color) { + if (_debug_drawer == NULL) { + create_debug_immediate_geometry(); + } + + ERR_FAIL_COND(_debug_drawer == NULL); + + _debug_drawer->clear(); + _debug_drawer->begin(Mesh::PRIMITIVE_LINES); + _debug_drawer->set_color(color); + + int a = 0; + + int64_t sx = static_cast(_size_x); + int64_t sy = static_cast(_size_y); + int64_t sz = static_cast(_size_y); + + for (int y = 0; y < sy; ++y) { + for (int z = 0; z < sz; ++z) { + for (int x = 0; x < sx; ++x) { + + int type = get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_TYPE); + + if (type == 0) { + continue; + } + + draw_cross_voxels_fill(Vector3(x, y, z), get_voxel(x, y, z, VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL) / 255.0 * get_voxel_scale() * 2.0); + + ++a; + + if (a > max) { + break; + } + } + } + } + + _debug_drawer->end(); +} + +void VoxelChunkDefault::draw_debug_voxel_lights() { + if (_debug_drawer == NULL) { + create_debug_immediate_geometry(); + } + + ERR_FAIL_COND(_debug_drawer == NULL); + + _debug_drawer->clear(); + _debug_drawer->begin(Mesh::PrimitiveType::PRIMITIVE_LINES); + _debug_drawer->set_color(Color(1, 1, 1)); + + for (int i = 0; i < _voxel_lights.size(); ++i) { + Ref v = _voxel_lights[i]; + + int pos_x = v->get_world_position_x() - (_size_x * _position_x); + int pos_y = v->get_world_position_y() - (_size_y * _position_y); + int pos_z = v->get_world_position_z() - (_size_z * _position_z); + + draw_cross_voxels_fill(Vector3(pos_x, pos_y, pos_z), 1.0); + } + + if (has_method("_draw_debug_voxel_lights")) + call("_draw_debug_voxel_lights", _debug_drawer); + + _debug_drawer->end(); +} + +void VoxelChunkDefault::free_chunk() { + free_main_mesh(); + remove_colliders(); + free_prop_mesh(); + free_prop_colliders(); + free_spawn_props(); + free_liquid_mesh(); + free_clutter_mesh(); +} + +VoxelChunkDefault::VoxelChunkDefault() { + _is_generating = false; + _is_build_threaded = false; + _abort_build = false; + _dirty = false; + _state = VOXEL_CHUNK_STATE_OK; + + _enabled = true; + _build_mesh = true; + _create_collider = true; + _bake_lights = true; + _current_build_phase = BUILD_PHASE_DONE; + _max_build_phases = BUILD_PHASE_MAX; + + _voxel_scale = 1; + _lod_size = 1; + + _debug_drawer = NULL; + _voxel_world = NULL; + + _position_x = 0; + _position_y = 0; + _position_z = 0; + + _size_x = 0; + _size_y = 0; + _size_z = 0; + + _data_size_x = 0; + _data_size_y = 0; + _data_size_z = 0; + + _margin_start = 0; + _margin_end = 0; + + _build_prioritized = false; + _build_phase_done_mutex = Mutex::create(); + _build_phase_done = false; + _build_thread = NULL; + _build_step_in_progress = false; + + _active_build_phase_type = BUILD_PHASE_TYPE_NORMAL; +} + +VoxelChunkDefault::~VoxelChunkDefault() { + if (_build_thread) { + _abort_build = true; + wait_and_finish_thread(); + } + + free_main_mesh(); + remove_colliders(); + free_prop_mesh(); + free_prop_colliders(); + free_liquid_mesh(); + free_clutter_mesh(); + + memdelete(_build_phase_done_mutex); +} + +void VoxelChunkDefault::_setup_channels() { + set_channel_count(MAX_DEFAULT_CHANNELS); +} + +void VoxelChunkDefault::_build_phase(int phase) { + ERR_FAIL_COND(!_library.is_valid()); + + switch (phase) { + case BUILD_PHASE_DONE: + return; + case BUILD_PHASE_SETUP: { + if (_meshers.size() == 0) { + create_meshers(); + } + + for (int i = 0; i < _meshers.size(); ++i) { + Ref mesher = _meshers.get(i); + + ERR_CONTINUE(!mesher.is_valid()); + + mesher->set_library(_library); + mesher->reset(); + } + + next_phase(); + + return; + } + case BUILD_PHASE_TERRARIN_MESH_SETUP: { + for (int i = 0; i < _meshers.size(); ++i) { + Ref mesher = _meshers.get(i); + + ERR_CONTINUE(!mesher.is_valid()); + + mesher->add_chunk(this); + } + + next_phase(); + + return; + } + case BUILD_PHASE_TERRARIN_MESH_COLLIDER: { + if (!get_create_collider()) { + next_phase(); + return; + } + + for (int i = 0; i < _meshers.size(); ++i) { + Ref mesher = _meshers.get(i); + + ERR_CONTINUE(!mesher.is_valid()); + + temp_arr_collider.append_array(mesher->build_collider()); + } + + if (temp_arr_collider.size() == 0) { + next_phase(); + return; + } + + if (_is_build_threaded) { + set_active_build_phase_type(BUILD_PHASE_TYPE_PHYSICS_PROCESS); + return; + } + + if (_body_rid == RID()) { + create_colliders(); + } + + PhysicsServer::get_singleton()->shape_set_data(_shape_rid, temp_arr_collider); + + //temp_arr_collider.resize(0); + + next_phase(); + + return; + } + case BUILD_PHASE_TERRARIN_MESH: { + for (int i = 0; i < _meshers.size(); ++i) { + Ref mesher = _meshers.get(i); + + ERR_CONTINUE(!mesher.is_valid()); + + mesher->bake_colors(this); + } + + for (int i = 0; i < _meshers.size(); ++i) { + Ref mesher = _meshers.get(i); + + ERR_CONTINUE(!mesher.is_valid()); + + mesher->set_library(_library); + } + + Ref mesher; + for (int i = 0; i < _meshers.size(); ++i) { + Ref m = _meshers.get(i); + + ERR_CONTINUE(!m.is_valid()); + + if (!mesher.is_valid()) { + mesher = m; + mesher->set_material(get_library()->get_material()); + continue; + } + + mesher->set_material(get_library()->get_material()); + mesher->add_mesher(m); + } + + ERR_FAIL_COND(!mesher.is_valid()); + + if (mesher->get_vertex_count() == 0) { + next_phase(); + return; + } + + if (_mesh_rid != RID()) + VS::get_singleton()->mesh_clear(_mesh_rid); + + Array temp_mesh_arr = mesher->build_mesh(); + + if (_mesh_rid == RID()) { + allocate_main_mesh(); + } + + VS::get_singleton()->mesh_add_surface_from_arrays(_mesh_rid, VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr); + + if (_library->get_material().is_valid()) + VS::get_singleton()->mesh_surface_set_material(_mesh_rid, 0, _library->get_material()->get_rid()); + + next_phase(); + + return; + } + case BUILD_PHASE_PROP_MESH: { + for (int i = 0; i < _meshers.size(); ++i) { + Ref mesher = _meshers.get(i); + + ERR_CONTINUE(!mesher.is_valid()); + + mesher->reset(); + } + + if (_props.size() > 0) { + if (_prop_mesh_rid == RID()) { + allocate_prop_mesh(); + } + + for (int i = 0; i < _meshers.size(); ++i) { + Ref mesher = _meshers.get(i); + + ERR_CONTINUE(!mesher.is_valid()); + + mesher->bake_colors(this); + mesher->set_material(get_library()->get_material()); + + ERR_FAIL_COND(_prop_mesh_rid == RID()); + + VS::get_singleton()->mesh_clear(_prop_mesh_rid); + + if (mesher->get_vertex_count() == 0) { + next_phase(); + return; + } + + Array arr = mesher->build_mesh(); + + VS::get_singleton()->mesh_add_surface_from_arrays(_prop_mesh_rid, VisualServer::PRIMITIVE_TRIANGLES, arr); + + if (_library->get_material().is_valid()) + VS::get_singleton()->mesh_surface_set_material(_prop_mesh_rid, 0, _library->get_material()->get_rid()); + } + } + + next_phase(); + + return; + } + case BUILD_PHASE_PROP_COLLIDER: { + if (!get_create_collider()) { + next_phase(); + return; + } + + for (int i = 0; i < _meshers.size(); ++i) { + Ref mesher = _meshers.get(i); + + ERR_CONTINUE(!mesher.is_valid()); + + temp_arr_collider.append_array(mesher->build_collider()); + } + + for (int i = 0; i < _meshers.size(); ++i) { + Ref mesher = _meshers.get(i); + + ERR_CONTINUE(!mesher.is_valid()); + + mesher->reset(); + } + + if (temp_arr_collider.size() == 0) { + next_phase(); + return; + } + + if (_is_build_threaded) { + set_active_build_phase_type(BUILD_PHASE_TYPE_PHYSICS_PROCESS); + return; + } + + if (_prop_body_rid == RID()) { + allocate_prop_colliders(); + } + + PhysicsServer::get_singleton()->shape_set_data(_shape_rid, temp_arr_collider); + + //temp_arr_collider.resize(0); + + next_phase(); + + return; + } + /* + case BUILD_PHASE_LIQUID: { + next_phase(); + return; + } + case BUILD_PHASE_CLUTTER: { + next_phase(); + return; + } + */ + case BUILD_PHASE_FINALIZE: { + if (_mesh_instance_rid != RID()) + VS::get_singleton()->instance_set_visible(_mesh_instance_rid, is_visible()); + + if (_prop_mesh_instance_rid != RID()) + VS::get_singleton()->instance_set_visible(_prop_mesh_instance_rid, is_visible()); + + if (_liquid_mesh_instance_rid != RID()) + VS::get_singleton()->instance_set_visible(_liquid_mesh_instance_rid, is_visible()); + + if (_clutter_mesh_instance_rid != RID()) + VS::get_singleton()->instance_set_visible(_clutter_mesh_instance_rid, is_visible()); + + next_phase(); + + return; + } + } +} + +void VoxelChunkDefault::_build_phase_process(int phase) { +} + +void VoxelChunkDefault::_build_phase_physics_process(int phase) { + if (phase == BUILD_PHASE_TERRARIN_MESH_COLLIDER) { + + if (_body_rid == RID()) { + create_colliders(); + } + + PhysicsServer::get_singleton()->shape_set_data(_shape_rid, temp_arr_collider); + //temp_arr_collider.resize(0); + + set_active_build_phase_type(BUILD_PHASE_TYPE_NORMAL); + next_phase(); + + } else if (phase == BUILD_PHASE_PROP_COLLIDER) { + + if (_prop_body_rid == RID()) { + allocate_prop_colliders(); + } + + PhysicsServer::get_singleton()->shape_set_data(_prop_shape_rid, temp_arr_collider); + //temp_arr_collider.resize(0); + + set_active_build_phase_type(BUILD_PHASE_TYPE_NORMAL); + next_phase(); + } +} + +void VoxelChunkDefault::_add_light(int local_x, int local_y, int local_z, int size, Color color) { + ERR_FAIL_COND(size < 0); + + //float sizef = static_cast(size); + //float rf = (color.r / sizef); + //float gf = (color.g / sizef); + //float bf = (color.b / sizef); + + int64_t dsx = static_cast(_data_size_x); + int64_t dsy = static_cast(_data_size_y); + int64_t dsz = static_cast(_data_size_z); + + for (int y = local_y - size; y <= local_y + size; ++y) { + if (y < 0 || y >= dsy) + continue; + + for (int z = local_z - size; z <= local_z + size; ++z) { + if (z < 0 || z >= dsz) + continue; + + for (int x = local_x - size; x <= local_x + size; ++x) { + if (x < 0 || x >= dsx) + continue; + + int lx = x - local_x; + int ly = y - local_y; + int lz = z - local_z; + + float str = size - (((float)lx * lx + ly * ly + lz * lz)); + str /= size; + + if (str < 0) + continue; + + int r = color.r * str * 255.0; + int g = color.g * str * 255.0; + int b = color.b * str * 255.0; + + r += get_voxel(x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_R); + g += get_voxel(x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_G); + b += get_voxel(x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_B); + + if (r > 255) + r = 255; + + if (g > 255) + g = 255; + + if (b > 255) + b = 255; + + set_voxel(r, x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_R); + set_voxel(g, x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_G); + set_voxel(b, x, y, z, DEFAULT_CHANNEL_LIGHT_COLOR_B); + } + } + } +} +void VoxelChunkDefault::_clear_baked_lights() { + fill_channel(0, DEFAULT_CHANNEL_LIGHT_COLOR_R); + fill_channel(0, DEFAULT_CHANNEL_LIGHT_COLOR_G); + fill_channel(0, DEFAULT_CHANNEL_LIGHT_COLOR_B); +} + +void VoxelChunkDefault::_create_meshers() { + add_mesher(Ref(memnew(VoxelMesherCubic()))); + + for (int i = 0; i < _meshers.size(); ++i) { + Ref mesher = _meshers.get(i); + + ERR_CONTINUE(!mesher.is_valid()); + + mesher->set_lod_size(get_lod_size()); + mesher->set_voxel_scale(get_voxel_scale()); + } +} + +void VoxelChunkDefault::_build(bool immediate) { + build_deferred(); +} + +void VoxelChunkDefault::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_EXIT_TREE: { + if (_build_thread) { + _abort_build = true; + + wait_and_finish_thread(); + } + } + case NOTIFICATION_INTERNAL_PROCESS: { + if (!get_is_generating() || !has_next_phase() || _build_step_in_progress) { + return; + } + + switch (_active_build_phase_type) { + case BUILD_PHASE_TYPE_PROCESS: { + if (!_voxel_world->can_chunk_do_build_step()) + return; + + _build_step_in_progress = true; + + while (has_next_phase() && _active_build_phase_type == BUILD_PHASE_TYPE_PROCESS) { + build_phase_process(); + + if (!get_build_phase_done()) + break; + } + + _build_step_in_progress = false; + return; + } + case BUILD_PHASE_TYPE_NORMAL: { + //normal mode -> build step is not in progress -> need to restart building + + if (!_voxel_world->can_chunk_do_build_step()) + return; + + build_step(); + + return; + } + case BUILD_PHASE_TYPE_PHYSICS_PROCESS: + return; + } + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + if (!get_is_generating() || !has_next_phase() || _build_step_in_progress) { + return; + } + + if (_active_build_phase_type == BUILD_PHASE_TYPE_PHYSICS_PROCESS) { + + if (!_voxel_world->can_chunk_do_build_step()) + return; + + _build_step_in_progress = true; + + while (has_next_phase() && _active_build_phase_type == BUILD_PHASE_TYPE_PHYSICS_PROCESS) { + build_phase_physics_process(); + + if (!get_build_phase_done()) + break; + } + + _build_step_in_progress = false; + + return; + } + } + } + } +} + +void VoxelChunkDefault::wait_and_finish_thread() { + if (_build_thread) { + Thread::wait_to_finish(_build_thread); + memdelete(_build_thread); + _build_thread = NULL; + } +} + +void VoxelChunkDefault::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_is_build_threaded"), &VoxelChunkDefault::get_is_build_threaded); + ClassDB::bind_method(D_METHOD("set_is_build_threaded", "value"), &VoxelChunkDefault::set_is_build_threaded); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_build_threaded"), "set_is_build_threaded", "get_is_build_threaded"); + + ClassDB::bind_method(D_METHOD("get_active_build_phase_type"), &VoxelChunkDefault::get_active_build_phase_type); + ClassDB::bind_method(D_METHOD("set_active_build_phase_type", "value"), &VoxelChunkDefault::set_active_build_phase_type); + ADD_PROPERTY(PropertyInfo(Variant::INT, "active_build_phase_type", PROPERTY_HINT_ENUM, BINDING_STRING_ACTIVE_BUILD_PHASE_TYPE), "set_active_build_phase_type", "get_active_build_phase_type"); + + ClassDB::bind_method(D_METHOD("get_lod_size"), &VoxelChunkDefault::get_lod_size); + ClassDB::bind_method(D_METHOD("set_lod_size", "value"), &VoxelChunkDefault::set_lod_size); + ADD_PROPERTY(PropertyInfo(Variant::INT, "lod_size"), "set_lod_size", "get_lod_size"); + + ClassDB::bind_method(D_METHOD("get_current_build_phase"), &VoxelChunkDefault::get_current_build_phase); + ClassDB::bind_method(D_METHOD("set_current_build_phase", "value"), &VoxelChunkDefault::set_current_build_phase); + ADD_PROPERTY(PropertyInfo(Variant::INT, "current_build_phase"), "set_current_build_phase", "get_current_build_phase"); + + ClassDB::bind_method(D_METHOD("get_max_build_phase"), &VoxelChunkDefault::get_max_build_phase); + ClassDB::bind_method(D_METHOD("set_max_build_phase", "value"), &VoxelChunkDefault::set_max_build_phase); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_build_phase"), "set_max_build_phase", "get_max_build_phase"); + + ADD_GROUP("Meshing", "meshing"); + ClassDB::bind_method(D_METHOD("meshing_get_create_collider"), &VoxelChunkDefault::get_create_collider); + ClassDB::bind_method(D_METHOD("meshing_set_create_collider", "value"), &VoxelChunkDefault::set_create_collider); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meshing_create_collider"), "meshing_set_create_collider", "meshing_get_create_collider"); + + ClassDB::bind_method(D_METHOD("meshing_get_bake_lights"), &VoxelChunkDefault::get_bake_lights); + ClassDB::bind_method(D_METHOD("meshing_set_bake_lights", "value"), &VoxelChunkDefault::set_bake_lights); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meshing_bake_lights"), "meshing_set_bake_lights", "meshing_get_bake_lights"); + + ClassDB::bind_method(D_METHOD("get_mesh_rid"), &VoxelChunkDefault::get_mesh_rid); + ClassDB::bind_method(D_METHOD("get_mesh_instance_rid"), &VoxelChunkDefault::get_mesh_instance_rid); + ClassDB::bind_method(D_METHOD("get_shape_rid"), &VoxelChunkDefault::get_shape_rid); + ClassDB::bind_method(D_METHOD("get_body_rid"), &VoxelChunkDefault::get_body_rid); + + ClassDB::bind_method(D_METHOD("get_prop_mesh_rid"), &VoxelChunkDefault::get_prop_mesh_rid); + ClassDB::bind_method(D_METHOD("get_prop_mesh_instance_rid"), &VoxelChunkDefault::get_prop_mesh_instance_rid); + ClassDB::bind_method(D_METHOD("get_prop_shape_rid"), &VoxelChunkDefault::get_prop_shape_rid); + ClassDB::bind_method(D_METHOD("get_prop_body_rid"), &VoxelChunkDefault::get_prop_body_rid); + + ClassDB::bind_method(D_METHOD("get_liquid_mesh_rid"), &VoxelChunkDefault::get_liquid_mesh_rid); + ClassDB::bind_method(D_METHOD("get_liquid_mesh_instance_rid"), &VoxelChunkDefault::get_liquid_mesh_instance_rid); + + ClassDB::bind_method(D_METHOD("get_clutter_mesh_rid"), &VoxelChunkDefault::get_clutter_mesh_rid); + ClassDB::bind_method(D_METHOD("get_clutter_mesh_instance_rid"), &VoxelChunkDefault::get_clutter_mesh_instance_rid); + + //Voxel Data + + //Data Management functions + ClassDB::bind_method(D_METHOD("generate_ao"), &VoxelChunkDefault::generate_ao); + ClassDB::bind_method(D_METHOD("add_light", "local_x", "local_y", "local_z", "size", "color"), &VoxelChunkDefault::add_light); + ClassDB::bind_method(D_METHOD("clear_baked_lights"), &VoxelChunkDefault::clear_baked_lights); + + //Meshes + BIND_VMETHOD(MethodInfo("_build_phase", PropertyInfo(Variant::INT, "phase"))); + BIND_VMETHOD(MethodInfo("_build_phase_process", PropertyInfo(Variant::INT, "phase"))); + BIND_VMETHOD(MethodInfo("_build_phase_physics_process", PropertyInfo(Variant::INT, "phase"))); + + ClassDB::bind_method(D_METHOD("build_deferred"), &VoxelChunkDefault::build_deferred); + ClassDB::bind_method(D_METHOD("build_prioritized"), &VoxelChunkDefault::build_prioritized); + + ClassDB::bind_method(D_METHOD("build_phase"), &VoxelChunkDefault::build_phase); + ClassDB::bind_method(D_METHOD("build_phase_process"), &VoxelChunkDefault::build_phase_process); + ClassDB::bind_method(D_METHOD("build_phase_physics_process"), &VoxelChunkDefault::build_phase_physics_process); + + ClassDB::bind_method(D_METHOD("next_phase"), &VoxelChunkDefault::next_phase); + ClassDB::bind_method(D_METHOD("has_next_phase"), &VoxelChunkDefault::has_next_phase); + + ClassDB::bind_method(D_METHOD("create_colliders"), &VoxelChunkDefault::create_colliders); + ClassDB::bind_method(D_METHOD("remove_colliders"), &VoxelChunkDefault::remove_colliders); + + ClassDB::bind_method(D_METHOD("allocate_main_mesh"), &VoxelChunkDefault::allocate_main_mesh); + ClassDB::bind_method(D_METHOD("free_main_mesh"), &VoxelChunkDefault::free_main_mesh); + + ClassDB::bind_method(D_METHOD("allocate_prop_mesh"), &VoxelChunkDefault::allocate_prop_mesh); + ClassDB::bind_method(D_METHOD("free_prop_mesh"), &VoxelChunkDefault::free_prop_mesh); + + ClassDB::bind_method(D_METHOD("allocate_prop_colliders"), &VoxelChunkDefault::allocate_prop_colliders); + ClassDB::bind_method(D_METHOD("free_prop_colliders"), &VoxelChunkDefault::free_prop_colliders); + + ClassDB::bind_method(D_METHOD("allocate_liquid_mesh"), &VoxelChunkDefault::allocate_liquid_mesh); + ClassDB::bind_method(D_METHOD("free_liquid_mesh"), &VoxelChunkDefault::free_liquid_mesh); + + ClassDB::bind_method(D_METHOD("allocate_clutter_mesh"), &VoxelChunkDefault::allocate_clutter_mesh); + ClassDB::bind_method(D_METHOD("free_clutter_mesh"), &VoxelChunkDefault::free_clutter_mesh); + + ClassDB::bind_method(D_METHOD("create_debug_immediate_geometry"), &VoxelChunkDefault::create_debug_immediate_geometry); + ClassDB::bind_method(D_METHOD("free_debug_immediate_geometry"), &VoxelChunkDefault::free_debug_immediate_geometry); + + ClassDB::bind_method(D_METHOD("free_chunk"), &VoxelChunkDefault::free_chunk); + + BIND_VMETHOD(MethodInfo("_draw_debug_voxel_lights", PropertyInfo(Variant::OBJECT, "debug_drawer", PROPERTY_HINT_RESOURCE_TYPE, "ImmediateGeometry"))); + + ClassDB::bind_method(D_METHOD("draw_cross_voxels", "max"), &VoxelChunkDefault::draw_cross_voxels); + ClassDB::bind_method(D_METHOD("draw_cross_voxels_fill", "max", "fill"), &VoxelChunkDefault::draw_cross_voxels_fill); + ClassDB::bind_method(D_METHOD("draw_debug_voxels", "max", "color"), &VoxelChunkDefault::draw_debug_voxels, DEFVAL(Color(1, 1, 1))); + + ClassDB::bind_method(D_METHOD("draw_debug_voxel_lights"), &VoxelChunkDefault::draw_debug_voxel_lights); + + ClassDB::bind_method(D_METHOD("_setup_channels"), &VoxelChunkDefault::_setup_channels); + ClassDB::bind_method(D_METHOD("_build_phase", "phase"), &VoxelChunkDefault::_build_phase); + ClassDB::bind_method(D_METHOD("_build_phase_process", "phase"), &VoxelChunkDefault::_build_phase_process); + ClassDB::bind_method(D_METHOD("_build_phase_physics_process", "phase"), &VoxelChunkDefault::_build_phase_physics_process); + + ClassDB::bind_method(D_METHOD("_add_light", "local_x", "local_y", "local_z", "size", "color"), &VoxelChunkDefault::_add_light); + + ClassDB::bind_method(D_METHOD("_clear_baked_lights"), &VoxelChunkDefault::_clear_baked_lights); + ClassDB::bind_method(D_METHOD("_create_meshers"), &VoxelChunkDefault::_create_meshers); + ClassDB::bind_method(D_METHOD("_build", "immediate"), &VoxelChunkDefault::_build); + + BIND_CONSTANT(BUILD_PHASE_DONE); + BIND_CONSTANT(BUILD_PHASE_SETUP); + BIND_CONSTANT(BUILD_PHASE_TERRARIN_MESH_SETUP); + BIND_CONSTANT(BUILD_PHASE_TERRARIN_MESH_COLLIDER); + BIND_CONSTANT(BUILD_PHASE_TERRARIN_MESH); + BIND_CONSTANT(BUILD_PHASE_LIGHTS); + BIND_CONSTANT(BUILD_PHASE_PROP_MESH); + BIND_CONSTANT(BUILD_PHASE_PROP_COLLIDER); + BIND_CONSTANT(BUILD_PHASE_FINALIZE); + BIND_CONSTANT(BUILD_PHASE_MAX); + + BIND_CONSTANT(VOXEL_CHUNK_STATE_GENERATION_QUEUED); + BIND_CONSTANT(VOXEL_CHUNK_STATE_GENERATION); + BIND_CONSTANT(VOXEL_CHUNK_STATE_MESH_GENERATION_QUEUED); + BIND_CONSTANT(VOXEL_CHUNK_STATE_MESH_GENERATION); + BIND_CONSTANT(VOXEL_CHUNK_STATE_MAX); + + BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_TYPE); + BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_ISOLEVEL); + BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_LIGHT_COLOR_R); + BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_LIGHT_COLOR_G); + BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_LIGHT_COLOR_B); + BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_AO); + BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_RANDOM_AO); + BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_LIQUID_TYPES); + BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_LIQUID_FILL); + BIND_ENUM_CONSTANT(DEFAULT_CHANNEL_LIQUID_FLOW); + BIND_ENUM_CONSTANT(MAX_DEFAULT_CHANNELS); + + BIND_ENUM_CONSTANT(BUILD_PHASE_TYPE_NORMAL); + BIND_ENUM_CONSTANT(BUILD_PHASE_TYPE_PROCESS); + BIND_ENUM_CONSTANT(BUILD_PHASE_TYPE_PHYSICS_PROCESS); +} diff --git a/world/voxel_chunk_default.h b/world/voxel_chunk_default.h new file mode 100644 index 0000000..c16ddf0 --- /dev/null +++ b/world/voxel_chunk_default.h @@ -0,0 +1,281 @@ +/* +Copyright (c) 2019-2020 Péter Magyar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef VOXEL_CHUNK_DEFAULT_H +#define VOXEL_CHUNK_DEFAULT_H + +#include "voxel_chunk.h" + +#include "scene/3d/spatial.h" + +#include "core/engine.h" +#include "core/os/mutex.h" +#include "core/os/thread.h" +#include "core/os/thread_safe.h" +#include "core/ustring.h" + +#include "core/array.h" +#include "core/pool_vector.h" +#include "scene/3d/collision_shape.h" +#include "scene/3d/mesh_instance.h" +#include "scene/3d/physics_body.h" +#include "scene/3d/spatial.h" +#include "scene/resources/concave_polygon_shape.h" +#include "scene/resources/packed_scene.h" + +#include "voxel_world.h" + +#include "../data/voxel_light.h" + +#include "../meshers/cubic_mesher/voxel_mesher_cubic.h" +#include "../meshers/voxel_mesher.h" + +#include "../library/voxel_surface.h" +#include "../library/voxelman_library.h" + +#include "../../mesh_data_resource/mesh_data_resource.h" +#include "../props/prop_data.h" +#include "../props/prop_data_entry.h" +#include "../props/prop_data_light.h" +#include "../props/prop_data_mesh.h" +#include "../props/prop_data_scene.h" +#include "voxel_chunk_prop_data.h" + +class VoxelWorld; + +class VoxelChunkDefault : public VoxelChunk { + GDCLASS(VoxelChunkDefault, VoxelChunk); + + _THREAD_SAFE_CLASS_ + +public: + static const String BINDING_STRING_ACTIVE_BUILD_PHASE_TYPE; + + enum { + VOXEL_CHUNK_STATE_GENERATION_QUEUED = 1, + VOXEL_CHUNK_STATE_GENERATION, + VOXEL_CHUNK_STATE_MESH_GENERATION_QUEUED, + VOXEL_CHUNK_STATE_MESH_GENERATION, + VOXEL_CHUNK_STATE_MAX, + }; + + enum { + BUILD_PHASE_DONE = 0, + BUILD_PHASE_SETUP, + BUILD_PHASE_TERRARIN_MESH_SETUP, + BUILD_PHASE_TERRARIN_MESH_COLLIDER, + BUILD_PHASE_LIGHTS, + BUILD_PHASE_TERRARIN_MESH, + BUILD_PHASE_PROP_MESH, + BUILD_PHASE_PROP_COLLIDER, + //BUILD_PHASE_LIQUID, + //BUILD_PHASE_CLUTTER, + BUILD_PHASE_FINALIZE, + BUILD_PHASE_MAX + }; + + enum DefaultChannels { + DEFAULT_CHANNEL_TYPE = 0, + DEFAULT_CHANNEL_ISOLEVEL, + DEFAULT_CHANNEL_LIGHT_COLOR_R, + DEFAULT_CHANNEL_LIGHT_COLOR_G, + DEFAULT_CHANNEL_LIGHT_COLOR_B, + DEFAULT_CHANNEL_AO, + DEFAULT_CHANNEL_RANDOM_AO, + DEFAULT_CHANNEL_LIQUID_TYPES, + DEFAULT_CHANNEL_LIQUID_FILL, + DEFAULT_CHANNEL_LIQUID_FLOW, + MAX_DEFAULT_CHANNELS + }; + + enum ActiveBuildPhaseType { + BUILD_PHASE_TYPE_NORMAL = 0, + BUILD_PHASE_TYPE_PROCESS, + BUILD_PHASE_TYPE_PHYSICS_PROCESS, + }; + +public: + bool get_is_build_threaded() const; + void set_is_build_threaded(bool value); + + ActiveBuildPhaseType get_active_build_phase_type() const; + void set_active_build_phase_type(const ActiveBuildPhaseType value); + + bool get_build_phase_done() const; + void set_build_phase_done(bool value); + + int get_lod_size() const; + void set_lod_size(int lod_size); + + int get_current_build_phase(); + void set_current_build_phase(int value); + + int get_max_build_phase(); + void set_max_build_phase(int value); + + bool get_create_collider() const; + void set_create_collider(bool value); + + bool get_bake_lights() const; + void set_bake_lights(bool value); + + RID get_mesh_rid(); + RID get_mesh_instance_rid(); + RID get_shape_rid(); + RID get_body_rid(); + + RID get_prop_mesh_rid(); + RID get_prop_mesh_instance_rid(); + RID get_prop_shape_rid(); + RID get_prop_body_rid(); + + RID get_liquid_mesh_rid(); + RID get_liquid_mesh_instance_rid(); + + RID get_clutter_mesh_rid(); + RID get_clutter_mesh_instance_rid(); + + //Data Management functions + void generate_ao(); + + //Meshing + void build_deferred(); + void build_prioritized(); + static void _build_step_threaded(void *_userdata); + + void build_step(); + + void build_phase(); + void build_phase_process(); + void build_phase_physics_process(); + + bool has_next_phase(); + void next_phase(); + + void clear(); + + //Colliders + void create_colliders(); + void remove_colliders(); + + //Meshes + void allocate_main_mesh(); + void free_main_mesh(); + + void allocate_prop_mesh(); + void free_prop_mesh(); + + void allocate_prop_colliders(); + void free_prop_colliders(); + + void allocate_liquid_mesh(); + void free_liquid_mesh(); + + void allocate_clutter_mesh(); + void free_clutter_mesh(); + + //Debug + void create_debug_immediate_geometry(); + void free_debug_immediate_geometry(); + + void draw_cross_voxels(Vector3 pos); + void draw_cross_voxels_fill(Vector3 pos, float fill); + void draw_debug_voxels(int max, Color color = Color(1, 1, 1)); + void draw_debug_voxel_lights(); + + //free + void free_chunk(); + + VoxelChunkDefault(); + ~VoxelChunkDefault(); + +protected: + virtual void _setup_channels(); + virtual void _build_phase(int phase); + virtual void _build_phase_process(int phase); + virtual void _build_phase_physics_process(int phase); + + virtual void _add_light(int local_x, int local_y, int local_z, int size, Color color); + virtual void _clear_baked_lights(); + virtual void _create_meshers(); + virtual void _build(bool immediate); + + void wait_and_finish_thread(); + + void _notification(int p_what); + + static void _bind_methods(); + + bool _is_build_threaded; + bool _abort_build; + + int _current_build_phase; + int _max_build_phases; + bool _enabled; + + int _lod_size; + + //voxel mesh + RID _mesh_rid; + RID _mesh_instance_rid; + + RID _shape_rid; + RID _body_rid; + + RID _prop_mesh_rid; + RID _prop_mesh_instance_rid; + + RID _prop_shape_rid; + RID _prop_body_rid; + + //liquids + RID _liquid_mesh_rid; + RID _liquid_mesh_instance_rid; + + //clutter + RID _clutter_mesh_rid; + RID _clutter_mesh_instance_rid; + + //debug + ImmediateGeometry *_debug_drawer; + + bool _build_mesh; + bool _create_collider; + + bool _bake_lights; + + bool _build_prioritized; + Mutex *_build_phase_done_mutex; + bool _build_phase_done; + Thread *_build_thread; + bool _build_step_in_progress; + + Array temp_array; + PoolVector temp_arr_collider; + + ActiveBuildPhaseType _active_build_phase_type; +}; + +VARIANT_ENUM_CAST(VoxelChunkDefault::DefaultChannels); +VARIANT_ENUM_CAST(VoxelChunkDefault::ActiveBuildPhaseType); + +#endif diff --git a/world/voxel_structure.cpp b/world/voxel_structure.cpp index b298dac..91f8c75 100644 --- a/world/voxel_structure.cpp +++ b/world/voxel_structure.cpp @@ -121,7 +121,7 @@ void VoxelStructure::clear() { } VoxelStructure::VoxelStructure() { - _channel_count = VoxelChunk::MAX_DEFAULT_CHANNELS; + _channel_count = 0; _world_position_x = 0; _world_position_y = 0; diff --git a/world/voxel_world.cpp b/world/voxel_world.cpp index 44c032f..9567f58 100644 --- a/world/voxel_world.cpp +++ b/world/voxel_world.cpp @@ -307,7 +307,11 @@ VoxelChunk *VoxelWorld::_create_chunk(int x, int y, int z, Node *p_chunk) { chunk->set_owner(get_tree()->get_edited_scene_root()); chunk->set_voxel_world(this); - chunk->set_is_build_threaded(_use_threads); + + //TODO this will need to be changed + if (chunk->has_method("set_is_build_threaded")) + chunk->call("set_is_build_threaded", _use_threads); + chunk->set_position(x, y, z); chunk->set_library(_library); chunk->set_voxel_scale(_voxel_scale); @@ -334,7 +338,7 @@ void VoxelWorld::generate_chunk(VoxelChunk *p_chunk) { call("_generate_chunk", p_chunk); - p_chunk->build_deferred(); + p_chunk->build(); } bool VoxelWorld::can_chunk_do_build_step() {