Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Convert MatrixDecomposition from SkMatrix44 to SkM44 #17760

Merged
merged 3 commits into from
Apr 16, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
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