gfx/2d/Matrix.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef MOZILLA_GFX_MATRIX_H_
michael@0 7 #define MOZILLA_GFX_MATRIX_H_
michael@0 8
michael@0 9 #include "Types.h"
michael@0 10 #include "Rect.h"
michael@0 11 #include "Point.h"
michael@0 12 #include <math.h>
michael@0 13
michael@0 14 namespace mozilla {
michael@0 15 namespace gfx {
michael@0 16
michael@0 17 class Matrix
michael@0 18 {
michael@0 19 public:
michael@0 20 Matrix()
michael@0 21 : _11(1.0f), _12(0)
michael@0 22 , _21(0), _22(1.0f)
michael@0 23 , _31(0), _32(0)
michael@0 24 {}
michael@0 25 Matrix(Float a11, Float a12, Float a21, Float a22, Float a31, Float a32)
michael@0 26 : _11(a11), _12(a12)
michael@0 27 , _21(a21), _22(a22)
michael@0 28 , _31(a31), _32(a32)
michael@0 29 {}
michael@0 30 Float _11, _12;
michael@0 31 Float _21, _22;
michael@0 32 Float _31, _32;
michael@0 33
michael@0 34 Point operator *(const Point &aPoint) const
michael@0 35 {
michael@0 36 Point retPoint;
michael@0 37
michael@0 38 retPoint.x = aPoint.x * _11 + aPoint.y * _21 + _31;
michael@0 39 retPoint.y = aPoint.x * _12 + aPoint.y * _22 + _32;
michael@0 40
michael@0 41 return retPoint;
michael@0 42 }
michael@0 43
michael@0 44 Size operator *(const Size &aSize) const
michael@0 45 {
michael@0 46 Size retSize;
michael@0 47
michael@0 48 retSize.width = aSize.width * _11 + aSize.height * _21;
michael@0 49 retSize.height = aSize.width * _12 + aSize.height * _22;
michael@0 50
michael@0 51 return retSize;
michael@0 52 }
michael@0 53
michael@0 54 GFX2D_API Rect TransformBounds(const Rect& rect) const;
michael@0 55
michael@0 56 // Apply a scale to this matrix. This scale will be applied -before- the
michael@0 57 // existing transformation of the matrix.
michael@0 58 Matrix &Scale(Float aX, Float aY)
michael@0 59 {
michael@0 60 _11 *= aX;
michael@0 61 _12 *= aX;
michael@0 62 _21 *= aY;
michael@0 63 _22 *= aY;
michael@0 64
michael@0 65 return *this;
michael@0 66 }
michael@0 67
michael@0 68 Matrix &Translate(Float aX, Float aY)
michael@0 69 {
michael@0 70 _31 += _11 * aX + _21 * aY;
michael@0 71 _32 += _12 * aX + _22 * aY;
michael@0 72
michael@0 73 return *this;
michael@0 74 }
michael@0 75
michael@0 76 Matrix &PostTranslate(Float aX, Float aY)
michael@0 77 {
michael@0 78 _31 += aX;
michael@0 79 _32 += aY;
michael@0 80 return *this;
michael@0 81 }
michael@0 82
michael@0 83 Matrix &Rotate(Float aAngle)
michael@0 84 {
michael@0 85 return *this = Matrix::Rotation(aAngle) * *this;
michael@0 86 }
michael@0 87
michael@0 88 bool Invert()
michael@0 89 {
michael@0 90 // Compute co-factors.
michael@0 91 Float A = _22;
michael@0 92 Float B = -_21;
michael@0 93 Float C = _21 * _32 - _22 * _31;
michael@0 94 Float D = -_12;
michael@0 95 Float E = _11;
michael@0 96 Float F = _31 * _12 - _11 * _32;
michael@0 97
michael@0 98 Float det = Determinant();
michael@0 99
michael@0 100 if (!det) {
michael@0 101 return false;
michael@0 102 }
michael@0 103
michael@0 104 Float inv_det = 1 / det;
michael@0 105
michael@0 106 _11 = inv_det * A;
michael@0 107 _12 = inv_det * D;
michael@0 108 _21 = inv_det * B;
michael@0 109 _22 = inv_det * E;
michael@0 110 _31 = inv_det * C;
michael@0 111 _32 = inv_det * F;
michael@0 112
michael@0 113 return true;
michael@0 114 }
michael@0 115
michael@0 116 Float Determinant() const
michael@0 117 {
michael@0 118 return _11 * _22 - _12 * _21;
michael@0 119 }
michael@0 120
michael@0 121 static Matrix Translation(Float aX, Float aY)
michael@0 122 {
michael@0 123 return Matrix(1.0f, 0.0f, 0.0f, 1.0f, aX, aY);
michael@0 124 }
michael@0 125
michael@0 126 static Matrix Translation(Point aPoint)
michael@0 127 {
michael@0 128 return Translation(aPoint.x, aPoint.y);
michael@0 129 }
michael@0 130
michael@0 131 GFX2D_API static Matrix Rotation(Float aAngle);
michael@0 132
michael@0 133 static Matrix Scaling(Float aX, Float aY)
michael@0 134 {
michael@0 135 return Matrix(aX, 0.0f, 0.0f, aY, 0.0f, 0.0f);
michael@0 136 }
michael@0 137
michael@0 138 Matrix operator*(const Matrix &aMatrix) const
michael@0 139 {
michael@0 140 Matrix resultMatrix;
michael@0 141
michael@0 142 resultMatrix._11 = this->_11 * aMatrix._11 + this->_12 * aMatrix._21;
michael@0 143 resultMatrix._12 = this->_11 * aMatrix._12 + this->_12 * aMatrix._22;
michael@0 144 resultMatrix._21 = this->_21 * aMatrix._11 + this->_22 * aMatrix._21;
michael@0 145 resultMatrix._22 = this->_21 * aMatrix._12 + this->_22 * aMatrix._22;
michael@0 146 resultMatrix._31 = this->_31 * aMatrix._11 + this->_32 * aMatrix._21 + aMatrix._31;
michael@0 147 resultMatrix._32 = this->_31 * aMatrix._12 + this->_32 * aMatrix._22 + aMatrix._32;
michael@0 148
michael@0 149 return resultMatrix;
michael@0 150 }
michael@0 151
michael@0 152 Matrix& operator*=(const Matrix &aMatrix)
michael@0 153 {
michael@0 154 Matrix resultMatrix = *this * aMatrix;
michael@0 155 return *this = resultMatrix;
michael@0 156 }
michael@0 157
michael@0 158 /* Returns true if the other matrix is fuzzy-equal to this matrix.
michael@0 159 * Note that this isn't a cheap comparison!
michael@0 160 */
michael@0 161 bool operator==(const Matrix& other) const
michael@0 162 {
michael@0 163 return FuzzyEqual(_11, other._11) && FuzzyEqual(_12, other._12) &&
michael@0 164 FuzzyEqual(_21, other._21) && FuzzyEqual(_22, other._22) &&
michael@0 165 FuzzyEqual(_31, other._31) && FuzzyEqual(_32, other._32);
michael@0 166 }
michael@0 167
michael@0 168 bool operator!=(const Matrix& other) const
michael@0 169 {
michael@0 170 return !(*this == other);
michael@0 171 }
michael@0 172
michael@0 173 /* Returns true if the matrix is a rectilinear transformation (i.e.
michael@0 174 * grid-aligned rectangles are transformed to grid-aligned rectangles)
michael@0 175 */
michael@0 176 bool IsRectilinear() const {
michael@0 177 if (FuzzyEqual(_12, 0) && FuzzyEqual(_21, 0)) {
michael@0 178 return true;
michael@0 179 } else if (FuzzyEqual(_22, 0) && FuzzyEqual(_11, 0)) {
michael@0 180 return true;
michael@0 181 }
michael@0 182
michael@0 183 return false;
michael@0 184 }
michael@0 185
michael@0 186 /**
michael@0 187 * Returns true if the matrix is anything other than a straight
michael@0 188 * translation by integers.
michael@0 189 */
michael@0 190 bool HasNonIntegerTranslation() const {
michael@0 191 return HasNonTranslation() ||
michael@0 192 !FuzzyEqual(_31, floor(_31 + 0.5)) ||
michael@0 193 !FuzzyEqual(_32, floor(_32 + 0.5));
michael@0 194 }
michael@0 195
michael@0 196 /**
michael@0 197 * Returns true if the matrix has any transform other
michael@0 198 * than a straight translation.
michael@0 199 */
michael@0 200 bool HasNonTranslation() const {
michael@0 201 return !FuzzyEqual(_11, 1.0) || !FuzzyEqual(_22, 1.0) ||
michael@0 202 !FuzzyEqual(_12, 0.0) || !FuzzyEqual(_21, 0.0);
michael@0 203 }
michael@0 204
michael@0 205 /* Returns true if the matrix is an identity matrix.
michael@0 206 */
michael@0 207 bool IsIdentity() const
michael@0 208 {
michael@0 209 return _11 == 1.0f && _12 == 0.0f &&
michael@0 210 _21 == 0.0f && _22 == 1.0f &&
michael@0 211 _31 == 0.0f && _32 == 0.0f;
michael@0 212 }
michael@0 213
michael@0 214 /* Returns true if the matrix is singular.
michael@0 215 */
michael@0 216 bool IsSingular() const
michael@0 217 {
michael@0 218 return Determinant() == 0;
michael@0 219 }
michael@0 220
michael@0 221 GFX2D_API void NudgeToIntegers();
michael@0 222
michael@0 223 bool IsTranslation() const
michael@0 224 {
michael@0 225 return FuzzyEqual(_11, 1.0f) && FuzzyEqual(_12, 0.0f) &&
michael@0 226 FuzzyEqual(_21, 0.0f) && FuzzyEqual(_22, 1.0f);
michael@0 227 }
michael@0 228
michael@0 229 bool IsIntegerTranslation() const
michael@0 230 {
michael@0 231 return IsTranslation() &&
michael@0 232 FuzzyEqual(_31, floorf(_31 + 0.5f)) &&
michael@0 233 FuzzyEqual(_32, floorf(_32 + 0.5f));
michael@0 234 }
michael@0 235
michael@0 236 Point GetTranslation() const {
michael@0 237 return Point(_31, _32);
michael@0 238 }
michael@0 239
michael@0 240 /**
michael@0 241 * Returns true if matrix is multiple of 90 degrees rotation with flipping,
michael@0 242 * scaling and translation.
michael@0 243 */
michael@0 244 bool PreservesAxisAlignedRectangles() const {
michael@0 245 return ((FuzzyEqual(_11, 0.0) && FuzzyEqual(_22, 0.0))
michael@0 246 || (FuzzyEqual(_12, 0.0) && FuzzyEqual(_21, 0.0)));
michael@0 247 }
michael@0 248
michael@0 249 /**
michael@0 250 * Returns true if the matrix has any transform other
michael@0 251 * than a translation or scale; this is, if there is
michael@0 252 * no rotation.
michael@0 253 */
michael@0 254 bool HasNonAxisAlignedTransform() const {
michael@0 255 return !FuzzyEqual(_21, 0.0) || !FuzzyEqual(_12, 0.0);
michael@0 256 }
michael@0 257
michael@0 258 /**
michael@0 259 * Returns true if the matrix has non-integer scale
michael@0 260 */
michael@0 261 bool HasNonIntegerScale() const {
michael@0 262 return !FuzzyEqual(_11, floor(_11 + 0.5)) ||
michael@0 263 !FuzzyEqual(_22, floor(_22 + 0.5));
michael@0 264 }
michael@0 265
michael@0 266 private:
michael@0 267 static bool FuzzyEqual(Float aV1, Float aV2) {
michael@0 268 // XXX - Check if fabs does the smart thing and just negates the sign bit.
michael@0 269 return fabs(aV2 - aV1) < 1e-6;
michael@0 270 }
michael@0 271 };
michael@0 272
michael@0 273 class Matrix4x4
michael@0 274 {
michael@0 275 public:
michael@0 276 Matrix4x4()
michael@0 277 : _11(1.0f), _12(0.0f), _13(0.0f), _14(0.0f)
michael@0 278 , _21(0.0f), _22(1.0f), _23(0.0f), _24(0.0f)
michael@0 279 , _31(0.0f), _32(0.0f), _33(1.0f), _34(0.0f)
michael@0 280 , _41(0.0f), _42(0.0f), _43(0.0f), _44(1.0f)
michael@0 281 {}
michael@0 282
michael@0 283 Float _11, _12, _13, _14;
michael@0 284 Float _21, _22, _23, _24;
michael@0 285 Float _31, _32, _33, _34;
michael@0 286 Float _41, _42, _43, _44;
michael@0 287
michael@0 288 /**
michael@0 289 * Returns true if the matrix is isomorphic to a 2D affine transformation.
michael@0 290 */
michael@0 291 bool Is2D() const
michael@0 292 {
michael@0 293 if (_13 != 0.0f || _14 != 0.0f ||
michael@0 294 _23 != 0.0f || _24 != 0.0f ||
michael@0 295 _31 != 0.0f || _32 != 0.0f || _33 != 1.0f || _34 != 0.0f ||
michael@0 296 _43 != 0.0f || _44 != 1.0f) {
michael@0 297 return false;
michael@0 298 }
michael@0 299 return true;
michael@0 300 }
michael@0 301
michael@0 302 bool Is2D(Matrix* aMatrix) const {
michael@0 303 if (!Is2D()) {
michael@0 304 return false;
michael@0 305 }
michael@0 306 if (aMatrix) {
michael@0 307 aMatrix->_11 = _11;
michael@0 308 aMatrix->_12 = _12;
michael@0 309 aMatrix->_21 = _21;
michael@0 310 aMatrix->_22 = _22;
michael@0 311 aMatrix->_31 = _41;
michael@0 312 aMatrix->_32 = _42;
michael@0 313 }
michael@0 314 return true;
michael@0 315 }
michael@0 316
michael@0 317 Matrix As2D() const
michael@0 318 {
michael@0 319 MOZ_ASSERT(Is2D(), "Matrix is not a 2D affine transform");
michael@0 320
michael@0 321 return Matrix(_11, _12, _21, _22, _41, _42);
michael@0 322 }
michael@0 323
michael@0 324 bool CanDraw2D(Matrix* aMatrix = nullptr) const {
michael@0 325 if (_14 != 0.0f ||
michael@0 326 _24 != 0.0f ||
michael@0 327 _44 != 1.0f) {
michael@0 328 return false;
michael@0 329 }
michael@0 330 if (aMatrix) {
michael@0 331 aMatrix->_11 = _11;
michael@0 332 aMatrix->_12 = _12;
michael@0 333 aMatrix->_21 = _21;
michael@0 334 aMatrix->_22 = _22;
michael@0 335 aMatrix->_31 = _41;
michael@0 336 aMatrix->_32 = _42;
michael@0 337 }
michael@0 338 return true;
michael@0 339 }
michael@0 340
michael@0 341 Matrix4x4& ProjectTo2D() {
michael@0 342 _31 = 0.0f;
michael@0 343 _32 = 0.0f;
michael@0 344 _13 = 0.0f;
michael@0 345 _23 = 0.0f;
michael@0 346 _33 = 1.0f;
michael@0 347 _43 = 0.0f;
michael@0 348 _34 = 0.0f;
michael@0 349 return *this;
michael@0 350 }
michael@0 351
michael@0 352 static Matrix4x4 From2D(const Matrix &aMatrix) {
michael@0 353 Matrix4x4 matrix;
michael@0 354 matrix._11 = aMatrix._11;
michael@0 355 matrix._12 = aMatrix._12;
michael@0 356 matrix._21 = aMatrix._21;
michael@0 357 matrix._22 = aMatrix._22;
michael@0 358 matrix._41 = aMatrix._31;
michael@0 359 matrix._42 = aMatrix._32;
michael@0 360 return matrix;
michael@0 361 }
michael@0 362
michael@0 363 bool Is2DIntegerTranslation() const
michael@0 364 {
michael@0 365 return Is2D() && As2D().IsIntegerTranslation();
michael@0 366 }
michael@0 367
michael@0 368 Point4D operator *(const Point4D& aPoint) const
michael@0 369 {
michael@0 370 Point4D retPoint;
michael@0 371
michael@0 372 retPoint.x = aPoint.x * _11 + aPoint.y * _21 + aPoint.z * _31 + _41;
michael@0 373 retPoint.y = aPoint.x * _12 + aPoint.y * _22 + aPoint.z * _32 + _42;
michael@0 374 retPoint.z = aPoint.x * _13 + aPoint.y * _23 + aPoint.z * _33 + _43;
michael@0 375 retPoint.w = aPoint.x * _14 + aPoint.y * _24 + aPoint.z * _34 + _44;
michael@0 376
michael@0 377 return retPoint;
michael@0 378 }
michael@0 379
michael@0 380 Point3D operator *(const Point3D& aPoint) const
michael@0 381 {
michael@0 382 Point4D temp(aPoint.x, aPoint.y, aPoint.z, 1);
michael@0 383
michael@0 384 temp = *this * temp;
michael@0 385 temp /= temp.w;
michael@0 386
michael@0 387 return Point3D(temp.x, temp.y, temp.z);
michael@0 388 }
michael@0 389
michael@0 390 Point operator *(const Point &aPoint) const
michael@0 391 {
michael@0 392 Point4D temp(aPoint.x, aPoint.y, 0, 1);
michael@0 393
michael@0 394 temp = *this * temp;
michael@0 395 temp /= temp.w;
michael@0 396
michael@0 397 return Point(temp.x, temp.y);
michael@0 398 }
michael@0 399
michael@0 400 GFX2D_API Rect TransformBounds(const Rect& rect) const;
michael@0 401
michael@0 402 // Apply a scale to this matrix. This scale will be applied -before- the
michael@0 403 // existing transformation of the matrix.
michael@0 404 Matrix4x4 &Scale(Float aX, Float aY, Float aZ)
michael@0 405 {
michael@0 406 _11 *= aX;
michael@0 407 _12 *= aX;
michael@0 408 _13 *= aX;
michael@0 409 _21 *= aY;
michael@0 410 _22 *= aY;
michael@0 411 _23 *= aY;
michael@0 412 _31 *= aZ;
michael@0 413 _32 *= aZ;
michael@0 414 _33 *= aZ;
michael@0 415
michael@0 416 return *this;
michael@0 417 }
michael@0 418
michael@0 419 Matrix4x4 &Translate(Float aX, Float aY, Float aZ)
michael@0 420 {
michael@0 421 _41 += aX * _11 + aY * _21 + aZ * _31;
michael@0 422 _42 += aX * _12 + aY * _22 + aZ * _32;
michael@0 423 _43 += aX * _13 + aY * _23 + aZ * _33;
michael@0 424 _44 += aX * _14 + aY * _24 + aZ * _34;
michael@0 425
michael@0 426 return *this;
michael@0 427 }
michael@0 428
michael@0 429 bool operator==(const Matrix4x4& o) const
michael@0 430 {
michael@0 431 // XXX would be nice to memcmp here, but that breaks IEEE 754 semantics
michael@0 432 return _11 == o._11 && _12 == o._12 && _13 == o._13 && _14 == o._14 &&
michael@0 433 _21 == o._21 && _22 == o._22 && _23 == o._23 && _24 == o._24 &&
michael@0 434 _31 == o._31 && _32 == o._32 && _33 == o._33 && _34 == o._34 &&
michael@0 435 _41 == o._41 && _42 == o._42 && _43 == o._43 && _44 == o._44;
michael@0 436 }
michael@0 437
michael@0 438 bool operator!=(const Matrix4x4& o) const
michael@0 439 {
michael@0 440 return !((*this) == o);
michael@0 441 }
michael@0 442
michael@0 443 Matrix4x4 operator*(const Matrix4x4 &aMatrix) const
michael@0 444 {
michael@0 445 Matrix4x4 matrix;
michael@0 446
michael@0 447 matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21 + _13 * aMatrix._31 + _14 * aMatrix._41;
michael@0 448 matrix._21 = _21 * aMatrix._11 + _22 * aMatrix._21 + _23 * aMatrix._31 + _24 * aMatrix._41;
michael@0 449 matrix._31 = _31 * aMatrix._11 + _32 * aMatrix._21 + _33 * aMatrix._31 + _34 * aMatrix._41;
michael@0 450 matrix._41 = _41 * aMatrix._11 + _42 * aMatrix._21 + _43 * aMatrix._31 + _44 * aMatrix._41;
michael@0 451 matrix._12 = _11 * aMatrix._12 + _12 * aMatrix._22 + _13 * aMatrix._32 + _14 * aMatrix._42;
michael@0 452 matrix._22 = _21 * aMatrix._12 + _22 * aMatrix._22 + _23 * aMatrix._32 + _24 * aMatrix._42;
michael@0 453 matrix._32 = _31 * aMatrix._12 + _32 * aMatrix._22 + _33 * aMatrix._32 + _34 * aMatrix._42;
michael@0 454 matrix._42 = _41 * aMatrix._12 + _42 * aMatrix._22 + _43 * aMatrix._32 + _44 * aMatrix._42;
michael@0 455 matrix._13 = _11 * aMatrix._13 + _12 * aMatrix._23 + _13 * aMatrix._33 + _14 * aMatrix._43;
michael@0 456 matrix._23 = _21 * aMatrix._13 + _22 * aMatrix._23 + _23 * aMatrix._33 + _24 * aMatrix._43;
michael@0 457 matrix._33 = _31 * aMatrix._13 + _32 * aMatrix._23 + _33 * aMatrix._33 + _34 * aMatrix._43;
michael@0 458 matrix._43 = _41 * aMatrix._13 + _42 * aMatrix._23 + _43 * aMatrix._33 + _44 * aMatrix._43;
michael@0 459 matrix._14 = _11 * aMatrix._14 + _12 * aMatrix._24 + _13 * aMatrix._34 + _14 * aMatrix._44;
michael@0 460 matrix._24 = _21 * aMatrix._14 + _22 * aMatrix._24 + _23 * aMatrix._34 + _24 * aMatrix._44;
michael@0 461 matrix._34 = _31 * aMatrix._14 + _32 * aMatrix._24 + _33 * aMatrix._34 + _34 * aMatrix._44;
michael@0 462 matrix._44 = _41 * aMatrix._14 + _42 * aMatrix._24 + _43 * aMatrix._34 + _44 * aMatrix._44;
michael@0 463
michael@0 464 return matrix;
michael@0 465 }
michael@0 466
michael@0 467
michael@0 468 /* Returns true if the matrix is an identity matrix.
michael@0 469 */
michael@0 470 bool IsIdentity() const
michael@0 471 {
michael@0 472 return _11 == 1.0f && _12 == 0.0f && _13 == 0.0f && _14 == 0.0f &&
michael@0 473 _21 == 0.0f && _22 == 1.0f && _23 == 0.0f && _24 == 0.0f &&
michael@0 474 _31 == 0.0f && _32 == 0.0f && _33 == 1.0f && _34 == 0.0f &&
michael@0 475 _41 == 0.0f && _42 == 0.0f && _43 == 0.0f && _44 == 1.0f;
michael@0 476 }
michael@0 477
michael@0 478 bool IsSingular() const
michael@0 479 {
michael@0 480 return Determinant() == 0.0;
michael@0 481 }
michael@0 482
michael@0 483 Float Determinant() const
michael@0 484 {
michael@0 485 return _14 * _23 * _32 * _41
michael@0 486 - _13 * _24 * _32 * _41
michael@0 487 - _14 * _22 * _33 * _41
michael@0 488 + _12 * _24 * _33 * _41
michael@0 489 + _13 * _22 * _34 * _41
michael@0 490 - _12 * _23 * _34 * _41
michael@0 491 - _14 * _23 * _31 * _42
michael@0 492 + _13 * _24 * _31 * _42
michael@0 493 + _14 * _21 * _33 * _42
michael@0 494 - _11 * _24 * _33 * _42
michael@0 495 - _13 * _21 * _34 * _42
michael@0 496 + _11 * _23 * _34 * _42
michael@0 497 + _14 * _22 * _31 * _43
michael@0 498 - _12 * _24 * _31 * _43
michael@0 499 - _14 * _21 * _32 * _43
michael@0 500 + _11 * _24 * _32 * _43
michael@0 501 + _12 * _21 * _34 * _43
michael@0 502 - _11 * _22 * _34 * _43
michael@0 503 - _13 * _22 * _31 * _44
michael@0 504 + _12 * _23 * _31 * _44
michael@0 505 + _13 * _21 * _32 * _44
michael@0 506 - _11 * _23 * _32 * _44
michael@0 507 - _12 * _21 * _33 * _44
michael@0 508 + _11 * _22 * _33 * _44;
michael@0 509 }
michael@0 510
michael@0 511 };
michael@0 512
michael@0 513 class Matrix5x4
michael@0 514 {
michael@0 515 public:
michael@0 516 Matrix5x4()
michael@0 517 : _11(1.0f), _12(0), _13(0), _14(0)
michael@0 518 , _21(0), _22(1.0f), _23(0), _24(0)
michael@0 519 , _31(0), _32(0), _33(1.0f), _34(0)
michael@0 520 , _41(0), _42(0), _43(0), _44(1.0f)
michael@0 521 , _51(0), _52(0), _53(0), _54(0)
michael@0 522 {}
michael@0 523 Matrix5x4(Float a11, Float a12, Float a13, Float a14,
michael@0 524 Float a21, Float a22, Float a23, Float a24,
michael@0 525 Float a31, Float a32, Float a33, Float a34,
michael@0 526 Float a41, Float a42, Float a43, Float a44,
michael@0 527 Float a51, Float a52, Float a53, Float a54)
michael@0 528 : _11(a11), _12(a12), _13(a13), _14(a14)
michael@0 529 , _21(a21), _22(a22), _23(a23), _24(a24)
michael@0 530 , _31(a31), _32(a32), _33(a33), _34(a34)
michael@0 531 , _41(a41), _42(a42), _43(a43), _44(a44)
michael@0 532 , _51(a51), _52(a52), _53(a53), _54(a54)
michael@0 533 {}
michael@0 534 Float _11, _12, _13, _14;
michael@0 535 Float _21, _22, _23, _24;
michael@0 536 Float _31, _32, _33, _34;
michael@0 537 Float _41, _42, _43, _44;
michael@0 538 Float _51, _52, _53, _54;
michael@0 539 };
michael@0 540
michael@0 541 }
michael@0 542 }
michael@0 543
michael@0 544 #endif /* MOZILLA_GFX_MATRIX_H_ */

mercurial