summaryrefslogtreecommitdiff
path: root/editor/import/resource_importer_scene.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/import/resource_importer_scene.cpp')
-rw-r--r--editor/import/resource_importer_scene.cpp111
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();
}
}