diff options
-rw-r--r-- | src/mapblock.cpp | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/src/mapblock.cpp b/src/mapblock.cpp index 910e91316..f52a5ee3f 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -494,22 +494,44 @@ static void correctBlockNodeIds(const NameIdMapping *nimap, MapNode *nodes, // correct ids. std::unordered_set<content_t> unnamed_contents; std::unordered_set<std::string> unallocatable_contents; + + bool previous_was_found = false; + content_t previous_local_id = CONTENT_IGNORE; + content_t previous_global_id = CONTENT_IGNORE; + for (u32 i = 0; i < MapBlock::nodecount; i++) { content_t local_id = nodes[i].getContent(); + // If previous node local_id was found and same than before, don't lookup maps + // apply directly previous resolved id + // This permits to massively improve loading performance when nodes are similar + // example: default:air, default:stone are massively present + if (previous_was_found && local_id == previous_local_id) { + nodes[i].setContent(previous_global_id); + continue; + } + std::string name; if (!nimap->getName(local_id, name)) { unnamed_contents.insert(local_id); + previous_was_found = false; continue; } + content_t global_id; if (!nodedef->getId(name, global_id)) { global_id = gamedef->allocateUnknownNodeId(name); - if(global_id == CONTENT_IGNORE){ + if (global_id == CONTENT_IGNORE) { unallocatable_contents.insert(name); + previous_was_found = false; continue; } } nodes[i].setContent(global_id); + + // Save previous node local_id & global_id result + previous_local_id = local_id; + previous_global_id = global_id; + previous_was_found = true; } for (const content_t c: unnamed_contents) { |