| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- //
- // Copyright (c) 2008-2017 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 "../Graphics/DrawableEvents.h"
- #include "../Scene/Component.h"
- #include "../Scene/Node.h"
- #include "../Atomic2D/SpriterInstance2D.h"
- #include <cmath>
- namespace Atomic
- {
- namespace Spriter
- {
- SpriterInstance::SpriterInstance(Component* owner, SpriterData* spriteData) :
- owner_(owner),
- spriterData_(spriteData),
- entity_(0),
- animation_(0)
- {
- }
- SpriterInstance::~SpriterInstance()
- {
- Clear();
- OnSetAnimation(0);
- OnSetEntity(0);
- }
- bool SpriterInstance::SetEntity(int index)
- {
- if (!spriterData_)
- return false;
- if (index < (int)spriterData_->entities_.Size())
- {
- OnSetEntity(spriterData_->entities_[index]);
- return true;
- }
- return false;
- }
- bool SpriterInstance::SetEntity(const String& entityName)
- {
- if (!spriterData_)
- return false;
- for (unsigned i = 0; i < spriterData_->entities_.Size(); ++i)
- {
- if (spriterData_->entities_[i]->name_ == entityName)
- {
- OnSetEntity(spriterData_->entities_[i]);
- return true;
- }
- }
- return false;
- }
- bool SpriterInstance::SetAnimation(int index, LoopMode loopMode)
- {
- if (!entity_)
- return false;
- if (index < (int)entity_->animations_.Size())
- {
- OnSetAnimation(entity_->animations_[index], loopMode);
- return true;
- }
- return false;
- }
- bool SpriterInstance::SetAnimation(const String& animationName, LoopMode loopMode)
- {
- if (!entity_)
- return false;
- for (unsigned i = 0; i < entity_->animations_.Size(); ++i)
- {
- if (entity_->animations_[i]->name_ == animationName)
- {
- OnSetAnimation(entity_->animations_[i], loopMode);
- return true;
- }
- }
- return false;
- }
- void SpriterInstance::setSpatialInfo(const SpatialInfo& spatialInfo)
- {
- this->spatialInfo_ = spatialInfo;
- }
- void SpriterInstance::setSpatialInfo(float x, float y, float angle, float scaleX, float scaleY)
- {
- spatialInfo_ = SpatialInfo(x, y, angle, scaleX, scaleY);
- }
- void SpriterInstance::Update(float deltaTime)
- {
- if (!animation_)
- return;
- Clear();
- float lastTime = currentTime_;
- currentTime_ += deltaTime;
- if (currentTime_ > animation_->length_)
- {
- bool sendFinishEvent = false;
- if (looping_)
- {
- currentTime_ = fmod(currentTime_, animation_->length_);
- sendFinishEvent = true;
- }
- else
- {
- currentTime_ = animation_->length_;
- sendFinishEvent = lastTime != currentTime_;
- }
- if (sendFinishEvent && owner_)
- {
- Node* senderNode = owner_->GetNode();
- if (senderNode)
- {
- using namespace AnimationFinished;
- VariantMap& eventData = senderNode->GetEventDataMap();
- eventData[P_NODE] = senderNode;
- eventData[P_ANIMATION] = animation_;
- eventData[P_NAME] = animation_->name_;
- eventData[P_LOOPED] = looping_;
-
- senderNode->SendEvent(E_ANIMATIONFINISHED, eventData);
- }
- }
- }
- UpdateMainlineKey();
- UpdateTimelineKeys();
- }
- void SpriterInstance::OnSetEntity(Entity* entity)
- {
- if (entity == this->entity_)
- return;
- OnSetAnimation(0);
- this->entity_ = entity;
- }
- void SpriterInstance::OnSetAnimation(Animation* animation, LoopMode loopMode)
- {
- if (animation == this->animation_)
- return;
- animation_ = animation;
- if (animation_)
- {
- if (loopMode == Default)
- looping_ = animation_->looping_;
- else if (loopMode == ForceLooped)
- looping_ = true;
- else
- looping_ = false;
- }
-
- currentTime_ = 0.0f;
- Clear();
- }
- void SpriterInstance::UpdateTimelineKeys()
- {
- for (unsigned i = 0; i < mainlineKey_->boneRefs_.Size(); ++i)
- {
- Ref* ref = mainlineKey_->boneRefs_[i];
- BoneTimelineKey* timelineKey = (BoneTimelineKey*)GetTimelineKey(ref);
- if (ref->parent_ >= 0)
- {
- timelineKey->info_ = timelineKey->info_.UnmapFromParent(timelineKeys_[ref->parent_]->info_);
- }
- else
- {
- timelineKey->info_ = timelineKey->info_.UnmapFromParent(spatialInfo_);
- }
- timelineKeys_.Push(timelineKey);
- }
- for (unsigned i = 0; i < mainlineKey_->objectRefs_.Size(); ++i)
- {
- Ref* ref = mainlineKey_->objectRefs_[i];
- SpriteTimelineKey* timelineKey = (SpriteTimelineKey*)GetTimelineKey(ref);
-
- if (ref->parent_ >= 0)
- {
- timelineKey->info_ = timelineKey->info_.UnmapFromParent(timelineKeys_[ref->parent_]->info_);
- }
- else
- {
- timelineKey->info_ = timelineKey->info_.UnmapFromParent(spatialInfo_);
- }
-
- timelineKey->zIndex_ = ref->zIndex_;
- timelineKeys_.Push(timelineKey);
- }
- }
- void SpriterInstance::UpdateMainlineKey()
- {
- const PODVector<MainlineKey*>& mainlineKeys = animation_->mainlineKeys_;
- for (unsigned i = 0; i < mainlineKeys.Size(); ++i)
- {
- if (mainlineKeys[i]->time_ <= currentTime_)
- {
- mainlineKey_ = mainlineKeys[i];
- }
- if (mainlineKeys[i]->time_ >= currentTime_)
- {
- break;
- }
- }
- if (!mainlineKey_)
- {
- mainlineKey_ = mainlineKeys[0];
- }
- }
- TimelineKey* SpriterInstance::GetTimelineKey(Ref* ref) const
- {
- Timeline* timeline = animation_->timelines_[ref->timeline_];
- TimelineKey* timelineKey = timeline->keys_[ref->key_]->Clone();
- if (timeline->keys_.Size() == 1 || timelineKey->curveType_ == INSTANT)
- {
- return timelineKey;
- }
- unsigned nextTimelineKeyIndex = ref->key_ + 1;
- if (nextTimelineKeyIndex >= timeline->keys_.Size())
- {
- if (animation_->looping_)
- {
- nextTimelineKeyIndex = 0;
- }
- else
- {
- return timelineKey;
- }
- }
- TimelineKey* nextTimelineKey = timeline->keys_[nextTimelineKeyIndex];
-
- float nextTimelineKeyTime = nextTimelineKey->time_;
- if (nextTimelineKey->time_ < timelineKey->time_)
- {
- nextTimelineKeyTime += animation_->length_;
- }
- float t = timelineKey->GetTByCurveType(currentTime_, nextTimelineKeyTime);
- timelineKey->Interpolate(*nextTimelineKey, t);
- return timelineKey;
- }
- void SpriterInstance::Clear()
- {
- mainlineKey_ = 0;
- if (!timelineKeys_.Empty())
- {
- for (unsigned i = 0; i < timelineKeys_.Size(); ++i)
- {
- delete timelineKeys_[i];
- }
- timelineKeys_.Clear();
- }
- }
- }
- }
|