Ported the lod implementation from Broken Seals.

This commit is contained in:
Relintai 2020-03-30 19:46:39 +02:00
parent 393ee1fb1b
commit f26fe74fc4
2 changed files with 143 additions and 12 deletions

View File

@ -101,6 +101,48 @@ void VoxelChunkDefault::set_bake_lights(bool value) {
_bake_lights = value; _bake_lights = value;
} }
bool VoxelChunkDefault::get_generate_lod() const {
return _generate_lod;
}
void VoxelChunkDefault::set_generate_lod(const bool value) {
_generate_lod = value;
}
int VoxelChunkDefault::get_lod_num() const {
return _lod_num;
}
void VoxelChunkDefault::set_lod_num(const int value) {
_lod_num = value;
}
int VoxelChunkDefault::get_current_lod_level() const {
return _current_lod_level;
}
void VoxelChunkDefault::set_current_lod_level(const int value) {
_current_lod_level = value;
if (!_generate_lod)
return;
if (_current_lod_level < 0)
_current_lod_level = 0;
if (_current_lod_level > _lod_num)
_current_lod_level = _lod_num;
for (int i = 0; i < _lod_num + 1; ++i) {
bool vis = false;
if (i == _current_lod_level)
vis = true;
RID rid = get_mesh_rid_index(MESH_INDEX_TERRARIN, MESH_TYPE_INDEX_MESH_INSTANCE, i);
if (rid != RID())
VisualServer::get_singleton()->instance_set_visible(rid, vis);
}
}
//Data Management functions //Data Management functions
void VoxelChunkDefault::generate_ao() { void VoxelChunkDefault::generate_ao() {
ERR_FAIL_COND(_data_size_x == 0 || _data_size_y == 0 || _data_size_z == 0); ERR_FAIL_COND(_data_size_x == 0 || _data_size_y == 0 || _data_size_z == 0);
@ -488,6 +530,9 @@ void VoxelChunkDefault::create_meshes(const int mesh_index, const int mesh_count
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))); 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)));
if (i != 0)
VS::get_singleton()->instance_set_visible(mesh_instance_rid, false);
am.push_back(mesh_rid); am.push_back(mesh_rid);
ami.push_back(mesh_instance_rid); ami.push_back(mesh_instance_rid);
} }
@ -743,19 +788,17 @@ void VoxelChunkDefault::visibility_changed(bool visible) {
} }
void VoxelChunkDefault::_visibility_changed(bool visible) { void VoxelChunkDefault::_visibility_changed(bool visible) {
/* needs LOD support if (visible) {
if (_mesh_instance_rid != RID()) set_current_lod_level(_current_lod_level);
VS::get_singleton()->instance_set_visible(_mesh_instance_rid, visible); return;
}
if (_prop_mesh_instance_rid != RID()) for (int i = 0; i < _lod_num + 1; ++i) {
VS::get_singleton()->instance_set_visible(_prop_mesh_instance_rid, visible); RID rid = get_mesh_rid_index(MESH_INDEX_TERRARIN, MESH_TYPE_INDEX_MESH_INSTANCE, i);
if (_liquid_mesh_instance_rid != RID()) if (rid != RID())
VS::get_singleton()->instance_set_visible(_liquid_mesh_instance_rid, visible); VisualServer::get_singleton()->instance_set_visible(rid, false);
}
if (_clutter_mesh_instance_rid != RID())
VS::get_singleton()->instance_set_visible(_clutter_mesh_instance_rid, visible);
*/
} }
void VoxelChunkDefault::free_chunk() { void VoxelChunkDefault::free_chunk() {
@ -804,6 +847,10 @@ VoxelChunkDefault::VoxelChunkDefault() {
_build_step_in_progress = false; _build_step_in_progress = false;
_active_build_phase_type = BUILD_PHASE_TYPE_NORMAL; _active_build_phase_type = BUILD_PHASE_TYPE_NORMAL;
_generate_lod = true;
_lod_num = 3;
_current_lod_level = 0;
} }
VoxelChunkDefault::~VoxelChunkDefault() { VoxelChunkDefault::~VoxelChunkDefault() {
@ -940,7 +987,7 @@ void VoxelChunkDefault::_build_phase(int phase) {
Array temp_mesh_arr = mesher->build_mesh(); Array temp_mesh_arr = mesher->build_mesh();
if (mesh_rid == RID()) { if (mesh_rid == RID()) {
create_meshes(MESH_INDEX_TERRARIN, 4); //TODO LOD create_meshes(MESH_INDEX_TERRARIN, _lod_num + 1);
mesh_rid = get_mesh_rid_index(MESH_INDEX_TERRARIN, MESH_TYPE_INDEX_MESH, 0); mesh_rid = get_mesh_rid_index(MESH_INDEX_TERRARIN, MESH_TYPE_INDEX_MESH, 0);
} }
@ -949,6 +996,63 @@ void VoxelChunkDefault::_build_phase(int phase) {
if (_library->get_material(0).is_valid()) if (_library->get_material(0).is_valid())
VS::get_singleton()->mesh_surface_set_material(mesh_rid, 0, _library->get_material(0)->get_rid()); VS::get_singleton()->mesh_surface_set_material(mesh_rid, 0, _library->get_material(0)->get_rid());
if (_generate_lod) {
if (_lod_num >= 1) {
//for lod 1 just remove uv2
temp_mesh_arr[VisualServer::ARRAY_TEX_UV2] = Variant();
VisualServer::get_singleton()->mesh_add_surface_from_arrays(get_mesh_rid_index(MESH_INDEX_TERRARIN, MESH_TYPE_INDEX_MESH, 1), VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr);
if (get_library()->get_material(1).is_valid())
VisualServer::get_singleton()->mesh_surface_set_material(get_mesh_rid_index(MESH_INDEX_TERRARIN, MESH_TYPE_INDEX_MESH, 1), 0, get_library()->get_material(1)->get_rid());
}
if (_lod_num >= 2) {
Array temp_mesh_arr2 = merge_mesh_array(temp_mesh_arr);
VisualServer::get_singleton()->mesh_add_surface_from_arrays(get_mesh_rid_index(MESH_INDEX_TERRARIN, MESH_TYPE_INDEX_MESH, 2), VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr2);
if (get_library()->get_material(2).is_valid())
VisualServer::get_singleton()->mesh_surface_set_material(get_mesh_rid_index(MESH_INDEX_TERRARIN, MESH_TYPE_INDEX_MESH, 2), 0, get_library()->get_material(2)->get_rid());
}
if (_lod_num >= 3) {
Ref<ShaderMaterial> mat = get_library()->get_material(0);
Ref<Texture> tex = mat->get_shader_param("texture_albedo");
temp_mesh_arr = bake_mesh_array_uv(temp_mesh_arr, tex);
temp_mesh_arr[VisualServer::ARRAY_TEX_UV] = Variant();
VisualServer::get_singleton()->mesh_add_surface_from_arrays(get_mesh_rid_index(MESH_INDEX_TERRARIN, MESH_TYPE_INDEX_MESH, 3), VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr);
if (get_library()->get_material(3).is_valid())
VisualServer::get_singleton()->mesh_surface_set_material(get_mesh_rid_index(MESH_INDEX_TERRARIN, MESH_TYPE_INDEX_MESH, 3), 0, get_library()->get_material(3)->get_rid());
}
/*
if (_lod_num > 4) {
Ref<FastQuadraticMeshSimplifier> fqms;
fqms.instance();
fqms->initialize(temp_mesh_arr);
Array arr_merged_simplified;
for (int i = 4; i < _lod_num; ++i) {
fqms->simplify_mesh(arr_merged_simplified[0].size() * 0.8, 7);
arr_merged_simplified = fqms->get_arrays();
if (arr_merged_simplified[0].size() == 0)
break;
VisualServer::get_singleton()->mesh_add_surface_from_arrays(get_mesh_rid_index(MESH_INDEX_TERRARIN, MESH_TYPE_INDEX_MESH, i), VisualServer::PRIMITIVE_TRIANGLES, arr_merged_simplified);
if (get_library()->get_material(i).is_valid())
VisualServer::get_singleton()->mesh_surface_set_material(get_mesh_rid_index(MESH_INDEX_TERRARIN, MESH_TYPE_INDEX_MESH, i), 0, get_library()->get_material(i)->get_rid());
}
}
*/
}
next_phase(); next_phase();
return; return;
@ -1302,6 +1406,18 @@ void VoxelChunkDefault::_bind_methods() {
ClassDB::bind_method(D_METHOD("meshing_set_bake_lights", "value"), &VoxelChunkDefault::set_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"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meshing_bake_lights"), "meshing_set_bake_lights", "meshing_get_bake_lights");
ClassDB::bind_method(D_METHOD("get_generate_lod"), &VoxelChunkDefault::get_generate_lod);
ClassDB::bind_method(D_METHOD("set_generate_lod"), &VoxelChunkDefault::set_generate_lod);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_lod"), "set_generate_lod", "get_generate_lod");
ClassDB::bind_method(D_METHOD("get_lod_num"), &VoxelChunkDefault::get_lod_num);
ClassDB::bind_method(D_METHOD("set_lod_num"), &VoxelChunkDefault::set_lod_num);
ADD_PROPERTY(PropertyInfo(Variant::INT, "lod_num"), "set_lod_num", "get_lod_num");
ClassDB::bind_method(D_METHOD("get_current_lod_level"), &VoxelChunkDefault::get_current_lod_level);
ClassDB::bind_method(D_METHOD("set_current_lod_level"), &VoxelChunkDefault::set_current_lod_level);
ADD_PROPERTY(PropertyInfo(Variant::INT, "current_lod_level"), "set_current_lod_level", "get_current_lod_level");
//Voxel Data //Voxel Data
//Data Management functions //Data Management functions

View File

@ -152,6 +152,16 @@ public:
bool get_bake_lights() const; bool get_bake_lights() const;
void set_bake_lights(bool value); void set_bake_lights(bool value);
//Lod
bool get_generate_lod() const;
void set_generate_lod(const bool value);
int get_lod_num() const;
void set_lod_num(const int value);
int get_current_lod_level() const;
void set_current_lod_level(const int value);
//Data Management functions //Data Management functions
void generate_ao(); void generate_ao();
@ -244,6 +254,11 @@ protected:
int _lod_size; int _lod_size;
//lod
bool _generate_lod;
int _lod_num;
int _current_lod_level;
//Meshes //Meshes
Dictionary _rids; Dictionary _rids;