Matrix4.js 27.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 ) {

14 15
    this.elements = new Float32Array(16);

M
Mr.doob 已提交
16 17
	this.set(

18 19 20 21
		( n11 !== undefined ) ? n11 : 1, n12 || 0, n13 || 0, n14 || 0,
		n21 || 0, ( n22 !== undefined ) ? n22 : 1, n23 || 0, n24 || 0,
		n31 || 0, n32 || 0, ( n33 !== undefined ) ? n33 : 1, n34 || 0,
		n41 || 0, n42 || 0, n43 || 0, ( n44 !== undefined ) ? n44 : 1
M
Mr.doob 已提交
22 23

	);
24

25
};
26

27
THREE.Matrix4.prototype = {
28

29 30 31
	constructor: THREE.Matrix4,

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

33 34 35 36
		this.elements[0] = n11; this.elements[4] = n12; this.elements[8] = n13; this.elements[12] = n14;
		this.elements[1] = n21; this.elements[5] = n22; this.elements[9] = n23; this.elements[13] = n24;
		this.elements[2] = n31; this.elements[6] = n32; this.elements[10] = n33; this.elements[14] = n34;
		this.elements[3] = n41; this.elements[7] = n42; this.elements[11] = n43; this.elements[15] = n44;
M
Mr.doob 已提交
37

38 39 40 41
		return this;

	},

42
	identity: function () {
43

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

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

		);
52 53 54

		return this;

55
	},
M
Mr.doob 已提交
56

57
	copy: function ( m ) {
M
Mr.doob 已提交
58

M
Mr.doob 已提交
59 60
		this.set(

61 62 63 64
			m.elements[0], m.elements[4], m.elements[8], m.elements[12],
			m.elements[1], m.elements[5], m.elements[9], m.elements[13],
			m.elements[2], m.elements[6], m.elements[10], m.elements[14],
			m.elements[3], m.elements[7], m.elements[11], m.elements[15]
M
Mr.doob 已提交
65 66

		);
M
Mr.doob 已提交
67

68 69
		return this;

M
Mr.doob 已提交
70 71
	},

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

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

78
		z.sub( eye, target ).normalize();
79

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

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

M
Mikael Emtinger 已提交
84
		}
85

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

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

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

M
Mikael Emtinger 已提交
93 94
		}

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

M
Mr.doob 已提交
97

98 99 100
		this.elements[0] = x.x; this.elements[4] = y.x; this.elements[8] = z.x;
		this.elements[1] = x.y; this.elements[5] = y.y; this.elements[9] = z.y;
		this.elements[2] = x.z; this.elements[6] = y.z; this.elements[10] = z.z;
M
Mr.doob 已提交
101

102 103
		return this;

104
	},
105

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

108 109 110 111
		var a11 = a.elements[0], a12 = a.elements[4], a13 = a.elements[8], a14 = a.elements[12];
		var a21 = a.elements[1], a22 = a.elements[5], a23 = a.elements[9], a24 = a.elements[13];
		var a31 = a.elements[2], a32 = a.elements[6], a33 = a.elements[10], a34 = a.elements[14];
		var a41 = a.elements[3], a42 = a.elements[7], a43 = a.elements[11], a44 = a.elements[15];
M
Mr.doob 已提交
112

113 114 115 116
		var b11 = b.elements[0], b12 = b.elements[4], b13 = b.elements[8], b14 = b.elements[12];
		var b21 = b.elements[1], b22 = b.elements[5], b23 = b.elements[9], b24 = b.elements[13];
		var b31 = b.elements[2], b32 = b.elements[6], b33 = b.elements[10], b34 = b.elements[14];
		var b41 = b.elements[3], b42 = b.elements[7], b43 = b.elements[11], b44 = b.elements[15];
M
Mr.doob 已提交
117

118 119 120 121
		this.elements[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
		this.elements[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
		this.elements[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
		this.elements[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
A
alteredq 已提交
122

123 124 125 126
		this.elements[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
		this.elements[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
		this.elements[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
		this.elements[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
A
alteredq 已提交
127

128 129 130 131
		this.elements[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
		this.elements[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
		this.elements[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
		this.elements[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
A
alteredq 已提交
132

133 134 135 136
		this.elements[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
		this.elements[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
		this.elements[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
		this.elements[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
137

A
alteredq 已提交
138 139 140 141
		return this;

	},

M
Mr.doob 已提交
142 143 144 145 146 147
	multiplySelf: function ( m ) {

		return this.multiply( this, m );

	},

148
	multiplyToArray: function ( a, b, r ) {
149

150
		this.multiply( a, b );
151

152 153 154 155
		r[ 0 ] = this.elements[0]; r[ 1 ] = this.elements[1]; r[ 2 ] = this.elements[2]; r[ 3 ] = this.elements[3];
		r[ 4 ] = this.elements[4]; r[ 5 ] = this.elements[5]; r[ 6 ] = this.elements[6]; r[ 7 ] = this.elements[7];
		r[ 8 ]  = this.elements[8]; r[ 9 ]  = this.elements[9]; r[ 10 ] = this.elements[10]; r[ 11 ] = this.elements[11];
		r[ 12 ] = this.elements[12]; r[ 13 ] = this.elements[13]; r[ 14 ] = this.elements[14]; r[ 15 ] = this.elements[15];
M
Mr.doob 已提交
156

157
		return this;
M
Mr.doob 已提交
158

159
	},
M
Mr.doob 已提交
160

161
	multiplyScalar: function ( s ) {
162

163 164 165 166
		this.elements[0] *= s; this.elements[4] *= s; this.elements[8] *= s; this.elements[12] *= s;
		this.elements[1] *= s; this.elements[5] *= s; this.elements[9] *= s; this.elements[13] *= s;
		this.elements[2] *= s; this.elements[6] *= s; this.elements[10] *= s; this.elements[14] *= s;
		this.elements[3] *= s; this.elements[7] *= s; this.elements[11] *= s; this.elements[15] *= s;
167

168 169
		return this;

170 171
	},

M
Mr.doob 已提交
172 173
	multiplyVector3: function ( v ) {

174
		var vx = v.x, vy = v.y, vz = v.z;
175
		var d = 1 / ( this.elements[3] * vx + this.elements[7] * vy + this.elements[11] * vz + this.elements[15] );
M
Mr.doob 已提交
176

177 178 179
		v.x = ( this.elements[0] * vx + this.elements[4] * vy + this.elements[8] * vz + this.elements[12] ) * d;
		v.y = ( this.elements[1] * vx + this.elements[5] * vy + this.elements[9] * vz + this.elements[13] ) * d;
		v.z = ( this.elements[2] * vx + this.elements[6] * vy + this.elements[10] * vz + this.elements[14] ) * d;
M
Mr.doob 已提交
180 181 182 183 184 185 186 187 188

		return v;

	},

	multiplyVector4: function ( v ) {

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

189 190 191 192
		v.x = this.elements[0] * vx + this.elements[4] * vy + this.elements[8] * vz + this.elements[12] * vw;
		v.y = this.elements[1] * vx + this.elements[5] * vy + this.elements[9] * vz + this.elements[13] * vw;
		v.z = this.elements[2] * vx + this.elements[6] * vy + this.elements[10] * vz + this.elements[14] * vw;
		v.w = this.elements[3] * vx + this.elements[7] * vy + this.elements[11] * vz + this.elements[15] * vw;
M
Mr.doob 已提交
193 194 195 196 197 198 199 200 201

		return v;

	},

	rotateAxis: function ( v ) {

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

202 203 204
		v.x = vx * this.elements[0] + vy * this.elements[4] + vz * this.elements[8];
		v.y = vx * this.elements[1] + vy * this.elements[5] + vz * this.elements[9];
		v.z = vx * this.elements[2] + vy * this.elements[6] + vz * this.elements[10];
M
Mr.doob 已提交
205 206 207 208 209 210 211 212 213 214 215

		v.normalize();

		return v;

	},

	crossVector: function ( a ) {

		var v = new THREE.Vector4();

216 217 218
		v.x = this.elements[0] * a.x + this.elements[4] * a.y + this.elements[8] * a.z + this.elements[12] * a.w;
		v.y = this.elements[1] * a.x + this.elements[5] * a.y + this.elements[9] * a.z + this.elements[13] * a.w;
		v.z = this.elements[2] * a.x + this.elements[6] * a.y + this.elements[10] * a.z + this.elements[14] * a.w;
M
Mr.doob 已提交
219

220
		v.w = ( a.w ) ? this.elements[3] * a.x + this.elements[7] * a.y + this.elements[11] * a.z + this.elements[15] * a.w : 1;
M
Mr.doob 已提交
221 222 223 224 225

		return v;

	},

226
	determinant: function () {
227

228 229 230 231
		var n11 = this.elements[0], n12 = this.elements[4], n13 = this.elements[8], n14 = this.elements[12];
		var n21 = this.elements[1], n22 = this.elements[5], n23 = this.elements[9], n24 = this.elements[13];
		var n31 = this.elements[2], n32 = this.elements[6], n33 = this.elements[10], n34 = this.elements[14];
		var n41 = this.elements[3], n42 = this.elements[7], n43 = this.elements[11], n44 = this.elements[15];
232

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

236
		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.elements[1]; this.elements[1] = this.elements[4]; this.elements[4] = tmp;
		tmp = this.elements[2]; this.elements[2] = this.elements[8]; this.elements[8] = tmp;
		tmp = this.elements[6]; this.elements[6] = this.elements[9]; this.elements[9] = tmp;
277

278 279 280
		tmp = this.elements[3]; this.elements[3] = this.elements[12]; this.elements[12] = tmp;
		tmp = this.elements[7]; this.elements[7] = this.elements[13]; this.elements[13] = tmp;
		tmp = this.elements[11]; this.elements[11] = this.elements[14]; this.elements[14] = tmp;
M
Mr.doob 已提交
281 282 283 284 285

		return this;

	},

286
	flattenToArray: function ( flat ) {
A
alteredq 已提交
287

288 289 290 291
		flat[ 0 ] = this.elements[0]; flat[ 1 ] = this.elements[1]; flat[ 2 ] = this.elements[2]; flat[ 3 ] = this.elements[3];
		flat[ 4 ] = this.elements[4]; flat[ 5 ] = this.elements[5]; flat[ 6 ] = this.elements[6]; flat[ 7 ] = this.elements[7];
		flat[ 8 ]  = this.elements[8]; flat[ 9 ]  = this.elements[9]; flat[ 10 ] = this.elements[10]; flat[ 11 ] = this.elements[11];
		flat[ 12 ] = this.elements[12]; flat[ 13 ] = this.elements[13]; flat[ 14 ] = this.elements[14]; flat[ 15 ] = this.elements[15];
292

293
		return flat;
M
Mr.doob 已提交
294

295
	},
296

297
	flattenToArrayOffset: function( flat, offset ) {
298

299 300 301 302
		flat[ offset ] = this.elements[0];
		flat[ offset + 1 ] = this.elements[1];
		flat[ offset + 2 ] = this.elements[2];
		flat[ offset + 3 ] = this.elements[3];
A
alteredq 已提交
303

304 305 306 307
		flat[ offset + 4 ] = this.elements[4];
		flat[ offset + 5 ] = this.elements[5];
		flat[ offset + 6 ] = this.elements[6];
		flat[ offset + 7 ] = this.elements[7];
A
alteredq 已提交
308

309 310 311 312
		flat[ offset + 8 ]  = this.elements[8];
		flat[ offset + 9 ]  = this.elements[9];
		flat[ offset + 10 ] = this.elements[10];
		flat[ offset + 11 ] = this.elements[11];
A
alteredq 已提交
313

314 315 316 317
		flat[ offset + 12 ] = this.elements[12];
		flat[ offset + 13 ] = this.elements[13];
		flat[ offset + 14 ] = this.elements[14];
		flat[ offset + 15 ] = this.elements[15];
A
alteredq 已提交
318 319 320 321 322

		return flat;

	},

323
	getPosition: function () {
324

325
		return THREE.Matrix4.__v1.set( this.elements[12], this.elements[13], this.elements[14] );
326 327 328

	},

329
	setPosition: function ( v ) {
330

331 332 333
		this.elements[12] = v.x;
		this.elements[13] = v.y;
		this.elements[14] = v.z;
334

335
		return this;
336

337
	},
338

339
	getColumnX: function () {
340

341
		return THREE.Matrix4.__v1.set( this.elements[0], this.elements[1], this.elements[2] );
342

343 344
	},

345
	getColumnY: function () {
346

347
		return THREE.Matrix4.__v1.set( this.elements[4], this.elements[5], this.elements[6] );
348

349 350
	},

351 352
	getColumnZ: function() {

353
		return THREE.Matrix4.__v1.set( this.elements[8], this.elements[9], this.elements[10] );
354

355
	},
356

357
	getInverse: function ( m ) {
358

M
Mr.doob 已提交
359 360
		// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm

361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
		var n11 = m.elements[0], n12 = m.elements[4], n13 = m.elements[8], n14 = m.elements[12];
		var n21 = m.elements[1], n22 = m.elements[5], n23 = m.elements[9], n24 = m.elements[13];
		var n31 = m.elements[2], n32 = m.elements[6], n33 = m.elements[10], n34 = m.elements[14];
		var n41 = m.elements[3], n42 = m.elements[7], n43 = m.elements[11], n44 = m.elements[15];

		this.elements[0] = n23*n34*n42 - n24*n33*n42 + n24*n32*n43 - n22*n34*n43 - n23*n32*n44 + n22*n33*n44;
		this.elements[4] = n14*n33*n42 - n13*n34*n42 - n14*n32*n43 + n12*n34*n43 + n13*n32*n44 - n12*n33*n44;
		this.elements[8] = n13*n24*n42 - n14*n23*n42 + n14*n22*n43 - n12*n24*n43 - n13*n22*n44 + n12*n23*n44;
		this.elements[12] = n14*n23*n32 - n13*n24*n32 - n14*n22*n33 + n12*n24*n33 + n13*n22*n34 - n12*n23*n34;
		this.elements[1] = n24*n33*n41 - n23*n34*n41 - n24*n31*n43 + n21*n34*n43 + n23*n31*n44 - n21*n33*n44;
		this.elements[5] = n13*n34*n41 - n14*n33*n41 + n14*n31*n43 - n11*n34*n43 - n13*n31*n44 + n11*n33*n44;
		this.elements[9] = n14*n23*n41 - n13*n24*n41 - n14*n21*n43 + n11*n24*n43 + n13*n21*n44 - n11*n23*n44;
		this.elements[13] = n13*n24*n31 - n14*n23*n31 + n14*n21*n33 - n11*n24*n33 - n13*n21*n34 + n11*n23*n34;
		this.elements[2] = n22*n34*n41 - n24*n32*n41 + n24*n31*n42 - n21*n34*n42 - n22*n31*n44 + n21*n32*n44;
		this.elements[6] = n14*n32*n41 - n12*n34*n41 - n14*n31*n42 + n11*n34*n42 + n12*n31*n44 - n11*n32*n44;
		this.elements[10] = n12*n24*n41 - n14*n22*n41 + n14*n21*n42 - n11*n24*n42 - n12*n21*n44 + n11*n22*n44;
		this.elements[14] = n14*n22*n31 - n12*n24*n31 - n14*n21*n32 + n11*n24*n32 + n12*n21*n34 - n11*n22*n34;
		this.elements[3] = n23*n32*n41 - n22*n33*n41 - n23*n31*n42 + n21*n33*n42 + n22*n31*n43 - n21*n32*n43;
		this.elements[7] = n12*n33*n41 - n13*n32*n41 + n13*n31*n42 - n11*n33*n42 - n12*n31*n43 + n11*n32*n43;
		this.elements[11] = n13*n22*n41 - n12*n23*n41 - n13*n21*n42 + n11*n23*n42 + n12*n21*n43 - n11*n22*n43;
		this.elements[15] = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33;
382 383 384
		this.multiplyScalar( 1 / m.determinant() );

		return this;
385

386
	},
387

388
	setRotationFromEuler: function( v, order ) {
389

390 391 392 393
		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 );
394

395
		switch ( order ) {
M
Mr.doob 已提交
396

397
			case 'YXZ':
M
Mr.doob 已提交
398

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

401 402 403
				this.elements[0] = ce + df * b;
				this.elements[4] = de * b - cf;
				this.elements[8] = a * d;
404

405 406 407
				this.elements[1] = a * f;
				this.elements[5] = a * e;
				this.elements[9] = - b;
408

409 410 411
				this.elements[2] = cf * b - de;
				this.elements[6] = df + ce * b;
				this.elements[10] = a * c;
412 413 414
				break;

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

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

418 419 420
				this.elements[0] = ce - df * b;
				this.elements[4] = - a * f;
				this.elements[8] = de + cf * b;
421

422 423 424
				this.elements[1] = cf + de * b;
				this.elements[5] = a * e;
				this.elements[9] = df - ce * b;
425

426 427 428
				this.elements[2] = - a * d;
				this.elements[6] = b;
				this.elements[10] = a * c;
429 430 431
				break;

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

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

435 436 437
				this.elements[0] = c * e;
				this.elements[4] = be * d - af;
				this.elements[8] = ae * d + bf;
438

439 440 441
				this.elements[1] = c * f;
				this.elements[5] = bf * d + ae;
				this.elements[9] = af * d - be;
442

443 444 445
				this.elements[2] = - d;
				this.elements[6] = b * c;
				this.elements[10] = a * c;
446 447 448
				break;

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

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

452 453 454
				this.elements[0] = c * e;
				this.elements[4] = bd - ac * f;
				this.elements[8] = bc * f + ad;
455

456 457 458
				this.elements[1] = f;
				this.elements[5] = a * e;
				this.elements[9] = - b * e;
459

460 461 462
				this.elements[2] = - d * e;
				this.elements[6] = ad * f + bc;
				this.elements[10] = ac - bd * f;
463 464 465
				break;

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

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

469 470 471
				this.elements[0] = c * e;
				this.elements[4] = - f;
				this.elements[8] = d * e;
472

473 474 475
				this.elements[1] = ac * f + bd;
				this.elements[5] = a * e;
				this.elements[9] = ad * f - bc;
476

477 478 479
				this.elements[2] = bc * f - ad;
				this.elements[6] = b * e;
				this.elements[10] = bd * f + ac;
480 481 482
				break;

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

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

486 487 488
				this.elements[0] = c * e;
				this.elements[4] = - c * f;
				this.elements[8] = d;
489

490 491 492
				this.elements[1] = af + be * d;
				this.elements[5] = ae - bf * d;
				this.elements[9] = - b * c;
493

494 495 496
				this.elements[2] = bf - ae * d;
				this.elements[6] = be + af * d;
				this.elements[10] = a * c;
497
				break;
M
Mr.doob 已提交
498

499
		}
500

501 502
		return this;

503 504
	},

505

506
	setRotationFromQuaternion: function( q ) {
507

508 509 510 511 512
		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;
513

514 515 516
		this.elements[0] = 1 - ( yy + zz );
		this.elements[4] = xy - wz;
		this.elements[8] = xz + wy;
517

518 519 520
		this.elements[1] = xy + wz;
		this.elements[5] = 1 - ( xx + zz );
		this.elements[9] = yz - wx;
521

522 523 524
		this.elements[2] = xz - wy;
		this.elements[6] = yz + wx;
		this.elements[10] = 1 - ( xx + yy );
525

526 527
		return this;

528
	},
529

M
Mr.doob 已提交
530
	compose: function ( translation, rotation, scale ) {
531 532 533 534 535 536 537

		var mRotation = THREE.Matrix4.__m1;
		var mScale = THREE.Matrix4.__m2;

		mRotation.identity();
		mRotation.setRotationFromQuaternion( rotation );

538
		mScale.makeScale( scale.x, scale.y, scale.z );
539 540 541

		this.multiply( mRotation, mScale );

542 543 544
		this.elements[12] = translation.x;
		this.elements[13] = translation.y;
		this.elements[14] = translation.z;
545

M
Mr.doob 已提交
546
		return this;
547

M
Mr.doob 已提交
548
	},
549

M
Mr.doob 已提交
550
	decompose: function ( translation, rotation, scale ) {
551 552 553 554 555 556 557

		// grab the axis vectors

		var x = THREE.Matrix4.__v1;
		var y = THREE.Matrix4.__v2;
		var z = THREE.Matrix4.__v3;

558 559 560
		x.set( this.elements[0], this.elements[1], this.elements[2] );
		y.set( this.elements[4], this.elements[5], this.elements[6] );
		z.set( this.elements[8], this.elements[9], this.elements[10] );
561 562 563 564 565

		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();

M
Mr.doob 已提交
566 567 568
		scale.x = x.length();
		scale.y = y.length();
		scale.z = z.length();
569

570 571 572
		translation.x = this.elements[12];
		translation.y = this.elements[13];
		translation.z = this.elements[14];
573

M
Mr.doob 已提交
574
		// scale the rotation part
575 576 577 578 579

		var matrix = THREE.Matrix4.__m1;

		matrix.copy( this );

580 581 582
		matrix.elements[0] /= scale.x;
		matrix.elements[1] /= scale.x;
		matrix.elements[2] /= scale.x;
583

584 585 586
		matrix.elements[4] /= scale.y;
		matrix.elements[5] /= scale.y;
		matrix.elements[6] /= scale.y;
587

588 589 590
		matrix.elements[8] /= scale.z;
		matrix.elements[9] /= scale.z;
		matrix.elements[10] /= scale.z;
591 592 593 594 595

		rotation.setFromRotationMatrix( matrix );

		return [ translation, rotation, scale ];

M
Mr.doob 已提交
596 597
	},

598
	extractPosition: function ( m ) {
M
Mr.doob 已提交
599

600 601 602
		this.elements[12] = m.elements[12];
		this.elements[13] = m.elements[13];
		this.elements[14] = m.elements[14];
M
Mr.doob 已提交
603

M
Mr.doob 已提交
604 605
		return this;

606
	},
607

M
Mr.doob 已提交
608
	extractRotation: function ( m ) {
609

M
Mr.doob 已提交
610
		var vector = THREE.Matrix4.__v1;
M
Mr.doob 已提交
611

612 613 614
		var scaleX = 1 / vector.set( m.elements[0], m.elements[1], m.elements[2] ).length();
		var scaleY = 1 / vector.set( m.elements[4], m.elements[5], m.elements[6] ).length();
		var scaleZ = 1 / vector.set( m.elements[8], m.elements[9], m.elements[10] ).length();
P
philogb 已提交
615

616 617 618
		this.elements[0] = m.elements[0] * scaleX;
		this.elements[1] = m.elements[1] * scaleX;
		this.elements[2] = m.elements[2] * scaleX;
619

620 621 622
		this.elements[4] = m.elements[4] * scaleY;
		this.elements[5] = m.elements[5] * scaleY;
		this.elements[6] = m.elements[6] * scaleY;
M
Mr.doob 已提交
623

624 625 626
		this.elements[8] = m.elements[8] * scaleZ;
		this.elements[9] = m.elements[9] * scaleZ;
		this.elements[10] = m.elements[10] * scaleZ;
M
Mr.doob 已提交
627 628

		return this;
M
Mr.doob 已提交
629

630 631
	},

632
	//
633

634
	translate: function ( v ) {
635

636
		var x = v.x, y = v.y, z = v.z;
637

638 639 640 641
		this.elements[12] = this.elements[0] * x + this.elements[4] * y + this.elements[8] * z + this.elements[12];
		this.elements[13] = this.elements[1] * x + this.elements[5] * y + this.elements[9] * z + this.elements[13];
		this.elements[14] = this.elements[2] * x + this.elements[6] * y + this.elements[10] * z + this.elements[14];
		this.elements[15] = this.elements[3] * x + this.elements[7] * y + this.elements[11] * z + this.elements[15];
642 643 644 645 646 647 648

		return this;

	},

	rotateX: function ( angle ) {

649 650 651 652 653 654 655 656
		var m12 = this.elements[4];
		var m22 = this.elements[5];
		var m32 = this.elements[6];
		var m42 = this.elements[7];
		var m13 = this.elements[8];
		var m23 = this.elements[9];
		var m33 = this.elements[10];
		var m43 = this.elements[11];
657 658
		var c = Math.cos( angle );
		var s = Math.sin( angle );
659

660 661 662 663
		this.elements[4] = c * m12 + s * m13;
		this.elements[5] = c * m22 + s * m23;
		this.elements[6] = c * m32 + s * m33;
		this.elements[7] = c * m42 + s * m43;
664

665 666 667 668
		this.elements[8] = c * m13 - s * m12;
		this.elements[9] = c * m23 - s * m22;
		this.elements[10] = c * m33 - s * m32;
		this.elements[11] = c * m43 - s * m42;
669 670 671 672 673 674 675

		return this;

  	},

	rotateY: function ( angle ) {

676 677 678 679 680 681 682 683
		var m11 = this.elements[0];
		var m21 = this.elements[1];
		var m31 = this.elements[2];
		var m41 = this.elements[3];
		var m13 = this.elements[8];
		var m23 = this.elements[9];
		var m33 = this.elements[10];
		var m43 = this.elements[11];
684 685
		var c = Math.cos( angle );
		var s = Math.sin( angle );
686

687 688 689 690
		this.elements[0] = c * m11 - s * m13;
		this.elements[1] = c * m21 - s * m23;
		this.elements[2] = c * m31 - s * m33;
		this.elements[3] = c * m41 - s * m43;
691

692 693 694 695
		this.elements[8] = c * m13 + s * m11;
		this.elements[9] = c * m23 + s * m21;
		this.elements[10] = c * m33 + s * m31;
		this.elements[11] = c * m43 + s * m41;
696 697 698 699 700 701 702

		return this;

	},

	rotateZ: function ( angle ) {

703 704 705 706 707 708 709 710
		var m11 = this.elements[0];
		var m21 = this.elements[1];
		var m31 = this.elements[2];
		var m41 = this.elements[3];
		var m12 = this.elements[4];
		var m22 = this.elements[5];
		var m32 = this.elements[6];
		var m42 = this.elements[7];
711 712
		var c = Math.cos( angle );
		var s = Math.sin( angle );
713

714 715 716 717
		this.elements[0] = c * m11 + s * m12;
		this.elements[1] = c * m21 + s * m22;
		this.elements[2] = c * m31 + s * m32;
		this.elements[3] = c * m41 + s * m42;
718

719 720 721 722
		this.elements[4] = c * m12 - s * m11;
		this.elements[5] = c * m22 - s * m21;
		this.elements[6] = c * m32 - s * m31;
		this.elements[7] = c * m42 - s * m41;
723 724 725 726 727

		return this;

	},

728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
	rotateByAxis: function ( axis, angle ) {

		// 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 );

		}

746 747
		var x = axis.x, y = axis.y, z = axis.z;
		var n = Math.sqrt(x * x + y * y + z * z);
748 749 750 751 752

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

753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773
		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;

774 775 776 777
		var m11 = this.elements[0], m21 = this.elements[1], m31 = this.elements[2], m41 = this.elements[3];
		var m12 = this.elements[4], m22 = this.elements[5], m32 = this.elements[6], m42 = this.elements[7];
		var m13 = this.elements[8], m23 = this.elements[9], m33 = this.elements[10], m43 = this.elements[11];
		var m14 = this.elements[12], m24 = this.elements[13], m34 = this.elements[14], m44 = this.elements[15];
778

779 780 781 782
		this.elements[0] = r11 * m11 + r21 * m12 + r31 * m13;
		this.elements[1] = r11 * m21 + r21 * m22 + r31 * m23;
		this.elements[2] = r11 * m31 + r21 * m32 + r31 * m33;
		this.elements[3] = r11 * m41 + r21 * m42 + r31 * m43;
783

784 785 786 787
		this.elements[4] = r12 * m11 + r22 * m12 + r32 * m13;
		this.elements[5] = r12 * m21 + r22 * m22 + r32 * m23;
		this.elements[6] = r12 * m31 + r22 * m32 + r32 * m33;
		this.elements[7] = r12 * m41 + r22 * m42 + r32 * m43;
788

789 790 791 792
		this.elements[8] = r13 * m11 + r23 * m12 + r33 * m13;
		this.elements[9] = r13 * m21 + r23 * m22 + r33 * m23;
		this.elements[10] = r13 * m31 + r23 * m32 + r33 * m33;
		this.elements[11] = r13 * m41 + r23 * m42 + r33 * m43;
793 794 795 796 797 798

		return this;

	},

	scale: function ( v ) {
799 800 801

		var x = v.x, y = v.y, z = v.z;

802 803 804 805
		this.elements[0] *= x; this.elements[4] *= y; this.elements[8] *= z;
		this.elements[1] *= x; this.elements[5] *= y; this.elements[9] *= z;
		this.elements[2] *= x; this.elements[6] *= y; this.elements[10] *= z;
		this.elements[3] *= x; this.elements[7] *= y; this.elements[11] *= z;
806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882

		return this;

	},

	//

	makeTranslation: function ( x, y, z ) {

		this.set(

			1, 0, 0, x,
			0, 1, 0, y,
			0, 0, 1, z,
			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

883 884 885 886 887
		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;
888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926

		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

		);

		 return this;

	},

	makeScale: function ( x, y, z ) {

		this.set(

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

		);

		return this;

	},

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

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

927 928 929 930
		this.elements[0] = x;  this.elements[4] = 0;  this.elements[8] = a;   this.elements[12] = 0;
		this.elements[1] = 0;  this.elements[5] = y;  this.elements[9] = b;   this.elements[13] = 0;
		this.elements[2] = 0;  this.elements[6] = 0;  this.elements[10] = c;   this.elements[14] = d;
		this.elements[3] = 0;  this.elements[7] = 0;  this.elements[11] = - 1; this.elements[15] = 0;
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

		return this;

	},

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

		var ymax = near * Math.tan( fov * Math.PI / 360 );
		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 ) {

		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;

957 958 959 960
		this.elements[0] = 2 / w; this.elements[4] = 0;     this.elements[8] = 0;      this.elements[12] = -x;
		this.elements[1] = 0;     this.elements[5] = 2 / h; this.elements[9] = 0;      this.elements[13] = -y;
		this.elements[2] = 0;     this.elements[6] = 0;     this.elements[10] = -2 / p; this.elements[14] = -z;
		this.elements[3] = 0;     this.elements[7] = 0;     this.elements[11] = 0;      this.elements[15] = 1;
961 962 963

		return this;

M
Mr.doob 已提交
964 965
	},

966

M
Mr.doob 已提交
967 968 969
	clone: function () {

		return new THREE.Matrix4(
970

971 972 973 974
			this.elements[0], this.elements[4], this.elements[8], this.elements[12],
			this.elements[1], this.elements[5], this.elements[9], this.elements[13],
			this.elements[2], this.elements[6], this.elements[10], this.elements[14],
			this.elements[3], this.elements[7], this.elements[11], this.elements[15]
975

M
Mr.doob 已提交
976 977
		);

978
	}
P
philogb 已提交
979 980 981

};

982 983 984
THREE.Matrix4.__v1 = new THREE.Vector3();
THREE.Matrix4.__v2 = new THREE.Vector3();
THREE.Matrix4.__v3 = new THREE.Vector3();
985 986 987

THREE.Matrix4.__m1 = new THREE.Matrix4();
THREE.Matrix4.__m2 = new THREE.Matrix4();