From: Taehyub Kim Date: Thu, 11 Mar 2021 08:25:47 +0000 (+0900) Subject: renderer, example: implments shape animation X-Git-Tag: submit/tizen/20210406.060732~16^2~16 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=93ff0c1c7e8cbc92f478c7b5153df7c5715fd94e;p=platform%2Fcore%2Fuifw%2Frive-tizen.git renderer, example: implments shape animation --- diff --git a/example/rive_viewer.cpp b/example/rive_viewer.cpp index f879228..5cae43f 100644 --- a/example/rive_viewer.cpp +++ b/example/rive_viewer.cpp @@ -13,8 +13,13 @@ using namespace std; #define HEIGHT 700 static unique_ptr canvas; +static tvg::Canvas *renderCanvas; +static rive::File* file = nullptr; static rive::Artboard* artboard = nullptr; static rive::LinearAnimationInstance* animationInstance = nullptr; +static Ecore_Animator *animator = nullptr; +static Eo* view = nullptr; +static double lastTime; static void deleteWindow(void *data, Evas_Object *obj, void *ev) { @@ -29,11 +34,40 @@ static void drawToCanvas(void* data, Eo* obj) } } +Eina_Bool animationLoop(void *data) +{ + double currentTime = ecore_time_get(); + float elapsed = currentTime - lastTime; + static float animationTime = 0; + lastTime = currentTime; + + if (artboard != nullptr) + { + if (animationInstance != nullptr) + { + animationInstance->advance(elapsed); + animationInstance->apply(artboard); + } + artboard->advance(elapsed); + + rive::TvgRenderer renderer(renderCanvas); + renderer.save(); + artboard->draw(&renderer); + renderer.restore(); + } + + evas_object_image_pixels_dirty_set(view, EINA_TRUE); + evas_object_image_data_update_add(view, 0, 0, WIDTH, HEIGHT); + + return ECORE_CALLBACK_RENEW; +} + static void runExample(uint32_t* buffer) { //Create a Canvas canvas = tvg::SwCanvas::gen(); canvas->target(buffer, WIDTH, WIDTH, HEIGHT, tvg::SwCanvas::ARGB8888); + renderCanvas = canvas.get(); // Load Rive File const char* filename = "../../example/shapes.riv"; @@ -52,7 +86,6 @@ static void runExample(uint32_t* buffer) } auto reader = rive::BinaryReader(bytes, length); - rive::File* file = nullptr; auto result = rive::File::import(reader, &file); if (result != rive::ImportResult::success) { @@ -62,6 +95,7 @@ static void runExample(uint32_t* buffer) } artboard = file->artboard(); + artboard->advance(0.0f); delete animationInstance; @@ -69,27 +103,23 @@ static void runExample(uint32_t* buffer) if (animation != nullptr) { animationInstance = new rive::LinearAnimationInstance(animation); - animationInstance->advance(0); } else { animationInstance = nullptr; } - rive::TvgRenderer renderer(canvas.get()); - - renderer.save(); - artboard->advance(0); - artboard->draw(&renderer); - renderer.restore(); + lastTime = ecore_time_get(); + ecore_animator_frametime_set(1. / 60); + animator = ecore_animator_add(animationLoop, nullptr); delete[] bytes; - delete file; } static void cleanExample() { + delete file; delete animationInstance; } @@ -99,7 +129,7 @@ static void setupScreen(uint32_t* buffer) Eo* win = elm_win_util_standard_add(NULL, "Rive Viewer"); evas_object_smart_callback_add(win, "delete,request", deleteWindow, 0); - Eo* view = evas_object_image_filled_add(evas_object_evas_get(win)); + view = evas_object_image_filled_add(evas_object_evas_get(win)); evas_object_image_size_set(view, WIDTH, HEIGHT); evas_object_image_data_set(view, buffer); evas_object_image_pixels_get_callback_set(view, drawToCanvas, nullptr); diff --git a/example/shapes.riv b/example/shapes.riv index 73e0d73..ec610a1 100644 Binary files a/example/shapes.riv and b/example/shapes.riv differ diff --git a/src/renderer/include/thorvg_renderer.hpp b/src/renderer/include/thorvg_renderer.hpp index 1fc1c4c..9b86fa6 100644 --- a/src/renderer/include/thorvg_renderer.hpp +++ b/src/renderer/include/thorvg_renderer.hpp @@ -10,11 +10,6 @@ using namespace std; namespace rive { - struct TvgPoint - { - float x, y; - }; - struct TvgPaint { int fillColor[4]; @@ -32,7 +27,7 @@ namespace rive private: Shape *m_Shape; vector m_PathType; - vector m_PathPoints; + vector m_PathPoints; bool m_Pushed = false; public: diff --git a/src/renderer/src/thorvg_renderer.cpp b/src/renderer/src/thorvg_renderer.cpp index e72076d..a2ad0b9 100644 --- a/src/renderer/src/thorvg_renderer.cpp +++ b/src/renderer/src/thorvg_renderer.cpp @@ -21,10 +21,28 @@ void TvgRenderPath::fillRule(FillRule value) } } +Vec2D applyTransform(const Vec2D &vec, const Mat2D &mat) +{ + tvg::Matrix m = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + m.e11 = mat[0]; + m.e12 = mat[2]; + m.e13 = mat[4]; + m.e21 = mat[1]; + m.e22 = mat[3]; + m.e23 = mat[5]; + + Vec2D ret; + ret[0] = round(vec[0] * m.e11 + vec[1] * m.e12 + m.e13); + ret[1] = round(vec[0] * m.e21 + vec[1] * m.e22 + m.e23); + + return ret; +} + void TvgRenderPath::addRenderPath(RenderPath* path, const Mat2D& transform) { auto m_PathType = reinterpret_cast(path)->m_PathType; auto m_PathPoints = reinterpret_cast(path)->m_PathPoints; + Vec2D vec1, vec2, vec3, vecOut1, vecOut2, vecOut3; int index = 0; for (size_t i = 0; i < m_PathType.size(); i++) @@ -33,17 +51,22 @@ void TvgRenderPath::addRenderPath(RenderPath* path, const Mat2D& transform) switch(type) { case PathCommand::MoveTo: - m_Shape->moveTo(m_PathPoints[index].x, m_PathPoints[index].y); + vecOut1 = applyTransform(m_PathPoints[index], transform); + m_Shape->moveTo(vecOut1[0], vecOut1[1]); index += 1; break; case PathCommand::LineTo: - m_Shape->lineTo(m_PathPoints[index].x, m_PathPoints[index].y); + vecOut1 = applyTransform(m_PathPoints[index], transform); + m_Shape->lineTo(vecOut1[0], vecOut1[1]); index += 1; break; case PathCommand::CubicTo: - m_Shape->cubicTo(m_PathPoints[index].x, m_PathPoints[index].y, - m_PathPoints[index+1].x, m_PathPoints[index+1].y, - m_PathPoints[index+2].x, m_PathPoints[index+2].y); + vecOut1 = applyTransform(m_PathPoints[index], transform); + vecOut2 = applyTransform(m_PathPoints[index + 1], transform); + vecOut3 = applyTransform(m_PathPoints[index + 2], transform); + m_Shape->cubicTo(vecOut1[0], vecOut1[1], + vecOut2[0], vecOut2[1], + vecOut3[0], vecOut3[1]); index += 3; break; case PathCommand::Close: @@ -55,6 +78,7 @@ void TvgRenderPath::addRenderPath(RenderPath* path, const Mat2D& transform) void TvgRenderPath::reset() { + m_Shape->reset(); m_PathType.clear(); m_PathPoints.clear(); } @@ -245,4 +269,4 @@ namespace rive { RenderPath* makeRenderPath() { return new TvgRenderPath();} RenderPaint* makeRenderPaint() { return new TvgRenderPaint();} -} \ No newline at end of file +}