Matrix4.js 19.9 KB
Newer Older
R
Rich Harris 已提交
1 2 3
import { _Math } from './Math';
import { Vector3 } from './Vector3';

M
Mr.doob 已提交
4
/**
M
Mr.doob 已提交
5
 * @author mrdoob / http://mrdoob.com/
M
Mr.doob 已提交
6 7
 * @author supereggbert / http://www.paulbrunt.co.uk/
 * @author philogb / http://blog.thejit.org/
8
 * @author jordi_ros / http://plattsoft.com
9
 * @author D1plo1d / http://github.com/D1plo1d
10 11
 * @author alteredq / http://alteredqualia.com/
 * @author mikael emtinger / http://gomo.se/
M
Mr.doob 已提交
12
 * @author timknip / http://www.floorplanner.com/
13
 * @author bhouston / http://clara.io
14
 * @author WestLangley / http://github.com/WestLangley
M
Mr.doob 已提交
15 16
 */

M
Mr.doob 已提交
17
function Matrix4() {
18

19
	this.elements = new Float32Array( [
20

21 22 23 24
		1, 0, 0, 0,
		0, 1, 0, 0,
		0, 0, 1, 0,
		0, 0, 0, 1
25

26
	] );
M
Mr.doob 已提交
27

28
	if ( arguments.length > 0 ) {
29

30
		console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );
31 32

	}
33

M
Mr.doob 已提交
34
}
35

R
Rich Harris 已提交
36
Matrix4.prototype = {
37

R
Rich Harris 已提交
38
	constructor: Matrix4,
39

40 41
	isMatrix4: true,

42
	set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
43 44 45

		var te = this.elements;

46 47 48 49
		te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;
		te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;
		te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;
		te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;
M
Mr.doob 已提交
50

51 52 53 54
		return this;

	},

55
	identity: function () {
56

M
Mr.doob 已提交
57 58 59 60 61 62 63 64
		this.set(

			1, 0, 0, 0,
			0, 1, 0, 0,
			0, 0, 1, 0,
			0, 0, 0, 1

		);
65 66 67

		return this;

68
	},
M
Mr.doob 已提交
69

70 71
	clone: function () {

R
Rich Harris 已提交
72
		return new Matrix4().fromArray( this.elements );
73 74 75

	},

76
	copy: function ( m ) {
77

78
		this.elements.set( m.elements );
M
Mr.doob 已提交
79

80 81
		return this;

M
Mr.doob 已提交
82 83
	},

84 85 86 87 88
	copyPosition: function ( m ) {

		var te = this.elements;
		var me = m.elements;

89 90 91
		te[ 12 ] = me[ 12 ];
		te[ 13 ] = me[ 13 ];
		te[ 14 ] = me[ 14 ];
92 93 94 95 96

		return this;

	},

97
	extractBasis: function ( xAxis, yAxis, zAxis ) {
C
Colin Ballast 已提交
98

99 100 101
		xAxis.setFromMatrixColumn( this, 0 );
		yAxis.setFromMatrixColumn( this, 1 );
		zAxis.setFromMatrixColumn( this, 2 );
C
Colin Ballast 已提交
102

G
gero3 已提交
103
		return this;
C
Colin Ballast 已提交
104

G
gero3 已提交
105
	},
M
Mr.doob 已提交
106

107 108
	makeBasis: function ( xAxis, yAxis, zAxis ) {

109 110 111 112 113 114
		this.set(
			xAxis.x, yAxis.x, zAxis.x, 0,
			xAxis.y, yAxis.y, zAxis.y, 0,
			xAxis.z, yAxis.z, zAxis.z, 0,
			0,       0,       0,       1
		);
115

G
gero3 已提交
116
		return this;
117 118 119

	},

120
	extractRotation: function () {
121

122
		var v1;
123

W
WestLangley 已提交
124
		return function extractRotation( m ) {
125

R
Rich Harris 已提交
126
			if ( v1 === undefined ) v1 = new Vector3();
127 128 129 130

			var te = this.elements;
			var me = m.elements;

131 132 133
			var scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();
			var scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();
			var scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();
134

135 136 137
			te[ 0 ] = me[ 0 ] * scaleX;
			te[ 1 ] = me[ 1 ] * scaleX;
			te[ 2 ] = me[ 2 ] * scaleX;
138

139 140 141
			te[ 4 ] = me[ 4 ] * scaleY;
			te[ 5 ] = me[ 5 ] * scaleY;
			te[ 6 ] = me[ 6 ] * scaleY;
142

143 144 145
			te[ 8 ] = me[ 8 ] * scaleZ;
			te[ 9 ] = me[ 9 ] * scaleZ;
			te[ 10 ] = me[ 10 ] * scaleZ;
146 147 148 149 150 151 152

			return this;

		};

	}(),

M
Mr.doob 已提交
153 154
	makeRotationFromEuler: function ( euler ) {

R
Rich Harris 已提交
155
		if ( (euler && euler.isEuler) === false ) {
156

157
			console.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );
M
Mr.doob 已提交
158

159
		}
160 161 162

		var te = this.elements;

M
Mr.doob 已提交
163
		var x = euler.x, y = euler.y, z = euler.z;
164 165 166 167
		var a = Math.cos( x ), b = Math.sin( x );
		var c = Math.cos( y ), d = Math.sin( y );
		var e = Math.cos( z ), f = Math.sin( z );

168
		if ( euler.order === 'XYZ' ) {
169 170 171

			var ae = a * e, af = a * f, be = b * e, bf = b * f;

172 173 174
			te[ 0 ] = c * e;
			te[ 4 ] = - c * f;
			te[ 8 ] = d;
175

176 177 178
			te[ 1 ] = af + be * d;
			te[ 5 ] = ae - bf * d;
			te[ 9 ] = - b * c;
179

180 181 182
			te[ 2 ] = bf - ae * d;
			te[ 6 ] = be + af * d;
			te[ 10 ] = a * c;
183

M
Mr.doob 已提交
184
		} else if ( euler.order === 'YXZ' ) {
185 186 187

			var ce = c * e, cf = c * f, de = d * e, df = d * f;

188 189 190
			te[ 0 ] = ce + df * b;
			te[ 4 ] = de * b - cf;
			te[ 8 ] = a * d;
191

192 193 194
			te[ 1 ] = a * f;
			te[ 5 ] = a * e;
			te[ 9 ] = - b;
195

196 197 198
			te[ 2 ] = cf * b - de;
			te[ 6 ] = df + ce * b;
			te[ 10 ] = a * c;
199

M
Mr.doob 已提交
200
		} else if ( euler.order === 'ZXY' ) {
201 202 203

			var ce = c * e, cf = c * f, de = d * e, df = d * f;

204 205 206
			te[ 0 ] = ce - df * b;
			te[ 4 ] = - a * f;
			te[ 8 ] = de + cf * b;
207

208 209 210
			te[ 1 ] = cf + de * b;
			te[ 5 ] = a * e;
			te[ 9 ] = df - ce * b;
211

212 213 214
			te[ 2 ] = - a * d;
			te[ 6 ] = b;
			te[ 10 ] = a * c;
215

M
Mr.doob 已提交
216
		} else if ( euler.order === 'ZYX' ) {
217 218 219

			var ae = a * e, af = a * f, be = b * e, bf = b * f;

220 221 222
			te[ 0 ] = c * e;
			te[ 4 ] = be * d - af;
			te[ 8 ] = ae * d + bf;
223

224 225 226
			te[ 1 ] = c * f;
			te[ 5 ] = bf * d + ae;
			te[ 9 ] = af * d - be;
227

228 229 230
			te[ 2 ] = - d;
			te[ 6 ] = b * c;
			te[ 10 ] = a * c;
231

M
Mr.doob 已提交
232
		} else if ( euler.order === 'YZX' ) {
233 234 235

			var ac = a * c, ad = a * d, bc = b * c, bd = b * d;

236 237 238
			te[ 0 ] = c * e;
			te[ 4 ] = bd - ac * f;
			te[ 8 ] = bc * f + ad;
239

240 241 242
			te[ 1 ] = f;
			te[ 5 ] = a * e;
			te[ 9 ] = - b * e;
243

244 245 246
			te[ 2 ] = - d * e;
			te[ 6 ] = ad * f + bc;
			te[ 10 ] = ac - bd * f;
247

M
Mr.doob 已提交
248
		} else if ( euler.order === 'XZY' ) {
249 250 251

			var ac = a * c, ad = a * d, bc = b * c, bd = b * d;

252 253 254
			te[ 0 ] = c * e;
			te[ 4 ] = - f;
			te[ 8 ] = d * e;
255

256 257 258
			te[ 1 ] = ac * f + bd;
			te[ 5 ] = a * e;
			te[ 9 ] = ad * f - bc;
259

260 261 262
			te[ 2 ] = bc * f - ad;
			te[ 6 ] = b * e;
			te[ 10 ] = bd * f + ac;
263 264 265

		}

266
		// last column
267 268 269
		te[ 3 ] = 0;
		te[ 7 ] = 0;
		te[ 11 ] = 0;
270 271

		// bottom row
272 273 274 275
		te[ 12 ] = 0;
		te[ 13 ] = 0;
		te[ 14 ] = 0;
		te[ 15 ] = 1;
276

277 278 279 280
		return this;

	},

281
	makeRotationFromQuaternion: function ( q ) {
282 283 284 285 286 287 288 289 290

		var te = this.elements;

		var x = q.x, y = q.y, z = q.z, w = q.w;
		var x2 = x + x, y2 = y + y, z2 = z + z;
		var xx = x * x2, xy = x * y2, xz = x * z2;
		var yy = y * y2, yz = y * z2, zz = z * z2;
		var wx = w * x2, wy = w * y2, wz = w * z2;

291 292 293
		te[ 0 ] = 1 - ( yy + zz );
		te[ 4 ] = xy - wz;
		te[ 8 ] = xz + wy;
294

295 296 297
		te[ 1 ] = xy + wz;
		te[ 5 ] = 1 - ( xx + zz );
		te[ 9 ] = yz - wx;
298

299 300 301
		te[ 2 ] = xz - wy;
		te[ 6 ] = yz + wx;
		te[ 10 ] = 1 - ( xx + yy );
302

303
		// last column
304 305 306
		te[ 3 ] = 0;
		te[ 7 ] = 0;
		te[ 11 ] = 0;
307 308

		// bottom row
309 310 311 312
		te[ 12 ] = 0;
		te[ 13 ] = 0;
		te[ 14 ] = 0;
		te[ 15 ] = 1;
313

314 315 316 317
		return this;

	},

318
	lookAt: function () {
319

320
		var x, y, z;
M
Mr.doob 已提交
321

W
WestLangley 已提交
322
		return function lookAt( eye, target, up ) {
323

324 325
			if ( x === undefined ) {

R
Rich Harris 已提交
326 327 328
				x = new Vector3();
				y = new Vector3();
				z = new Vector3();
329 330

			}
331

332
			var te = this.elements;
M
Mr.doob 已提交
333

334
			z.subVectors( eye, target ).normalize();
M
Mr.doob 已提交
335

M
Mugen87 已提交
336
			if ( z.lengthSq() === 0 ) {
337

338
				z.z = 1;
339

340
			}
341

342
			x.crossVectors( up, z ).normalize();
343

M
Mugen87 已提交
344
			if ( x.lengthSq() === 0 ) {
M
Mikael Emtinger 已提交
345

346
				z.z += 0.0001;
347
				x.crossVectors( up, z ).normalize();
348

349
			}
350

351
			y.crossVectors( z, x );
M
Mikael Emtinger 已提交
352

M
Mr.doob 已提交
353

354 355 356
			te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;
			te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;
			te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;
M
Mr.doob 已提交
357

358
			return this;
M
Mr.doob 已提交
359

360
		};
361

362
	}(),
363

364 365 366 367
	multiply: function ( m, n ) {

		if ( n !== undefined ) {

368
			console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );
369 370 371
			return this.multiplyMatrices( m, n );

		}
372 373 374 375 376

		return this.multiplyMatrices( this, m );

	},

377 378 379 380 381 382
	premultiply: function ( m ) {

		return this.multiplyMatrices( m, this );

	},

383
	multiplyMatrices: function ( a, b ) {
384 385 386 387

		var ae = a.elements;
		var be = b.elements;
		var te = this.elements;
388

389 390 391 392
		var a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];
		var a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];
		var a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];
		var a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];
393

394 395 396 397
		var b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];
		var b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];
		var b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];
		var b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];
398

399 400 401 402
		te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
		te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
		te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
		te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
403

404 405 406 407
		te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
		te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
		te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
		te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
408

409 410 411 412
		te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
		te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
		te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
		te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
413

414 415 416 417
		te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
		te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
		te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
		te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
418

A
alteredq 已提交
419 420 421 422
		return this;

	},

423
	multiplyToArray: function ( a, b, r ) {
424 425 426

		var te = this.elements;

427
		this.multiplyMatrices( a, b );
428

429 430 431 432
		r[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];
		r[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];
		r[ 8 ]  = te[ 8 ]; r[ 9 ]  = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];
		r[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];
M
Mr.doob 已提交
433

434
		return this;
M
Mr.doob 已提交
435

436
	},
M
Mr.doob 已提交
437

438
	multiplyScalar: function ( s ) {
439 440 441

		var te = this.elements;

442 443 444 445
		te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;
		te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;
		te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;
		te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;
446

447 448
		return this;

449 450
	},

451
	applyToBufferAttribute: function () {
B
Ben Adams 已提交
452 453 454

		var v1;

455
		return function applyToBufferAttribute( attribute ) {
B
Ben Adams 已提交
456

R
Rich Harris 已提交
457
			if ( v1 === undefined ) v1 = new Vector3();
B
Ben Adams 已提交
458

459
			for ( var i = 0, l = attribute.count; i < l; i ++ ) {
B
Ben Adams 已提交
460

461 462 463
				v1.x = attribute.getX( i );
				v1.y = attribute.getY( i );
				v1.z = attribute.getZ( i );
B
Ben Adams 已提交
464 465 466

				v1.applyMatrix4( this );

467
				attribute.setXYZ( i, v1.x, v1.y, v1.z );
B
Ben Adams 已提交
468 469 470

			}

471
			return attribute;
B
Ben Adams 已提交
472 473 474 475 476

		};

	}(),

477
	determinant: function () {
478

479 480
		var te = this.elements;

481 482 483 484
		var n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];
		var n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];
		var n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];
		var n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];
485

486 487
		//TODO: make this more efficient
		//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
488

489
		return (
490
			n41 * (
491 492 493 494 495 496
				+ n14 * n23 * n32
				 - n13 * n24 * n32
				 - n14 * n22 * n33
				 + n12 * n24 * n33
				 + n13 * n22 * n34
				 - n12 * n23 * n34
M
Mr.doob 已提交
497
			) +
498
			n42 * (
499 500 501 502 503 504
				+ n11 * n23 * n34
				 - n11 * n24 * n33
				 + n14 * n21 * n33
				 - n13 * n21 * n34
				 + n13 * n24 * n31
				 - n14 * n23 * n31
M
Mr.doob 已提交
505
			) +
506
			n43 * (
507 508 509 510 511 512
				+ n11 * n24 * n32
				 - n11 * n22 * n34
				 - n14 * n21 * n32
				 + n12 * n21 * n34
				 + n14 * n22 * n31
				 - n12 * n24 * n31
M
Mr.doob 已提交
513 514
			) +
			n44 * (
515 516 517 518 519 520
				- n13 * n22 * n31
				 - n11 * n23 * n32
				 + n11 * n22 * n33
				 + n13 * n21 * n32
				 - n12 * n21 * n33
				 + n12 * n23 * n31
M
Mr.doob 已提交
521
			)
522

M
Mr.doob 已提交
523
		);
524 525

	},
M
Mr.doob 已提交
526

527
	transpose: function () {
528 529

		var te = this.elements;
530
		var tmp;
531

532 533 534
		tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;
		tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;
		tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;
535

536 537 538
		tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;
		tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;
		tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;
M
Mr.doob 已提交
539 540 541 542 543

		return this;

	},

544
	setPosition: function ( v ) {
545 546 547

		var te = this.elements;

548 549 550
		te[ 12 ] = v.x;
		te[ 13 ] = v.y;
		te[ 14 ] = v.z;
551

552
		return this;
553

554
	},
555

T
tschw 已提交
556
	getInverse: function ( m, throwOnDegenerate ) {
557

M
Mr.doob 已提交
558
		// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
T
tschw 已提交
559 560
		var te = this.elements,
			me = m.elements,
561

T
tschw 已提交
562 563 564 565
			n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],
			n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],
			n13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],
			n14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],
566

T
tschw 已提交
567 568 569 570
			t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,
			t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,
			t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,
			t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
571

T
tschw 已提交
572
		var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
573

F
Fabian Lange 已提交
574
		if ( det === 0 ) {
575

576
			var msg = "THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0";
577

578
			if ( throwOnDegenerate === true ) {
579

580
				throw new Error( msg );
581

M
Mr.doob 已提交
582
			} else {
583

584
				console.warn( msg );
585 586 587

			}

T
tschw 已提交
588
			return this.identity();
589

590
		}
591

C
Corey Maler 已提交
592
		var detInv = 1 / det;
593

C
Corey Maler 已提交
594 595 596 597
		te[ 0 ] = t11 * detInv;
		te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;
		te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;
		te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;
598

C
Corey Maler 已提交
599 600 601 602
		te[ 4 ] = t12 * detInv;
		te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;
		te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;
		te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;
T
tschw 已提交
603

C
Corey Maler 已提交
604 605 606 607
		te[ 8 ] = t13 * detInv;
		te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;
		te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;
		te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;
T
tschw 已提交
608

C
Corey Maler 已提交
609 610 611 612
		te[ 12 ] = t14 * detInv;
		te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;
		te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;
		te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;
T
tschw 已提交
613

C
Corey Maler 已提交
614
		return this;
615

616
	},
617

618
	scale: function ( v ) {
619 620

		var te = this.elements;
621 622
		var x = v.x, y = v.y, z = v.z;

623 624 625 626
		te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;
		te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;
		te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;
		te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;
627 628 629 630

		return this;

	},
I
ide user ide_gero3 已提交
631

632 633 634
	getMaxScaleOnAxis: function () {

		var te = this.elements;
I
ide user ide_gero3 已提交
635

636 637 638
		var scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];
		var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];
		var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];
639

M
Mr.doob 已提交
640
		return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );
641 642

	},
643

644
	makeTranslation: function ( x, y, z ) {
645 646 647

		this.set(

648 649 650
			1, 0, 0, x,
			0, 1, 0, y,
			0, 0, 1, z,
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665
			0, 0, 0, 1

		);

		return this;

	},

	makeRotationX: function ( theta ) {

		var c = Math.cos( theta ), s = Math.sin( theta );

		this.set(

			1, 0,  0, 0,
666
			0, c, - s, 0,
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683
			0, s,  c, 0,
			0, 0,  0, 1

		);

		return this;

	},

	makeRotationY: function ( theta ) {

		var c = Math.cos( theta ), s = Math.sin( theta );

		this.set(

			 c, 0, s, 0,
			 0, 1, 0, 0,
684
			- s, 0, c, 0,
685 686 687 688 689 690 691 692 693 694 695 696 697 698
			 0, 0, 0, 1

		);

		return this;

	},

	makeRotationZ: function ( theta ) {

		var c = Math.cos( theta ), s = Math.sin( theta );

		this.set(

699
			c, - s, 0, 0,
700 701 702 703 704 705 706 707 708 709 710 711 712 713
			s,  c, 0, 0,
			0,  0, 1, 0,
			0,  0, 0, 1

		);

		return this;

	},

	makeRotationAxis: function ( axis, angle ) {

		// Based on http://www.gamedev.net/reference/articles/article1199.asp

714 715 716 717 718
		var c = Math.cos( angle );
		var s = Math.sin( angle );
		var t = 1 - c;
		var x = axis.x, y = axis.y, z = axis.z;
		var tx = t * x, ty = t * y;
719 720 721

		this.set(

722
			tx * x + c, tx * y - s * z, tx * z + s * y, 0,
723 724 725 726 727 728 729 730 731 732
			tx * y + s * z, ty * y + c, ty * z - s * x, 0,
			tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
			0, 0, 0, 1

		);

		 return this;

	},

733
	makeScale: function ( x, y, z ) {
734 735 736

		this.set(

737 738 739
			x, 0, 0, 0,
			0, y, 0, 0,
			0, 0, z, 0,
740 741 742 743 744 745 746 747
			0, 0, 0, 1

		);

		return this;

	},

748 749 750 751 752 753 754 755 756 757 758 759 760 761 762
	makeShear: function ( x, y, z ) {

		this.set(

			1, y, z, 0,
			x, 1, z, 0,
			x, y, 1, 0,
			0, 0, 0, 1

		);

		return this;

	},

M
Mr.doob 已提交
763 764 765 766 767 768 769 770 771 772
	compose: function ( position, quaternion, scale ) {

		this.makeRotationFromQuaternion( quaternion );
		this.scale( scale );
		this.setPosition( position );

		return this;

	},

773 774
	decompose: function () {

775
		var vector, matrix;
776

W
WestLangley 已提交
777
		return function decompose( position, quaternion, scale ) {
778

779 780
			if ( vector === undefined ) {

R
Rich Harris 已提交
781 782
				vector = new Vector3();
				matrix = new Matrix4();
783 784

			}
785

786 787
			var te = this.elements;

788 789 790
			var sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();
			var sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();
			var sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();
791

792 793
			// if determine is negative, we need to invert one scale
			var det = this.determinant();
794
			if ( det < 0 ) {
795

796
				sx = - sx;
797

798 799
			}

800 801 802
			position.x = te[ 12 ];
			position.y = te[ 13 ];
			position.z = te[ 14 ];
803 804 805 806 807

			// scale the rotation part

			matrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()

808 809 810
			var invSX = 1 / sx;
			var invSY = 1 / sy;
			var invSZ = 1 / sz;
811

812 813 814
			matrix.elements[ 0 ] *= invSX;
			matrix.elements[ 1 ] *= invSX;
			matrix.elements[ 2 ] *= invSX;
815

816 817 818
			matrix.elements[ 4 ] *= invSY;
			matrix.elements[ 5 ] *= invSY;
			matrix.elements[ 6 ] *= invSY;
819

820 821 822
			matrix.elements[ 8 ] *= invSZ;
			matrix.elements[ 9 ] *= invSZ;
			matrix.elements[ 10 ] *= invSZ;
823 824 825 826 827 828 829 830 831 832 833 834 835

			quaternion.setFromRotationMatrix( matrix );

			scale.x = sx;
			scale.y = sy;
			scale.z = sz;

			return this;

		};

	}(),

836
	makePerspective: function ( left, right, top, bottom, near, far ) {
837

838 839
		if ( far === undefined ) {

M
Mugen87 已提交
840
			console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );
841 842 843

		}

844
		var te = this.elements;
845 846 847 848 849 850 851 852
		var x = 2 * near / ( right - left );
		var y = 2 * near / ( top - bottom );

		var a = ( right + left ) / ( right - left );
		var b = ( top + bottom ) / ( top - bottom );
		var c = - ( far + near ) / ( far - near );
		var d = - 2 * far * near / ( far - near );

853 854 855 856
		te[ 0 ] = x;	te[ 4 ] = 0;	te[ 8 ] = a;	te[ 12 ] = 0;
		te[ 1 ] = 0;	te[ 5 ] = y;	te[ 9 ] = b;	te[ 13 ] = 0;
		te[ 2 ] = 0;	te[ 6 ] = 0;	te[ 10 ] = c;	te[ 14 ] = d;
		te[ 3 ] = 0;	te[ 7 ] = 0;	te[ 11 ] = - 1;	te[ 15 ] = 0;
857 858 859 860 861 862

		return this;

	},

	makeOrthographic: function ( left, right, top, bottom, near, far ) {
863 864

		var te = this.elements;
865 866 867
		var w = 1.0 / ( right - left );
		var h = 1.0 / ( top - bottom );
		var p = 1.0 / ( far - near );
868

869 870 871
		var x = ( right + left ) * w;
		var y = ( top + bottom ) * h;
		var z = ( far + near ) * p;
872

873 874 875
		te[ 0 ] = 2 * w;	te[ 4 ] = 0;	te[ 8 ] = 0;	te[ 12 ] = - x;
		te[ 1 ] = 0;	te[ 5 ] = 2 * h;	te[ 9 ] = 0;	te[ 13 ] = - y;
		te[ 2 ] = 0;	te[ 6 ] = 0;	te[ 10 ] = - 2 * p;	te[ 14 ] = - z;
876
		te[ 3 ] = 0;	te[ 7 ] = 0;	te[ 11 ] = 0;	te[ 15 ] = 1;
877 878 879

		return this;

M
Mr.doob 已提交
880 881
	},

M
Mr.doob 已提交
882 883 884 885 886 887 888 889 890 891 892 893 894 895 896
	equals: function ( matrix ) {

		var te = this.elements;
		var me = matrix.elements;

		for ( var i = 0; i < 16; i ++ ) {

			if ( te[ i ] !== me[ i ] ) return false;

		}

		return true;

	},

897
	fromArray: function ( array, offset ) {
898

899 900 901 902 903 904 905
		if ( offset === undefined ) offset = 0;

		for( var i = 0; i < 16; i ++ ) {

			this.elements[ i ] = array[ i + offset ];

		}
906 907 908 909 910

		return this;

	},

T
tschw 已提交
911 912 913 914
	toArray: function ( array, offset ) {

		if ( array === undefined ) array = [];
		if ( offset === undefined ) offset = 0;
915 916 917

		var te = this.elements;

T
tschw 已提交
918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938
		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 ];
		array[ offset + 9 ]  = te[ 9 ];
		array[ offset + 10 ] = te[ 10 ];
		array[ offset + 11 ] = te[ 11 ];

		array[ offset + 12 ] = te[ 12 ];
		array[ offset + 13 ] = te[ 13 ];
		array[ offset + 14 ] = te[ 14 ];
		array[ offset + 15 ] = te[ 15 ];

		return array;
939

940
	}
P
philogb 已提交
941

942
};
R
Rich Harris 已提交
943 944


945
export { Matrix4 };