172 lines
5.2 KiB
C
172 lines
5.2 KiB
C
|
/*
|
||
|
* Copyright 2020 Google Inc.
|
||
|
*
|
||
|
* Use of this source code is governed by a BSD-style license that can be
|
||
|
* found in the LICENSE file.
|
||
|
*/
|
||
|
|
||
|
#ifndef SkM44_DEFINED
|
||
|
#define SkM44_DEFINED
|
||
|
|
||
|
#include "include/core/SkScalar.h"
|
||
|
|
||
|
class SkMatrix;
|
||
|
|
||
|
class SkM44 {
|
||
|
public:
|
||
|
SkM44(const SkM44& src) = default;
|
||
|
SkM44& operator=(const SkM44& src) = default;
|
||
|
|
||
|
constexpr SkM44()
|
||
|
: fMat{1, 0, 0, 0,
|
||
|
0, 1, 0, 0,
|
||
|
0, 0, 1, 0,
|
||
|
0, 0, 0, 1}
|
||
|
{}
|
||
|
|
||
|
SkM44(const SkM44& a, const SkM44& b) {
|
||
|
this->setConcat(a, b);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Parameters are treated as row-major.
|
||
|
*/
|
||
|
SkM44(SkScalar m0, SkScalar m4, SkScalar m8, SkScalar m12,
|
||
|
SkScalar m1, SkScalar m5, SkScalar m9, SkScalar m13,
|
||
|
SkScalar m2, SkScalar m6, SkScalar m10, SkScalar m14,
|
||
|
SkScalar m3, SkScalar m7, SkScalar m11, SkScalar m15)
|
||
|
{
|
||
|
fMat[0] = m0; fMat[4] = m4; fMat[8] = m8; fMat[12] = m12;
|
||
|
fMat[1] = m1; fMat[5] = m5; fMat[9] = m9; fMat[13] = m13;
|
||
|
fMat[2] = m2; fMat[6] = m6; fMat[10] = m10; fMat[14] = m14;
|
||
|
fMat[3] = m3; fMat[7] = m7; fMat[11] = m11; fMat[15] = m15;
|
||
|
}
|
||
|
|
||
|
static SkM44 Translate(SkScalar x, SkScalar y, SkScalar z = 0) {
|
||
|
return SkM44(1, 0, 0, x,
|
||
|
0, 1, 0, y,
|
||
|
0, 0, 1, z,
|
||
|
0, 0, 0, 1);
|
||
|
}
|
||
|
|
||
|
static SkM44 Scale(SkScalar x, SkScalar y, SkScalar z = 1) {
|
||
|
return SkM44(x, 0, 0, 0,
|
||
|
0, y, 0, 0,
|
||
|
0, 0, z, 0,
|
||
|
0, 0, 0, 1);
|
||
|
}
|
||
|
|
||
|
bool operator==(const SkM44& other) const;
|
||
|
bool operator!=(const SkM44& other) const {
|
||
|
return !(other == *this);
|
||
|
}
|
||
|
|
||
|
void getColMajor(SkScalar v[]) const {
|
||
|
memcpy(v, fMat, sizeof(fMat));
|
||
|
}
|
||
|
void getRowMajor(SkScalar v[]) const;
|
||
|
|
||
|
SkM44& setColMajor(const SkScalar v[]) {
|
||
|
memcpy(fMat, v, sizeof(fMat));
|
||
|
return *this;
|
||
|
}
|
||
|
SkM44& setRowMajor(const SkScalar v[]);
|
||
|
|
||
|
/* Parameters are treated as row-major.
|
||
|
*/
|
||
|
SkM44& setRowMajor(SkScalar m0, SkScalar m4, SkScalar m8, SkScalar m12,
|
||
|
SkScalar m1, SkScalar m5, SkScalar m9, SkScalar m13,
|
||
|
SkScalar m2, SkScalar m6, SkScalar m10, SkScalar m14,
|
||
|
SkScalar m3, SkScalar m7, SkScalar m11, SkScalar m15) {
|
||
|
fMat[0] = m0; fMat[4] = m4; fMat[8] = m8; fMat[12] = m12;
|
||
|
fMat[1] = m1; fMat[5] = m5; fMat[9] = m9; fMat[13] = m13;
|
||
|
fMat[2] = m2; fMat[6] = m6; fMat[10] = m10; fMat[14] = m14;
|
||
|
fMat[3] = m3; fMat[7] = m7; fMat[11] = m11; fMat[15] = m15;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
SkScalar atColMajor(int index) const {
|
||
|
SkASSERT(index >= 0 && index < 16);
|
||
|
return fMat[index];
|
||
|
}
|
||
|
|
||
|
SkM44& setIdentity() {
|
||
|
return this->setRowMajor(1, 0, 0, 0,
|
||
|
0, 1, 0, 0,
|
||
|
0, 0, 1, 0,
|
||
|
0, 0, 0, 1);
|
||
|
}
|
||
|
|
||
|
SkM44& setTranslate(SkScalar x, SkScalar y, SkScalar z = 0) {
|
||
|
return this->setRowMajor(1, 0, 0, x,
|
||
|
0, 1, 0, y,
|
||
|
0, 0, 1, z,
|
||
|
0, 0, 0, 1);
|
||
|
}
|
||
|
|
||
|
SkM44& setScale(SkScalar x, SkScalar y, SkScalar z = 1) {
|
||
|
return this->setRowMajor(x, 0, 0, 0,
|
||
|
0, y, 0, 0,
|
||
|
0, 0, z, 0,
|
||
|
0, 0, 0, 1);
|
||
|
}
|
||
|
|
||
|
SkM44& setConcat(const SkM44& a, const SkM44& b);
|
||
|
|
||
|
friend SkM44 operator*(const SkM44& a, const SkM44& b) {
|
||
|
return SkM44(a, b);
|
||
|
}
|
||
|
|
||
|
/** If this is invertible, return that in inverse and return true. If it is
|
||
|
* not invertible, return false and leave the inverse parameter unchanged.
|
||
|
*/
|
||
|
bool invert(SkM44* inverse) const;
|
||
|
|
||
|
void dump() const;
|
||
|
|
||
|
////////////////////// Converting to/from SkMatrix
|
||
|
|
||
|
/* When converting from SkM44 to SkMatrix, the third row and
|
||
|
* column is dropped. When converting from SkMatrix to SkM44
|
||
|
* the third row and column remain as identity:
|
||
|
* [ a b c ] [ a b 0 c ]
|
||
|
* [ d e f ] -> [ d e 0 f ]
|
||
|
* [ g h i ] [ 0 0 1 0 ]
|
||
|
* [ g h 0 i ]
|
||
|
*/
|
||
|
SkMatrix asM33() const {
|
||
|
return SkMatrix::MakeAll(fMat[0], fMat[4], fMat[12],
|
||
|
fMat[1], fMat[5], fMat[13],
|
||
|
fMat[3], fMat[7], fMat[15]);
|
||
|
}
|
||
|
|
||
|
SkM44(const SkMatrix& src)
|
||
|
: SkM44(src[SkMatrix::kMScaleX], src[SkMatrix::kMSkewX], 0, src[SkMatrix::kMTransX],
|
||
|
src[SkMatrix::kMSkewY], src[SkMatrix::kMScaleY], 0, src[SkMatrix::kMTransY],
|
||
|
0, 0, 1, 0,
|
||
|
src[SkMatrix::kMPersp0], src[SkMatrix::kMPersp1], 0, src[SkMatrix::kMPersp2])
|
||
|
{}
|
||
|
|
||
|
SkM44& operator=(const SkMatrix& src) {
|
||
|
*this = SkM44(src);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
SkM44& preTranslate(SkScalar x, SkScalar y);
|
||
|
SkM44& preConcat(const SkMatrix&);
|
||
|
|
||
|
private:
|
||
|
/* Stored in column-major.
|
||
|
* Indices
|
||
|
* 0 4 8 12 1 0 0 trans_x
|
||
|
* 1 5 9 13 e.g. 0 1 0 trans_y
|
||
|
* 2 6 10 14 0 0 1 trans_z
|
||
|
* 3 7 11 15 0 0 0 1
|
||
|
*/
|
||
|
SkScalar fMat[16];
|
||
|
|
||
|
double determinant() const;
|
||
|
};
|
||
|
|
||
|
#endif
|