Facet extraction works with transparent sides

This commit is contained in:
Marc Gilleron 2016-05-05 02:12:23 +02:00
parent c452d73a3a
commit ad124f418a
4 changed files with 29 additions and 5 deletions

View File

@ -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> Voxel::set_id(int id) {
ERR_FAIL_COND_V(id < 0 || id >= 256, Ref<Voxel>(this));
// Cannot modify ID after creation
ERR_FAIL_COND_V(_id != -1, Ref<Voxel>(this));
_id = id;
return Ref<Voxel>(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);

View File

@ -1,7 +1,7 @@
#include "voxel_library.h"
VoxelLibrary::VoxelLibrary() : Reference(), _atlas_size(1) {
create_voxel(0, "air")->set_transparent(true);
}
VoxelLibrary::~VoxelLibrary() {

View File

@ -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<Mesh> VoxelMeshBuilder::build(Ref<VoxelBuffer> buffer_ref) {
ERR_FAIL_COND_V(buffer_ref.is_null(), Ref<Mesh>());
ERR_FAIL_COND_V(_library.is_null(), Ref<Mesh>());
@ -194,7 +210,7 @@ Ref<Mesh> VoxelMeshBuilder::build(Ref<VoxelBuffer> 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<Mesh> VoxelMeshBuilder::build(Ref<VoxelBuffer> 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<Mesh> VoxelMeshBuilder::build(Ref<VoxelBuffer> 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;
}
}

View File

@ -36,6 +36,7 @@ public:
Ref<Mesh> build(Ref<VoxelBuffer> buffer_ref);
protected:
static void _bind_methods();
};