Matrix4.js 20.1 KB
Newer Older
M
Mr.doob 已提交
1 2
/**
 * @author mr.doob / 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/
M
Mr.doob 已提交
10 11
 */

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

M
Mr.doob 已提交
14 15 16 17 18 19 20 21
	this.set(

		n11 || 1, n12 || 0, n13 || 0, n14 || 0,
		n21 || 0, n22 || 1, n23 || 0, n24 || 0,
		n31 || 0, n32 || 0, n33 || 1, n34 || 0,
		n41 || 0, n42 || 0, n43 || 0, n44 || 1

	);
22

23 24
	this.flat = new Array( 16 );
	this.m33 = new THREE.Matrix3();
25

26
};
27

28
THREE.Matrix4.prototype = {
29

30 31 32
	constructor: THREE.Matrix4,

	set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
M
Mr.doob 已提交
33

M
Mr.doob 已提交
34 35 36 37
		this.n11 = n11; this.n12 = n12; this.n13 = n13; this.n14 = n14;
		this.n21 = n21; this.n22 = n22; this.n23 = n23; this.n24 = n24;
		this.n31 = n31; this.n32 = n32; this.n33 = n33; this.n34 = n34;
		this.n41 = n41; this.n42 = n42; this.n43 = n43; this.n44 = 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 ) {
M
Mr.doob 已提交
59

M
Mr.doob 已提交
60 61 62 63 64 65 66 67
		this.set(

			m.n11, m.n12, m.n13, m.n14,
			m.n21, m.n22, m.n23, m.n24,
			m.n31, m.n32, m.n33, m.n34,
			m.n41, m.n42, m.n43, m.n44

		);
M
Mr.doob 已提交
68

69 70
		return this;

M
Mr.doob 已提交
71 72
	},

73
	lookAt: function ( eye, center, up ) {
M
Mr.doob 已提交
74

75
		var x = THREE.Matrix4.__v1, y = THREE.Matrix4.__v2, z = THREE.Matrix4.__v3;
M
Mr.doob 已提交
76

M
Mr.doob 已提交
77
		z.sub( eye, center ).normalize();
78

M
Mikael Emtinger 已提交
79
		if ( z.length() === 0 ) {
80

M
Mikael Emtinger 已提交
81
			z.z = 1;
82

M
Mikael Emtinger 已提交
83
		}
84

M
Mr.doob 已提交
85
		x.cross( up, z ).normalize();
M
Mikael Emtinger 已提交
86 87

		if ( x.length() === 0 ) {
88

M
Mikael Emtinger 已提交
89 90
			z.x += 0.0001;
			x.cross( up, z ).normalize();
91

M
Mikael Emtinger 已提交
92 93
		}

M
Mr.doob 已提交
94
		y.cross( z, x ).normalize();
M
Mr.doob 已提交
95

M
Mr.doob 已提交
96

97 98 99
		this.n11 = x.x; this.n12 = y.x; this.n13 = z.x;
		this.n21 = x.y; this.n22 = y.y; this.n23 = z.y;
		this.n31 = x.z; this.n32 = y.z; this.n33 = z.z;
M
Mr.doob 已提交
100

101 102
		return this;

103
	},
104

105
	multiplyVector3: function ( v ) {
106

107 108
		var vx = v.x, vy = v.y, vz = v.z,
		d = 1 / ( this.n41 * vx + this.n42 * vy + this.n43 * vz + this.n44 );
109

110 111 112
		v.x = ( this.n11 * vx + this.n12 * vy + this.n13 * vz + this.n14 ) * d;
		v.y = ( this.n21 * vx + this.n22 * vy + this.n23 * vz + this.n24 ) * d;
		v.z = ( this.n31 * vx + this.n32 * vy + this.n33 * vz + this.n34 ) * d;
113

114 115
		return v;

M
Mr.doob 已提交
116
	},
117

118
	multiplyVector4: function ( v ) {
119

M
Mr.doob 已提交
120
		var vx = v.x, vy = v.y, vz = v.z, vw = v.w;
M
Mr.doob 已提交
121

M
Mr.doob 已提交
122 123 124 125
		v.x = this.n11 * vx + this.n12 * vy + this.n13 * vz + this.n14 * vw;
		v.y = this.n21 * vx + this.n22 * vy + this.n23 * vz + this.n24 * vw;
		v.z = this.n31 * vx + this.n32 * vy + this.n33 * vz + this.n34 * vw;
		v.w = this.n41 * vx + this.n42 * vy + this.n43 * vz + this.n44 * vw;
M
Mr.doob 已提交
126

127 128
		return v;

129
	},
130

131
	rotateAxis: function ( v ) {
132 133 134 135 136 137 138 139 140 141 142 143 144

		var vx = v.x, vy = v.y, vz = v.z;

		v.x = vx * this.n11 + vy * this.n12 + vz * this.n13;
		v.y = vx * this.n21 + vy * this.n22 + vz * this.n23;
		v.z = vx * this.n31 + vy * this.n32 + vz * this.n33;

		v.normalize();

		return v;

	},

145
	crossVector: function ( a ) {
M
Mr.doob 已提交
146

147
		var v = new THREE.Vector4();
M
Mr.doob 已提交
148

149 150 151
		v.x = this.n11 * a.x + this.n12 * a.y + this.n13 * a.z + this.n14 * a.w;
		v.y = this.n21 * a.x + this.n22 * a.y + this.n23 * a.z + this.n24 * a.w;
		v.z = this.n31 * a.x + this.n32 * a.y + this.n33 * a.z + this.n34 * a.w;
M
Mr.doob 已提交
152

153
		v.w = ( a.w ) ? this.n41 * a.x + this.n42 * a.y + this.n43 * a.z + this.n44 * a.w : 1;
154

155
		return v;
M
Mr.doob 已提交
156

157
	},
158

159
	multiply: function ( a, b ) {
M
Mr.doob 已提交
160

M
Mr.doob 已提交
161 162 163 164 165 166 167 168 169 170
		var a11 = a.n11, a12 = a.n12, a13 = a.n13, a14 = a.n14,
		a21 = a.n21, a22 = a.n22, a23 = a.n23, a24 = a.n24,
		a31 = a.n31, a32 = a.n32, a33 = a.n33, a34 = a.n34,
		a41 = a.n41, a42 = a.n42, a43 = a.n43, a44 = a.n44,

		b11 = b.n11, b12 = b.n12, b13 = b.n13, b14 = b.n14,
		b21 = b.n21, b22 = b.n22, b23 = b.n23, b24 = b.n24,
		b31 = b.n31, b32 = b.n32, b33 = b.n33, b34 = b.n34,
		b41 = b.n41, b42 = b.n42, b43 = b.n43, b44 = b.n44;

A
alteredq 已提交
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
		this.n11 = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
		this.n12 = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
		this.n13 = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
		this.n14 = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;

		this.n21 = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
		this.n22 = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
		this.n23 = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
		this.n24 = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;

		this.n31 = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
		this.n32 = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
		this.n33 = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
		this.n34 = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;

		this.n41 = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
		this.n42 = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
		this.n43 = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
		this.n44 = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
190

A
alteredq 已提交
191 192 193 194
		return this;

	},

195
	multiplyToArray: function ( a, b, r ) {
196

197
		this.multiply( a, b );
198

199 200 201 202
		r[ 0 ] = this.n11; r[ 1 ] = this.n21; r[ 2 ] = this.n31; r[ 3 ] = this.n41;
		r[ 4 ] = this.n12; r[ 5 ] = this.n22; r[ 6 ] = this.n32; r[ 7 ] = this.n42;
		r[ 8 ]  = this.n13; r[ 9 ]  = this.n23; r[ 10 ] = this.n33; r[ 11 ] = this.n43;
		r[ 12 ] = this.n14; r[ 13 ] = this.n24; r[ 14 ] = this.n34; r[ 15 ] = this.n44;
M
Mr.doob 已提交
203

204
		return this;
M
Mr.doob 已提交
205

206
	},
M
Mr.doob 已提交
207

208
	multiplySelf: function ( m ) {
M
Mr.doob 已提交
209

210
		this.multiply( this, m );
211

212 213
		return this;

214 215
	},

216
	multiplyScalar: function ( s ) {
217 218 219 220 221 222

		this.n11 *= s; this.n12 *= s; this.n13 *= s; this.n14 *= s;
		this.n21 *= s; this.n22 *= s; this.n23 *= s; this.n24 *= s;
		this.n31 *= s; this.n32 *= s; this.n33 *= s; this.n34 *= s;
		this.n41 *= s; this.n42 *= s; this.n43 *= s; this.n44 *= s;

223 224
		return this;

225 226
	},

227
	determinant: function () {
228

229 230 231 232 233
		var n11 = this.n11, n12 = this.n12, n13 = this.n13, n14 = this.n14,
		n21 = this.n21, n22 = this.n22, n23 = this.n23, n24 = this.n24,
		n31 = this.n31, n32 = this.n32, n33 = this.n33, n34 = this.n34,
		n41 = this.n41, n42 = this.n42, n43 = this.n43, n44 = this.n44;

234 235 236
		//TODO: make this more efficient
		//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
		return (
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
			n14 * n23 * n32 * n41-
			n13 * n24 * n32 * n41-
			n14 * n22 * n33 * n41+
			n12 * n24 * n33 * n41+

			n13 * n22 * n34 * n41-
			n12 * n23 * n34 * n41-
			n14 * n23 * n31 * n42+
			n13 * n24 * n31 * n42+

			n14 * n21 * n33 * n42-
			n11 * n24 * n33 * n42-
			n13 * n21 * n34 * n42+
			n11 * n23 * n34 * n42+

			n14 * n22 * n31 * n43-
			n12 * n24 * n31 * n43-
			n14 * n21 * n32 * n43+
			n11 * n24 * n32 * n43+

			n12 * n21 * n34 * n43-
			n11 * n22 * n34 * n43-
			n13 * n22 * n31 * n44+
			n12 * n23 * n31 * n44+

			n13 * n21 * n32 * n44-
			n11 * n23 * n32 * n44-
			n12 * n21 * n33 * n44+
M
Mr.doob 已提交
265 266
			n11 * n22 * n33 * n44
		);
267 268

	},
M
Mr.doob 已提交
269

270
	transpose: function () {
M
Mr.doob 已提交
271

272
		var tmp;
273

274 275 276
		tmp = this.n21; this.n21 = this.n12; this.n12 = tmp;
		tmp = this.n31; this.n31 = this.n13; this.n13 = tmp;
		tmp = this.n32; this.n32 = this.n23; this.n23 = tmp;
277

278 279 280
		tmp = this.n41; this.n41 = this.n14; this.n14 = tmp;
		tmp = this.n42; this.n42 = this.n24; this.n24 = tmp;
		tmp = this.n43; this.n43 = this.n34; this.n43 = tmp;
M
Mr.doob 已提交
281 282 283 284 285

		return this;

	},

286
	clone: function () {
287 288

		var m = new THREE.Matrix4();
289

290 291 292 293
		m.n11 = this.n11; m.n12 = this.n12; m.n13 = this.n13; m.n14 = this.n14;
		m.n21 = this.n21; m.n22 = this.n22; m.n23 = this.n23; m.n24 = this.n24;
		m.n31 = this.n31; m.n32 = this.n32; m.n33 = this.n33; m.n34 = this.n34;
		m.n41 = this.n41; m.n42 = this.n42; m.n43 = this.n43; m.n44 = this.n44;
294

295 296 297
		return m;

	},
M
Mr.doob 已提交
298

299
	flatten: function () {
300 301 302 303 304

		this.flat[ 0 ] = this.n11; this.flat[ 1 ] = this.n21; this.flat[ 2 ] = this.n31; this.flat[ 3 ] = this.n41;
		this.flat[ 4 ] = this.n12; this.flat[ 5 ] = this.n22; this.flat[ 6 ] = this.n32; this.flat[ 7 ] = this.n42;
		this.flat[ 8 ]  = this.n13; this.flat[ 9 ]  = this.n23; this.flat[ 10 ] = this.n33; this.flat[ 11 ] = this.n43;
		this.flat[ 12 ] = this.n14; this.flat[ 13 ] = this.n24; this.flat[ 14 ] = this.n34; this.flat[ 15 ] = this.n44;
305

M
Mr.doob 已提交
306
		return this.flat;
307 308 309

	},

310
	flattenToArray: function ( flat ) {
A
alteredq 已提交
311

M
Mr.doob 已提交
312 313 314 315
		flat[ 0 ] = this.n11; flat[ 1 ] = this.n21; flat[ 2 ] = this.n31; flat[ 3 ] = this.n41;
		flat[ 4 ] = this.n12; flat[ 5 ] = this.n22; flat[ 6 ] = this.n32; flat[ 7 ] = this.n42;
		flat[ 8 ]  = this.n13; flat[ 9 ]  = this.n23; flat[ 10 ] = this.n33; flat[ 11 ] = this.n43;
		flat[ 12 ] = this.n14; flat[ 13 ] = this.n24; flat[ 14 ] = this.n34; flat[ 15 ] = this.n44;
316

317
		return flat;
M
Mr.doob 已提交
318

319
	},
320

321
	flattenToArrayOffset: function( flat, offset ) {
322

M
Mr.doob 已提交
323
		flat[ offset ] = this.n11;
A
alteredq 已提交
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
		flat[ offset + 1 ] = this.n21;
		flat[ offset + 2 ] = this.n31;
		flat[ offset + 3 ] = this.n41;

		flat[ offset + 4 ] = this.n12;
		flat[ offset + 5 ] = this.n22;
		flat[ offset + 6 ] = this.n32;
		flat[ offset + 7 ] = this.n42;

		flat[ offset + 8 ]  = this.n13;
		flat[ offset + 9 ]  = this.n23;
		flat[ offset + 10 ] = this.n33;
		flat[ offset + 11 ] = this.n43;

		flat[ offset + 12 ] = this.n14;
		flat[ offset + 13 ] = this.n24;
		flat[ offset + 14 ] = this.n34;
		flat[ offset + 15 ] = this.n44;

		return flat;

	},

347
	setTranslation: function( x, y, z ) {
348

M
Mr.doob 已提交
349 350 351 352 353 354 355 356
		this.set(

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

		);
357

358
		return this;
359

360
	},
361

362
	setScale: function ( x, y, z ) {
M
Mr.doob 已提交
363 364 365 366 367 368 369

		this.set(

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

M
Mr.doob 已提交
371
		);
372

373
		return this;
374

375
	},
376

377
	setRotationX: function ( theta ) {
378 379

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

M
Mr.doob 已提交
381 382 383 384 385 386 387 388
		this.set(

			1, 0,  0, 0,
			0, c, -s, 0,
			0, s,  c, 0,
			0, 0,  0, 1

		);
389

390
		return this;
391

392
	},
393

394
	setRotationY: function( theta ) {
395 396 397

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

M
Mr.doob 已提交
398 399 400 401 402 403 404 405
		this.set(

			 c, 0, s, 0,
			 0, 1, 0, 0,
			-s, 0, c, 0,
			 0, 0, 0, 1

		);
406

407
		return this;
408

409
	},
410

411
	setRotationZ: function( theta ) {
412 413

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

M
Mr.doob 已提交
415 416 417 418 419 420 421 422
		this.set(

			c, -s, 0, 0,
			s,  c, 0, 0,
			0,  0, 1, 0,
			0,  0, 0, 1

		);
423

424
		return this;
425

426
	},
427

428
	setRotationAxis: function( axis, angle ) {
429

M
Mr.doob 已提交
430
		// Based on http://www.gamedev.net/reference/articles/article1199.asp
431

432
		var c = Math.cos( angle ),
M
Mr.doob 已提交
433 434 435 436 437 438 439 440 441 442 443
		s = Math.sin( angle ),
		t = 1 - c,
		x = axis.x, y = axis.y, z = axis.z,
		tx = t * x, ty = t * y;

		this.set(

		 	tx * x + c, tx * y - s * z, tx * z + s * y, 0,
			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
444

M
Mr.doob 已提交
445
		);
446

447 448
		 return this;

449
	},
450

451
	setPosition: function( v ) {
452

M
Mr.doob 已提交
453 454 455
		this.n14 = v.x;
		this.n24 = v.y;
		this.n34 = v.z;
456

457
		return this;
458

459
	},
460 461 462 463 464

	getPosition: function() {

		if ( ! this.position ) {

465
			this.position = new THREE.Vector3();
466

467
		}
468

469
		this.position.set( this.n14, this.n24, this.n34 );
470

471
		return this.position;
472

473 474
	},

475 476 477 478
	getColumnX: function() {

		if ( ! this.columnX ) {

479
			this.columnX = new THREE.Vector3();
480

481
		}
482

483
		this.columnX.set( this.n11, this.n21, this.n31 );
484

485 486 487
		return this.columnX;
	},

488 489 490 491
	getColumnY: function() {

		if ( ! this.columnY ) {

492
			this.columnY = new THREE.Vector3();
493

494
		}
495

496
		this.columnY.set( this.n12, this.n22, this.n32 );
497

498
		return this.columnY;
499

500 501
	},

502 503 504 505
	getColumnZ: function() {

		if ( ! this.columnZ ) {

506
			this.columnZ = new THREE.Vector3();
507

508
		}
509

510
		this.columnZ.set( this.n13, this.n23, this.n33 );
511

512
		return this.columnZ;
513

514
	},
515

516
	setRotationFromEuler: function( v, order ) {
517

M
Mr.doob 已提交
518
		var x = v.x, y = v.y, z = v.z,
519 520
		a = Math.cos( x ), b = Math.sin( x ),
		c = Math.cos( y ), d = Math.sin( y ),
521
		e = Math.cos( z ), f = Math.sin( z );
522

523
		switch ( order ) {
M
Mr.doob 已提交
524

525
			case 'YXZ':
M
Mr.doob 已提交
526

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

529 530 531
				this.n11 = ce + df * b;
				this.n12 = de * b - cf;
				this.n13 = a * d;
532

533 534 535 536 537 538 539 540 541 542
				this.n21 = a * f;
				this.n22 = a * e;
				this.n23 = - b;

				this.n31 = cf * b - de;
				this.n32 = df + ce * b;
				this.n33 = a * c;
				break;

			case 'ZXY':
M
Mr.doob 已提交
543

544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
				var ce = c * e, cf = c * f, de = d * e, df = d * f;

				this.n11 = ce - df * b;
				this.n12 = - a * f;
				this.n13 = de + cf * b;

				this.n21 = cf + de * b;
				this.n22 = a * e;
				this.n23 = df - ce * b;

				this.n31 = - a * d;
				this.n32 = b;
				this.n33 = a * c;
				break;

			case 'ZYX':
M
Mr.doob 已提交
560

561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
				var ae = a * e, af = a * f, be = b * e, bf = b * f;

				this.n11 = c * e;
				this.n12 = be * d - af;
				this.n13 = ae * d + bf;

				this.n21 = c * f;
				this.n22 = bf * d + ae;
				this.n23 = af * d - be;

				this.n31 = - d;
				this.n32 = b * c;
				this.n33 = a * c;
				break;

			case 'YZX':
M
Mr.doob 已提交
577

578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
				var ac = a * c, ad = a * d, bc = b * c, bd = b * d;

				this.n11 = c * e;
				this.n12 = bd - ac * f;
				this.n13 = bc * f + ad;

				this.n21 = f;
				this.n22 = a * e;
				this.n23 = - b * e;

				this.n31 = - d * e;
				this.n32 = ad * f + bc;
				this.n33 = ac - bd * f;
				break;

			case 'XZY':
M
Mr.doob 已提交
594

595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610
				var ac = a * c, ad = a * d, bc = b * c, bd = b * d;

				this.n11 = c * e;
				this.n12 = - f;
				this.n13 = d * e;

				this.n21 = ac * f + bd;
				this.n22 = a * e;
				this.n23 = ad * f - bc;

				this.n31 = bc * f - ad;
				this.n32 = b * e;
				this.n33 = bd * f + ac;
				break;

			default: // 'XYZ'
M
Mr.doob 已提交
611

612 613 614 615 616 617 618 619 620 621 622 623 624 625
				var ae = a * e, af = a * f, be = b * e, bf = b * f;

				this.n11 = c * e;
				this.n12 = - c * f;
				this.n13 = d;

				this.n21 = af + be * d;
				this.n22 = ae - bf * d;
				this.n23 = - b * c;

				this.n31 = bf - ae * d;
				this.n32 = be + af * d;
				this.n33 = a * c;
				break;
M
Mr.doob 已提交
626

627
		}
628

629 630
		return this;

631 632
	},

633

634
	setRotationFromQuaternion: function( q ) {
635

M
Mr.doob 已提交
636
		var x = q.x, y = q.y, z = q.z, w = q.w,
M
Mr.doob 已提交
637 638 639 640
		x2 = x + x, y2 = y + y, z2 = z + z,
		xx = x * x2, xy = x * y2, xz = x * z2,
		yy = y * y2, yz = y * z2, zz = z * z2,
		wx = w * x2, wy = w * y2, wz = w * z2;
641

642 643 644
		this.n11 = 1 - ( yy + zz );
		this.n12 = xy - wz;
		this.n13 = xz + wy;
645

646 647 648
		this.n21 = xy + wz;
		this.n22 = 1 - ( xx + zz );
		this.n23 = yz - wx;
649

650 651 652
		this.n31 = xz - wy;
		this.n32 = yz + wx;
		this.n33 = 1 - ( xx + yy );
653

654 655
		return this;

656
	},
657

658
	scale: function ( v ) {
659

M
Mr.doob 已提交
660
		var x = v.x, y = v.y, z = v.z;
661

M
Mr.doob 已提交
662 663 664 665
		this.n11 *= x; this.n12 *= y; this.n13 *= z;
		this.n21 *= x; this.n22 *= y; this.n23 *= z;
		this.n31 *= x; this.n32 *= y; this.n33 *= z;
		this.n41 *= x; this.n42 *= y; this.n43 *= z;
666 667

		return this;
A
alteredq 已提交
668

669
	},
M
Mr.doob 已提交
670

M
Mr.doob 已提交
671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723
	compose: function ( translation, rotation, scale ) {
		var mr = new THREE.Matrix4();
		var ms = new THREE.Matrix4();
		
		mr.setRotationFromQuaternion(rotation);
		ms.setScale(scale.x, scale.y, scale.z);
		
		this.multiply(mr, ms);
		this.n14 = translation.x;
		this.n24 = translation.y;
		this.n34 = translation.z;
		
		return this;
	},
	
	decompose: function ( translation, rotation, scale ) {
		// grab the axis vecs
		var x = new THREE.Vector3(this.n11, this.n21, this.n31);
		var y = new THREE.Vector3(this.n12, this.n22, this.n32);
		var z = new THREE.Vector3(this.n13, this.n23, this.n33);
	
		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();
	
		scale.x = x.length();
		scale.y = y.length();
		scale.z = z.length();
	
		translation.x = this.n14;
		translation.y = this.n24;
		translation.z = this.n34;
	
		// scale the rotation part
		var matrix = this.clone();
	
		matrix.n11 /= scale.x;
		matrix.n21 /= scale.x;
		matrix.n31 /= scale.x;
	
		matrix.n12 /= scale.y;
		matrix.n22 /= scale.y;
		matrix.n32 /= scale.y;
	
		matrix.n13 /= scale.z;
		matrix.n23 /= scale.z;
		matrix.n33 /= scale.z;
	
		rotation.setFromRotationMatrix(matrix);
		
		return [translation, rotation, scale];
	},

724
	extractPosition: function ( m ) {
M
Mr.doob 已提交
725

726 727 728
		this.n14 = m.n14;
		this.n24 = m.n24;
		this.n34 = m.n34;
M
Mr.doob 已提交
729

730
	},
M
Mr.doob 已提交
731
	
732
	extractRotation: function ( m, s ) {
733

734
		var invScaleX = 1 / s.x, invScaleY = 1 / s.y, invScaleZ = 1 / s.z;
M
Mr.doob 已提交
735

736 737 738
		this.n11 = m.n11 * invScaleX;
		this.n21 = m.n21 * invScaleX;
		this.n31 = m.n31 * invScaleX;
P
philogb 已提交
739

740 741 742
		this.n12 = m.n12 * invScaleY;
		this.n22 = m.n22 * invScaleY;
		this.n32 = m.n32 * invScaleY;
743

744 745 746
		this.n13 = m.n13 * invScaleZ;
		this.n23 = m.n23 * invScaleZ;
		this.n33 = m.n33 * invScaleZ;
M
Mr.doob 已提交
747

748
	}
P
philogb 已提交
749 750 751

};

A
alteredq 已提交
752 753 754 755 756
THREE.Matrix4.makeInvert = function ( m1, m2 ) {

	// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm

	var n11 = m1.n11, n12 = m1.n12, n13 = m1.n13, n14 = m1.n14,
M
Mr.doob 已提交
757 758 759
	n21 = m1.n21, n22 = m1.n22, n23 = m1.n23, n24 = m1.n24,
	n31 = m1.n31, n32 = m1.n32, n33 = m1.n33, n34 = m1.n34,
	n41 = m1.n41, n42 = m1.n42, n43 = m1.n43, n44 = m1.n44;
A
alteredq 已提交
760

761
	if ( m2 === undefined ) m2 = new THREE.Matrix4();
A
alteredq 已提交
762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784

	m2.n11 = n23*n34*n42 - n24*n33*n42 + n24*n32*n43 - n22*n34*n43 - n23*n32*n44 + n22*n33*n44;
	m2.n12 = n14*n33*n42 - n13*n34*n42 - n14*n32*n43 + n12*n34*n43 + n13*n32*n44 - n12*n33*n44;
	m2.n13 = n13*n24*n42 - n14*n23*n42 + n14*n22*n43 - n12*n24*n43 - n13*n22*n44 + n12*n23*n44;
	m2.n14 = n14*n23*n32 - n13*n24*n32 - n14*n22*n33 + n12*n24*n33 + n13*n22*n34 - n12*n23*n34;
	m2.n21 = n24*n33*n41 - n23*n34*n41 - n24*n31*n43 + n21*n34*n43 + n23*n31*n44 - n21*n33*n44;
	m2.n22 = n13*n34*n41 - n14*n33*n41 + n14*n31*n43 - n11*n34*n43 - n13*n31*n44 + n11*n33*n44;
	m2.n23 = n14*n23*n41 - n13*n24*n41 - n14*n21*n43 + n11*n24*n43 + n13*n21*n44 - n11*n23*n44;
	m2.n24 = n13*n24*n31 - n14*n23*n31 + n14*n21*n33 - n11*n24*n33 - n13*n21*n34 + n11*n23*n34;
	m2.n31 = n22*n34*n41 - n24*n32*n41 + n24*n31*n42 - n21*n34*n42 - n22*n31*n44 + n21*n32*n44;
	m2.n32 = n14*n32*n41 - n12*n34*n41 - n14*n31*n42 + n11*n34*n42 + n12*n31*n44 - n11*n32*n44;
	m2.n33 = n13*n24*n41 - n14*n22*n41 + n14*n21*n42 - n11*n24*n42 - n12*n21*n44 + n11*n22*n44;
	m2.n34 = n14*n22*n31 - n12*n24*n31 - n14*n21*n32 + n11*n24*n32 + n12*n21*n34 - n11*n22*n34;
	m2.n41 = n23*n32*n41 - n22*n33*n41 - n23*n31*n42 + n21*n33*n42 + n22*n31*n43 - n21*n32*n43;
	m2.n42 = n12*n33*n41 - n13*n32*n41 + n13*n31*n42 - n11*n33*n42 - n12*n31*n43 + n11*n32*n43;
	m2.n43 = n13*n22*n41 - n12*n23*n41 - n13*n21*n42 + n11*n23*n42 + n12*n21*n43 - n11*n22*n43;
	m2.n44 = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33;
	m2.multiplyScalar( 1 / m1.determinant() );

	return m2;

};

785
THREE.Matrix4.makeInvert3x3 = function ( m1 ) {
786

787
	// input:  THREE.Matrix4, output: THREE.Matrix3
788 789
	// ( based on http://code.google.com/p/webgl-mjs/ )

790
	var m33 = m1.m33, m33m = m33.m,
791 792 793 794 795 796 797 798 799
	a11 =   m1.n33 * m1.n22 - m1.n32 * m1.n23,
	a21 = - m1.n33 * m1.n21 + m1.n31 * m1.n23,
	a31 =   m1.n32 * m1.n21 - m1.n31 * m1.n22,
	a12 = - m1.n33 * m1.n12 + m1.n32 * m1.n13,
	a22 =   m1.n33 * m1.n11 - m1.n31 * m1.n13,
	a32 = - m1.n32 * m1.n11 + m1.n31 * m1.n12,
	a13 =   m1.n23 * m1.n12 - m1.n22 * m1.n13,
	a23 = - m1.n23 * m1.n11 + m1.n21 * m1.n13,
	a33 =   m1.n22 * m1.n11 - m1.n21 * m1.n12,
800

801
	det = m1.n11 * a11 + m1.n21 * a12 + m1.n31 * a13,
802

803 804 805
	idet;

	// no inverse
806 807 808 809
	if ( det == 0 ) {

		console.error( 'THREE.Matrix4.makeInvert3x3: Matrix not invertible.' );

M
Mikael Emtinger 已提交
810
	}
811

812 813
	idet = 1.0 / det;

814 815 816
	m33m[ 0 ] = idet * a11; m33m[ 1 ] = idet * a21; m33m[ 2 ] = idet * a31;
	m33m[ 3 ] = idet * a12; m33m[ 4 ] = idet * a22; m33m[ 5 ] = idet * a32;
	m33m[ 6 ] = idet * a13; m33m[ 7 ] = idet * a23; m33m[ 8 ] = idet * a33;
817

818
	return m33;
819

820 821
}

822
THREE.Matrix4.makeFrustum = function ( left, right, bottom, top, near, far ) {
M
Mr.doob 已提交
823

824
	var m, x, y, a, b, c, d;
M
Mr.doob 已提交
825

826 827 828 829 830 831 832
	m = new THREE.Matrix4();
	x = 2 * near / ( right - left );
	y = 2 * near / ( top - bottom );
	a = ( right + left ) / ( right - left );
	b = ( top + bottom ) / ( top - bottom );
	c = - ( far + near ) / ( far - near );
	d = - 2 * far * near / ( far - near );
M
Mr.doob 已提交
833

834 835 836 837
	m.n11 = x;  m.n12 = 0;  m.n13 = a;   m.n14 = 0;
	m.n21 = 0;  m.n22 = y;  m.n23 = b;   m.n24 = 0;
	m.n31 = 0;  m.n32 = 0;  m.n33 = c;   m.n34 = d;
	m.n41 = 0;  m.n42 = 0;  m.n43 = - 1; m.n44 = 0;
M
Mr.doob 已提交
838

839
	return m;
840

M
Mr.doob 已提交
841
};
M
Mr.doob 已提交
842

843
THREE.Matrix4.makePerspective = function ( fov, aspect, near, far ) {
M
Mr.doob 已提交
844

845 846 847 848 849 850 851 852 853 854 855
	var ymax, ymin, xmin, xmax;

	ymax = near * Math.tan( fov * Math.PI / 360 );
	ymin = - ymax;
	xmin = ymin * aspect;
	xmax = ymax * aspect;

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

};

856
THREE.Matrix4.makeOrtho = function ( left, right, top, bottom, near, far ) {
857 858 859 860 861

	var m, x, y, z, w, h, p;

	m = new THREE.Matrix4();
	w = right - left;
862
	h = top - bottom;
863 864
	p = far - near;
	x = ( right + left ) / w;
865
	y = ( top + bottom ) / h;
866
	z = ( far + near ) / p;
867

868 869 870 871
	m.n11 = 2 / w; m.n12 = 0;     m.n13 = 0;      m.n14 = -x;
	m.n21 = 0;     m.n22 = 2 / h; m.n23 = 0;      m.n24 = -y;
	m.n31 = 0;     m.n32 = 0;     m.n33 = -2 / p; m.n34 = -z;
	m.n41 = 0;     m.n42 = 0;     m.n43 = 0;      m.n44 = 1;
872

873
	return m;
874

M
Mr.doob 已提交
875
};
A
alteredq 已提交
876

877 878 879
THREE.Matrix4.__v1 = new THREE.Vector3();
THREE.Matrix4.__v2 = new THREE.Vector3();
THREE.Matrix4.__v3 = new THREE.Vector3();