Skip to content

Commit

Permalink
editor and runtime: fix vector n-slicer hit area
Browse files Browse the repository at this point in the history
This PR changes the vector slicing world upside-down (or outside in)! (hehe :P)

Before this PR, on the editor, when you are trying to alt-select a shape in a vector n-slicer, you have to hover over the original shape's position to get the box to show up. I was trying to fix this when I realized that there are many places where the bounds of the shape is checked. E.g. in the state machine, the bounds of the shape is used to detect hover listeners. There were too many places to audit, so that's when I realized I wanted to deform directly on the path instead of just at the rendering layer in the path composer.

Path can be categorized into points path and parametric paths (e.g. rects, ellipses, stars). Points path can be deformed by skin. The skin deformation is at the update level of the points path, before the super's update. So by changing _buildPath directly, the deformation happens after skin, which is the same sequence as what's on master today.

As such, there are two places I changed on the editor
1. I moved the deforming logic from path_composer to path directly, to preserve the rendering behavior.
2. I changed hit testing logic, so the bounds are computed correctly

on the runtime side, I just had to change 1, since 2 is done on the raw path directly, so it just worked.

Demo. Left is the current behavior, note that you have to hover over the original button's bounds to get the leaves to show. The right side is after this PR, right+up for editor, right+down for runtime.
![a4](https://github.com/user-attachments/assets/6128c202-0a2a-491a-875d-cbc4571f2128)

Diffs=
8826406ff1 editor and runtime: fix vector n-slicer hit area (#8512)

Co-authored-by: Susan Wang <[email protected]>
  • Loading branch information
susan101566 and susan101566 committed Nov 8, 2024
1 parent 308c1f1 commit 3ff5ac9
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .rive_head
Original file line number Diff line number Diff line change
@@ -1 +1 @@
98e6822f02c4935577ee4d7509b3243802260603
8826406ff178cf3e63341087d1611811cc32ced5
2 changes: 2 additions & 0 deletions include/rive/shapes/path.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace rive
{
class Shape;
class PathVertex;
class RenderPathDeformer;

#ifdef ENABLE_QUERY_FLAT_VERTICES
/// Optionally compiled in for tools that need to compute per frame world
Expand Down Expand Up @@ -42,6 +43,7 @@ class Path : public PathBase
bool m_deferredPathDirt = false;
PathFlags m_pathFlags = PathFlags::none;
RawPath m_rawPath;
RenderPathDeformer* deformer() const;

public:
Shape* shape() const { return m_Shape; }
Expand Down
23 changes: 22 additions & 1 deletion src/shapes/path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "rive/renderer.hpp"
#include "rive/shapes/cubic_vertex.hpp"
#include "rive/shapes/cubic_detached_vertex.hpp"
#include "rive/shapes/deformer.hpp"
#include "rive/shapes/path_vertex.hpp"
#include "rive/shapes/shape.hpp"
#include "rive/shapes/straight_vertex.hpp"
Expand All @@ -28,6 +29,15 @@ static float computeIdealControlPointDistance(const Vec2D& toPrev,
(angle < math::PI / 2 ? 1 + cos(angle) : 2.0f - sin(angle)));
}

RenderPathDeformer* Path::deformer() const
{
if (m_Shape != nullptr)
{
return m_Shape->deformer();
}
return nullptr;
}

StatusCode Path::onAddedClean(CoreContext* context)
{
StatusCode code = Super::onAddedClean(context);
Expand Down Expand Up @@ -252,6 +262,14 @@ void Path::buildPath(RawPath& rawPath) const
}
rawPath.close();
}

RenderPathDeformer* pathDeformer = deformer();
if (pathDeformer != nullptr)
{
Mat2D transform = pathTransform();
Mat2D inverse = transform.invertOrIdentity();
pathDeformer->deformLocalRenderPath(rawPath, transform, inverse);
}
}

void Path::markPathDirty(bool sendToLayout)
Expand Down Expand Up @@ -279,7 +297,10 @@ void Path::update(ComponentDirt value)
{
Super::update(value);

if (hasDirt(value, ComponentDirt::Path))
bool pathChanged = hasDirt(value, ComponentDirt::Path);
bool worldTransformChanged = hasDirt(value, ComponentDirt::WorldTransform);

if (pathChanged || (deformer() != nullptr && worldTransformChanged))
{
if (canDeferPathUpdate())
{
Expand Down
13 changes: 0 additions & 13 deletions src/shapes/path_composer.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "rive/shapes/path_composer.hpp"
#include "rive/artboard.hpp"
#include "rive/renderer.hpp"
#include "rive/shapes/deformer.hpp"
#include "rive/shapes/path.hpp"
#include "rive/shapes/shape.hpp"
#include "rive/factory.hpp"
Expand Down Expand Up @@ -68,13 +67,6 @@ void PathComposer::update(ComponentDirt value)
}
}

if (const RenderPathDeformer* deformer = m_shape->deformer())
{
deformer->deformLocalRenderPath(m_localRawPath,
world,
inverseWorld);
}

// TODO: add a CommandPath::copy(RawPath)
m_localRawPath.addTo(m_localPath.get());
}
Expand All @@ -98,11 +90,6 @@ void PathComposer::update(ComponentDirt value)
}
}

if (const RenderPathDeformer* deformer = m_shape->deformer())
{
deformer->deformWorldRenderPath(m_worldRawPath);
}

// TODO: add a CommandPath::copy(RawPath)
m_worldRawPath.addTo(m_worldPath.get());
}
Expand Down

0 comments on commit 3ff5ac9

Please sign in to comment.