Skip to content

Commit

Permalink
Convert MatrixDecomposition from SkMatrix44 to SkM44 (flutter#17760)
Browse files Browse the repository at this point in the history
* Convert MatrixDecomposition from SkMatrix44 to SkM44

SkMatrix44 is deprecated and being removed.
  • Loading branch information
brianosman authored Apr 16, 2020
1 parent e368377 commit ef161fb
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 169 deletions.
142 changes: 58 additions & 84 deletions flow/matrix_decomposition.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,140 +6,114 @@

namespace flutter {

static inline SkVector3 SkVector3Combine(const SkVector3& a,
float a_scale,
const SkVector3& b,
float b_scale) {
return {
a_scale * a.fX + b_scale * b.fX, //
a_scale * a.fY + b_scale * b.fY, //
a_scale * a.fZ + b_scale * b.fZ, //
};
}

static inline SkVector3 SkVector3Cross(const SkVector3& a, const SkVector3& b) {
return {
(a.fY * b.fZ) - (a.fZ * b.fY), //
(a.fZ * b.fX) - (a.fX * b.fZ), //
(a.fX * b.fY) - (a.fY * b.fX) //
};
static inline SkV3 SkV3Combine(const SkV3& a,
float a_scale,
const SkV3& b,
float b_scale) {
return (a * a_scale) + (b * b_scale);
}

MatrixDecomposition::MatrixDecomposition(const SkMatrix& matrix)
: MatrixDecomposition(SkMatrix44{matrix}) {}
: MatrixDecomposition(SkM44{matrix}) {}

// Use custom normalize to avoid skia precision loss/normalize() privatization.
static inline void SkVector3Normalize(SkVector3& v) {
double mag = sqrt(v.fX * v.fX + v.fY * v.fY + v.fZ * v.fZ);
static inline void SkV3Normalize(SkV3& v) {
double mag = sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
double scale = 1.0 / mag;
v.fX *= scale;
v.fY *= scale;
v.fZ *= scale;
v.x *= scale;
v.y *= scale;
v.z *= scale;
}

MatrixDecomposition::MatrixDecomposition(SkMatrix44 matrix) : valid_(false) {
if (matrix.get(3, 3) == 0) {
MatrixDecomposition::MatrixDecomposition(SkM44 matrix) : valid_(false) {
if (matrix.rc(3, 3) == 0) {
return;
}

for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
matrix.set(j, i, matrix.get(j, i) / matrix.get(3, 3));
matrix.setRC(j, i, matrix.rc(j, i) / matrix.rc(3, 3));
}
}

SkMatrix44 perpective_matrix = matrix;
SkM44 perpective_matrix = matrix;
for (int i = 0; i < 3; i++) {
perpective_matrix.set(3, i, 0.0);
perpective_matrix.setRC(3, i, 0.0);
}

perpective_matrix.set(3, 3, 1.0);
perpective_matrix.setRC(3, 3, 1.0);

if (perpective_matrix.determinant() == 0.0) {
SkM44 inverted(SkM44::Uninitialized_Constructor::kUninitialized_Constructor);
if (!perpective_matrix.invert(&inverted)) {
return;
}

if (matrix.get(3, 0) != 0.0 || matrix.get(3, 1) != 0.0 ||
matrix.get(3, 2) != 0.0) {
const SkVector4 right_hand_side(matrix.get(3, 0), matrix.get(3, 1),
matrix.get(3, 2), matrix.get(3, 3));

SkMatrix44 inverted_transposed(
SkMatrix44::Uninitialized_Constructor::kUninitialized_Constructor);
if (!perpective_matrix.invert(&inverted_transposed)) {
return;
}
inverted_transposed.transpose();
if (matrix.rc(3, 0) != 0.0 || matrix.rc(3, 1) != 0.0 ||
matrix.rc(3, 2) != 0.0) {
const SkV4 right_hand_side = matrix.row(3);

perspective_ = inverted_transposed * right_hand_side;
perspective_ = inverted.transpose() * right_hand_side;

matrix.set(3, 0, 0);
matrix.set(3, 1, 0);
matrix.set(3, 2, 0);
matrix.set(3, 3, 1);
matrix.setRow(3, {0, 0, 0, 1});
}

translation_ = {matrix.get(0, 3), matrix.get(1, 3), matrix.get(2, 3)};
translation_ = {matrix.rc(0, 3), matrix.rc(1, 3), matrix.rc(2, 3)};

matrix.set(0, 3, 0.0);
matrix.set(1, 3, 0.0);
matrix.set(2, 3, 0.0);
matrix.setRC(0, 3, 0.0);
matrix.setRC(1, 3, 0.0);
matrix.setRC(2, 3, 0.0);

SkVector3 row[3];
SkV3 row[3];
for (int i = 0; i < 3; i++) {
row[i].set(matrix.get(0, i), matrix.get(1, i), matrix.get(2, i));
row[i] = {matrix.rc(0, i), matrix.rc(1, i), matrix.rc(2, i)};
}

scale_.fX = row[0].length();
scale_.x = row[0].length();

SkVector3Normalize(row[0]);
SkV3Normalize(row[0]);

shear_.fX = row[0].dot(row[1]);
row[1] = SkVector3Combine(row[1], 1.0, row[0], -shear_.fX);
shear_.x = row[0].dot(row[1]);
row[1] = SkV3Combine(row[1], 1.0, row[0], -shear_.x);

scale_.fY = row[1].length();
scale_.y = row[1].length();

SkVector3Normalize(row[1]);
SkV3Normalize(row[1]);

shear_.fX /= scale_.fY;
shear_.x /= scale_.y;

shear_.fY = row[0].dot(row[2]);
row[2] = SkVector3Combine(row[2], 1.0, row[0], -shear_.fY);
shear_.fZ = row[1].dot(row[2]);
row[2] = SkVector3Combine(row[2], 1.0, row[1], -shear_.fZ);
shear_.y = row[0].dot(row[2]);
row[2] = SkV3Combine(row[2], 1.0, row[0], -shear_.y);
shear_.z = row[1].dot(row[2]);
row[2] = SkV3Combine(row[2], 1.0, row[1], -shear_.z);

scale_.fZ = row[2].length();
scale_.z = row[2].length();

SkVector3Normalize(row[2]);
SkV3Normalize(row[2]);

shear_.fY /= scale_.fZ;
shear_.fZ /= scale_.fZ;
shear_.y /= scale_.z;
shear_.z /= scale_.z;

if (row[0].dot(SkVector3Cross(row[1], row[2])) < 0) {
scale_.fX *= -1;
scale_.fY *= -1;
scale_.fZ *= -1;
if (row[0].dot(row[1].cross(row[2])) < 0) {
scale_ *= -1;

for (int i = 0; i < 3; i++) {
row[i].fX *= -1;
row[i].fY *= -1;
row[i].fZ *= -1;
row[i] *= -1;
}
}

rotation_.set(0.5 * sqrt(fmax(1.0 + row[0].fX - row[1].fY - row[2].fZ, 0.0)),
0.5 * sqrt(fmax(1.0 - row[0].fX + row[1].fY - row[2].fZ, 0.0)),
0.5 * sqrt(fmax(1.0 - row[0].fX - row[1].fY + row[2].fZ, 0.0)),
0.5 * sqrt(fmax(1.0 + row[0].fX + row[1].fY + row[2].fZ, 0.0)));
rotation_.x = 0.5 * sqrt(fmax(1.0 + row[0].x - row[1].y - row[2].z, 0.0));
rotation_.y = 0.5 * sqrt(fmax(1.0 - row[0].x + row[1].y - row[2].z, 0.0));
rotation_.z = 0.5 * sqrt(fmax(1.0 - row[0].x - row[1].y + row[2].z, 0.0));
rotation_.w = 0.5 * sqrt(fmax(1.0 + row[0].x + row[1].y + row[2].z, 0.0));

if (row[2].fY > row[1].fZ) {
rotation_.fData[0] = -rotation_.fData[0];
if (row[2].y > row[1].z) {
rotation_.x = -rotation_.x;
}
if (row[0].fZ > row[2].fX) {
rotation_.fData[1] = -rotation_.fData[1];
if (row[0].z > row[2].x) {
rotation_.y = -rotation_.y;
}
if (row[1].fX > row[0].fY) {
rotation_.fData[2] = -rotation_.fData[2];
if (row[1].x > row[0].y) {
rotation_.z = -rotation_.z;
}

valid_ = true;
Expand Down
25 changes: 12 additions & 13 deletions flow/matrix_decomposition.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
#define FLUTTER_FLOW_MATRIX_DECOMPOSITION_H_

#include "flutter/fml/macros.h"
#include "third_party/skia/include/core/SkM44.h"
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkMatrix44.h"
#include "third_party/skia/include/core/SkPoint3.h"

namespace flutter {

Expand All @@ -19,29 +18,29 @@ class MatrixDecomposition {
public:
MatrixDecomposition(const SkMatrix& matrix);

MatrixDecomposition(SkMatrix44 matrix);
MatrixDecomposition(SkM44 matrix);

~MatrixDecomposition();

bool IsValid() const;

const SkVector3& translation() const { return translation_; }
const SkV3& translation() const { return translation_; }

const SkVector3& scale() const { return scale_; }
const SkV3& scale() const { return scale_; }

const SkVector3& shear() const { return shear_; }
const SkV3& shear() const { return shear_; }

const SkVector4& perspective() const { return perspective_; }
const SkV4& perspective() const { return perspective_; }

const SkVector4& rotation() const { return rotation_; }
const SkV4& rotation() const { return rotation_; }

private:
bool valid_;
SkVector3 translation_;
SkVector3 scale_;
SkVector3 shear_;
SkVector4 perspective_;
SkVector4 rotation_;
SkV3 translation_;
SkV3 scale_;
SkV3 shear_;
SkV4 perspective_;
SkV4 rotation_;

FML_DISALLOW_COPY_AND_ASSIGN(MatrixDecomposition);
};
Expand Down
Loading

0 comments on commit ef161fb

Please sign in to comment.