| #include "rive/animation/linear_animation.hpp" | |
| #include "rive/animation/keyed_object.hpp" | |
| #include "rive/artboard.hpp" | |
| #include "rive/importers/artboard_importer.hpp" | |
| #include "rive/importers/import_stack.hpp" | |
| using namespace rive; | |
| #ifdef TESTING | |
| int LinearAnimation::deleteCount = 0; | |
| #endif | |
| LinearAnimation::~LinearAnimation() { | |
| #ifdef TESTING | |
| deleteCount++; | |
| #endif | |
| for (auto object : m_KeyedObjects) { | |
| delete object; | |
| } | |
| } | |
| StatusCode LinearAnimation::onAddedDirty(CoreContext* context) { | |
| StatusCode code; | |
| for (auto object : m_KeyedObjects) { | |
| if ((code = object->onAddedDirty(context)) != StatusCode::Ok) { | |
| return code; | |
| } | |
| } | |
| return StatusCode::Ok; | |
| } | |
| StatusCode LinearAnimation::onAddedClean(CoreContext* context) { | |
| StatusCode code; | |
| for (auto object : m_KeyedObjects) { | |
| if ((code = object->onAddedClean(context)) != StatusCode::Ok) { | |
| return code; | |
| } | |
| } | |
| return StatusCode::Ok; | |
| } | |
| void LinearAnimation::addKeyedObject(KeyedObject* object) { m_KeyedObjects.push_back(object); } | |
| void LinearAnimation::apply(Artboard* artboard, float time, float mix) const { | |
| for (auto object : m_KeyedObjects) { | |
| object->apply(artboard, time, mix); | |
| } | |
| } | |
| StatusCode LinearAnimation::import(ImportStack& importStack) { | |
| auto artboardImporter = importStack.latest<ArtboardImporter>(ArtboardBase::typeKey); | |
| if (artboardImporter == nullptr) { | |
| return StatusCode::MissingObject; | |
| } | |
| artboardImporter->addAnimation(this); | |
| return Super::import(importStack); | |
| } | |
| float LinearAnimation::startSeconds() const { | |
| return (enableWorkArea() ? workStart() : 0) / (float)fps(); | |
| } | |
| float LinearAnimation::endSeconds() const { | |
| return (enableWorkArea() ? workEnd() : duration()) / (float)fps(); | |
| } | |
| float LinearAnimation::durationSeconds() const { return endSeconds() - startSeconds(); } | |
| float LinearAnimation::globalToLocalSeconds(float seconds) const { | |
| switch (loop()) { | |
| case Loop::oneShot: | |
| return seconds + startSeconds(); | |
| case Loop::loop: | |
| return std::fmod(seconds, (endSeconds() - startSeconds())) + startSeconds(); | |
| case Loop::pingPong: | |
| float localTime = std::fmod(seconds, (endSeconds() - startSeconds())); | |
| int direction = ((int)(seconds / (endSeconds() - startSeconds()))) % 2; | |
| return direction == 0 ? localTime + startSeconds() : endSeconds() - localTime; | |
| } | |
| } |