gfx/thebes/gfx3DMatrix.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: 4 -*-
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 GFX_3DMATRIX_H
michael@0 7 #define GFX_3DMATRIX_H
michael@0 8
michael@0 9 #include <gfxTypes.h>
michael@0 10 #include <gfxPoint3D.h>
michael@0 11 #include <gfxPointH3D.h>
michael@0 12 #include <gfxQuad.h>
michael@0 13
michael@0 14 struct gfxMatrix;
michael@0 15
michael@0 16 /**
michael@0 17 * This class represents a 3D transformation. The matrix is laid
michael@0 18 * out as follows:
michael@0 19 *
michael@0 20 * _11 _12 _13 _14
michael@0 21 * _21 _22 _23 _24
michael@0 22 * _31 _32 _33 _34
michael@0 23 * _41 _42 _43 _44
michael@0 24 *
michael@0 25 * This matrix is treated as row-major. Assuming we consider our vectors row
michael@0 26 * vectors, this matrix type will be identical in memory to the OpenGL and D3D
michael@0 27 * matrices. OpenGL matrices are column-major, however OpenGL also treats
michael@0 28 * vectors as column vectors, the double transposition makes everything work
michael@0 29 * out nicely.
michael@0 30 */
michael@0 31 class gfx3DMatrix
michael@0 32 {
michael@0 33 public:
michael@0 34 /**
michael@0 35 * Create matrix.
michael@0 36 */
michael@0 37 gfx3DMatrix(void);
michael@0 38
michael@0 39 /**
michael@0 40 * Matrix multiplication.
michael@0 41 */
michael@0 42 gfx3DMatrix operator*(const gfx3DMatrix &aMatrix) const;
michael@0 43 gfx3DMatrix& operator*=(const gfx3DMatrix &aMatrix);
michael@0 44
michael@0 45 gfxPointH3D& operator[](int aIndex)
michael@0 46 {
michael@0 47 NS_ABORT_IF_FALSE(aIndex >= 0 && aIndex <= 3, "Invalid matrix array index");
michael@0 48 return *reinterpret_cast<gfxPointH3D*>((&_11)+4*aIndex);
michael@0 49 }
michael@0 50 const gfxPointH3D& operator[](int aIndex) const
michael@0 51 {
michael@0 52 NS_ABORT_IF_FALSE(aIndex >= 0 && aIndex <= 3, "Invalid matrix array index");
michael@0 53 return *reinterpret_cast<const gfxPointH3D*>((&_11)+4*aIndex);
michael@0 54 }
michael@0 55
michael@0 56 /**
michael@0 57 * Return true if this matrix and |aMatrix| are the same matrix.
michael@0 58 */
michael@0 59 bool operator==(const gfx3DMatrix& aMatrix) const;
michael@0 60 bool operator!=(const gfx3DMatrix& aMatrix) const;
michael@0 61
michael@0 62 bool FuzzyEqual(const gfx3DMatrix& aMatrix) const;
michael@0 63
michael@0 64 /**
michael@0 65 * Divide all values in the matrix by a scalar value
michael@0 66 */
michael@0 67 gfx3DMatrix& operator/=(gfxFloat scalar);
michael@0 68
michael@0 69 /**
michael@0 70 * Create a 3D matrix from a gfxMatrix 2D affine transformation.
michael@0 71 *
michael@0 72 * \param aMatrix gfxMatrix 2D affine transformation.
michael@0 73 */
michael@0 74 static gfx3DMatrix From2D(const gfxMatrix &aMatrix);
michael@0 75
michael@0 76 /**
michael@0 77 * Returns true if the matrix is isomorphic to a 2D affine transformation
michael@0 78 * (i.e. as obtained by From2D). If it is, optionally returns the 2D
michael@0 79 * matrix in aMatrix.
michael@0 80 */
michael@0 81 bool Is2D(gfxMatrix* aMatrix) const;
michael@0 82 bool Is2D() const;
michael@0 83
michael@0 84 /**
michael@0 85 * Returns true if the matrix can be reduced to a 2D affine transformation
michael@0 86 * (i.e. as obtained by From2D). If it is, optionally returns the 2D
michael@0 87 * matrix in aMatrix. This should only be used on matrices required for
michael@0 88 * rendering, not for intermediate calculations. It is assumed that the 2D
michael@0 89 * matrix will only be used for transforming objects on to the z=0 plane,
michael@0 90 * therefore any z-component perspective is ignored. This means that if
michael@0 91 * aMatrix is applied to objects with z != 0, the results may be incorrect.
michael@0 92 *
michael@0 93 * Since drawing is to a 2d plane, any 3d transform without perspective
michael@0 94 * can be reduced by dropping the z row and column.
michael@0 95 */
michael@0 96 bool CanDraw2D(gfxMatrix* aMatrix = nullptr) const;
michael@0 97
michael@0 98 /**
michael@0 99 * Converts the matrix to one that doesn't modify the z coordinate of points,
michael@0 100 * but leaves the rest of the transformation unchanged.
michael@0 101 */
michael@0 102 gfx3DMatrix& ProjectTo2D();
michael@0 103
michael@0 104 /**
michael@0 105 * Returns true if the matrix is the identity matrix. The most important
michael@0 106 * property we require is that gfx3DMatrix().IsIdentity() returns true.
michael@0 107 */
michael@0 108 bool IsIdentity() const;
michael@0 109
michael@0 110 /**
michael@0 111 * Pre-multiplication transformation functions:
michael@0 112 *
michael@0 113 * These functions construct a temporary matrix containing
michael@0 114 * a single transformation and pre-multiply it onto the current
michael@0 115 * matrix.
michael@0 116 */
michael@0 117
michael@0 118 /**
michael@0 119 * Add a translation by aPoint to the matrix.
michael@0 120 *
michael@0 121 * This creates this temporary matrix:
michael@0 122 * | 1 0 0 0 |
michael@0 123 * | 0 1 0 0 |
michael@0 124 * | 0 0 1 0 |
michael@0 125 * | aPoint.x aPoint.y aPoint.z 1 |
michael@0 126 */
michael@0 127 void Translate(const gfxPoint3D& aPoint);
michael@0 128
michael@0 129 /**
michael@0 130 * Skew the matrix.
michael@0 131 *
michael@0 132 * This creates this temporary matrix:
michael@0 133 * | 1 tan(aYSkew) 0 0 |
michael@0 134 * | tan(aXSkew) 1 0 0 |
michael@0 135 * | 0 0 1 0 |
michael@0 136 * | 0 0 0 1 |
michael@0 137 */
michael@0 138 void SkewXY(double aXSkew, double aYSkew);
michael@0 139
michael@0 140 void SkewXY(double aSkew);
michael@0 141 void SkewXZ(double aSkew);
michael@0 142 void SkewYZ(double aSkew);
michael@0 143
michael@0 144 /**
michael@0 145 * Scale the matrix
michael@0 146 *
michael@0 147 * This creates this temporary matrix:
michael@0 148 * | aX 0 0 0 |
michael@0 149 * | 0 aY 0 0 |
michael@0 150 * | 0 0 aZ 0 |
michael@0 151 * | 0 0 0 1 |
michael@0 152 */
michael@0 153 void Scale(float aX, float aY, float aZ);
michael@0 154
michael@0 155 /**
michael@0 156 * Return the currently set scaling factors.
michael@0 157 */
michael@0 158 float GetXScale() const { return _11; }
michael@0 159 float GetYScale() const { return _22; }
michael@0 160 float GetZScale() const { return _33; }
michael@0 161
michael@0 162 /**
michael@0 163 * Rotate around the X axis..
michael@0 164 *
michael@0 165 * This creates this temporary matrix:
michael@0 166 * | 1 0 0 0 |
michael@0 167 * | 0 cos(aTheta) sin(aTheta) 0 |
michael@0 168 * | 0 -sin(aTheta) cos(aTheta) 0 |
michael@0 169 * | 0 0 0 1 |
michael@0 170 */
michael@0 171 void RotateX(double aTheta);
michael@0 172
michael@0 173 /**
michael@0 174 * Rotate around the Y axis..
michael@0 175 *
michael@0 176 * This creates this temporary matrix:
michael@0 177 * | cos(aTheta) 0 -sin(aTheta) 0 |
michael@0 178 * | 0 1 0 0 |
michael@0 179 * | sin(aTheta) 0 cos(aTheta) 0 |
michael@0 180 * | 0 0 0 1 |
michael@0 181 */
michael@0 182 void RotateY(double aTheta);
michael@0 183
michael@0 184 /**
michael@0 185 * Rotate around the Z axis..
michael@0 186 *
michael@0 187 * This creates this temporary matrix:
michael@0 188 * | cos(aTheta) sin(aTheta) 0 0 |
michael@0 189 * | -sin(aTheta) cos(aTheta) 0 0 |
michael@0 190 * | 0 0 1 0 |
michael@0 191 * | 0 0 0 1 |
michael@0 192 */
michael@0 193 void RotateZ(double aTheta);
michael@0 194
michael@0 195 /**
michael@0 196 * Apply perspective to the matrix.
michael@0 197 *
michael@0 198 * This creates this temporary matrix:
michael@0 199 * | 1 0 0 0 |
michael@0 200 * | 0 1 0 0 |
michael@0 201 * | 0 0 1 -1/aDepth |
michael@0 202 * | 0 0 0 1 |
michael@0 203 */
michael@0 204 void Perspective(float aDepth);
michael@0 205
michael@0 206 /**
michael@0 207 * Pre multiply an existing matrix onto the current
michael@0 208 * matrix
michael@0 209 */
michael@0 210 void PreMultiply(const gfx3DMatrix& aOther);
michael@0 211 void PreMultiply(const gfxMatrix& aOther);
michael@0 212
michael@0 213 /**
michael@0 214 * Post-multiplication transformation functions:
michael@0 215 *
michael@0 216 * These functions construct a temporary matrix containing
michael@0 217 * a single transformation and post-multiply it onto the current
michael@0 218 * matrix.
michael@0 219 */
michael@0 220
michael@0 221 /**
michael@0 222 * Add a translation by aPoint after the matrix.
michael@0 223 * This is functionally equivalent to:
michael@0 224 * matrix * gfx3DMatrix::Translation(aPoint)
michael@0 225 */
michael@0 226 void TranslatePost(const gfxPoint3D& aPoint);
michael@0 227
michael@0 228 void ScalePost(float aX, float aY, float aZ);
michael@0 229
michael@0 230 /**
michael@0 231 * Transforms a point according to this matrix.
michael@0 232 */
michael@0 233 gfxPoint Transform(const gfxPoint& point) const;
michael@0 234
michael@0 235 /**
michael@0 236 * Transforms a rectangle according to this matrix
michael@0 237 */
michael@0 238 gfxRect TransformBounds(const gfxRect& rect) const;
michael@0 239
michael@0 240
michael@0 241 gfxQuad TransformRect(const gfxRect& aRect) const;
michael@0 242
michael@0 243 /**
michael@0 244 * Transforms a 3D vector according to this matrix.
michael@0 245 */
michael@0 246 gfxPoint3D Transform3D(const gfxPoint3D& point) const;
michael@0 247 gfxPointH3D Transform4D(const gfxPointH3D& aPoint) const;
michael@0 248 gfxPointH3D TransposeTransform4D(const gfxPointH3D& aPoint) const;
michael@0 249
michael@0 250 gfxPoint ProjectPoint(const gfxPoint& aPoint) const;
michael@0 251 gfxRect ProjectRectBounds(const gfxRect& aRect) const;
michael@0 252
michael@0 253 /**
michael@0 254 * Transforms a point by the inverse of this matrix. In the case of perspective transforms, some screen
michael@0 255 * points have no equivalent in the untransformed plane (if they exist past the vanishing point). To
michael@0 256 * avoid this, we need to specify the bounds of the untransformed plane to restrict the search area.
michael@0 257 *
michael@0 258 * @param aPoint Point to untransform.
michael@0 259 * @param aChildBounds Bounds of the untransformed plane.
michael@0 260 * @param aOut Untransformed point.
michael@0 261 * @return Returns true if a point was found within a ChildBounds, false otherwise.
michael@0 262 */
michael@0 263 bool UntransformPoint(const gfxPoint& aPoint, const gfxRect& aChildBounds, gfxPoint* aOut) const;
michael@0 264
michael@0 265
michael@0 266 /**
michael@0 267 * Same as UntransformPoint, but untransforms a rect and returns the bounding rect of the result.
michael@0 268 * Returns an empty rect if the result doesn't intersect aChildBounds.
michael@0 269 */
michael@0 270 gfxRect UntransformBounds(const gfxRect& aRect, const gfxRect& aChildBounds) const;
michael@0 271
michael@0 272
michael@0 273 /**
michael@0 274 * Inverts this matrix, if possible. Otherwise, the matrix is left
michael@0 275 * unchanged.
michael@0 276 */
michael@0 277 gfx3DMatrix Inverse() const;
michael@0 278
michael@0 279 gfx3DMatrix& Invert()
michael@0 280 {
michael@0 281 *this = Inverse();
michael@0 282 return *this;
michael@0 283 }
michael@0 284
michael@0 285 gfx3DMatrix& Normalize();
michael@0 286
michael@0 287 gfxPointH3D TransposedVector(int aIndex) const
michael@0 288 {
michael@0 289 NS_ABORT_IF_FALSE(aIndex >= 0 && aIndex <= 3, "Invalid matrix array index");
michael@0 290 return gfxPointH3D(*((&_11)+aIndex), *((&_21)+aIndex), *((&_31)+aIndex), *((&_41)+aIndex));
michael@0 291 }
michael@0 292
michael@0 293 void SetTransposedVector(int aIndex, gfxPointH3D &aVector)
michael@0 294 {
michael@0 295 NS_ABORT_IF_FALSE(aIndex >= 0 && aIndex <= 3, "Invalid matrix array index");
michael@0 296 *((&_11)+aIndex) = aVector.x;
michael@0 297 *((&_21)+aIndex) = aVector.y;
michael@0 298 *((&_31)+aIndex) = aVector.z;
michael@0 299 *((&_41)+aIndex) = aVector.w;
michael@0 300 }
michael@0 301
michael@0 302 gfx3DMatrix& Transpose();
michael@0 303 gfx3DMatrix Transposed() const;
michael@0 304
michael@0 305 /**
michael@0 306 * Returns a unit vector that is perpendicular to the plane formed
michael@0 307 * by transform the screen plane (z=0) by this matrix.
michael@0 308 */
michael@0 309 gfxPoint3D GetNormalVector() const;
michael@0 310
michael@0 311 /**
michael@0 312 * Returns true if a plane transformed by this matrix will
michael@0 313 * have it's back face visible.
michael@0 314 */
michael@0 315 bool IsBackfaceVisible() const;
michael@0 316
michael@0 317 /**
michael@0 318 * Check if matrix is singular (no inverse exists).
michael@0 319 */
michael@0 320 bool IsSingular() const;
michael@0 321
michael@0 322 /**
michael@0 323 * Create a translation matrix.
michael@0 324 *
michael@0 325 * \param aX Translation on X-axis.
michael@0 326 * \param aY Translation on Y-axis.
michael@0 327 * \param aZ Translation on Z-axis.
michael@0 328 */
michael@0 329 static gfx3DMatrix Translation(float aX, float aY, float aZ);
michael@0 330 static gfx3DMatrix Translation(const gfxPoint3D& aPoint);
michael@0 331
michael@0 332 /**
michael@0 333 * Create a scale matrix. Scales uniformly along all axes.
michael@0 334 *
michael@0 335 * \param aScale Scale factor
michael@0 336 */
michael@0 337 static gfx3DMatrix ScalingMatrix(float aFactor);
michael@0 338
michael@0 339 /**
michael@0 340 * Create a scale matrix.
michael@0 341 */
michael@0 342 static gfx3DMatrix ScalingMatrix(float aX, float aY, float aZ);
michael@0 343
michael@0 344 gfxFloat Determinant() const;
michael@0 345
michael@0 346 void NudgeToIntegers(void);
michael@0 347
michael@0 348 private:
michael@0 349
michael@0 350 gfxFloat Determinant3x3() const;
michael@0 351 gfx3DMatrix Inverse3x3() const;
michael@0 352
michael@0 353 gfx3DMatrix Multiply2D(const gfx3DMatrix &aMatrix) const;
michael@0 354
michael@0 355 public:
michael@0 356
michael@0 357 /** Matrix elements */
michael@0 358 float _11, _12, _13, _14;
michael@0 359 float _21, _22, _23, _24;
michael@0 360 float _31, _32, _33, _34;
michael@0 361 float _41, _42, _43, _44;
michael@0 362 };
michael@0 363
michael@0 364 #endif /* GFX_3DMATRIX_H */

mercurial