| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613 |
- /**
- * Represents a 3x3 matrix.
- *
- * A Note on Row-Major and Column-Major Ordering:
- *
- * The constructor and {@link Matrix3#set} method take arguments in
- * [row-major](https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order)
- * order, while internally they are stored in the {@link Matrix3#elements} array in column-major order.
- * This means that calling:
- * ```js
- * const m = new THREE.Matrix();
- * m.set( 11, 12, 13,
- * 21, 22, 23,
- * 31, 32, 33 );
- * ```
- * will result in the elements array containing:
- * ```js
- * m.elements = [ 11, 21, 31,
- * 12, 22, 32,
- * 13, 23, 33 ];
- * ```
- * and internally all calculations are performed using column-major ordering.
- * However, as the actual ordering makes no difference mathematically and
- * most people are used to thinking about matrices in row-major order, the
- * three.js documentation shows matrices in row-major order. Just bear in
- * mind that if you are reading the source code, you'll have to take the
- * transpose of any matrices outlined here to make sense of the calculations.
- */
- class Matrix3 {
- /**
- * Constructs a new 3x3 matrix. The arguments are supposed to be
- * in row-major order. If no arguments are provided, the constructor
- * initializes the matrix as an identity matrix.
- *
- * @param {number} [n11] - 1-1 matrix element.
- * @param {number} [n12] - 1-2 matrix element.
- * @param {number} [n13] - 1-3 matrix element.
- * @param {number} [n21] - 2-1 matrix element.
- * @param {number} [n22] - 2-2 matrix element.
- * @param {number} [n23] - 2-3 matrix element.
- * @param {number} [n31] - 3-1 matrix element.
- * @param {number} [n32] - 3-2 matrix element.
- * @param {number} [n33] - 3-3 matrix element.
- */
- constructor( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
- /**
- * This flag can be used for type testing.
- *
- * @type {boolean}
- * @readonly
- * @default true
- */
- Matrix3.prototype.isMatrix3 = true;
- /**
- * A column-major list of matrix values.
- *
- * @type {Array<number>}
- */
- this.elements = [
- 1, 0, 0,
- 0, 1, 0,
- 0, 0, 1
- ];
- if ( n11 !== undefined ) {
- this.set( n11, n12, n13, n21, n22, n23, n31, n32, n33 );
- }
- }
- /**
- * Sets the elements of the matrix.The arguments are supposed to be
- * in row-major order.
- *
- * @param {number} [n11] - 1-1 matrix element.
- * @param {number} [n12] - 1-2 matrix element.
- * @param {number} [n13] - 1-3 matrix element.
- * @param {number} [n21] - 2-1 matrix element.
- * @param {number} [n22] - 2-2 matrix element.
- * @param {number} [n23] - 2-3 matrix element.
- * @param {number} [n31] - 3-1 matrix element.
- * @param {number} [n32] - 3-2 matrix element.
- * @param {number} [n33] - 3-3 matrix element.
- * @return {Matrix3} A reference to this matrix.
- */
- set( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
- const te = this.elements;
- te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;
- te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;
- te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;
- return this;
- }
- /**
- * Sets this matrix to the 3x3 identity matrix.
- *
- * @return {Matrix3} A reference to this matrix.
- */
- identity() {
- this.set(
- 1, 0, 0,
- 0, 1, 0,
- 0, 0, 1
- );
- return this;
- }
- /**
- * Copies the values of the given matrix to this instance.
- *
- * @param {Matrix3} m - The matrix to copy.
- * @return {Matrix3} A reference to this matrix.
- */
- copy( m ) {
- const te = this.elements;
- const me = m.elements;
- te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ];
- te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ];
- te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ];
- return this;
- }
- /**
- * Extracts the basis of this matrix into the three axis vectors provided.
- *
- * @param {Vector3} xAxis - The basis's x axis.
- * @param {Vector3} yAxis - The basis's y axis.
- * @param {Vector3} zAxis - The basis's z axis.
- * @return {Matrix3} A reference to this matrix.
- */
- extractBasis( xAxis, yAxis, zAxis ) {
- xAxis.setFromMatrix3Column( this, 0 );
- yAxis.setFromMatrix3Column( this, 1 );
- zAxis.setFromMatrix3Column( this, 2 );
- return this;
- }
- /**
- * Set this matrix to the upper 3x3 matrix of the given 4x4 matrix.
- *
- * @param {Matrix4} m - The 4x4 matrix.
- * @return {Matrix3} A reference to this matrix.
- */
- setFromMatrix4( m ) {
- const me = m.elements;
- this.set(
- me[ 0 ], me[ 4 ], me[ 8 ],
- me[ 1 ], me[ 5 ], me[ 9 ],
- me[ 2 ], me[ 6 ], me[ 10 ]
- );
- return this;
- }
- /**
- * Post-multiplies this matrix by the given 3x3 matrix.
- *
- * @param {Matrix3} m - The matrix to multiply with.
- * @return {Matrix3} A reference to this matrix.
- */
- multiply( m ) {
- return this.multiplyMatrices( this, m );
- }
- /**
- * Pre-multiplies this matrix by the given 3x3 matrix.
- *
- * @param {Matrix3} m - The matrix to multiply with.
- * @return {Matrix3} A reference to this matrix.
- */
- premultiply( m ) {
- return this.multiplyMatrices( m, this );
- }
- /**
- * Multiples the given 3x3 matrices and stores the result
- * in this matrix.
- *
- * @param {Matrix3} a - The first matrix.
- * @param {Matrix3} b - The second matrix.
- * @return {Matrix3} A reference to this matrix.
- */
- multiplyMatrices( a, b ) {
- const ae = a.elements;
- const be = b.elements;
- const te = this.elements;
- const a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ];
- const a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ];
- const a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ];
- const b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ];
- const b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ];
- const b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ];
- te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31;
- te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32;
- te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33;
- te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31;
- te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32;
- te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33;
- te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31;
- te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32;
- te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33;
- return this;
- }
- /**
- * Multiplies every component of the matrix by the given scalar.
- *
- * @param {number} s - The scalar.
- * @return {Matrix3} A reference to this matrix.
- */
- multiplyScalar( s ) {
- const te = this.elements;
- te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;
- te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;
- te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;
- return this;
- }
- /**
- * Computes and returns the determinant of this matrix.
- *
- * @return {number} The determinant.
- */
- determinant() {
- const te = this.elements;
- const a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],
- d = te[ 3 ], e = te[ 4 ], f = te[ 5 ],
- g = te[ 6 ], h = te[ 7 ], i = te[ 8 ];
- return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;
- }
- /**
- * Inverts this matrix, using the [analytic method](https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution).
- * You can not invert with a determinant of zero. If you attempt this, the method produces
- * a zero matrix instead.
- *
- * @return {Matrix3} A reference to this matrix.
- */
- invert() {
- const te = this.elements,
- n11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ],
- n12 = te[ 3 ], n22 = te[ 4 ], n32 = te[ 5 ],
- n13 = te[ 6 ], n23 = te[ 7 ], n33 = te[ 8 ],
- t11 = n33 * n22 - n32 * n23,
- t12 = n32 * n13 - n33 * n12,
- t13 = n23 * n12 - n22 * n13,
- det = n11 * t11 + n21 * t12 + n31 * t13;
- if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0 );
- const detInv = 1 / det;
- te[ 0 ] = t11 * detInv;
- te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;
- te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;
- te[ 3 ] = t12 * detInv;
- te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;
- te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;
- te[ 6 ] = t13 * detInv;
- te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;
- te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;
- return this;
- }
- /**
- * Transposes this matrix in place.
- *
- * @return {Matrix3} A reference to this matrix.
- */
- transpose() {
- let tmp;
- const m = this.elements;
- tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;
- tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;
- tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;
- return this;
- }
- /**
- * Computes the normal matrix which is the inverse transpose of the upper
- * left 3x3 portion of the given 4x4 matrix.
- *
- * @param {Matrix4} matrix4 - The 4x4 matrix.
- * @return {Matrix3} A reference to this matrix.
- */
- getNormalMatrix( matrix4 ) {
- return this.setFromMatrix4( matrix4 ).invert().transpose();
- }
- /**
- * Transposes this matrix into the supplied array, and returns itself unchanged.
- *
- * @param {Array<number>} r - An array to store the transposed matrix elements.
- * @return {Matrix3} A reference to this matrix.
- */
- transposeIntoArray( r ) {
- const m = this.elements;
- r[ 0 ] = m[ 0 ];
- r[ 1 ] = m[ 3 ];
- r[ 2 ] = m[ 6 ];
- r[ 3 ] = m[ 1 ];
- r[ 4 ] = m[ 4 ];
- r[ 5 ] = m[ 7 ];
- r[ 6 ] = m[ 2 ];
- r[ 7 ] = m[ 5 ];
- r[ 8 ] = m[ 8 ];
- return this;
- }
- /**
- * Sets the UV transform matrix from offset, repeat, rotation, and center.
- *
- * @param {number} tx - Offset x.
- * @param {number} ty - Offset y.
- * @param {number} sx - Repeat x.
- * @param {number} sy - Repeat y.
- * @param {number} rotation - Rotation, in radians. Positive values rotate counterclockwise.
- * @param {number} cx - Center x of rotation.
- * @param {number} cy - Center y of rotation
- * @return {Matrix3} A reference to this matrix.
- */
- setUvTransform( tx, ty, sx, sy, rotation, cx, cy ) {
- const c = Math.cos( rotation );
- const s = Math.sin( rotation );
- this.set(
- sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx,
- - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty,
- 0, 0, 1
- );
- return this;
- }
- /**
- * Scales this matrix with the given scalar values.
- *
- * @param {number} sx - The amount to scale in the X axis.
- * @param {number} sy - The amount to scale in the Y axis.
- * @return {Matrix3} A reference to this matrix.
- */
- scale( sx, sy ) {
- this.premultiply( _m3.makeScale( sx, sy ) );
- return this;
- }
- /**
- * Rotates this matrix by the given angle.
- *
- * @param {number} theta - The rotation in radians.
- * @return {Matrix3} A reference to this matrix.
- */
- rotate( theta ) {
- this.premultiply( _m3.makeRotation( - theta ) );
- return this;
- }
- /**
- * Translates this matrix by the given scalar values.
- *
- * @param {number} tx - The amount to translate in the X axis.
- * @param {number} ty - The amount to translate in the Y axis.
- * @return {Matrix3} A reference to this matrix.
- */
- translate( tx, ty ) {
- this.premultiply( _m3.makeTranslation( tx, ty ) );
- return this;
- }
- // for 2D Transforms
- /**
- * Sets this matrix as a 2D translation transform.
- *
- * @param {number|Vector2} x - The amount to translate in the X axis or alternatively a translation vector.
- * @param {number} y - The amount to translate in the Y axis.
- * @return {Matrix3} A reference to this matrix.
- */
- makeTranslation( x, y ) {
- if ( x.isVector2 ) {
- this.set(
- 1, 0, x.x,
- 0, 1, x.y,
- 0, 0, 1
- );
- } else {
- this.set(
- 1, 0, x,
- 0, 1, y,
- 0, 0, 1
- );
- }
- return this;
- }
- /**
- * Sets this matrix as a 2D rotational transformation.
- *
- * @param {number} theta - The rotation in radians.
- * @return {Matrix3} A reference to this matrix.
- */
- makeRotation( theta ) {
- // counterclockwise
- const c = Math.cos( theta );
- const s = Math.sin( theta );
- this.set(
- c, - s, 0,
- s, c, 0,
- 0, 0, 1
- );
- return this;
- }
- /**
- * Sets this matrix as a 2D scale transform.
- *
- * @param {number} x - The amount to scale in the X axis.
- * @param {number} y - The amount to scale in the Y axis.
- * @return {Matrix3} A reference to this matrix.
- */
- makeScale( x, y ) {
- this.set(
- x, 0, 0,
- 0, y, 0,
- 0, 0, 1
- );
- return this;
- }
- /**
- * Returns `true` if this matrix is equal with the given one.
- *
- * @param {Matrix3} matrix - The matrix to test for equality.
- * @return {boolean} Whether this matrix is equal with the given one.
- */
- equals( matrix ) {
- const te = this.elements;
- const me = matrix.elements;
- for ( let i = 0; i < 9; i ++ ) {
- if ( te[ i ] !== me[ i ] ) return false;
- }
- return true;
- }
- /**
- * Sets the elements of the matrix from the given array.
- *
- * @param {Array<number>} array - The matrix elements in column-major order.
- * @param {number} [offset=0] - Index of the first element in the array.
- * @return {Matrix3} A reference to this matrix.
- */
- fromArray( array, offset = 0 ) {
- for ( let i = 0; i < 9; i ++ ) {
- this.elements[ i ] = array[ i + offset ];
- }
- return this;
- }
- /**
- * Writes the elements of this matrix to the given array. If no array is provided,
- * the method returns a new instance.
- *
- * @param {Array<number>} [array=[]] - The target array holding the matrix elements in column-major order.
- * @param {number} [offset=0] - Index of the first element in the array.
- * @return {Array<number>} The matrix elements in column-major order.
- */
- toArray( array = [], offset = 0 ) {
- const te = this.elements;
- array[ offset ] = te[ 0 ];
- array[ offset + 1 ] = te[ 1 ];
- array[ offset + 2 ] = te[ 2 ];
- array[ offset + 3 ] = te[ 3 ];
- array[ offset + 4 ] = te[ 4 ];
- array[ offset + 5 ] = te[ 5 ];
- array[ offset + 6 ] = te[ 6 ];
- array[ offset + 7 ] = te[ 7 ];
- array[ offset + 8 ] = te[ 8 ];
- return array;
- }
- /**
- * Returns a matrix with copied values from this instance.
- *
- * @return {Matrix3} A clone of this instance.
- */
- clone() {
- return new this.constructor().fromArray( this.elements );
- }
- }
- const _m3 = /*@__PURE__*/ new Matrix3();
- export { Matrix3 };
|