Matrix4.js 23.3 KB
Newer Older
M
Mr.doob 已提交
1
/**
M
Mr.doob 已提交
2
 * @author mrdoob / http://mrdoob.com/
M
Mr.doob 已提交
3 4
 * @author supereggbert / http://www.paulbrunt.co.uk/
 * @author philogb / http://blog.thejit.org/
5
 * @author jordi_ros / http://plattsoft.com
6
 * @author D1plo1d / http://github.com/D1plo1d
7 8
 * @author alteredq / http://alteredqualia.com/
 * @author mikael emtinger / http://gomo.se/
M
Mr.doob 已提交
9
 * @author timknip / http://www.floorplanner.com/
B
Ben Houston 已提交
10
 * @author bhouston / http://exocortex.com
M
Mr.doob 已提交
11 12
 */

13

14 15
THREE.Matrix4 = function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {

16
	var te = this.elements = new Float32Array( 16 );
17

18 19
	// TODO: if n11 is undefined, then just set to identity, otherwise copy all other values into matrix
	//   we should not support semi specification of Matrix4, it is just weird.
M
Mr.doob 已提交
20

21 22 23 24
	te[0] = ( n11 !== undefined ) ? n11 : 1; te[4] = n12 || 0; te[8] = n13 || 0; te[12] = n14 || 0;
	te[1] = n21 || 0; te[5] = ( n22 !== undefined ) ? n22 : 1; te[9] = n23 || 0; te[13] = n24 || 0;
	te[2] = n31 || 0; te[6] = n32 || 0; te[10] = ( n33 !== undefined ) ? n33 : 1; te[14] = n34 || 0;
	te[3] = n41 || 0; te[7] = n42 || 0; te[11] = n43 || 0; te[15] = ( n44 !== undefined ) ? n44 : 1;
25

26
};
27

28
THREE.extend( THREE.Matrix4.prototype, {
29

30
	set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
31 32 33

		var te = this.elements;

34 35 36 37
		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 已提交
38

39 40 41 42
		return this;

	},

43
	identity: function () {
44

M
Mr.doob 已提交
45 46 47 48 49 50 51 52
		this.set(

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

		);
53 54 55

		return this;

56
	},
M
Mr.doob 已提交
57

58
	copy: function ( m ) {
59 60 61

		var me = m.elements;

M
Mr.doob 已提交
62 63
		this.set(

I
ide user ide_gero3 已提交
64 65 66 67
			me[0], me[4], me[8], me[12],
			me[1], me[5], me[9], me[13],
			me[2], me[6], me[10], me[14],
			me[3], me[7], me[11], me[15]
M
Mr.doob 已提交
68 69

		);
M
Mr.doob 已提交
70

71 72
		return this;

M
Mr.doob 已提交
73 74
	},

75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
	setRotationFromEuler: function ( v, order ) {

		var te = this.elements;

		var x = v.x, y = v.y, z = v.z;
		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 );

		if ( order === undefined || order === 'XYZ' ) {

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

			te[0] = c * e;
			te[4] = - c * f;
			te[8] = d;

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

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

		} else if ( order === 'YXZ' ) {

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

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

			te[1] = a * f;
			te[5] = a * e;
			te[9] = - b;

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

		} else if ( order === 'ZXY' ) {

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

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

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

			te[2] = - a * d;
			te[6] = b;
			te[10] = a * c;

		} else if ( order === 'ZYX' ) {

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

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

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

			te[2] = - d;
			te[6] = b * c;
			te[10] = a * c;

		} else if ( order === 'YZX' ) {

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

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

			te[1] = f;
			te[5] = a * e;
			te[9] = - b * e;

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

		} else if ( order === 'XZY' ) {

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

			te[0] = c * e;
			te[4] = - f;
			te[8] = d * e;

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

			te[2] = bc * f - ad;
			te[6] = b * e;
			te[10] = bd * f + ac;

		}

		return this;

	},

	setRotationFromQuaternion: function ( q ) {

		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;

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

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

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

		return this;

	},

212
	lookAt: function() {
213

M
Mr.doob 已提交
214 215 216 217
		var x = new THREE.Vector3();
		var y = new THREE.Vector3();
		var z = new THREE.Vector3();

218
		return function ( eye, target, up ) {
219

220
			var te = this.elements;
M
Mr.doob 已提交
221

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

224
			if ( z.length() === 0 ) {
225

226
				z.z = 1;
227

228
			}
229

230
			x.crossVectors( up, z ).normalize();
231

232
			if ( x.length() === 0 ) {
M
Mikael Emtinger 已提交
233

234 235
				z.x += 0.0001;
				x.crossVectors( up, z ).normalize();
236

237
			}
238

239
			y.crossVectors( z, x );
M
Mikael Emtinger 已提交
240

M
Mr.doob 已提交
241

242 243 244
			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 已提交
245

246
			return this;
M
Mr.doob 已提交
247

248
		};
249

250
	}(),
251

252 253 254 255 256 257 258 259
	multiply: function ( m, n ) {

		if ( n !== undefined ) {

			console.warn( 'DEPRECATED: Matrix4\'s .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );
			return this.multiplyMatrices( m, n );

		}
260 261 262 263 264 265

		return this.multiplyMatrices( this, m );

	},

	multiplyMatrices: function ( a, b ) {
266 267 268 269

		var ae = a.elements;
		var be = b.elements;
		var te = this.elements;
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290

		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];

		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];

		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;

		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;

291
		te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
292 293 294 295 296 297 298 299
		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;

		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;
300

A
alteredq 已提交
301 302 303 304
		return this;

	},

305
	multiplyToArray: function ( a, b, r ) {
306 307 308

		var te = this.elements;

309
		this.multiplyMatrices( a, b );
310

311 312 313 314
		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 已提交
315

316
		return this;
M
Mr.doob 已提交
317

318
	},
M
Mr.doob 已提交
319

320
	multiplyScalar: function ( s ) {
321 322 323

		var te = this.elements;

324 325 326 327
		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;
328

329 330
		return this;

331 332
	},

333 334
	multiplyVector3: function ( vector ) {

335 336
		console.warn( 'DEPRECATED: Matrix4\'s .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' );
		return vector.applyProjection( this );
337 338 339 340 341

	},

	multiplyVector4: function ( vector ) {

342
		console.warn( 'DEPRECATED: Matrix4\'s .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
343 344 345 346
		return vector.applyMatrix4( this );

	},

347
	multiplyVector3Array: function() {
348

349
		var v1 = new THREE.Vector3();
M
Mr.doob 已提交
350

351
		return function ( a ) {
352

353
			for ( var i = 0, il = a.length; i < il; i += 3 ) {
354

355 356 357
				v1.x = a[ i ];
				v1.y = a[ i + 1 ];
				v1.z = a[ i + 2 ];
358

359
				v1.applyProjection( this );
360

361 362 363
				a[ i ]     = v1.x;
				a[ i + 1 ] = v1.y;
				a[ i + 2 ] = v1.z;
364

365
			}
366

367
			return a;
368

369 370 371
		};

	}(),
372

M
Mr.doob 已提交
373
	rotateAxis: function ( v ) {
374 375

		var te = this.elements;
M
Mr.doob 已提交
376 377
		var vx = v.x, vy = v.y, vz = v.z;

378 379 380
		v.x = vx * te[0] + vy * te[4] + vz * te[8];
		v.y = vx * te[1] + vy * te[5] + vz * te[9];
		v.z = vx * te[2] + vy * te[6] + vz * te[10];
M
Mr.doob 已提交
381 382 383 384 385 386 387 388

		v.normalize();

		return v;

	},

	crossVector: function ( a ) {
389 390

		var te = this.elements;
M
Mr.doob 已提交
391 392
		var v = new THREE.Vector4();

393 394 395
		v.x = te[0] * a.x + te[4] * a.y + te[8] * a.z + te[12] * a.w;
		v.y = te[1] * a.x + te[5] * a.y + te[9] * a.z + te[13] * a.w;
		v.z = te[2] * a.x + te[6] * a.y + te[10] * a.z + te[14] * a.w;
M
Mr.doob 已提交
396

397
		v.w = ( a.w ) ? te[3] * a.x + te[7] * a.y + te[11] * a.z + te[15] * a.w : 1;
M
Mr.doob 已提交
398 399 400 401 402

		return v;

	},

403
	determinant: function () {
404

405 406
		var te = this.elements;

407 408 409 410
		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];
411

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

415
		return (
416
			n41 * (
M
Mr.doob 已提交
417 418 419 420 421 422 423
				+n14 * n23 * n32
				-n13 * n24 * n32
				-n14 * n22 * n33
				+n12 * n24 * n33
				+n13 * n22 * n34
				-n12 * n23 * n34
			) +
424
			n42 * (
M
Mr.doob 已提交
425 426 427 428 429 430 431
				+n11 * n23 * n34
				-n11 * n24 * n33
				+n14 * n21 * n33
				-n13 * n21 * n34
				+n13 * n24 * n31
				-n14 * n23 * n31
			) +
432
			n43 * (
M
Mr.doob 已提交
433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
				+n11 * n24 * n32
				-n11 * n22 * n34
				-n14 * n21 * n32
				+n12 * n21 * n34
				+n14 * n22 * n31
				-n12 * n24 * n31
			) +
			n44 * (
				-n13 * n22 * n31
				-n11 * n23 * n32
				+n11 * n22 * n33
				+n13 * n21 * n32
				-n12 * n21 * n33
				+n12 * n23 * n31
			)
448

M
Mr.doob 已提交
449
		);
450 451

	},
M
Mr.doob 已提交
452

453
	transpose: function () {
454 455

		var te = this.elements;
456
		var tmp;
457

458 459 460
		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;
461

462 463 464
		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 已提交
465 466 467 468 469

		return this;

	},

470
	flattenToArray: function ( flat ) {
A
alteredq 已提交
471

472
		var te = this.elements;
473 474
		flat[ 0 ] = te[0]; flat[ 1 ] = te[1]; flat[ 2 ] = te[2]; flat[ 3 ] = te[3];
		flat[ 4 ] = te[4]; flat[ 5 ] = te[5]; flat[ 6 ] = te[6]; flat[ 7 ] = te[7];
M
Mr.doob 已提交
475
		flat[ 8 ] = te[8]; flat[ 9 ] = te[9]; flat[ 10 ] = te[10]; flat[ 11 ] = te[11];
476
		flat[ 12 ] = te[12]; flat[ 13 ] = te[13]; flat[ 14 ] = te[14]; flat[ 15 ] = te[15];
477

478
		return flat;
M
Mr.doob 已提交
479

480
	},
481

482
	flattenToArrayOffset: function( flat, offset ) {
483

484
		var te = this.elements;
485 486 487 488
		flat[ offset ] = te[0];
		flat[ offset + 1 ] = te[1];
		flat[ offset + 2 ] = te[2];
		flat[ offset + 3 ] = te[3];
A
alteredq 已提交
489

490 491 492 493
		flat[ offset + 4 ] = te[4];
		flat[ offset + 5 ] = te[5];
		flat[ offset + 6 ] = te[6];
		flat[ offset + 7 ] = te[7];
A
alteredq 已提交
494

495 496 497 498
		flat[ offset + 8 ]  = te[8];
		flat[ offset + 9 ]  = te[9];
		flat[ offset + 10 ] = te[10];
		flat[ offset + 11 ] = te[11];
A
alteredq 已提交
499

500 501 502 503
		flat[ offset + 12 ] = te[12];
		flat[ offset + 13 ] = te[13];
		flat[ offset + 14 ] = te[14];
		flat[ offset + 15 ] = te[15];
A
alteredq 已提交
504 505 506 507 508

		return flat;

	},

509
	getPosition: function() {
510

511
		var v1 = new THREE.Vector3();
M
Mr.doob 已提交
512

513
		return function () {
514

515 516
			console.warn( 'DEPRECATED: Matrix4\'s .getPosition() has been removed. Use Vector3.getPositionFromMatrix( matrix ) instead.' );

517 518 519 520 521 522
			var te = this.elements;
			return v1.set( te[12], te[13], te[14] );

		};

	}(),
523

524
	setPosition: function ( v ) {
525 526 527

		var te = this.elements;

528 529 530
		te[12] = v.x;
		te[13] = v.y;
		te[14] = v.z;
531

532
		return this;
533

534
	},
535

536 537
	getInverse: function ( m, throwOnInvertible ) {

M
Mr.doob 已提交
538
		// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
539 540 541
		var te = this.elements;
		var me = m.elements;

I
ide user ide_gero3 已提交
542 543 544 545
		var n11 = me[0], n12 = me[4], n13 = me[8], n14 = me[12];
		var n21 = me[1], n22 = me[5], n23 = me[9], n24 = me[13];
		var n31 = me[2], n32 = me[6], n33 = me[10], n34 = me[14];
		var n41 = me[3], n42 = me[7], n43 = me[11], n44 = me[15];
546

547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
		te[0] = n23*n34*n42 - n24*n33*n42 + n24*n32*n43 - n22*n34*n43 - n23*n32*n44 + n22*n33*n44;
		te[4] = n14*n33*n42 - n13*n34*n42 - n14*n32*n43 + n12*n34*n43 + n13*n32*n44 - n12*n33*n44;
		te[8] = n13*n24*n42 - n14*n23*n42 + n14*n22*n43 - n12*n24*n43 - n13*n22*n44 + n12*n23*n44;
		te[12] = n14*n23*n32 - n13*n24*n32 - n14*n22*n33 + n12*n24*n33 + n13*n22*n34 - n12*n23*n34;
		te[1] = n24*n33*n41 - n23*n34*n41 - n24*n31*n43 + n21*n34*n43 + n23*n31*n44 - n21*n33*n44;
		te[5] = n13*n34*n41 - n14*n33*n41 + n14*n31*n43 - n11*n34*n43 - n13*n31*n44 + n11*n33*n44;
		te[9] = n14*n23*n41 - n13*n24*n41 - n14*n21*n43 + n11*n24*n43 + n13*n21*n44 - n11*n23*n44;
		te[13] = n13*n24*n31 - n14*n23*n31 + n14*n21*n33 - n11*n24*n33 - n13*n21*n34 + n11*n23*n34;
		te[2] = n22*n34*n41 - n24*n32*n41 + n24*n31*n42 - n21*n34*n42 - n22*n31*n44 + n21*n32*n44;
		te[6] = n14*n32*n41 - n12*n34*n41 - n14*n31*n42 + n11*n34*n42 + n12*n31*n44 - n11*n32*n44;
		te[10] = n12*n24*n41 - n14*n22*n41 + n14*n21*n42 - n11*n24*n42 - n12*n21*n44 + n11*n22*n44;
		te[14] = n14*n22*n31 - n12*n24*n31 - n14*n21*n32 + n11*n24*n32 + n12*n21*n34 - n11*n22*n34;
		te[3] = n23*n32*n41 - n22*n33*n41 - n23*n31*n42 + n21*n33*n42 + n22*n31*n43 - n21*n32*n43;
		te[7] = n12*n33*n41 - n13*n32*n41 + n13*n31*n42 - n11*n33*n42 - n12*n31*n43 + n11*n32*n43;
		te[11] = n13*n22*n41 - n12*n23*n41 - n13*n21*n42 + n11*n23*n42 + n12*n21*n43 - n11*n22*n43;
		te[15] = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33;
563

564 565
		var det = me[ 0 ] * te[ 0 ] + me[ 1 ] * te[ 4 ] + me[ 2 ] * te[ 8 ] + me[ 3 ] * te[ 12 ];

M
Mr.doob 已提交
566
		if ( det == 0 ) {
567 568 569

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

M
Mr.doob 已提交
570
			if ( throwOnInvertible || false ) {
571 572 573

				throw new Error( msg ); 

M
Mr.doob 已提交
574
			} else {
575 576 577 578 579 580 581 582 583 584

				console.warn( msg );

			}

			this.identity();

			return this;
		}

585
		this.multiplyScalar( 1 / det );
586 587

		return this;
588

589
	},
590

591
	compose: function() {
592

593 594 595 596
		var mRotation = new THREE.Matrix4(),
			mScale = new THREE.Matrix4();
		
		return function ( translation, rotation, scale ) {
597

598
			var te = this.elements;
M
Mr.doob 已提交
599

600 601
			mRotation.identity();
			mRotation.setRotationFromQuaternion( rotation );
602

603
			mScale.makeScale( scale.x, scale.y, scale.z );
604

605
			this.multiplyMatrices( mRotation, mScale );
606

607 608 609
			te[12] = translation.x;
			te[13] = translation.y;
			te[14] = translation.z;
610

611
			return this;
612

613
		};
614

615
	}(),
616

617
	decompose: function() {
618

619 620
		var x = new THREE.Vector3(),
			y = new THREE.Vector3(),
621 622
			z = new THREE.Vector3(),
			matrix = new THREE.Matrix4();
M
Mr.doob 已提交
623

624
		return function ( translation, rotation, scale ) {
625

626
			var te = this.elements;
627

M
Mr.doob 已提交
628
			// grab the axis vectors
629 630 631
			x.set( te[0], te[1], te[2] );
			y.set( te[4], te[5], te[6] );
			z.set( te[8], te[9], te[10] );
632

633 634 635
			translation = ( translation instanceof THREE.Vector3 ) ? translation : new THREE.Vector3();
			rotation = ( rotation instanceof THREE.Quaternion ) ? rotation : new THREE.Quaternion();
			scale = ( scale instanceof THREE.Vector3 ) ? scale : new THREE.Vector3();
636

637 638 639
			scale.x = x.length();
			scale.y = y.length();
			scale.z = z.length();
640

641 642 643
			translation.x = te[12];
			translation.y = te[13];
			translation.z = te[14];
644

645
			// scale the rotation part
M
Mr.doob 已提交
646

647
			matrix.copy( this );
648

649 650 651
			matrix.elements[0] /= scale.x;
			matrix.elements[1] /= scale.x;
			matrix.elements[2] /= scale.x;
652

653 654 655
			matrix.elements[4] /= scale.y;
			matrix.elements[5] /= scale.y;
			matrix.elements[6] /= scale.y;
656

657 658 659
			matrix.elements[8] /= scale.z;
			matrix.elements[9] /= scale.z;
			matrix.elements[10] /= scale.z;
660

661
			rotation.setFromRotationMatrix( matrix );
662

663 664 665 666 667
			return [ translation, rotation, scale ];

		};

	}(),
M
Mr.doob 已提交
668

669
	extractPosition: function ( m ) {
670 671 672 673

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

I
ide user ide_gero3 已提交
674 675 676
		te[12] = me[12];
		te[13] = me[13];
		te[14] = me[14];
M
Mr.doob 已提交
677

M
Mr.doob 已提交
678 679
		return this;

680
	},
681

682
	extractRotation: function() {
683

684
		var v1 = new THREE.Vector3();
M
Mr.doob 已提交
685

686
		return function ( m ) {
687

688 689
			var te = this.elements;
			var me = m.elements;
M
Mr.doob 已提交
690

691 692 693
			var scaleX = 1 / v1.set( me[0], me[1], me[2] ).length();
			var scaleY = 1 / v1.set( me[4], me[5], me[6] ).length();
			var scaleZ = 1 / v1.set( me[8], me[9], me[10] ).length();
P
philogb 已提交
694

695 696 697
			te[0] = me[0] * scaleX;
			te[1] = me[1] * scaleX;
			te[2] = me[2] * scaleX;
698

699 700 701
			te[4] = me[4] * scaleY;
			te[5] = me[5] * scaleY;
			te[6] = me[6] * scaleY;
M
Mr.doob 已提交
702

703 704 705
			te[8] = me[8] * scaleZ;
			te[9] = me[9] * scaleZ;
			te[10] = me[10] * scaleZ;
M
Mr.doob 已提交
706

707
			return this;
M
Mr.doob 已提交
708

709
		};
710

711
	}(),
712

713
	translate: function ( v ) {
714 715

		var te = this.elements;
716
		var x = v.x, y = v.y, z = v.z;
717

718 719 720 721
		te[12] = te[0] * x + te[4] * y + te[8] * z + te[12];
		te[13] = te[1] * x + te[5] * y + te[9] * z + te[13];
		te[14] = te[2] * x + te[6] * y + te[10] * z + te[14];
		te[15] = te[3] * x + te[7] * y + te[11] * z + te[15];
722 723 724 725 726 727

		return this;

	},

	rotateX: function ( angle ) {
728 729

		var te = this.elements;
730 731 732 733 734 735 736 737
		var m12 = te[4];
		var m22 = te[5];
		var m32 = te[6];
		var m42 = te[7];
		var m13 = te[8];
		var m23 = te[9];
		var m33 = te[10];
		var m43 = te[11];
738 739
		var c = Math.cos( angle );
		var s = Math.sin( angle );
740

741 742 743 744
		te[4] = c * m12 + s * m13;
		te[5] = c * m22 + s * m23;
		te[6] = c * m32 + s * m33;
		te[7] = c * m42 + s * m43;
745

746 747 748 749
		te[8] = c * m13 - s * m12;
		te[9] = c * m23 - s * m22;
		te[10] = c * m33 - s * m32;
		te[11] = c * m43 - s * m42;
750 751 752

		return this;

753
	},
754 755

	rotateY: function ( angle ) {
756 757

		var te = this.elements;
758 759 760 761 762 763 764 765
		var m11 = te[0];
		var m21 = te[1];
		var m31 = te[2];
		var m41 = te[3];
		var m13 = te[8];
		var m23 = te[9];
		var m33 = te[10];
		var m43 = te[11];
766 767
		var c = Math.cos( angle );
		var s = Math.sin( angle );
768

769 770 771 772
		te[0] = c * m11 - s * m13;
		te[1] = c * m21 - s * m23;
		te[2] = c * m31 - s * m33;
		te[3] = c * m41 - s * m43;
773

774 775 776 777
		te[8] = c * m13 + s * m11;
		te[9] = c * m23 + s * m21;
		te[10] = c * m33 + s * m31;
		te[11] = c * m43 + s * m41;
778 779 780 781 782 783

		return this;

	},

	rotateZ: function ( angle ) {
784 785

		var te = this.elements;
786 787 788 789 790 791 792 793
		var m11 = te[0];
		var m21 = te[1];
		var m31 = te[2];
		var m41 = te[3];
		var m12 = te[4];
		var m22 = te[5];
		var m32 = te[6];
		var m42 = te[7];
794 795
		var c = Math.cos( angle );
		var s = Math.sin( angle );
796

797 798 799 800
		te[0] = c * m11 + s * m12;
		te[1] = c * m21 + s * m22;
		te[2] = c * m31 + s * m32;
		te[3] = c * m41 + s * m42;
801

802 803 804 805
		te[4] = c * m12 - s * m11;
		te[5] = c * m22 - s * m21;
		te[6] = c * m32 - s * m31;
		te[7] = c * m42 - s * m41;
806 807 808 809 810

		return this;

	},

811
	rotateByAxis: function ( axis, angle ) {
812 813 814

		var te = this.elements;

815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830
		// optimize by checking axis

		if ( axis.x === 1 && axis.y === 0 && axis.z === 0 ) {

			return this.rotateX( angle );

		} else if ( axis.x === 0 && axis.y === 1 && axis.z === 0 ) {

			return this.rotateY( angle );

		} else if ( axis.x === 0 && axis.y === 0 && axis.z === 1 ) {

			return this.rotateZ( angle );

		}

831 832
		var x = axis.x, y = axis.y, z = axis.z;
		var n = Math.sqrt(x * x + y * y + z * z);
833 834 835 836 837

		x /= n;
		y /= n;
		z /= n;

838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858
		var xx = x * x, yy = y * y, zz = z * z;
		var c = Math.cos( angle );
		var s = Math.sin( angle );
		var oneMinusCosine = 1 - c;
		var xy = x * y * oneMinusCosine;
		var xz = x * z * oneMinusCosine;
		var yz = y * z * oneMinusCosine;
		var xs = x * s;
		var ys = y * s;
		var zs = z * s;

		var r11 = xx + (1 - xx) * c;
		var r21 = xy + zs;
		var r31 = xz - ys;
		var r12 = xy - zs;
		var r22 = yy + (1 - yy) * c;
		var r32 = yz + xs;
		var r13 = xz + ys;
		var r23 = yz - xs;
		var r33 = zz + (1 - zz) * c;

859 860 861 862
		var m11 = te[0], m21 = te[1], m31 = te[2], m41 = te[3];
		var m12 = te[4], m22 = te[5], m32 = te[6], m42 = te[7];
		var m13 = te[8], m23 = te[9], m33 = te[10], m43 = te[11];
		var m14 = te[12], m24 = te[13], m34 = te[14], m44 = te[15];
863

864 865 866 867
		te[0] = r11 * m11 + r21 * m12 + r31 * m13;
		te[1] = r11 * m21 + r21 * m22 + r31 * m23;
		te[2] = r11 * m31 + r21 * m32 + r31 * m33;
		te[3] = r11 * m41 + r21 * m42 + r31 * m43;
868

869 870 871 872
		te[4] = r12 * m11 + r22 * m12 + r32 * m13;
		te[5] = r12 * m21 + r22 * m22 + r32 * m23;
		te[6] = r12 * m31 + r22 * m32 + r32 * m33;
		te[7] = r12 * m41 + r22 * m42 + r32 * m43;
873

874 875 876 877
		te[8] = r13 * m11 + r23 * m12 + r33 * m13;
		te[9] = r13 * m21 + r23 * m22 + r33 * m23;
		te[10] = r13 * m31 + r23 * m32 + r33 * m33;
		te[11] = r13 * m41 + r23 * m42 + r33 * m43;
878 879 880 881 882 883

		return this;

	},

	scale: function ( v ) {
884 885

		var te = this.elements;
886 887
		var x = v.x, y = v.y, z = v.z;

888 889 890 891
		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;
892 893 894 895

		return this;

	},
I
ide user ide_gero3 已提交
896

897 898 899
	getMaxScaleOnAxis: function () {

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

M
Mr.doob 已提交
901 902 903
		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];
904 905 906 907

		return Math.sqrt( Math.max( scaleXSq, Math.max( scaleYSq, scaleZSq ) ) );

	},
908

909
	makeTranslation: function ( x, y, z ) {
910 911 912

		this.set(

913 914 915
			1, 0, 0, x,
			0, 1, 0, y,
			0, 0, 1, z,
916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978
			0, 0, 0, 1

		);

		return this;

	},

	makeRotationX: function ( theta ) {

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

		this.set(

			1, 0,  0, 0,
			0, c, -s, 0,
			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,
			-s, 0, c, 0,
			 0, 0, 0, 1

		);

		return this;

	},

	makeRotationZ: function ( theta ) {

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

		this.set(

			c, -s, 0, 0,
			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

979 980 981 982 983
		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;
984 985 986

		this.set(

987
			tx * x + c, tx * y - s * z, tx * z + s * y, 0,
988 989 990 991 992 993 994 995 996 997
			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;

	},

998
	makeScale: function ( x, y, z ) {
999 1000 1001

		this.set(

1002 1003 1004
			x, 0, 0, 0,
			0, y, 0, 0,
			0, 0, z, 0,
1005 1006 1007 1008 1009 1010 1011 1012 1013
			0, 0, 0, 1

		);

		return this;

	},

	makeFrustum: function ( left, right, bottom, top, near, far ) {
1014 1015

		var te = this.elements;
1016 1017 1018 1019 1020 1021 1022 1023
		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 );

M
Mr.doob 已提交
1024 1025 1026 1027
		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;
1028 1029 1030 1031 1032 1033 1034

		return this;

	},

	makePerspective: function ( fov, aspect, near, far ) {

1035
		var ymax = near * Math.tan( THREE.Math.degToRad( fov * 0.5 ) );
1036 1037 1038 1039 1040 1041 1042 1043 1044
		var ymin = - ymax;
		var xmin = ymin * aspect;
		var xmax = ymax * aspect;

		return this.makeFrustum( xmin, xmax, ymin, ymax, near, far );

	},

	makeOrthographic: function ( left, right, top, bottom, near, far ) {
1045 1046

		var te = this.elements;
1047 1048 1049 1050 1051 1052 1053 1054
		var w = right - left;
		var h = top - bottom;
		var p = far - near;

		var x = ( right + left ) / w;
		var y = ( top + bottom ) / h;
		var z = ( far + near ) / p;

M
Mr.doob 已提交
1055 1056 1057 1058
		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;
		te[3] = 0;	te[7] = 0;	te[11] = 0;	te[15] = 1;
1059 1060 1061

		return this;

M
Mr.doob 已提交
1062 1063 1064
	},

	clone: function () {
1065 1066 1067

		var te = this.elements;

M
Mr.doob 已提交
1068
		return new THREE.Matrix4(
1069

1070 1071 1072 1073
			te[0], te[4], te[8], te[12],
			te[1], te[5], te[9], te[13],
			te[2], te[6], te[10], te[14],
			te[3], te[7], te[11], te[15]
1074

M
Mr.doob 已提交
1075 1076
		);

1077
	}
P
philogb 已提交
1078

M
Mr.doob 已提交
1079
} );