skia2/include/private/SkM44.h

172 lines
5.2 KiB
C
Raw Normal View History

/*
* 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