Added StateMachine and pointer actions 04/282604/3
authorMichal Maciola <m.maciola@samsung.com>
Thu, 6 Oct 2022 09:52:55 +0000 (11:52 +0200)
committerMichal Maciola <m.maciola@samsung.com>
Wed, 2 Nov 2022 08:38:26 +0000 (09:38 +0100)
Added interfaces:
- pointerMove, pointerDown, pointerUp
- setNumberState, setBooleanState, fireState
- private useDefaultStateMachine
- private getStateMachine

Change-Id: I956a304dc0ab9b1e4f56e1cac31a4e858b1e7812

inc/rive_tizen.hpp
src/rive_tizen.cpp

index 8b1ade4d3c29fdca1861a3213390b0b425e2f312..fea5dc67d197c55551435171c7d545d8302d32d8 100644 (file)
@@ -4,6 +4,7 @@
 #include <rive/artboard.hpp>
 #include <rive/file.hpp>
 #include <rive/animation/linear_animation_instance.hpp>
+#include <rive/animation/state_machine.hpp>
 
 class RiveTizen {
     public:
@@ -25,6 +26,18 @@ class RiveTizen {
         bool setNodeScale(const std::string &name, float scale_x, float scale_y);
         bool setNodeRotation(const std::string &name, float degree);
         bool setNodePosition(const std::string &name, float position_x, float position_y);
+
+        void pointerMove(float x, float y);
+        void pointerDown(float x, float y);
+        void pointerUp(float x, float y);
+
+        bool setNumberState(const std::string& stateMachineName, const std::string& inputName, float value);
+        bool setBooleanState(const std::string& stateMachineName, const std::string& inputName, bool value);
+        bool fireState(const std::string& stateMachineName, const std::string& inputName);
+
+    private:
+        rive::StateMachine* getStateMachine(const std::string& stateMachineName);
+        void useDefaultStateMachine();
 };
 
 #endif // _RIVE_TIZEN_HPP_
index 5b8ad9d0fbc92c55a2cab700916450157d2a3bd9..7e723d5251c53d77f624100e1566a50cd83358a1 100644 (file)
 #include <rive/shapes/paint/stroke.hpp>
 #include <rive/shapes/paint/fill.hpp>
 #include <rive/artboard.hpp>
+#include <rive/animation/state_machine_instance.hpp>
+#include <rive/animation/state_machine_input_instance.hpp>
+#include <rive/animation/state_machine_bool.hpp>
+#include <rive/animation/state_machine_number.hpp>
+#include <rive/animation/state_machine_trigger.hpp>
 
 #ifdef LOG_TAG
 #undef LOG_TAG
@@ -43,6 +48,8 @@ static SkCanvas *mSkiaCanvas = nullptr;
 static rive::SkiaFactory mSkiaFactory;
 static std::unique_ptr<rive::File> mFile;
 static std::unique_ptr<rive::ArtboardInstance> mArtboardInstance;
+static std::unique_ptr<rive::StateMachineInstance> mCurrentScene;
+rive::Mat2D mInverseViewTransform;
 
 #ifdef USE_GL
 static sk_sp<GrDirectContext> mContext;
@@ -61,40 +68,39 @@ rive::Artboard *RiveTizen::getArtboard()
    return mArtboardInstance.get();
 }
 
-void RiveTizen::animationAdvanceApply(rive::LinearAnimationInstance *animation, double elapsed)
+rive::LinearAnimationInstance *RiveTizen::createLinearAnimationInstance(size_t index)
 {
+   auto animation = mArtboardInstance->animation(index);
+
    if (!animation)
    {
       LOGE("[Invalid parameter][animation == nullptr]");
-      return;
+      return nullptr;
    }
-   animation->advanceAndApply(elapsed);
-   animation->apply();
+
+   rive::LinearAnimationInstance *instance = new rive::LinearAnimationInstance(animation, mArtboardInstance.get());
+   return instance;
 }
 
-void RiveTizen::animationApply(rive::LinearAnimationInstance *animation, double elapsed)
+void RiveTizen::animationAdvanceApply(rive::LinearAnimationInstance *animation, double elapsed)
 {
    if (!animation)
    {
       LOGE("[Invalid parameter][animation == nullptr]");
       return;
    }
-   animation->time(elapsed);
+   animation->advanceAndApply(elapsed);
    animation->apply();
 }
 
-rive::LinearAnimationInstance *RiveTizen::createLinearAnimationInstance(size_t index)
+void RiveTizen::animationApply(rive::LinearAnimationInstance *animation, double elapsed)
 {
-   auto animation = mArtboardInstance->animation(index);
-
    if (!animation)
    {
       LOGE("[Invalid parameter][animation == nullptr]");
-      return nullptr;
+      return;
    }
-
-   rive::LinearAnimationInstance *instance = new rive::LinearAnimationInstance(animation, mArtboardInstance.get());
-   return instance;
+   animation->time(elapsed);
 }
 
 bool RiveTizen::loadRiveResource(uint8_t *bytes, size_t size)
@@ -114,6 +120,8 @@ bool RiveTizen::loadRiveResource(uint8_t *bytes, size_t size)
    mArtboardInstance = mFile->artboardDefault();
    mArtboardInstance->advance(0.0f);
 
+   useDefaultStateMachine();
+
    return true;
 }
 
@@ -160,7 +168,15 @@ bool RiveTizen::render(double elapsed, unsigned int width, unsigned int height)
                                                rive::AABB(0, 0, width, height), mArtboardInstance->bounds());
 
    renderer.transform(viewTransform);
-   mArtboardInstance->draw(&renderer);
+   mInverseViewTransform = viewTransform.invertOrIdentity();
+
+   if (mCurrentScene) {
+      mCurrentScene->advanceAndApply(elapsed);
+      mCurrentScene->draw(&renderer);
+   } else {
+      mArtboardInstance->draw(&renderer);
+   }
+
    renderer.restore();
 
 #ifdef USE_GL
@@ -233,3 +249,101 @@ bool RiveTizen::setNodePosition(const std::string &name, float position_x, float
    nodeInstance->y(position_y);
    return true;
 }
+
+void RiveTizen::pointerMove(float x, float y) {
+   if (!mCurrentScene) return;
+   auto pointer = mInverseViewTransform * rive::Vec2D(x, y);
+   mCurrentScene->pointerMove(pointer);
+}
+
+void RiveTizen::pointerDown(float x, float y) {
+   if (!mCurrentScene) return;
+   auto pointer = mInverseViewTransform * rive::Vec2D(x, y);
+   mCurrentScene->pointerDown(pointer);
+}
+
+void RiveTizen::pointerUp(float x, float y) {
+   if (!mCurrentScene) return;
+   auto pointer = mInverseViewTransform * rive::Vec2D(x, y);
+   mCurrentScene->pointerUp(pointer);
+}
+
+bool RiveTizen::setNumberState(const std::string& stateMachineName, const std::string& inputName, float value) {
+   auto sm = getStateMachine(stateMachineName);
+   if (!sm) return false;
+
+   auto smi = std::make_unique<rive::StateMachineInstance>(sm, mArtboardInstance.get());
+   auto number = smi->getNumber(inputName);
+   if (!number) {
+      LOGE("Number state \"%s\" not found.", inputName.c_str());
+      return false;
+   }
+
+   number->value(value);
+   mCurrentScene = std::move(smi);
+   return true;
+}
+
+bool RiveTizen::setBooleanState(const std::string& stateMachineName, const std::string& inputName, bool value) {
+   auto sm = getStateMachine(stateMachineName);
+   if (!sm) return false;
+
+   auto smi = std::make_unique<rive::StateMachineInstance>(sm, mArtboardInstance.get());
+   auto boolean = smi->getBool(inputName);
+   if (!boolean) {
+      LOGE("Boolean state \"%s\" not found.", inputName.c_str());
+      return false;
+   }
+
+   boolean->value(value);
+   mCurrentScene = std::move(smi);
+   return true;
+}
+
+bool RiveTizen::fireState(const std::string& stateMachineName, const std::string& inputName) {
+   auto sm = getStateMachine(stateMachineName);
+   if (!sm) return false;
+
+   auto smi = std::make_unique<rive::StateMachineInstance>(sm, mArtboardInstance.get());
+   auto trigger = smi->getTrigger(inputName);
+   if (!trigger) {
+      LOGE("Trigger state \"%s\" not found.", inputName.c_str());
+      return false;
+   }
+
+   trigger->fire();
+   mCurrentScene = std::move(smi);
+   return true;
+}
+
+rive::StateMachine* RiveTizen::getStateMachine(const std::string& stateMachineName) {
+   rive::StateMachine* sm = nullptr;
+   if (!stateMachineName.empty()) {
+      sm = mArtboardInstance->stateMachine(stateMachineName);
+      if (!sm) {
+         LOGE("StateMachine named \"%s\" not found.", stateMachineName.c_str());
+      }
+   } else {
+      const int index = mArtboardInstance->defaultStateMachineIndex();
+      if (index >= 0) {
+         sm = mArtboardInstance->stateMachine(index);
+      } else {
+         LOGE("No default stateMachine.");
+      }
+   }
+   return sm;
+}
+
+void RiveTizen::useDefaultStateMachine() {
+   mCurrentScene = mArtboardInstance->defaultStateMachine();
+   if (!mCurrentScene) {
+      int index = mArtboardInstance->defaultStateMachineIndex();
+      if (index >= mArtboardInstance->stateMachineCount()) index = 0;
+      if (index >= 0) mCurrentScene = mArtboardInstance->stateMachineAt(index);
+   }
+   if (mCurrentScene) {
+      mCurrentScene->inputCount();
+   } else {
+      LOGE("No default stateMachine");
+   }
+}