Browse Source

Merge pull request #3063 from thomasbiang/gltf2_blendshape_export

Blendshape Support in Assimp Gltf2/Glb2 Exporter (positions, normals)
Kim Kulling 5 years ago
parent
commit
3e78e8b5d3
2 changed files with 59 additions and 0 deletions
  1. 18 0
      code/glTF2/glTF2AssetWriter.inl
  2. 41 0
      code/glTF2/glTF2Exporter.cpp

+ 18 - 0
code/glTF2/glTF2AssetWriter.inl

@@ -446,6 +446,24 @@ namespace glTF2 {
                     WriteAttrs(w, attrs, p.attributes.weight, "WEIGHTS", true);
                 }
                 prim.AddMember("attributes", attrs, w.mAl);
+
+                // targets for blendshapes
+                if (p.targets.size() > 0) {
+                    Value tjs;
+                    tjs.SetArray();
+                    tjs.Reserve(unsigned(p.targets.size()), w.mAl);
+                    for (unsigned int t = 0; t < p.targets.size(); ++t) {
+                        Value tj;
+                        tj.SetObject();
+                        {
+                            WriteAttrs(w, tj, p.targets[t].position, "POSITION");
+                            WriteAttrs(w, tj, p.targets[t].normal, "NORMAL");
+                            WriteAttrs(w, tj, p.targets[t].tangent, "TANGENT");
+                        }
+                        tjs.PushBack(tj, w.mAl);
+                    }
+                    prim.AddMember("targets", tjs, w.mAl);
+                }
             }
             primitives.PushBack(prim, w.mAl);
         }

+ 41 - 0
code/glTF2/glTF2Exporter.cpp

@@ -814,6 +814,47 @@ void glTF2Exporter::ExportMeshes()
         if(aim->HasBones()) {
             ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData);
         }
+
+        /*************** Targets for blendshapes ****************/
+        if (aim->mNumAnimMeshes > 0) {
+            p.targets.resize(aim->mNumAnimMeshes);
+            for (unsigned int am = 0; am < aim->mNumAnimMeshes; ++am) {
+                aiAnimMesh *pAnimMesh = aim->mAnimMeshes[am];
+
+                // position
+                if (pAnimMesh->HasPositions()) {
+                    // NOTE: in gltf it is the diff stored
+                    aiVector3D *pPositionDiff = new aiVector3D[pAnimMesh->mNumVertices];
+                    for (unsigned int vt = 0; vt < pAnimMesh->mNumVertices; ++vt) {
+                        pPositionDiff[vt] = pAnimMesh->mVertices[vt] - aim->mVertices[vt];
+                    }
+                    Ref<Accessor> v = ExportData(*mAsset, meshId, b,
+                            pAnimMesh->mNumVertices, pPositionDiff,
+                            AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
+                    if (v) {
+                        p.targets[am].position.push_back(v);
+                    }
+                    delete[] pPositionDiff;
+                }
+
+                // normal
+                if (pAnimMesh->HasNormals()) {
+                    aiVector3D *pNormalDiff = new aiVector3D[pAnimMesh->mNumVertices];
+                    for (unsigned int vt = 0; vt < pAnimMesh->mNumVertices; ++vt) {
+                        pNormalDiff[vt] = pAnimMesh->mNormals[vt] - aim->mNormals[vt];
+                    }
+                    Ref<Accessor> v = ExportData(*mAsset, meshId, b,
+                            pAnimMesh->mNumVertices, pNormalDiff,
+                            AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
+                    if (v) {
+                        p.targets[am].normal.push_back(v);
+                    }
+                    delete[] pNormalDiff;
+                }
+
+                // tangent?
+            }
+        }
     }
 
     //----------------------------------------