diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index a98fe5ab2..c9390d8d4 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -971,6 +971,8 @@ namespace glTF2 Ref Create(const std::string& id) { return Create(id.c_str()); } + unsigned int Remove(const char* id); + inline unsigned int Size() const { return unsigned(mObjs.size()); } diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 8b50fa1d3..c7d0cdc54 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -193,6 +193,50 @@ inline void LazyDict::DetachFromDocument() mDict = 0; } +template +unsigned int LazyDict::Remove(const char* id) +{ + id = T::TranslateId(mAsset, id); + + typename IdDict::iterator it = mObjsById.find(id); + + if (it == mObjsById.end()) { + throw DeadlyExportError("GLTF: Object with id \"" + std::string(id) + "\" is not found"); + } + + const int index = it->second; + + mAsset.mUsedIds[id] = false; + mObjsById.erase(id); + mObjsByOIndex.erase(index); + mObjs.erase(mObjs.begin() + index); + + //update index of object in mObjs; + for (size_t i = index; i < mObjs.size(); ++i) { + T *obj = mObjs[i]; + + obj->index = i; + } + + for (IdDict::iterator it = mObjsById.begin(); it != mObjsById.end(); ++it) { + if (it->second <= index) { + continue; + } + + mObjsById[it->first] = it->second - 1; + } + + for (Dict::iterator it = mObjsByOIndex.begin(); it != mObjsByOIndex.end(); ++it) { + if (it->second <= index) { + continue; + } + + mObjsByOIndex[it->first] = it->second - 1; + } + + return index; +} + template Ref LazyDict::Retrieve(unsigned int i) { diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index d8cff897c..e71d949be 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -800,9 +800,33 @@ void glTF2Exporter::MergeMeshes() for (unsigned int m = nMeshes - 1; m >= 1; --m) { Ref mesh = node->meshes.at(m); - firstMesh->primitives.insert(firstMesh->primitives.end(), mesh->primitives.begin(), mesh->primitives.end()); + //append this mesh's primitives to the first mesh's primitives + firstMesh->primitives.insert( + firstMesh->primitives.end(), + mesh->primitives.begin(), + mesh->primitives.end() + ); - node->meshes.erase(node->meshes.begin() + m); + //remove the mesh from the list of meshes + unsigned int removedIndex = mAsset->meshes.Remove(mesh->id.c_str()); + + //find the presence of the removed mesh in other nodes + for (unsigned int nn = 0; nn < mAsset->nodes.Size(); ++nn) { + Ref node = mAsset->nodes.Get(nn); + + for (unsigned int mm = 0; mm < node->meshes.size(); ++mm) { + Ref& meshRef = node->meshes.at(mm); + unsigned int meshIndex = meshRef.GetIndex(); + + if (meshIndex == removedIndex) { + node->meshes.erase(node->meshes.begin() + mm); + } else if (meshIndex > removedIndex) { + Ref newMeshRef = mAsset->meshes.Get(meshIndex - 1); + + meshRef = newMeshRef; + } + } + } } //since we were looping backwards, reverse the order of merged primitives to their original order