Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Impeller] Move SeparatedVector2 to impeller/geometry. #53264

Merged
merged 3 commits into from
Jun 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -42151,6 +42151,8 @@ ORIGIN: ../../../flutter/impeller/geometry/rect.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/rect.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/saturated_math.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/scalar.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/separated_vector.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/separated_vector.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/shear.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/shear.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/sigma.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -45017,6 +45019,8 @@ FILE: ../../../flutter/impeller/geometry/rect.cc
FILE: ../../../flutter/impeller/geometry/rect.h
FILE: ../../../flutter/impeller/geometry/saturated_math.h
FILE: ../../../flutter/impeller/geometry/scalar.h
FILE: ../../../flutter/impeller/geometry/separated_vector.cc
FILE: ../../../flutter/impeller/geometry/separated_vector.h
FILE: ../../../flutter/impeller/geometry/shear.cc
FILE: ../../../flutter/impeller/geometry/shear.h
FILE: ../../../flutter/impeller/geometry/sigma.cc
Expand Down
49 changes: 9 additions & 40 deletions impeller/entity/geometry/stroke_path_geometry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "impeller/geometry/constants.h"
#include "impeller/geometry/path_builder.h"
#include "impeller/geometry/path_component.h"
#include "impeller/geometry/separated_vector.h"

namespace impeller {
using VS = SolidFillVertexShader;
Expand Down Expand Up @@ -163,45 +164,13 @@ class StrokeGenerator {
}
}

/// @brief Represents a ray in 2D space.
///
/// This is a simple convenience struct for handling polyline offset
/// values when generating stroke geometry. For performance reasons,
/// it's sometimes adventageous to track the direction and magnitude
/// for offsets separately.
struct Ray {
/// The normalized direction of the ray.
Vector2 direction;

/// The magnitude of the ray.
Scalar magnitude = 0.0;

/// Returns the vector representation of the ray.
Vector2 GetVector() const { return direction * magnitude; }

/// Returns the scalar alignment of the two rays.
///
/// Domain: [-1, 1]
/// A value of 1 indicates the rays are parallel and pointing in the same
/// direction. A value of -1 indicates the rays are parallel and pointing in
/// opposite directions. A value of 0 indicates the rays are perpendicular.
Scalar GetAlignment(const Ray& other) const {
return direction.Dot(other.direction);
}

/// Returns the scalar angle between the two rays.
Radians AngleTo(const Ray& other) const {
return direction.AngleTo(other.direction);
}
};

/// Computes offset by calculating the direction from point_i - 1 to point_i
/// if point_i is within `contour_start_point_i` and `contour_end_point_i`;
/// Otherwise, it uses direction from contour.
Ray ComputeOffset(const size_t point_i,
const size_t contour_start_point_i,
const size_t contour_end_point_i,
const Path::PolylineContour& contour) const {
SeparatedVector2 ComputeOffset(const size_t point_i,
const size_t contour_start_point_i,
const size_t contour_end_point_i,
const Path::PolylineContour& contour) const {
Point direction;
if (point_i >= contour_end_point_i) {
direction = contour.end_direction;
Expand All @@ -211,8 +180,8 @@ class StrokeGenerator {
direction = (polyline.GetPoint(point_i) - polyline.GetPoint(point_i - 1))
.Normalize();
}
return {.direction = Vector2{-direction.y, direction.x},
.magnitude = stroke_width * 0.5f};
return SeparatedVector2(Vector2{-direction.y, direction.x},
stroke_width * 0.5f);
}

void AddVerticesForLinearComponent(VertexWriter& vtx_builder,
Expand Down Expand Up @@ -338,8 +307,8 @@ class StrokeGenerator {
const CapProc<VertexWriter>& cap_proc;
const Scalar scale;

Ray previous_offset;
Ray offset;
SeparatedVector2 previous_offset;
SeparatedVector2 offset;
SolidFillVertexShader::PerVertexData vtx;
};

Expand Down
2 changes: 2 additions & 0 deletions impeller/geometry/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ impeller_component("geometry") {
"rect.h",
"saturated_math.h",
"scalar.h",
"separated_vector.cc",
"separated_vector.h",
"shear.cc",
"shear.h",
"sigma.cc",
Expand Down
51 changes: 51 additions & 0 deletions impeller/geometry/geometry_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "impeller/geometry/point.h"
#include "impeller/geometry/rect.h"
#include "impeller/geometry/scalar.h"
#include "impeller/geometry/separated_vector.h"
#include "impeller/geometry/size.h"

// TODO(zanderso): https://github.com/flutter/flutter/issues/127701
Expand Down Expand Up @@ -1141,6 +1142,56 @@ TEST(GeometryTest, Vector4Lerp) {
ASSERT_VECTOR4_NEAR(result, expected);
}

TEST(GeometryTest, SeparatedVector2NormalizesWithConstructor) {
SeparatedVector2 v(Vector2(10, 0));
ASSERT_POINT_NEAR(v.direction, Vector2(1, 0));
ASSERT_NEAR(v.magnitude, 10, kEhCloseEnough);
}

TEST(GeometryTest, SeparatedVector2GetVector) {
SeparatedVector2 v(Vector2(10, 0));
ASSERT_POINT_NEAR(v.GetVector(), Vector2(10, 0));
}

TEST(GeometryTest, SeparatedVector2GetAlignment) {
// Parallel
{
SeparatedVector2 v(Vector2(10, 0));
Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(5, 0)));
ASSERT_NEAR(actual, 1, kEhCloseEnough);
}

// Perpendicular
{
SeparatedVector2 v(Vector2(10, 0));
Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(0, 5)));
ASSERT_NEAR(actual, 0, kEhCloseEnough);
}

// Opposite parallel
{
SeparatedVector2 v(Vector2(0, 10));
Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(0, -5)));
ASSERT_NEAR(actual, -1, kEhCloseEnough);
}
}

TEST(GeometryTest, SeparatedVector2AngleTo) {
{
SeparatedVector2 v(Vector2(10, 0));
Radians actual = v.AngleTo(SeparatedVector2(Vector2(5, 0)));
Radians expected = Radians{0};
ASSERT_NEAR(actual.radians, expected.radians, kEhCloseEnough);
}

{
SeparatedVector2 v(Vector2(10, 0));
Radians actual = v.AngleTo(SeparatedVector2(Vector2(0, -5)));
Radians expected = Radians{-kPi / 2};
ASSERT_NEAR(actual.radians, expected.radians, kEhCloseEnough);
}
}

TEST(GeometryTest, CanUseVector3AssignmentOperators) {
{
Vector3 p(1, 2, 4);
Expand Down
29 changes: 29 additions & 0 deletions impeller/geometry/separated_vector.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "separated_vector.h"

namespace impeller {

SeparatedVector2::SeparatedVector2() = default;

SeparatedVector2::SeparatedVector2(Vector2 direction, Scalar magnitude)
: direction(direction), magnitude(magnitude){};

SeparatedVector2::SeparatedVector2(Vector2 vector)
: direction(vector.Normalize()), magnitude(vector.GetLength()){};

Vector2 SeparatedVector2::GetVector() const {
return direction * magnitude;
}

Scalar SeparatedVector2::GetAlignment(const SeparatedVector2& other) const {
return direction.Dot(other.direction);
}

Radians SeparatedVector2::AngleTo(const SeparatedVector2& other) const {
return direction.AngleTo(other.direction);
}

} // namespace impeller
51 changes: 51 additions & 0 deletions impeller/geometry/separated_vector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_IMPELLER_GEOMETRY_SEPARATED_VECTOR_H_
#define FLUTTER_IMPELLER_GEOMETRY_SEPARATED_VECTOR_H_

#include "impeller/geometry/point.h"

#include "impeller/geometry/scalar.h"

namespace impeller {

/// @brief A Vector2, broken down as a separate magnitude and direction.
/// Assumes that the direction given is normalized.
///
/// This is a simple convenience struct for handling polyline offset
/// values when generating stroke geometry. For performance reasons,
/// it's sometimes adventageous to track the direction and magnitude
/// for offsets separately.
struct SeparatedVector2 {
/// The normalized direction of the vector.
Vector2 direction;

/// The magnitude of the vector.
Scalar magnitude = 0.0;

SeparatedVector2();
SeparatedVector2(Vector2 direction, Scalar magnitude);
explicit SeparatedVector2(Vector2 vector);

/// Returns the vector representation of the vector.
Vector2 GetVector() const;

/// Returns the scalar alignment of the two vectors.
/// In other words, the dot product of the two normalized vectors.
///
/// Range: [-1, 1]
/// A value of 1 indicates the directions are parallel and pointing in the
/// same direction. A value of -1 indicates the vectors are parallel and
/// pointing in opposite directions. A value of 0 indicates the vectors are
/// perpendicular.
Scalar GetAlignment(const SeparatedVector2& other) const;

/// Returns the scalar angle between the two rays.
Radians AngleTo(const SeparatedVector2& other) const;
};

#endif // FLUTTER_IMPELLER_GEOMETRY_SEPARATED_VECTOR_H_

} // namespace impeller