瀏覽代碼

Add support for tangents in glTF2.0 import

Closes #1562
awefers 7 年之前
父節點
當前提交
0031165789
共有 3 個文件被更改,包括 30 次插入3 次删除
  1. 1 1
      code/glTF2Asset.h
  2. 4 1
      code/glTF2Asset.inl
  3. 25 1
      code/glTF2Importer.cpp

+ 1 - 1
code/glTF2Asset.h

@@ -775,7 +775,7 @@ namespace glTF2
             PrimitiveMode mode;
 
             struct Attributes {
-                AccessorList position, normal, texcoord, color, joint, jointmatrix, weight;
+                AccessorList position, normal, tangent, texcoord, color, joint, jointmatrix, weight;
             } attributes;
 
             Ref<Accessor> indices;

+ 4 - 1
code/glTF2Asset.inl

@@ -867,6 +867,9 @@ namespace {
         else if ((pos = Compare(attr, "NORMAL"))) {
             v = &(p.attributes.normal);
         }
+        else if ((pos = Compare(attr, "TANGENT"))) {
+            v = &(p.attributes.tangent);
+        }
         else if ((pos = Compare(attr, "TEXCOORD"))) {
             v = &(p.attributes.texcoord);
         }
@@ -906,7 +909,7 @@ inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root)
                 for (Value::MemberIterator it = attrs->MemberBegin(); it != attrs->MemberEnd(); ++it) {
                     if (!it->value.IsUint()) continue;
                     const char* attr = it->name.GetString();
-                    // Valid attribute semantics include POSITION, NORMAL, TEXCOORD, COLOR, JOINT, JOINTMATRIX,
+                    // Valid attribute semantics include POSITION, NORMAL, TANGENT, TEXCOORD, COLOR, JOINT, JOINTMATRIX,
                     // and WEIGHT.Attribute semantics can be of the form[semantic]_[set_index], e.g., TEXCOORD_0, TEXCOORD_1, etc.
 
                     int undPos = 0;

+ 25 - 1
code/glTF2Importer.cpp

@@ -362,7 +362,31 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
                 attr.position[0]->ExtractData(aim->mVertices);
             }
 
-            if (attr.normal.size() > 0 && attr.normal[0]) attr.normal[0]->ExtractData(aim->mNormals);
+            if (attr.normal.size() > 0 && attr.normal[0]) {
+                attr.normal[0]->ExtractData(aim->mNormals);
+
+                // only extract tangents if normals are present
+                if (attr.tangent.size() > 0 && attr.tangent[0]) {
+                    // generate bitangents from normals and tangents according to spec
+                    struct Tangent
+                    {
+                        aiVector3D xyz;
+                        ai_real w;
+                    } *tangents = nullptr;
+
+                    attr.tangent[0]->ExtractData(tangents);
+
+                    aim->mTangents = new aiVector3D[aim->mNumVertices];
+                    aim->mBitangents = new aiVector3D[aim->mNumVertices];
+
+                    for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
+                        aim->mTangents[i] = tangents[i].xyz;
+                        aim->mBitangents[i] = (aim->mNormals[i] ^ tangents[i].xyz) * tangents[i].w;
+                    }
+
+                    delete tangents;
+                }
+            }
 
             for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
                 attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);