diff options
Diffstat (limited to 'editor/import/resource_importer_scene.cpp')
-rw-r--r-- | editor/import/resource_importer_scene.cpp | 111 |
1 files changed, 96 insertions, 15 deletions
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index b5766a48a0..239fae2268 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -1429,29 +1429,110 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p Map<Ref<ArrayMesh>, Transform> meshes; _find_meshes(scene, meshes); - if (light_bake_mode == 2) { + String file_id = src_path.get_file(); + String cache_file_path = base_path.plus_file(file_id + ".unwrap_cache"); - float texel_size = p_options["meshes/lightmap_texel_size"]; - texel_size = MAX(0.001, texel_size); + Vector<unsigned char> cache_data; - EditorProgress progress2("gen_lightmaps", TTR("Generating Lightmaps"), meshes.size()); - int step = 0; - for (Map<Ref<ArrayMesh>, Transform>::Element *E = meshes.front(); E; E = E->next()) { + if (FileAccess::exists(cache_file_path)) { + Error err2; + FileAccess *file = FileAccess::open(cache_file_path, FileAccess::READ, &err2); - Ref<ArrayMesh> mesh = E->key(); - String name = mesh->get_name(); - if (name == "") { //should not happen but.. - name = "Mesh " + itos(step); + if (err2) { + if (file) + memdelete(file); + } else { + int cache_size = file->get_len(); + cache_data.resize(cache_size); + file->get_buffer(cache_data.ptrw(), cache_size); + } + } + + float texel_size = p_options["meshes/lightmap_texel_size"]; + texel_size = MAX(0.001, texel_size); + + Map<String, unsigned int> used_unwraps; + + EditorProgress progress2("gen_lightmaps", TTR("Generating Lightmaps"), meshes.size()); + int step = 0; + for (Map<Ref<ArrayMesh>, Transform>::Element *E = meshes.front(); E; E = E->next()) { + + Ref<ArrayMesh> mesh = E->key(); + String name = mesh->get_name(); + if (name == "") { //should not happen but.. + name = "Mesh " + itos(step); + } + + progress2.step(TTR("Generating for Mesh: ") + name + " (" + itos(step) + "/" + itos(meshes.size()) + ")", step); + + int *ret_cache_data = (int *)cache_data.ptrw(); + unsigned int ret_cache_size = cache_data.size(); + bool ret_used_cache = true; // Tell the unwrapper to use the cache + Error err2 = mesh->lightmap_unwrap_cached(ret_cache_data, ret_cache_size, ret_used_cache, E->get(), texel_size); + + if (err2 != OK) { + EditorNode::add_io_error("Mesh '" + name + "' failed lightmap generation. Please fix geometry."); + } else { + + String hash = String::md5((unsigned char *)ret_cache_data); + used_unwraps.insert(hash, ret_cache_size); + + if (!ret_used_cache) { + // Cache was not used, add the generated entry to the current cache + if (cache_data.empty()) { + cache_data.resize(4 + ret_cache_size); + int *data = (int *)cache_data.ptrw(); + data[0] = 1; + memcpy(&data[1], ret_cache_data, ret_cache_size); + } else { + int current_size = cache_data.size(); + cache_data.resize(cache_data.size() + ret_cache_size); + unsigned char *ptrw = cache_data.ptrw(); + memcpy(&ptrw[current_size], ret_cache_data, ret_cache_size); + int *data = (int *)ptrw; + data[0] += 1; + } } + } + step++; + } - progress2.step(TTR("Generating for Mesh: ") + name + " (" + itos(step) + "/" + itos(meshes.size()) + ")", step); + Error err2; + FileAccess *file = FileAccess::open(cache_file_path, FileAccess::WRITE, &err2); - Error err2 = mesh->lightmap_unwrap(E->get(), texel_size); - if (err2 != OK) { - EditorNode::add_io_error("Mesh '" + name + "' failed lightmap generation. Please fix geometry."); + if (err2) { + if (file) + memdelete(file); + } else { + + // Store number of entries + file->store_32(used_unwraps.size()); + + // Store cache entries + const int *cache = (int *)cache_data.ptr(); + unsigned int r_idx = 1; + for (int i = 0; i < cache[0]; ++i) { + unsigned char *entry_start = (unsigned char *)&cache[r_idx]; + String entry_hash = String::md5(entry_start); + if (used_unwraps.has(entry_hash)) { + unsigned int entry_size = used_unwraps[entry_hash]; + file->store_buffer(entry_start, entry_size); } - step++; + + r_idx += 4; // hash + r_idx += 2; // size hint + + int vertex_count = cache[r_idx]; + r_idx += 1; // vertex count + r_idx += vertex_count; // vertex + r_idx += vertex_count * 2; // uvs + + int index_count = cache[r_idx]; + r_idx += 1; // index count + r_idx += index_count; // indices } + + file->close(); } } |