From 4ac57f1fabf65df9f9b89ed672dbdef7c4483f20 Mon Sep 17 00:00:00 2001 From: Angelo Scandaliato Date: Thu, 6 Oct 2016 02:34:11 -0700 Subject: [PATCH] fixed issues to get node animations working --- code/glTFAsset.h | 10 +++- code/glTFAssetWriter.inl | 28 +++++---- code/glTFExporter.cpp | 126 ++++++++++++++++++++++++++++----------- 3 files changed, 115 insertions(+), 49 deletions(-) diff --git a/code/glTFAsset.h b/code/glTFAsset.h index b7ea8fbba..4b5fb6737 100644 --- a/code/glTFAsset.h +++ b/code/glTFAsset.h @@ -950,9 +950,13 @@ namespace glTF Ref 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 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 Samplers; //!< The parameterized inputs representing the key-frame data. Animation() {} void Read(Value& obj, Asset& r); diff --git a/code/glTFAssetWriter.inl b/code/glTFAssetWriter.inl index a5603a3ca..3589ceee7 100644 --- a/code/glTFAssetWriter.inl +++ b/code/glTFAssetWriter.inl @@ -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) diff --git a/code/glTFExporter.cpp b/code/glTFExporter.cpp index 86592d245..7a0a9a8a3 100644 --- a/code/glTFExporter.cpp +++ b/code/glTFExporter.cpp @@ -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 = 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 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 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 timeAccessor = ExportAnimationData(mAsset, animId, buffer, nodeChannel->mNumPositionKeys, &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT); - if (timeAccessor) animRef->Parameters.TIME = timeAccessor; + Ref 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 tranAccessor = ExportAnimationData(mAsset, animId, buffer, nodeChannel->mNumPositionKeys, translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); - if (tranAccessor) animRef->Parameters.translation = tranAccessor; + Ref 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 scaleAccessor = ExportAnimationData(mAsset, animId, buffer, nodeChannel->mNumScalingKeys, scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); - if (scaleAccessor) animRef->Parameters.scale = scaleAccessor; + Ref 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; + 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 rotAccessor = ExportAnimationData(mAsset, animId, buffer, nodeChannel->mNumRotationKeys, rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); + if (rotAccessor) animRef->Parameters.rotation = rotAccessor; } - - Ref 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 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";