浏览代码

Merge pull request #1446 from Matter-and-Form/feature/gltf2-primitives

glTF2 primitives fixes
Kim Kulling 8 年之前
父节点
当前提交
adec1b2175
共有 6 个文件被更改,包括 59 次插入27 次删除
  1. 1 1
      code/glTF2Asset.h
  2. 5 1
      code/glTF2Asset.inl
  3. 2 2
      code/glTF2AssetWriter.inl
  4. 37 8
      code/glTF2Exporter.cpp
  5. 1 0
      code/glTF2Exporter.h
  6. 13 15
      code/glTF2Importer.cpp

+ 1 - 1
code/glTF2Asset.h

@@ -781,7 +781,7 @@ namespace glTF2
     struct Node : public Object
     {
         std::vector< Ref<Node> > children;
-        Ref<Mesh> mesh;
+        std::vector< Ref<Mesh> > meshes;
 
         Nullable<mat4> matrix;
         Nullable<vec3> translation;

+ 5 - 1
code/glTF2Asset.inl

@@ -934,9 +934,13 @@ inline void Node::Read(Value& obj, Asset& r)
     }
 
     if (Value* mesh = FindUInt(obj, "mesh")) {
+        unsigned numMeshes = 1;
+
+        this->meshes.reserve(numMeshes);
+
         Ref<Mesh> meshRef = r.meshes.Retrieve((*mesh).GetUint());
 
-        if (meshRef) this->mesh = meshRef;
+        if (meshRef) this->meshes.push_back(meshRef);
     }
 
     if (Value* camera = FindUInt(obj, "camera")) {

+ 2 - 2
code/glTF2AssetWriter.inl

@@ -417,8 +417,8 @@ namespace glTF2 {
 
         AddRefsVector(obj, "children", n.children, w.mAl);
 
-        if (n.mesh) {
-            obj.AddMember("mesh", n.mesh->index, w.mAl);
+        if (!n.meshes.empty()) {
+            obj.AddMember("mesh", n.meshes[0]->index, w.mAl);
         }
 
         AddRefsVector(obj, "skeletons", n.skeletons, w.mAl);

+ 37 - 8
code/glTF2Exporter.cpp

@@ -110,6 +110,7 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai
     }
 
     ExportMeshes();
+    MergeMeshes();
 
     ExportScene();
 
@@ -476,10 +477,11 @@ void glTF2Exporter::ExportMaterials()
  */
 bool FindMeshNode(Ref<Node>& nodeIn, Ref<Node>& meshNode, std::string meshID)
 {
-
-    if (nodeIn->mesh && meshID.compare(nodeIn->mesh->id) == 0) {
-        meshNode = nodeIn;
-        return true;
+    for (unsigned int i = 0; i < nodeIn->meshes.size(); ++i) {
+        if (meshID.compare(nodeIn->meshes[i]->id) == 0) {
+            meshNode = nodeIn;
+            return true;
+        }
     }
 
     for (unsigned int i = 0; i < nodeIn->children.size(); ++i) {
@@ -742,6 +744,33 @@ void glTF2Exporter::ExportMeshes()
     }
 }
 
+//merges a node's multiple meshes (with one primitive each) into one mesh with multiple primitives
+void glTF2Exporter::MergeMeshes()
+{
+    for (unsigned int n = 0; n < mAsset->nodes.Size(); ++n) {
+        Ref<Node> node = mAsset->nodes.Get(n);
+
+        unsigned int nMeshes = node->meshes.size();
+
+        //skip if it's 1 or less meshes per node
+        if (nMeshes > 1) {
+            Ref<Mesh> firstMesh = node->meshes.at(0);
+
+            //loop backwards to allow easy removal of a mesh from a node once it's merged
+            for (unsigned int m = nMeshes - 1; m >= 1; --m) {
+                Ref<Mesh> mesh = node->meshes.at(m);
+
+                firstMesh->primitives.insert(firstMesh->primitives.end(), mesh->primitives.begin(), mesh->primitives.end());
+
+                node->meshes.erase(node->meshes.begin() + m);
+            }
+
+            //since we were looping backwards, reverse the order of merged primitives to their original order
+            std::reverse(firstMesh->primitives.begin() + 1, firstMesh->primitives.end());
+        }
+    }
+}
+
 /*
  * Export the root node of the node hierarchy.
  * Calls ExportNode for all children.
@@ -755,8 +784,8 @@ unsigned int glTF2Exporter::ExportNodeHierarchy(const aiNode* n)
         CopyValue(n->mTransformation, node->matrix.value);
     }
 
-    if (n->mNumMeshes > 0) {
-        node->mesh = mAsset->meshes.Get(n->mMeshes[0]);
+    for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
+        node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i]));
     }
 
     for (unsigned int i = 0; i < n->mNumChildren; ++i) {
@@ -784,8 +813,8 @@ unsigned int glTF2Exporter::ExportNode(const aiNode* n, Ref<Node>& parent)
         CopyValue(n->mTransformation, node->matrix.value);
     }
 
-    if (n->mNumMeshes > 0) {
-        node->mesh = mAsset->meshes.Get(n->mMeshes[0]);
+    for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
+        node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i]));
     }
 
     for (unsigned int i = 0; i < n->mNumChildren; ++i) {

+ 1 - 0
code/glTF2Exporter.h

@@ -120,6 +120,7 @@ namespace Assimp
         void ExportMetadata();
         void ExportMaterials();
         void ExportMeshes();
+        void MergeMeshes();
         unsigned int ExportNodeHierarchy(const aiNode* n);
         unsigned int ExportNode(const aiNode* node, glTF2::Ref<glTF2::Node>& parent);
         void ExportScene();

+ 13 - 15
code/glTF2Importer.cpp

@@ -517,24 +517,22 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
         }
     }
 
-    if (node.mesh) {
-
-        int idx = node.mesh.GetIndex();
+    if (!node.meshes.empty()) {
+        int count = 0;
+        for (size_t i = 0; i < node.meshes.size(); ++i) {
+            int idx = node.meshes[i].GetIndex();
+            count += meshOffsets[idx + 1] - meshOffsets[idx];
+        }
+        ainode->mNumMeshes = count;
 
-        ai_assert(idx >= 0 && idx < meshOffsets.size());
+        ainode->mMeshes = new unsigned int[count];
 
-        unsigned int offBegin = meshOffsets[idx];
-        unsigned int offEnd = meshOffsets[idx + 1];
         int k = 0;
-        
-        ai_assert(offEnd >= offBegin);
-
-        ainode->mNumMeshes = offEnd - offBegin;
-        ainode->mMeshes = new unsigned int[ainode->mNumMeshes];
-
-        for (unsigned int j = offBegin; j < offEnd; ++j, ++k) {
-            ai_assert(k < ainode->mNumMeshes);
-            ainode->mMeshes[k] = j;
+        for (size_t i = 0; i < node.meshes.size(); ++i) {
+            int idx = node.meshes[i].GetIndex();
+            for (unsigned int j = meshOffsets[idx]; j < meshOffsets[idx + 1]; ++j, ++k) {
+                ainode->mMeshes[k] = j;
+            }
         }
     }