hack up main to test hittesting
diff --git a/skia/viewer/src/main.cpp b/skia/viewer/src/main.cpp
index a64d569..2023a41 100644
--- a/skia/viewer/src/main.cpp
+++ b/skia/viewer/src/main.cpp
@@ -22,6 +22,7 @@
#include "rive/artboard.hpp"
#include "rive/file.hpp"
#include "rive/layout.hpp"
+#include "rive/nested_artboard.hpp"
#include "rive/math/aabb.hpp"
#include "skia_renderer.hpp"
@@ -32,6 +33,9 @@
#include <stdio.h>
std::string filename;
+const char* artboardName = "Bullet Man";
+const char* animationName;
+
rive::File* currentFile = nullptr;
rive::Artboard* artboard = nullptr;
rive::StateMachineInstance* stateMachineInstance = nullptr;
@@ -54,7 +58,10 @@
fprintf(stderr, "failed to import file\n");
return;
}
- auto sourceArtboard = file->artboard();
+ auto sourceArtboard = file->artboard(artboardName);
+ if (!sourceArtboard) {
+ sourceArtboard = file->artboard();
+ }
// Artboard should always be instance and hence must be deleted.
delete artboard;
artboard = sourceArtboard->instance();
@@ -76,6 +83,41 @@
currentFile = file;
}
+static void dump_inputs(rive::StateMachine* machine) {
+ std::unique_ptr<rive::StateMachineInstance> inst(new rive::StateMachineInstance(machine));
+
+ printf("state machine: %s needs advance %d\n",
+ machine->name().c_str(), inst->needsAdvance());
+
+ for (size_t i = 0; i < inst->inputCount(); ++i) {
+ rive::SMIInput* input = inst->input(i);
+ auto input_inst = input->input();
+ const char* name = input_inst->name().c_str();
+ if (input_inst->is<rive::StateMachineNumber>()) {
+ printf(" number: %s\n", name);
+ }
+ else if (input_inst->is<rive::StateMachineBool>()) {
+ printf(" bool: %s\n", name);
+ }
+ else if (input_inst->is<rive::StateMachineTrigger>()) {
+ printf(" trigger: %s\n", name);
+ }
+ }
+}
+
+static void dump_machines(rive::Artboard* artboard) {
+ for (size_t i = 0; i < artboard->stateMachineCount(); ++i) {
+ auto machine = artboard->stateMachine(i);
+ dump_inputs(machine);
+ }
+}
+
+static void fire(rive::StateMachineInstance* smi, const char trigger[]) {
+ auto tr = smi->getTrigger(trigger);
+ assert(tr);
+ tr->fire();
+}
+
void initAnimation(int index) {
animationIndex = index;
stateMachineIndex = -1;
@@ -88,7 +130,12 @@
fprintf(stderr, "failed to import file\n");
return;
}
- auto sourceArtboard = file->artboard();
+ auto sourceArtboard = file->artboard(artboardName);
+ if (!sourceArtboard) {
+ sourceArtboard = file->artboard();
+ }
+ dump_machines(sourceArtboard);
+
// Artboard should always be instance and hence must be deleted.
delete artboard;
artboard = sourceArtboard->instance();
@@ -108,6 +155,8 @@
}
currentFile = file;
+
+ initStateMachine(0);
}
void glfwErrorCallback(int error, const char* description) {
@@ -116,6 +165,7 @@
void glfwDropCallback(GLFWwindow* window, int count, const char** paths) {
// Just get the last dropped file for now...
+ printf("dropcallback %d %s\n", count, paths[count-1]);
filename = paths[count - 1];
FILE* fp = fopen(filename.c_str(), "r");
@@ -132,7 +182,90 @@
initAnimation(0);
}
-int main() {
+static bool handle_click(rive::Artboard* artboard, const char name[]) {
+ const struct {
+ const char* click;
+ const char* machine;
+ const char* trigger;
+ } triggers[] = {
+ { "hand-wick", "State Machine 1", "Light", },
+ { "hand-fire", "State Machine 1", "Cannon", },
+ { "hand-helmet", "State Machine 1", "Helmet", },
+ };
+
+ for (const auto& t : triggers) {
+ if (strcmp(name, t.click) == 0) {
+ printf("found\n");
+ fire(stateMachineInstance, t.trigger);
+ return true;
+ }
+ }
+ return false;
+}
+
+static void test_hittest(rive::Artboard* artboard, const SkMatrix& ctm) {
+ const auto mouse = ImGui::GetMousePos();
+
+ SkMatrix inv;
+ (void)ctm.invert(&inv);
+ auto pt = inv.mapXY(mouse.x * 2, mouse.y * 2);
+
+ const auto bounds = artboard->bounds();
+ if (pt.x() < bounds.left() || pt.x() >= bounds.right() ||
+ pt.y() < bounds.top() || pt.y() >= bounds.bottom()) {
+ return;
+ }
+
+ rive::HitInfo hinfo;
+ hinfo.area = rive::AABB(pt.fX - 1, pt.fY - 1, pt.fX + 2, pt.fY + 2).round();
+
+ static rive::Core* gPrev;
+
+ auto node = artboard->hitTest(&hinfo);
+ if (node != gPrev) {
+ gPrev = node;
+ const char* name = nullptr;
+ if (node) {
+ assert(node->is<rive::Component>());
+
+ name = node->as<rive::Component>()->name().c_str();
+ printf("(%s) mounts [ ", name);
+ for (auto na : hinfo.mounts) {
+ const char* naname = nullptr;
+ if (na) {
+ naname = na->name().c_str();
+ }
+ printf("(%s) ", naname);
+ }
+ printf("]\n");
+
+ if (hinfo.mounts.size() == 1) {
+ handle_click(artboard, hinfo.mounts[0]->name().c_str());
+ }
+ } else {
+ printf("no hit\n");
+ }
+ }
+}
+
+int main(int argc, const char* argv[]) {
+ for (int i = 1; i < argc; ++i) {
+ if (strcmp(argv[i], "--file") == 0) {
+ filename = argv[++i];
+ printf("file %s\n", filename.c_str());
+ continue;
+ }
+ if (strcmp(argv[i], "--artboard") == 0) {
+ artboardName = argv[++i];
+ printf("artb %s\n", artboardName);
+ continue;
+ }
+ if (strcmp(argv[i], "--animation") == 0) {
+ animationName = argv[++i];
+ continue;
+ }
+ }
+
if (!glfwInit()) {
fprintf(stderr, "Failed to initialize glfw.\n");
return 1;
@@ -250,8 +383,12 @@
rive::Alignment::center,
rive::AABB(0, 0, width, height),
artboard->bounds());
+ auto mx = canvas->getTotalMatrix();
+
artboard->draw(&renderer);
renderer.restore();
+
+ test_hittest(artboard, mx);
}
context->flush();
@@ -373,4 +510,4 @@
glfwTerminate();
return 0;
-}
\ No newline at end of file
+}