created the asset writer function for animations export gltf
authorAngelo Scandaliato <angelo@adtile.me>
Tue, 4 Oct 2016 14:09:01 +0000 (07:09 -0700)
committerAngelo Scandaliato <angelo@adtile.me>
Tue, 4 Oct 2016 14:09:01 +0000 (07:09 -0700)
code/glTFAsset.h
code/glTFAssetWriter.inl
code/glTFExporter.cpp

index 6afd6bb..dd94f2b 100644 (file)
@@ -915,35 +915,37 @@ namespace glTF
         void SetDefaults();
     };
 
+    struct Animation : public Object
+    {
+        struct AnimSampler {
+            std::string id;               //!< The ID of this sampler.
+            std::string input;            //!< The ID of a parameter in this animation to use as key-frame input.
+            std::string interpolation;    //!< Type of interpolation algorithm to use between key-frames.
+            std::string output;           //!< The ID of a parameter in this animation to use as key-frame output.
+        };
 
-    struct AnimSampler {
-        std::string input;            //!< The ID of a parameter in this animation to use as key-frame input.
-        std::string interpolation;    //!< Type of interpolation algorithm to use between key-frames.
-        std::string output;           //!< The ID of a parameter in this animation to use as key-frame output.
-    };
-
-    struct AnimTarget {
-        Ref<Node> id;                 //!< The ID of the node to animate.
-        std::string path;             //!< The name of property of the node to animate ("translation", "rotation", or "scale").
-    };
+        struct AnimChannel {
+            std::string sampler;         //!< The ID of one sampler present in the containing animation's samplers property.
 
-    struct AnimChannel {
-        Ref<AnimSampler> sampler;         //!< The ID of one of the samplers present in the containing animation's samplers property.
-        AnimTarget target;
-    };
+            struct AnimTarget {
+                Ref<Node> id;            //!< The ID of the node to animate.
+                std::string path;        //!< The name of property of the node to animate ("translation", "rotation", or "scale").
+            } target;
+        };
 
-    struct AnimParameters {
-        Ref<Accessor> TIME;           //!< Accessor reference to a buffer storing a array of floating point scalar values.
-        Ref<Accessor> rotation;       //!< Accessor reference to a buffer storing a array of four-component floating-point vectors.
-        Ref<Accessor> scale;          //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
-        Ref<Accessor> translation;    //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
-    };
+        struct AnimParameters {
+            Ref<Accessor> TIME;           //!< Accessor reference to a buffer storing a array of floating point scalar values.
+            Ref<Accessor> rotation;       //!< Accessor reference to a buffer storing a array of four-component floating-point vectors.
+            Ref<Accessor> scale;          //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
+            Ref<Accessor> translation;    //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
+        };
 
-    struct Animation : public Object
-    {
         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.
+
+        Animation() {}
+        void Read(Value& obj, Asset& r);
     };
 
 
@@ -979,7 +981,7 @@ namespace glTF
         typedef typename std::gltf_unordered_map< std::string, unsigned int > Dict;
 
         std::vector<T*>  mObjs;      //! The read objects
-        Dict             mObjsById;  //! The read objects accesible by id
+        Dict             mObjsById;  //! The read objects accessible by id
         const char*      mDictId;    //! ID of the dictionary object
         const char*      mExtId;     //! ID of the extension defining the dictionary
         Value*           mDict;      //! JSON dictionary object
index 2022305..d79a64d 100644 (file)
@@ -102,7 +102,57 @@ namespace glTF {
 
     inline void Write(Value& obj, Animation& a, AssetWriter& w)
     {
+        /****************** Channels *******************/
+        Value channels;
+        channels.SetArray();
+        channels.Reserve(3/*unsigned(a.Channels.size())*/, w.mAl);
+
+        for (size_t i = 0; i < 3/*a.Channels.size()*/; ++i) {
+            Animation::AnimChannel& c = a.Channels[i];
+            Value valChannel;
+            valChannel.SetObject();
+            {
+                valChannel.AddMember("sampler", c.sampler, w.mAl);
 
+                Value valTarget;
+                valTarget.SetObject();
+                {
+                    valTarget.AddMember("id", StringRef(c.target.id->id), w.mAl);
+                    valTarget.AddMember("path", c.target.path, w.mAl);
+                }
+                valChannel.AddMember("target", valTarget, w.mAl);
+            }
+            channels.PushBack(valChannel, 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);
+        }
+        obj.AddMember("Parameters", valParameters, w.mAl);
+
+        /****************** Samplers *******************/
+        Value valSamplers;
+        valSamplers.SetObject();
+
+        for (size_t i = 0; i < 3/*a.Samplers.size()*/; ++i) {
+            Animation::AnimSampler& s = a.Samplers[i];
+            Value valSampler;
+            valSampler.SetObject();
+            {
+                valSampler.AddMember("input", s.input, w.mAl);
+                valSampler.AddMember("interpolation", s.interpolation, w.mAl);
+                valSampler.AddMember("output", s.output, w.mAl);
+            }
+            valSamplers.AddMember(StringRef(s.id), valSampler, w.mAl);
+        }
+        obj.AddMember("Samplers", valSamplers, w.mAl);
     }
 
     inline void Write(Value& obj, Buffer& b, AssetWriter& w)
index 56f5488..5cf4f84 100644 (file)
@@ -80,7 +80,6 @@ namespace Assimp {
     // Worker function for exporting a scene to GLTF. Prototyped and registered in Exporter.cpp
     void ExportSceneGLTF(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
     {
-
         // invoke the exporter
         glTFExporter exporter(pFile, pIOSystem, pScene, pProperties, false);
     }
@@ -146,6 +145,8 @@ glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiSc
 
     ExportScene();
 
+    ExportAnimations();
+
     glTF::AssetWriter writer(*mAsset);
 
     if (isBinary) {
@@ -369,7 +370,7 @@ void glTFExporter::ExportMeshes()
     typedef unsigned short IndicesType;
 
     // Variables needed for compression. BEGIN.
-    // Indices, not pointers - because pointer to buffer is changin while writing to it.
+    // Indices, not pointers - because pointer to buffer is changing while writing to it.
     size_t idx_srcdata_begin;// Index of buffer before writing mesh data. Also, index of begin of coordinates array in buffer.
     size_t idx_srcdata_normal = SIZE_MAX;// Index of begin of normals array in buffer. SIZE_MAX - mean that mesh has no normals.
     std::vector<size_t> idx_srcdata_tc;// Array of indices. Every index point to begin of texture coordinates array in buffer.
@@ -625,6 +626,32 @@ void glTFExporter::ExportMetadata()
 
 void glTFExporter::ExportAnimations()
 {
+    // //--------------------------
+    // // Setup to output buffer data
+    // // Not for
+    // //     using IndicesType = decltype(aiFace::mNumIndices);
+    // // But yes for
+    // //     using IndicesType = unsigned short;
+    // // because "ComponentType_UNSIGNED_SHORT" used for indices. And it's a maximal type according to glTF specification.
+    // typedef unsigned short IndicesType;
+
+    // // Variables needed for compression. BEGIN.
+    // // Indices, not pointers - because pointer to buffer is changing while writing to it.
+    // size_t idx_srcdata_begin;// Index of buffer before writing mesh data. Also, index of begin of coordinates array in buffer.
+    // size_t idx_srcdata_normal = SIZE_MAX;// Index of begin of normals array in buffer. SIZE_MAX - mean that mesh has no normals.
+    // std::vector<size_t> idx_srcdata_tc;// Array of indices. Every index point to begin of texture coordinates array in buffer.
+    // size_t idx_srcdata_ind;// Index of begin of coordinates indices array in buffer.
+    // bool comp_allow;// Point that data of current mesh can be compressed.
+    // // Variables needed for compression. END.
+
+    // std::string fname = std::string(mFilename);
+    // std::string bufferIdPrefix = fname.substr(0, fname.find("."));
+    // std::string bufferId = mAsset->FindUniqueID("", bufferIdPrefix.c_str());
+
+    // Ref<Buffer> b = mAsset->GetBodyBuffer();
+    // // Setup to output buffer data
+    // //--------------------------
+
     // aiString aiName;
     for (unsigned int i = 0; i < mScene->mNumAnimations; ++i) {
         const aiAnimation* anim = mScene->mAnimations[i];
@@ -637,32 +664,38 @@ void glTFExporter::ExportAnimations()
 
         Ref<Animation> animRef = mAsset->animations.Create(name);
 
-        animRef->Parameters.TIME;
-        animRef->Parameters.rotation;
-        animRef->Parameters.scale;
-        animRef->Parameters.translation;
+        // These are accessors to bufferviews to buffer data.
+
+        Ref<Accessor> acc = mAsset->accessors.Get(unsigned (0));
+
+        animRef->Parameters.TIME = acc;
+        animRef->Parameters.rotation = acc;
+        animRef->Parameters.scale = acc;
+        animRef->Parameters.translation = acc;
 
         for (unsigned int channelIndex = 0; channelIndex < anim->mNumChannels; ++channelIndex) {
             const aiNodeAnim* nodeChannel = anim->mChannels[channelIndex];
 
             for (unsigned int j = 0; j < 3; ++j) {
+                std::string channelType;
                 switch (j) {
                     case 0:
-                        animRef->Channels[j].target.path = "rotation";
-                        animRef->Samplers[j].output = "rotation";
+                        channelType = "rotation";
                         break;
                     case 1:
-                        animRef->Channels[j].target.path = "scale";
-                        animRef->Samplers[j].output = "scale";
+                        channelType = "scale";
                         break;
                     case 2:
-                        animRef->Channels[j].target.path = "translation";
-                        animRef->Samplers[j].output = "translation";
+                        channelType = "translation";
                         break;
                 }
 
-                animRef->Channels[j].sampler;
-                animRef->Channels[j].target.id = mAsset->FindUniqueID(nodeChannel->mNodeName.C_Str(), "node");
+                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";