GLTF exporter: ensure animation accessors have same count
authorjamesgk <jamesgk19@gmail.com>
Fri, 5 May 2017 23:45:28 +0000 (16:45 -0700)
committerjamesgk <jamesgk19@gmail.com>
Mon, 8 May 2017 21:45:26 +0000 (14:45 -0700)
code/glTFExporter.cpp

index af5cbe9..110a3c2 100644 (file)
@@ -845,30 +845,45 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
     //    If yes, then reference the existing corresponding accessor.
     //    Otherwise, add to the buffer and create a new accessor.
 
+    size_t counts[3] = {
+        nodeChannel->mNumPositionKeys,
+        nodeChannel->mNumScalingKeys,
+        nodeChannel->mNumRotationKeys,
+    };
+    size_t numKeyframes = 1;
+    for (int i = 0; i < 3; ++i) {
+        if (counts[i] > numKeyframes) {
+            numKeyframes = counts[i];
+        }
+    }
+
     //-------------------------------------------------------
     // Extract TIME parameter data.
     // Check if the timeStamps are the same for mPositionKeys, mRotationKeys, and mScalingKeys.
     if(nodeChannel->mNumPositionKeys > 0) {
         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()
+        timeData.resize(numKeyframes);
+        for (size_t i = 0; i < numKeyframes; ++i) {
+            size_t frameIndex = i * nodeChannel->mNumPositionKeys / numKeyframes;
+            // Check if we have to cast type here. e.g. uint16_t()
+            timeData[i] = nodeChannel->mPositionKeys[frameIndex].mTime;
         }
 
-        Ref<Accessor> timeAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumPositionKeys, &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT);
+        Ref<Accessor> timeAccessor = ExportData(mAsset, animId, buffer, numKeyframes, &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT);
         if (timeAccessor) animRef->Parameters.TIME = timeAccessor;
     }
 
     //-------------------------------------------------------
     // Extract translation parameter data
     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;
+        C_STRUCT aiVector3D* translationData = new aiVector3D[numKeyframes];
+        for (size_t i = 0; i < numKeyframes; ++i) {
+            size_t frameIndex = i * nodeChannel->mNumPositionKeys / numKeyframes;
+            translationData[i] = nodeChannel->mPositionKeys[frameIndex].mValue;
         }
 
-        Ref<Accessor> tranAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumPositionKeys, translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
+        Ref<Accessor> tranAccessor = ExportData(mAsset, animId, buffer, numKeyframes, translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
         if ( tranAccessor ) {
             animRef->Parameters.translation = tranAccessor;
         }
@@ -878,12 +893,13 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
     //-------------------------------------------------------
     // Extract scale parameter data
     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;
+        C_STRUCT aiVector3D* scaleData = new aiVector3D[numKeyframes];
+        for (size_t i = 0; i < numKeyframes; ++i) {
+            size_t frameIndex = i * nodeChannel->mNumScalingKeys / numKeyframes;
+            scaleData[i] = nodeChannel->mScalingKeys[frameIndex].mValue;
         }
 
-        Ref<Accessor> scaleAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumScalingKeys, scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
+        Ref<Accessor> scaleAccessor = ExportData(mAsset, animId, buffer, numKeyframes, scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
         if ( scaleAccessor ) {
             animRef->Parameters.scale = scaleAccessor;
         }
@@ -893,15 +909,16 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
     //-------------------------------------------------------
     // Extract rotation parameter data
     if(nodeChannel->mNumRotationKeys > 0) {
-        vec4* rotationData = new vec4[nodeChannel->mNumRotationKeys];
-        for (size_t i = 0; i < nodeChannel->mNumRotationKeys; ++i) {
-            rotationData[i][0] = nodeChannel->mRotationKeys[i].mValue.x;
-            rotationData[i][1] = nodeChannel->mRotationKeys[i].mValue.y;
-            rotationData[i][2] = nodeChannel->mRotationKeys[i].mValue.z;
-            rotationData[i][3] = nodeChannel->mRotationKeys[i].mValue.w;
+        vec4* rotationData = new vec4[numKeyframes];
+        for (size_t i = 0; i < numKeyframes; ++i) {
+            size_t frameIndex = i * nodeChannel->mNumRotationKeys / numKeyframes;
+            rotationData[i][0] = nodeChannel->mRotationKeys[frameIndex].mValue.x;
+            rotationData[i][1] = nodeChannel->mRotationKeys[frameIndex].mValue.y;
+            rotationData[i][2] = nodeChannel->mRotationKeys[frameIndex].mValue.z;
+            rotationData[i][3] = nodeChannel->mRotationKeys[frameIndex].mValue.w;
         }
 
-        Ref<Accessor> rotAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumRotationKeys, rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
+        Ref<Accessor> rotAccessor = ExportData(mAsset, animId, buffer, numKeyframes, rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
         if ( rotAccessor ) {
             animRef->Parameters.rotation = rotAccessor;
         }