/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #include "motion/motion.h" #include "log/log.h" using namespace GS::Core; using GS::NML::Tag; //------------------------------------------------------------------------------ bool Motion::FromMetaTag(Tag &tag) { if (tag.name != "Motion") __ERR__(__LOG_E__ << "Could not parse motion, incorrect root tag (" << tag.name << ").\n", false) use_quaternion = false; // Parse root tags. NMLTagForeach(pt, tag) { if (pt->name == "Id") name = pt->GetString(); else if (pt->name == "UseQuaternion") use_quaternion = pt->GetBool(); else if (pt->name == "QChannel") quaternion.FromMetaTag(*pt); else if (pt->name == "Channel") { MotionChannel *chn = AddChannel(MotionChannel::Undf); chn->FromMetaTag(*pt); } else if (pt->name == "DataKnot") { Tag *count_tag = pt->GetTag("Count"); ArrayListDeleteAllPtr(SDataPoint *, data_point) if (count_tag && count_tag->GetInteger() > 0) { uint n = (uint)count_tag->GetInteger(); while (n--) if (!data_point.Add(new SDataPoint)) return false; n = 0; NMLTagForeach(st, *pt) { if (st->name == "Knot") { if (n == data_point.GetCount()) { __LOG_E__ << "Too many knot in , " << data_point.GetCount() << " expected.\n"; break; } if (const char *p = st->GetString()) { data_point[n]->t = Time::fromSec(String::atof(p)); p = String::strfindchar(p, ':'); data_point[n]->data = Variant(p + 1); n++; } else __LOG_W__ << "Invalid knot tag while parsing curve.\n"; } } } } else __LOG_W__ << "Unknown tag '" << pt->name << "' in .\n"; } return true; } Tag *Motion::AsMetaTag() { Tag *root = new Tag("Motion"); if (!root) __ERR__(__LOG_E__ << "Could not create root tag to serialize.\n", NULL) root->AddChild("Id", name.c_str()); // Dump quaternion channel. root->AddChild("UseQuaternion", use_quaternion); root->AddChild(quaternion.AsMetaTag()); // Dump all channels. ListForeachPtr(MotionChannel *, channel, channel_list) root->AddChild(channel->AsMetaTag()); // Dump the data array if (data_point.GetCount()) if (Tag *data_knot_tag = root->AddChild("DataKnot")) { data_knot_tag->AddChild("Count", (int)data_point.GetCount()); ArrayListForeachPtr(SDataPoint *, data, data_point) data_knot_tag->AddChild("Knot",String::Format("%f:%s", data->t.toSec(), data->data.s_value.c_str()).c_str()); } return root; } //------------------------------------------------------------------------------