fixed issues to get node animations working
authorAngelo Scandaliato <angelo@adtile.me>
Thu, 6 Oct 2016 09:34:11 +0000 (02:34 -0700)
committerAngelo Scandaliato <angelo@adtile.me>
Thu, 6 Oct 2016 09:34:11 +0000 (02:34 -0700)
code/glTFAsset.h
code/glTFAssetWriter.inl
code/glTFExporter.cpp

index b7ea8fb..4b5fb67 100644 (file)
@@ -950,9 +950,13 @@ namespace glTF
             Ref<Accessor> translation;    //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
         };
 
-        AnimChannel Channels[3];            //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
-        AnimParameters Parameters;          //!< The samplers that interpolate between the key-frames.
-        AnimSampler Samplers[3];            //!< The parameterized inputs representing the key-frame data.
+        // AnimChannel Channels[3];            //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
+        // AnimParameters Parameters;          //!< The samplers that interpolate between the key-frames.
+        // AnimSampler Samplers[3];            //!< The parameterized inputs representing the key-frame data.
+
+        std::vector<AnimChannel> Channels;            //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
+        AnimParameters Parameters;                    //!< The samplers that interpolate between the key-frames.
+        std::vector<AnimSampler> Samplers;         //!< The parameterized inputs representing the key-frame data.
 
         Animation() {}
         void Read(Value& obj, Asset& r);
index a5603a3..3589cee 100644 (file)
@@ -105,9 +105,9 @@ namespace glTF {
         /****************** Channels *******************/
         Value channels;
         channels.SetArray();
-        channels.Reserve(3/*unsigned(a.Channels.size())*/, w.mAl);
+        channels.Reserve(unsigned(a.Channels.size()), w.mAl);
 
-        for (size_t i = 0; i < 3/*a.Channels.size()*/; ++i) {
+        for (size_t i = 0; i < unsigned(a.Channels.size()); ++i) {
             Animation::AnimChannel& c = a.Channels[i];
             Value valChannel;
             valChannel.SetObject();
@@ -124,24 +124,32 @@ namespace glTF {
             }
             channels.PushBack(valChannel, w.mAl);
         }
-        obj.AddMember("Channels", channels, w.mAl);
+        obj.AddMember("channels", channels, w.mAl);
 
         /****************** Parameters *******************/
         Value valParameters;
         valParameters.SetObject();
         {
-            valParameters.AddMember("TIME", StringRef(a.Parameters.TIME->id), w.mAl);
-            valParameters.AddMember("rotation", StringRef(a.Parameters.rotation->id), w.mAl);
-            valParameters.AddMember("scale", StringRef(a.Parameters.scale->id), w.mAl);
-            valParameters.AddMember("translation", StringRef(a.Parameters.translation->id), w.mAl);
+            if (a.Parameters.TIME) {
+                valParameters.AddMember("TIME", StringRef(a.Parameters.TIME->id), w.mAl);
+            }
+            if (a.Parameters.rotation) {
+                valParameters.AddMember("rotation", StringRef(a.Parameters.rotation->id), w.mAl);
+            }
+            if (a.Parameters.scale) {
+                valParameters.AddMember("scale", StringRef(a.Parameters.scale->id), w.mAl);
+            }
+            if (a.Parameters.translation) {
+                valParameters.AddMember("translation", StringRef(a.Parameters.translation->id), w.mAl);
+            }
         }
-        obj.AddMember("Parameters", valParameters, w.mAl);
+        obj.AddMember("parameters", valParameters, w.mAl);
 
         /****************** Samplers *******************/
         Value valSamplers;
         valSamplers.SetObject();
 
-        for (size_t i = 0; i < 3/*a.Samplers.size()*/; ++i) {
+        for (size_t i = 0; i < unsigned(a.Samplers.size()); ++i) {
             Animation::AnimSampler& s = a.Samplers[i];
             Value valSampler;
             valSampler.SetObject();
@@ -152,7 +160,7 @@ namespace glTF {
             }
             valSamplers.AddMember(StringRef(s.id), valSampler, w.mAl);
         }
-        obj.AddMember("Samplers", valSamplers, w.mAl);
+        obj.AddMember("samplers", valSamplers, w.mAl);
     }
 
     inline void Write(Value& obj, Buffer& b, AssetWriter& w)
index 86592d2..7a0a9a8 100644 (file)
@@ -146,7 +146,7 @@ glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiSc
 
     ExportAnimations();
 
-    ExportSkins();
+    // ExportSkins();
 
     glTF::AssetWriter writer(*mAsset);
 
@@ -586,7 +586,9 @@ void glTFExporter::ExportMeshes()
 
 unsigned int glTFExporter::ExportNode(const aiNode* n)
 {
+    std::cout<< "n->mName.C_Str() " << n->mName.C_Str() << "\n";
     Ref<Node> node = mAsset->nodes.Create(mAsset->FindUniqueID(n->mName.C_Str(), "node"));
+    std::cout<< "node->id " << node->id << "\n";
 
     if (!n->mTransformation.IsIdentity()) {
         node->matrix.isPresent = true;
@@ -705,46 +707,54 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
     //-------------------------------------------------------
     // Extract TIME parameter data.
     // Check if the timeStamps are the same for mPositionKeys, mRotationKeys, and mScalingKeys.
-    typedef float TimeType;
-    std::vector<TimeType> timeData;
-    timeData.resize(nodeChannel->mNumPositionKeys);
-    for (size_t i = 0; i < nodeChannel->mNumPositionKeys; ++i) {
-        timeData[i] = nodeChannel->mPositionKeys[i].mTime;  // Check if we have to cast type here. e.g. uint16_t()
-    }
+    if(nodeChannel->mNumPositionKeys > 0) {
+        std::cout<< "Parameters.TIME\n";
+        typedef float TimeType;
+        std::vector<TimeType> timeData;
+        timeData.resize(nodeChannel->mNumPositionKeys);
+        for (size_t i = 0; i < nodeChannel->mNumPositionKeys; ++i) {
+            timeData[i] = nodeChannel->mPositionKeys[i].mTime;  // Check if we have to cast type here. e.g. uint16_t()
+        }
 
-    Ref<Accessor> timeAccessor = ExportAnimationData(mAsset, animId, buffer, nodeChannel->mNumPositionKeys, &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT);
-    if (timeAccessor) animRef->Parameters.TIME = timeAccessor;
+        Ref<Accessor> timeAccessor = ExportAnimationData(mAsset, animId, buffer, nodeChannel->mNumPositionKeys, &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT);
+        if (timeAccessor) animRef->Parameters.TIME = timeAccessor;
+    }
 
     //-------------------------------------------------------
     // Extract translation parameter data
-    C_STRUCT aiVector3D* translationData = new aiVector3D[nodeChannel->mNumPositionKeys];
-    for (size_t i = 0; i < nodeChannel->mNumPositionKeys; ++i) {
-        translationData[i] = nodeChannel->mPositionKeys[i].mValue;
-    }
+    if(nodeChannel->mNumPositionKeys > 0) {
+        C_STRUCT aiVector3D* translationData = new aiVector3D[nodeChannel->mNumPositionKeys];
+        for (size_t i = 0; i < nodeChannel->mNumPositionKeys; ++i) {
+            translationData[i] = nodeChannel->mPositionKeys[i].mValue;
+        }
 
-    Ref<Accessor> tranAccessor = ExportAnimationData(mAsset, animId, buffer, nodeChannel->mNumPositionKeys, translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
-    if (tranAccessor) animRef->Parameters.translation = tranAccessor;
+        Ref<Accessor> tranAccessor = ExportAnimationData(mAsset, animId, buffer, nodeChannel->mNumPositionKeys, translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
+        if (tranAccessor) animRef->Parameters.translation = tranAccessor;
+    }
 
     //-------------------------------------------------------
     // Extract scale parameter data
-    C_STRUCT aiVector3D* scaleData = new aiVector3D[nodeChannel->mNumScalingKeys];
-    for (size_t i = 0; i < nodeChannel->mNumScalingKeys; ++i) {
-        scaleData[i] = nodeChannel->mScalingKeys[i].mValue;
-    }
+    if(nodeChannel->mNumScalingKeys > 0) {
+        C_STRUCT aiVector3D* scaleData = new aiVector3D[nodeChannel->mNumScalingKeys];
+        for (size_t i = 0; i < nodeChannel->mNumScalingKeys; ++i) {
+            scaleData[i] = nodeChannel->mScalingKeys[i].mValue;
+        }
 
-    Ref<Accessor> scaleAccessor = ExportAnimationData(mAsset, animId, buffer, nodeChannel->mNumScalingKeys, scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
-    if (scaleAccessor) animRef->Parameters.scale = scaleAccessor;
+        Ref<Accessor> scaleAccessor = ExportAnimationData(mAsset, animId, buffer, nodeChannel->mNumScalingKeys, scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
+        if (scaleAccessor) animRef->Parameters.scale = scaleAccessor;
+    }
 
     //-------------------------------------------------------
     // Extract rotation parameter data
-    C_STRUCT aiQuaternion* rotationData = new aiQuaternion[nodeChannel->mNumRotationKeys];
-    for (size_t i = 0; i < nodeChannel->mNumRotationKeys; ++i) {
-        rotationData[i] = nodeChannel->mRotationKeys[i].mValue;
-    }
-
-    Ref<Accessor> rotAccessor = ExportAnimationData(mAsset, animId, buffer, nodeChannel->mNumRotationKeys, rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
-    if (rotAccessor) animRef->Parameters.rotation = rotAccessor;
+    if(nodeChannel->mNumRotationKeys > 0) {
+        C_STRUCT aiQuaternion* rotationData = new aiQuaternion[nodeChannel->mNumRotationKeys];
+        for (size_t i = 0; i < nodeChannel->mNumRotationKeys; ++i) {
+            rotationData[i] = nodeChannel->mRotationKeys[i].mValue;
+        }
 
+        Ref<Accessor> rotAccessor = ExportAnimationData(mAsset, animId, buffer, nodeChannel->mNumRotationKeys, rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
+        if (rotAccessor) animRef->Parameters.rotation = rotAccessor;
+    }
 }
 
 
@@ -784,7 +794,7 @@ void glTFExporter::ExportAnimations()
     for (unsigned int i = 0; i < mScene->mNumAnimations; ++i) {
         const aiAnimation* anim = mScene->mAnimations[i];
 
-        std::string nameAnim;
+        std::string nameAnim = "anim";
         if (anim->mName.length > 0) {
             nameAnim = anim->mName.C_Str();
         }
@@ -798,6 +808,7 @@ void glTFExporter::ExportAnimations()
             std::string name = nameAnim + "_" + std::to_string(channelIndex);
             name = mAsset->FindUniqueID(name, "animation");
             Ref<Animation> animRef = mAsset->animations.Create(name);
+            std::cout<<"channelName " << name << "\n";
 
             /******************* Parameters ********************/
             // If compression is used then you need parameters of uncompressed region: begin and size. At this step "begin" is stored.
@@ -808,30 +819,73 @@ void glTFExporter::ExportAnimations()
             //    Otherwise, add to the buffer and create a new accessor.
             ExtractAnimationData(*mAsset, name, animRef, bufferRef, nodeChannel);
 
+            // for (unsigned int j = 0; j < 3; ++j) {
+            //     std::string channelType;
+            //     switch (j) {
+            //         case 0:
+            //             channelType = "rotation";
+            //             break;
+            //         case 1:
+            //             channelType = "scale";
+            //             break;
+            //         case 2:
+            //             channelType = "translation";
+            //             break;
+            //     }
+
+            //     animRef->Channels[j].sampler = name + "_" + channelType;
+            //     animRef->Channels[j].target.path = channelType;
+            //     animRef->Samplers[j].output = channelType;
+            //     animRef->Samplers[j].id = name + "_" + channelType;
+
+            //     animRef->Channels[j].target.id = mAsset->nodes.Get(nodeChannel->mNodeName.C_Str());
+
+            //     animRef->Samplers[j].input = "TIME";
+            //     animRef->Samplers[j].interpolation = "LINEAR";
+            // }
+
+
             for (unsigned int j = 0; j < 3; ++j) {
                 std::string channelType;
+                int channelSize;
                 switch (j) {
                     case 0:
                         channelType = "rotation";
+                        channelSize = nodeChannel->mNumRotationKeys;
                         break;
                     case 1:
                         channelType = "scale";
+                        channelSize = nodeChannel->mNumScalingKeys;
                         break;
                     case 2:
                         channelType = "translation";
+                        channelSize = nodeChannel->mNumPositionKeys;
                         break;
                 }
 
-                animRef->Channels[j].sampler = name + "_" + channelType;
-                animRef->Channels[j].target.path = channelType;
-                animRef->Samplers[j].output = channelType;
-                animRef->Samplers[j].id = name + "_" + channelType;
+                if (channelSize < 1) { continue; }
 
-                animRef->Channels[j].target.id = mAsset->nodes.Get(nodeChannel->mNodeName.C_Str());
+                std::cout<<"channelType " << channelType << "\n";
 
-                animRef->Samplers[j].input = "TIME";
-                animRef->Samplers[j].interpolation = "LINEAR";
+                Animation::AnimChannel tmpAnimChannel;
+                Animation::AnimSampler tmpAnimSampler;
+
+                tmpAnimChannel.sampler = name + "_" + channelType;
+                tmpAnimChannel.target.path = channelType;
+                tmpAnimSampler.output = channelType;
+                tmpAnimSampler.id = name + "_" + channelType;
+
+                std::cout<<"nodeChannel->mNodeName.C_Str() " << nodeChannel->mNodeName.C_Str() << "\n";
+                tmpAnimChannel.target.id = mAsset->nodes.Get(nodeChannel->mNodeName.C_Str());
+                std::cout<<"tmpAnimChannel.target.id " << tmpAnimChannel.target.id << "\n";
+
+                tmpAnimSampler.input = "TIME";
+                tmpAnimSampler.interpolation = "LINEAR";
+
+                animRef->Channels.push_back(tmpAnimChannel);
+                animRef->Samplers.push_back(tmpAnimSampler);
             }
+
         }
 
         std::cout<<"mNumMeshChannels " << anim->mNumMeshChannels << "\n";