From af38a0cf871efcf30d102f1be8075211d20be2f4 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 25 Mar 2019 12:00:31 -0700 Subject: [PATCH] Fabric: `Transform` type was moved to `graphics` module. Summary: We will use it inside `core` module, so we have to decouple it from `view`. As part of this, I added some comments, changed `const Float &` to just `Float` and put the implementation into `.cpp` file. Reviewed By: mdvacca Differential Revision: D14593952 fbshipit-source-id: 80f7746f4fc5b95febc8df9f5a9c0386a6425c88 --- React/Fabric/RCTConversions.h | 3 +- .../fabric/components/view/ViewProps.h | 1 + .../fabric/components/view/conversions.h | 1 + .../fabric/components/view/primitives.h | 161 ------------------ ReactCommon/fabric/graphics/Transform.cpp | 153 +++++++++++++++++ ReactCommon/fabric/graphics/Transform.h | 97 +++++++++++ 6 files changed, 254 insertions(+), 162 deletions(-) create mode 100644 ReactCommon/fabric/graphics/Transform.cpp create mode 100644 ReactCommon/fabric/graphics/Transform.h diff --git a/React/Fabric/RCTConversions.h b/React/Fabric/RCTConversions.h index 1f0716eed..12f2aa483 100644 --- a/React/Fabric/RCTConversions.h +++ b/React/Fabric/RCTConversions.h @@ -8,10 +8,11 @@ #import -#import #import +#import #import #import +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ReactCommon/fabric/components/view/ViewProps.h b/ReactCommon/fabric/components/view/ViewProps.h index 5259a85fd..c026db5b7 100644 --- a/ReactCommon/fabric/components/view/ViewProps.h +++ b/ReactCommon/fabric/components/view/ViewProps.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace facebook { namespace react { diff --git a/ReactCommon/fabric/components/view/conversions.h b/ReactCommon/fabric/components/view/conversions.h index 4599d87ea..a926f5ab3 100644 --- a/ReactCommon/fabric/components/view/conversions.h +++ b/ReactCommon/fabric/components/view/conversions.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/ReactCommon/fabric/components/view/primitives.h b/ReactCommon/fabric/components/view/primitives.h index d7900c232..bdfd018c0 100644 --- a/ReactCommon/fabric/components/view/primitives.h +++ b/ReactCommon/fabric/components/view/primitives.h @@ -16,167 +16,6 @@ namespace facebook { namespace react { -struct Transform { - std::array matrix{ - {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}}; - - static Transform Identity() { - return {}; - } - - static Transform Perspective(const Float &perspective) { - auto transform = Transform{}; - transform.matrix[11] = -1.0 / perspective; - return transform; - } - - static Transform - Scale(const Float &factorX, const Float &factorY, const Float &factorZ) { - auto transform = Transform{}; - transform.matrix[0] = factorX; - transform.matrix[5] = factorY; - transform.matrix[10] = factorZ; - return transform; - } - - static Transform Translate(const Float &x, const Float &y, const Float &z) { - auto transform = Transform{}; - transform.matrix[12] = x; - transform.matrix[13] = y; - transform.matrix[14] = z; - return transform; - } - - static Transform Skew(const Float &x, const Float &y) { - auto transform = Transform{}; - transform.matrix[4] = std::tan(x); - transform.matrix[1] = std::tan(y); - return transform; - } - - static Transform RotateX(const Float &radians) { - auto transform = Transform{}; - transform.matrix[5] = std::cos(radians); - transform.matrix[6] = std::sin(radians); - transform.matrix[9] = -std::sin(radians); - transform.matrix[10] = std::cos(radians); - return transform; - } - - static Transform RotateY(const Float &radians) { - auto transform = Transform{}; - transform.matrix[0] = std::cos(radians); - transform.matrix[2] = -std::sin(radians); - transform.matrix[8] = std::sin(radians); - transform.matrix[10] = std::cos(radians); - return transform; - } - - static Transform RotateZ(const Float &radians) { - auto transform = Transform{}; - transform.matrix[0] = std::cos(radians); - transform.matrix[1] = std::sin(radians); - transform.matrix[4] = -std::sin(radians); - transform.matrix[5] = std::cos(radians); - return transform; - } - - static Transform Rotate(const Float &x, const Float &y, const Float &z) { - auto transform = Transform{}; - if (x != 0) { - transform = transform * Transform::RotateX(x); - } - if (y != 0) { - transform = transform * Transform::RotateY(y); - } - if (z != 0) { - transform = transform * Transform::RotateZ(z); - } - return transform; - } - - bool operator==(const Transform &rhs) const { - for (auto i = 0; i < 16; i++) { - if (matrix[i] != rhs.matrix[i]) { - return false; - } - } - return true; - } - - bool operator!=(const Transform &rhs) const { - return !(*this == rhs); - } - - Transform operator*(const Transform &rhs) const { - if (*this == Transform::Identity()) { - return rhs; - } - - const auto &lhs = *this; - auto result = Transform{}; - - auto lhs00 = lhs.matrix[0], lhs01 = lhs.matrix[1], lhs02 = lhs.matrix[2], - lhs03 = lhs.matrix[3], lhs10 = lhs.matrix[4], lhs11 = lhs.matrix[5], - lhs12 = lhs.matrix[6], lhs13 = lhs.matrix[7], lhs20 = lhs.matrix[8], - lhs21 = lhs.matrix[9], lhs22 = lhs.matrix[10], lhs23 = lhs.matrix[11], - lhs30 = lhs.matrix[12], lhs31 = lhs.matrix[13], lhs32 = lhs.matrix[14], - lhs33 = lhs.matrix[15]; - - auto rhs0 = rhs.matrix[0], rhs1 = rhs.matrix[1], rhs2 = rhs.matrix[2], - rhs3 = rhs.matrix[3]; - result.matrix[0] = - rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30; - result.matrix[1] = - rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31; - result.matrix[2] = - rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32; - result.matrix[3] = - rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33; - - rhs0 = rhs.matrix[4]; - rhs1 = rhs.matrix[5]; - rhs2 = rhs.matrix[6]; - rhs3 = rhs.matrix[7]; - result.matrix[4] = - rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30; - result.matrix[5] = - rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31; - result.matrix[6] = - rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32; - result.matrix[7] = - rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33; - - rhs0 = rhs.matrix[8]; - rhs1 = rhs.matrix[9]; - rhs2 = rhs.matrix[10]; - rhs3 = rhs.matrix[11]; - result.matrix[8] = - rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30; - result.matrix[9] = - rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31; - result.matrix[10] = - rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32; - result.matrix[11] = - rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33; - - rhs0 = rhs.matrix[12]; - rhs1 = rhs.matrix[13]; - rhs2 = rhs.matrix[14]; - rhs3 = rhs.matrix[15]; - result.matrix[12] = - rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30; - result.matrix[13] = - rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31; - result.matrix[14] = - rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32; - result.matrix[15] = - rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33; - - return result; - } -}; - enum class PointerEventsMode { Auto, None, BoxNone, BoxOnly }; enum class BorderStyle { Solid, Dotted, Dashed }; diff --git a/ReactCommon/fabric/graphics/Transform.cpp b/ReactCommon/fabric/graphics/Transform.cpp new file mode 100644 index 000000000..bfcb45f25 --- /dev/null +++ b/ReactCommon/fabric/graphics/Transform.cpp @@ -0,0 +1,153 @@ +// Copyright (c) Facebook, Inc. and its affiliates. + +// This source code is licensed under the MIT license found in the +// LICENSE file in the root directory of this source tree. + +#include "Transform.h" + +#include + +namespace facebook { +namespace react { + +Transform Transform::Identity() { + return {}; +} + +Transform Transform::Perspective(Float perspective) { + auto transform = Transform{}; + transform.matrix[11] = -1.0 / perspective; + return transform; +} + +Transform Transform::Scale(Float factorX, Float factorY, Float factorZ) { + auto transform = Transform{}; + transform.matrix[0] = factorX; + transform.matrix[5] = factorY; + transform.matrix[10] = factorZ; + return transform; +} + +Transform Transform::Translate(Float x, Float y, Float z) { + auto transform = Transform{}; + transform.matrix[12] = x; + transform.matrix[13] = y; + transform.matrix[14] = z; + return transform; +} + +Transform Transform::Skew(Float x, Float y) { + auto transform = Transform{}; + transform.matrix[4] = std::tan(x); + transform.matrix[1] = std::tan(y); + return transform; +} + +Transform Transform::RotateX(Float radians) { + auto transform = Transform{}; + transform.matrix[5] = std::cos(radians); + transform.matrix[6] = std::sin(radians); + transform.matrix[9] = -std::sin(radians); + transform.matrix[10] = std::cos(radians); + return transform; +} + +Transform Transform::RotateY(Float radians) { + auto transform = Transform{}; + transform.matrix[0] = std::cos(radians); + transform.matrix[2] = -std::sin(radians); + transform.matrix[8] = std::sin(radians); + transform.matrix[10] = std::cos(radians); + return transform; +} + +Transform Transform::RotateZ(Float radians) { + auto transform = Transform{}; + transform.matrix[0] = std::cos(radians); + transform.matrix[1] = std::sin(radians); + transform.matrix[4] = -std::sin(radians); + transform.matrix[5] = std::cos(radians); + return transform; +} + +Transform Transform::Rotate(Float x, Float y, Float z) { + auto transform = Transform{}; + if (x != 0) { + transform = transform * Transform::RotateX(x); + } + if (y != 0) { + transform = transform * Transform::RotateY(y); + } + if (z != 0) { + transform = transform * Transform::RotateZ(z); + } + return transform; +} + +bool Transform::operator==(Transform const &rhs) const { + for (auto i = 0; i < 16; i++) { + if (matrix[i] != rhs.matrix[i]) { + return false; + } + } + return true; +} + +bool Transform::operator!=(Transform const &rhs) const { + return !(*this == rhs); +} + +Transform Transform::operator*(Transform const &rhs) const { + if (*this == Transform::Identity()) { + return rhs; + } + + const auto &lhs = *this; + auto result = Transform{}; + + auto lhs00 = lhs.matrix[0], lhs01 = lhs.matrix[1], lhs02 = lhs.matrix[2], + lhs03 = lhs.matrix[3], lhs10 = lhs.matrix[4], lhs11 = lhs.matrix[5], + lhs12 = lhs.matrix[6], lhs13 = lhs.matrix[7], lhs20 = lhs.matrix[8], + lhs21 = lhs.matrix[9], lhs22 = lhs.matrix[10], lhs23 = lhs.matrix[11], + lhs30 = lhs.matrix[12], lhs31 = lhs.matrix[13], lhs32 = lhs.matrix[14], + lhs33 = lhs.matrix[15]; + + auto rhs0 = rhs.matrix[0], rhs1 = rhs.matrix[1], rhs2 = rhs.matrix[2], + rhs3 = rhs.matrix[3]; + result.matrix[0] = rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30; + result.matrix[1] = rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31; + result.matrix[2] = rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32; + result.matrix[3] = rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33; + + rhs0 = rhs.matrix[4]; + rhs1 = rhs.matrix[5]; + rhs2 = rhs.matrix[6]; + rhs3 = rhs.matrix[7]; + result.matrix[4] = rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30; + result.matrix[5] = rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31; + result.matrix[6] = rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32; + result.matrix[7] = rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33; + + rhs0 = rhs.matrix[8]; + rhs1 = rhs.matrix[9]; + rhs2 = rhs.matrix[10]; + rhs3 = rhs.matrix[11]; + result.matrix[8] = rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30; + result.matrix[9] = rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31; + result.matrix[10] = rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32; + result.matrix[11] = rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33; + + rhs0 = rhs.matrix[12]; + rhs1 = rhs.matrix[13]; + rhs2 = rhs.matrix[14]; + rhs3 = rhs.matrix[15]; + result.matrix[12] = rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30; + result.matrix[13] = rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31; + result.matrix[14] = rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32; + result.matrix[15] = rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33; + + return result; +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/graphics/Transform.h b/ReactCommon/fabric/graphics/Transform.h new file mode 100644 index 000000000..75eff7559 --- /dev/null +++ b/ReactCommon/fabric/graphics/Transform.h @@ -0,0 +1,97 @@ +// Copyright (c) Facebook, Inc. and its affiliates. + +// This source code is licensed under the MIT license found in the +// LICENSE file in the root directory of this source tree. + +#pragma once + +#include + +#include +#include + +namespace facebook { +namespace react { + +/* + * Defines transform matrix to apply affine transformations. + */ +struct Transform { + std::array matrix{ + {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}}; + + /* + * Returs the identity transform (`[1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 1]`). + */ + static Transform Identity(); + + /* + * Returns a Perspective transform. + */ + static Transform Perspective(Float perspective); + + /* + * Returns a Scale transform. + */ + static Transform Scale(Float factorX, Float factorY, Float factorZ); + + /* + * Returns a Translate transform. + */ + static Transform Translate(Float x, Float y, Float z); + + /* + * Returns a Skew transform. + */ + static Transform Skew(Float x, Float y); + + /* + * Returns a transform that rotates by `angle` radians along the given axis. + */ + static Transform RotateX(Float angle); + static Transform RotateY(Float angle); + static Transform RotateZ(Float angle); + static Transform Rotate(Float angleX, Float angleY, Float angleZ); + + /* + * Equality operators. + */ + bool operator==(Transform const &rhs) const; + bool operator!=(Transform const &rhs) const; + + /* + * Concatenates (multiplies) transform matrices. + */ + Transform operator*(Transform const &rhs) const; +}; + +} // namespace react +} // namespace facebook + +namespace std { + +template <> +struct hash { + size_t operator()(const facebook::react::Transform &transform) const { + return folly::hash::hash_combine( + 0, + transform.matrix[0], + transform.matrix[1], + transform.matrix[2], + transform.matrix[3], + transform.matrix[4], + transform.matrix[5], + transform.matrix[6], + transform.matrix[7], + transform.matrix[8], + transform.matrix[9], + transform.matrix[10], + transform.matrix[11], + transform.matrix[12], + transform.matrix[13], + transform.matrix[14], + transform.matrix[15]); + } +}; + +} // namespace std