/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #include "motion/scene_motion.h" #include "log/log.h" using namespace GS; using namespace GS::Core; using GS::NML::Tag; //------------------------------------------------------------------------------ Motion *SceneMotion::GetItemMotion(uint uid, bool create_if_missing) { ListForeachPtr(ItemMotion *, m, item_motions) if (m->uid == uid) return m->motion; if (!create_if_missing) return NULL; ItemMotion *item_motion = new ItemMotion; if (!item_motion) __ERR__(__LOG_E__ << "Failed to allocate item motion.\n", NULL) item_motion->uid = uid; item_motion->motion = new Motion; item_motions.Add(item_motion); return item_motion->motion; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void SceneMotion::Clone(const SceneMotion &src, const TimeRange &range, bool enforce_loop) { // Clone item motions. item_motions.Clear(); ListForeachPtr(ItemMotion *, m, src.item_motions) { ItemMotion *c = new ItemMotion; if (c == NULL) continue; c->uid = m->uid; c->motion = new Motion; c->motion->Clone(*m->motion, range, enforce_loop); item_motions.Add(c); } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ TimeRange SceneMotion::GetTimeRange() const { List ::Item *i = item_motions.GetRoot(); if (i == NULL) return TimeRange(); TimeRange range = i->Object()->motion->GetTimeRange(); for (i = i->Next(); i; i = i->Next()) range = TimeRange::Union(range, i->Object()->motion->GetTimeRange()); return range; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ bool SceneMotion::FromMetaTag(Tag &tag, const Map *uid_map) { if (tag.name != "SceneMotion") __ERR__(__LOG_E__ << "Could not parse scene motion, incorrect root tag (" << tag.name << ").\n", false) item_motions.Clear(); // Parse root tags. NMLTagForeach(pt, tag) { if (pt->name == "Name") name = pt->GetString(); else if (pt->name == "ItemMotions") { NMLTagForeach(it, *pt) { if (it->name == "ItemMotion") { Tag *uid_tag = it->GetTypedTag("UId", Variant::VariantInteger), *motion_tag = it->GetTag("Motion"); if (uid_tag && motion_tag) { uint uid = uid_tag->GetUnsigned(); if (uid_map && !uid_map->HasKey(uid)) continue; // item got lost, don't load ItemMotion *item_motion = new ItemMotion; item_motion->uid = uid_map ? (*uid_map)[uid] : uid; item_motion->motion = new Motion; item_motion->motion->FromMetaTag(*motion_tag); item_motions.Add(item_motion); } else __LOG_W__ << "Mangled item motion tag.\n"; } } } else __LOG_W__ << "Unknown tag '" << pt->name << "' in .\n"; } return true; } Tag *SceneMotion::AsMetaTag() { Tag *root = new Tag("SceneMotion"); if (!root) __ERR__(__LOG_E__ << "Could not create root tag to serialize.\n", NULL) root->AddChild("Name", name); if (Tag *pim = root->AddChild("ItemMotions")) ListForeachPtr(ItemMotion *, m, item_motions) if (Tag *pm = pim->AddChild("ItemMotion")) { pm->AddChild("UId", m->uid); pm->AddChild(m->motion->AsMetaTag()); } return root; } //------------------------------------------------------------------------------