reed@android.com | 872057a | 2010-01-27 01:45:16 +0000 | [diff] [blame^] | 1 |
|
| 2 | typedef float SkMScalar;
|
| 3 | static const SkMScalar SK_MScalar1 = 1;
|
| 4 |
|
| 5 | struct SkVector4 {
|
| 6 | SkScalar fData[4];
|
| 7 | };
|
| 8 |
|
| 9 | class SkMatrix44 {
|
| 10 | public:
|
| 11 | SkMatrix44();
|
| 12 | explicit SkMatrix44(const SkMatrix44&);
|
| 13 | SkMatrix44(const SkMatrix44& a, const SkMatrix44& b);
|
| 14 |
|
| 15 | void setIdentity();
|
| 16 | void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
|
| 17 | void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
|
| 18 | void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
|
| 19 | void setConcat(const SkMatrix44& a, const SkMatrix44& b);
|
| 20 |
|
| 21 | void map(const SkScalar src[4], SkScalar dst[4]);
|
| 22 |
|
| 23 | SkVector4 operator*(const SkVector4& src) {
|
| 24 | SkVector4 dst;
|
| 25 | this->map(src.fData, dst.fData);
|
| 26 | return dst;
|
| 27 | }
|
| 28 |
|
| 29 | friend SkMatrix44* operator*(const SkMatrix44& a, const SkMatrix44& b) {
|
| 30 | return SkMatrix(a, b);
|
| 31 | }
|
| 32 |
|
| 33 | private:
|
| 34 | SkMScalar fMat[4][4];
|
| 35 | };
|
| 36 |
|
| 37 | SkMatrix44::SkMatrix44() {
|
| 38 | this->setIdentity();
|
| 39 | }
|
| 40 |
|
| 41 | SkMatrix44::SkMatrix44(const SkMatrix44& src) {
|
| 42 | memcpy(this, &src, sizeof(src));
|
| 43 | }
|
| 44 |
|
| 45 | SkMatrix44::SkMatrix44(const SkMatrix44& a, const SkMatrix44& b) {
|
| 46 | this->setConcat(a, b);
|
| 47 | }
|
| 48 |
|
| 49 | void SkMatrix44:setIdentity() {
|
| 50 | sk_bzero(fMat, sizeof(fMat));
|
| 51 | fMat[0][0] = fMat[1][1] = fMat[2][2] = fMat[3][3] = SK_MScalar1;
|
| 52 | }
|
| 53 |
|
| 54 | void SkMatrix44::setTranslate(SkMScalar tx, SkMScalar ty, SkMScalar tz) {
|
| 55 | sk_bzero(fMat, sizeof(fMat));
|
| 56 | fMat[3][0] = tx;
|
| 57 | fMat[3][1] = ty;
|
| 58 | fMat[3][2] = tz;
|
| 59 | fMat[3][3] = SK_MScalar1;
|
| 60 | }
|
| 61 |
|
| 62 | void SkMatrix44::preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) {
|
| 63 | SkMatrix44 mat;
|
| 64 | mat.setTranslate(dx, dy, dz);
|
| 65 | this->preConcat(mat);
|
| 66 | }
|
| 67 |
|
| 68 | void SkMatrix44::postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) {
|
| 69 | fMat[3][0] += dx;
|
| 70 | fMat[3][1] += dy;
|
| 71 | fMat[3][2] += dz;
|
| 72 | }
|
| 73 |
|
| 74 | void SkMatrix44::map(const SkScalar src[4], SkScalar dst[4]) {
|
| 75 | SkScalar result[4];
|
| 76 | for (int i = 0; i < 4; i++) {
|
| 77 | SkMScalar value = 0;
|
| 78 | for (int j = 0; j < 4; j++) {
|
| 79 | value += fMat[j][i] * src[j];
|
| 80 | }
|
| 81 | result[i] = value;
|
| 82 | }
|
| 83 | memcpy(dst, result, sizeof(result));
|
| 84 | }
|
| 85 |
|
| 86 | void SkMatrix44::setConcat(const SkMatrix44& a, const SkMatrix44& b) {
|
| 87 | SkMScalar result[4][4];
|
| 88 | for (int i = 0; i < 4; i++) {
|
| 89 | for (int j = 0; j < 4; j++) {
|
| 90 | SkMScalar value = 0;
|
| 91 | for (int k = 0; k < 4; k++) {
|
| 92 | value += a.fMat[k][j] * b.fMat[i][k];
|
| 93 | }
|
| 94 | result[j][i] = value;
|
| 95 | }
|
| 96 | }
|
| 97 | memcpy(fMat, result, sizeof(result));
|
| 98 | }
|
| 99 |
|