created the asset writer function for animations export gltf

pull/1024/head
Angelo Scandaliato 2016-10-04 07:09:01 -07:00
parent 37d32e79c9
commit d249cca011
3 changed files with 124 additions and 39 deletions

View File

@ -915,21 +915,22 @@ namespace glTF
void SetDefaults(); void SetDefaults();
}; };
struct Animation : public Object
{
struct AnimSampler { 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 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 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. std::string output; //!< The ID of a parameter in this animation to use as key-frame output.
}; };
struct AnimChannel {
std::string sampler; //!< The ID of one sampler present in the containing animation's samplers property.
struct AnimTarget { struct AnimTarget {
Ref<Node> id; //!< The ID of the node to animate. 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"). std::string path; //!< The name of property of the node to animate ("translation", "rotation", or "scale").
}; } target;
struct AnimChannel {
Ref<AnimSampler> sampler; //!< The ID of one of the samplers present in the containing animation's samplers property.
AnimTarget target;
}; };
struct AnimParameters { struct AnimParameters {
@ -939,11 +940,12 @@ namespace glTF
Ref<Accessor> translation; //!< 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. 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. AnimParameters Parameters; //!< The samplers that interpolate between the key-frames.
AnimSampler Samplers[3]; //!< The parameterized inputs representing the key-frame data. 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; typedef typename std::gltf_unordered_map< std::string, unsigned int > Dict;
std::vector<T*> mObjs; //! The read objects 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* mDictId; //! ID of the dictionary object
const char* mExtId; //! ID of the extension defining the dictionary const char* mExtId; //! ID of the extension defining the dictionary
Value* mDict; //! JSON dictionary object Value* mDict; //! JSON dictionary object

View File

@ -102,7 +102,57 @@ namespace glTF {
inline void Write(Value& obj, Animation& a, AssetWriter& w) 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) inline void Write(Value& obj, Buffer& b, AssetWriter& w)

View File

@ -80,7 +80,6 @@ namespace Assimp {
// Worker function for exporting a scene to GLTF. Prototyped and registered in Exporter.cpp // 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) void ExportSceneGLTF(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
{ {
// invoke the exporter // invoke the exporter
glTFExporter exporter(pFile, pIOSystem, pScene, pProperties, false); glTFExporter exporter(pFile, pIOSystem, pScene, pProperties, false);
} }
@ -146,6 +145,8 @@ glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiSc
ExportScene(); ExportScene();
ExportAnimations();
glTF::AssetWriter writer(*mAsset); glTF::AssetWriter writer(*mAsset);
if (isBinary) { if (isBinary) {
@ -369,7 +370,7 @@ void glTFExporter::ExportMeshes()
typedef unsigned short IndicesType; typedef unsigned short IndicesType;
// Variables needed for compression. BEGIN. // 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_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. 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. 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() 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; // aiString aiName;
for (unsigned int i = 0; i < mScene->mNumAnimations; ++i) { for (unsigned int i = 0; i < mScene->mNumAnimations; ++i) {
const aiAnimation* anim = mScene->mAnimations[i]; const aiAnimation* anim = mScene->mAnimations[i];
@ -637,32 +664,38 @@ void glTFExporter::ExportAnimations()
Ref<Animation> animRef = mAsset->animations.Create(name); Ref<Animation> animRef = mAsset->animations.Create(name);
animRef->Parameters.TIME; // These are accessors to bufferviews to buffer data.
animRef->Parameters.rotation;
animRef->Parameters.scale; Ref<Accessor> acc = mAsset->accessors.Get(unsigned (0));
animRef->Parameters.translation;
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) { for (unsigned int channelIndex = 0; channelIndex < anim->mNumChannels; ++channelIndex) {
const aiNodeAnim* nodeChannel = anim->mChannels[channelIndex]; const aiNodeAnim* nodeChannel = anim->mChannels[channelIndex];
for (unsigned int j = 0; j < 3; ++j) { for (unsigned int j = 0; j < 3; ++j) {
std::string channelType;
switch (j) { switch (j) {
case 0: case 0:
animRef->Channels[j].target.path = "rotation"; channelType = "rotation";
animRef->Samplers[j].output = "rotation";
break; break;
case 1: case 1:
animRef->Channels[j].target.path = "scale"; channelType = "scale";
animRef->Samplers[j].output = "scale";
break; break;
case 2: case 2:
animRef->Channels[j].target.path = "translation"; channelType = "translation";
animRef->Samplers[j].output = "translation";
break; break;
} }
animRef->Channels[j].sampler; animRef->Channels[j].sampler = name + "_" + channelType;
animRef->Channels[j].target.id = mAsset->FindUniqueID(nodeChannel->mNodeName.C_Str(), "node"); 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].input = "TIME";
animRef->Samplers[j].interpolation = "LINEAR"; animRef->Samplers[j].interpolation = "LINEAR";