diff --git a/voxel.cpp b/voxel.cpp index 12fc891..b5d69b6 100644 --- a/voxel.cpp +++ b/voxel.cpp @@ -3,7 +3,7 @@ #include "voxel_mesh_builder.h" Voxel::Voxel() : Reference(), - _id(0), + _id(-1), _material_id(0), _is_transparent(false), _library(NULL), @@ -12,7 +12,11 @@ Voxel::Voxel() : Reference(), Ref Voxel::set_id(int id) { ERR_FAIL_COND_V(id < 0 || id >= 256, Ref(this)); + // Cannot modify ID after creation + ERR_FAIL_COND_V(_id != -1, Ref(this)); + _id = id; + return Ref(this); } @@ -173,6 +177,9 @@ void Voxel::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_transparent:Voxel", "color"), &Voxel::set_transparent, DEFVAL(true)); ObjectTypeDB::bind_method(_MD("is_transparent"), &Voxel::is_transparent); + ObjectTypeDB::bind_method(_MD("set_material_id", "id"), &Voxel::set_material_id); + ObjectTypeDB::bind_method(_MD("get_material_id"), &Voxel::get_material_id); + ObjectTypeDB::bind_method(_MD("set_cube_geometry:Voxel", "height"), &Voxel::set_cube_geometry, DEFVAL(1.f)); ObjectTypeDB::bind_method(_MD("set_cube_uv_all_sides:Voxel", "atlas_pos"), &Voxel::set_cube_uv_all_sides); ObjectTypeDB::bind_method(_MD("set_cube_uv_tbs_sides:Voxel", "top_atlas_pos", "side_atlas_pos", "bottom_atlas_pos"), &Voxel::set_cube_uv_tbs_sides); diff --git a/voxel_library.cpp b/voxel_library.cpp index 801ca28..19960dd 100644 --- a/voxel_library.cpp +++ b/voxel_library.cpp @@ -1,7 +1,7 @@ #include "voxel_library.h" VoxelLibrary::VoxelLibrary() : Reference(), _atlas_size(1) { - + create_voxel(0, "air")->set_transparent(true); } VoxelLibrary::~VoxelLibrary() { diff --git a/voxel_mesh_builder.cpp b/voxel_mesh_builder.cpp index 6de1760..aa32464 100644 --- a/voxel_mesh_builder.cpp +++ b/voxel_mesh_builder.cpp @@ -149,6 +149,22 @@ void VoxelMeshBuilder::set_occlusion_enabled(bool enable) { inline Color Color_greyscale(float c) { return Color(c, c, c); } +inline bool is_face_visible(const VoxelLibrary & lib, const Voxel & vt, int other_voxel_id) { + if (other_voxel_id == 0) // air + return true; + if (lib.has_voxel(other_voxel_id)) { + const Voxel & other_vt = lib.get_voxel_const(other_voxel_id); + return other_vt.is_transparent() && vt.get_id() != other_voxel_id; + } + return true; +} + +inline bool is_transparent(const VoxelLibrary & lib, int voxel_id) { + if (lib.has_voxel(voxel_id)) + return lib.get_voxel_const(voxel_id).is_transparent(); + return true; +} + Ref VoxelMeshBuilder::build(Ref buffer_ref) { ERR_FAIL_COND_V(buffer_ref.is_null(), Ref()); ERR_FAIL_COND_V(_library.is_null(), Ref()); @@ -194,7 +210,7 @@ Ref VoxelMeshBuilder::build(Ref buffer_ref) { int neighbor_voxel_id = buffer.get_voxel_local(nx, ny, nz, 0); // TODO Better face visibility test - if (neighbor_voxel_id == 0) { + if (is_face_visible(library, voxel, neighbor_voxel_id)) { // The face is visible @@ -210,7 +226,7 @@ Ref VoxelMeshBuilder::build(Ref buffer_ref) { unsigned ex = x + edge_normal.x; unsigned ey = y + edge_normal.y; unsigned ez = z + edge_normal.z; - if (buffer.get_voxel_local(ex, ey, ez) != 0) { + if (!is_transparent(library, buffer.get_voxel_local(ex, ey, ez))) { shaded_corner[g_edge_corners[edge][0]] += 1; shaded_corner[g_edge_corners[edge][1]] += 1; } @@ -225,7 +241,7 @@ Ref VoxelMeshBuilder::build(Ref buffer_ref) { unsigned int cx = x + corner_normal.x; unsigned int cy = y + corner_normal.y; unsigned int cz = z + corner_normal.z; - if (buffer.get_voxel_local(cx, cy, cz) != 0) { + if (!is_transparent(library, buffer.get_voxel_local(cx, cy, cz))) { shaded_corner[corner] += 1; } } diff --git a/voxel_mesh_builder.h b/voxel_mesh_builder.h index 2fd4c93..0838c21 100644 --- a/voxel_mesh_builder.h +++ b/voxel_mesh_builder.h @@ -36,6 +36,7 @@ public: Ref build(Ref buffer_ref); protected: + static void _bind_methods(); };