// // Copyright (c) 2008-2014 the Urho3D project. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // #include "Precompiled.h" #include "AttributeAnimation.h" #include "Context.h" #include "ObjectAnimation.h" #include "XMLFile.h" #include "DebugNew.h" namespace Urho3D { const char* wrapModeNames[] = { "Loop", "Once", "Clamp", 0 }; ObjectAnimation::ObjectAnimation(Context* context) : Resource(context) { } ObjectAnimation::~ObjectAnimation() { } void ObjectAnimation::RegisterObject(Context* context) { context->RegisterFactory(); } bool ObjectAnimation::Load(Deserializer& source) { XMLFile xmlFile(context_); if (!xmlFile.Load(source)) return false; return LoadXML(xmlFile.GetRoot()); } bool ObjectAnimation::Save(Serializer& dest) const { XMLFile xmlFile(context_); XMLElement rootElem = xmlFile.CreateRoot("objectAnimation"); if (!SaveXML(rootElem)) return false; return xmlFile.Save(dest); } bool ObjectAnimation::LoadXML(const XMLElement& source) { attributeAnimations_.Clear(); XMLElement animElem; animElem = source.GetChild("attributeAnimation"); while (animElem) { String name = animElem.GetAttribute("name"); SharedPtr animation(new AttributeAnimation(context_)); if (!animation->LoadXML(animElem)) return false; String wrapModeString = source.GetAttribute("wrapMode"); WrapMode wrapMode = WM_LOOP; for (int i = 0; i <= WM_CLAMP; ++i) { if (wrapModeString == wrapModeNames[i]) { wrapMode = (WrapMode)i; break; } } float speed = animElem.GetFloat("speed"); AddAttributeAnimation(name, animation, wrapMode, speed); animElem = animElem.GetNext("attributeAnimation"); } return true; } bool ObjectAnimation::SaveXML(XMLElement& dest) const { for (HashMap >::ConstIterator i = attributeAnimations_.Begin(); i != attributeAnimations_.End(); ++i) { XMLElement animElem = dest.CreateChild("attributeAnimation"); animElem.SetAttribute("name", i->first_); if (!i->second_->SaveXML(animElem)) return false; animElem.SetAttribute("wrapMode", wrapModeNames[GetAttributeAnimationWrapMode(i->first_)]); animElem.SetFloat("speed", GetAttributeAnimationSpeed(i->first_)); } return true; } void ObjectAnimation::AddAttributeAnimation(const String& name, AttributeAnimation* attributeAnimation, WrapMode wrapMode, float speed) { if (!attributeAnimation) return; attributeAnimation->SetObjectAnimation(this); attributeAnimations_[name] = attributeAnimation; attributeAnimationWrapModes_[name] = wrapMode; attributeAnimationSpeeds_[name] = speed; } void ObjectAnimation::RemoveAttributeAnimation(const String& name) { RemoveAttributeAnimation(GetAttributeAnimation(name)); } void ObjectAnimation::RemoveAttributeAnimation(AttributeAnimation* attributeAnimation) { if (!attributeAnimation) return; String name; for (HashMap >::Iterator i = attributeAnimations_.Begin(); i != attributeAnimations_.End(); ++i) { if (i->second_ == attributeAnimation) { name = i->first_; attributeAnimation->SetObjectAnimation(0); attributeAnimations_.Erase(i); break; } } if (!name.Empty()) { attributeAnimationWrapModes_.Erase(name); attributeAnimationSpeeds_.Erase(name); } } AttributeAnimation* ObjectAnimation::GetAttributeAnimation(const String& name) const { HashMap >::ConstIterator i = attributeAnimations_.Find(name); if (i != attributeAnimations_.End()) return i->second_; return 0; } WrapMode ObjectAnimation::GetAttributeAnimationWrapMode(const String& name) const { HashMap::ConstIterator i = attributeAnimationWrapModes_.Find(name); if (i != attributeAnimationWrapModes_.End()) return i->second_; return WM_LOOP; } float ObjectAnimation::GetAttributeAnimationSpeed(const String& name) const { HashMap::ConstIterator i = attributeAnimationSpeeds_.Find(name); if (i != attributeAnimationSpeeds_.End()) return i->second_; return 1.0f; } }