Vector4.js 8.1 KB
Newer Older
1 2
/**
 * @author supereggbert / http://www.paulbrunt.co.uk/
M
Mr.doob 已提交
3
 * @author philogb / http://blog.thejit.org/
4
 * @author mikael emtinger / http://gomo.se/
M
Mr.doob 已提交
5
 * @author egraether / http://egraether.com/
W
WestLangley 已提交
6
 * @author WestLangley / http://github.com/WestLangley
7 8 9 10
 */

THREE.Vector4 = function ( x, y, z, w ) {

11 12 13
	this.x = x || 0;
	this.y = y || 0;
	this.z = z || 0;
14
	this.w = ( w !== undefined ) ? w : 1;
15 16 17 18 19

};

THREE.Vector4.prototype = {

20 21 22
	constructor: THREE.Vector4,

	set: function ( x, y, z, w ) {
23

24 25 26 27
		this.x = x;
		this.y = y;
		this.z = z;
		this.w = w;
28

29
		return this;
30

31
	},
32

33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
	setX: function ( x ) {

		this.x = x;

		return this;

	},

	setY: function ( y ) {

		this.y = y;

		return this;

	},

	setZ: function ( z ) {

		this.z = z;

		return this;

	},

	setW: function ( w ) {

		this.w = w;

		return this;

	},

M
Mr.doob 已提交
65
	setComponent: function ( index, value ) {
B
Ben Houston 已提交
66

M
Mr.doob 已提交
67
		switch ( index ) {
B
Ben Houston 已提交
68

M
Mr.doob 已提交
69 70 71 72 73
			case 0: this.x = value; break;
			case 1: this.y = value; break;
			case 2: this.z = value; break;
			case 3: this.w = value; break;
			default: throw new Error( "index is out of range: " + index );
74

M
Mr.doob 已提交
75
		}
B
Ben Houston 已提交
76

M
Mr.doob 已提交
77
	},
78

M
Mr.doob 已提交
79
	getComponent: function ( index ) {
80

M
Mr.doob 已提交
81
		switch ( index ) {
82

M
Mr.doob 已提交
83 84 85 86 87
			case 0: return this.x;
			case 1: return this.y;
			case 2: return this.z;
			case 3: return this.w;
			default: throw new Error( "index is out of range: " + index );
88

M
Mr.doob 已提交
89
		}
90

M
Mr.doob 已提交
91
	},
92

93
	copy: function ( v ) {
M
Mr.doob 已提交
94

95 96 97
		this.x = v.x;
		this.y = v.y;
		this.z = v.z;
98
		this.w = ( v.w !== undefined ) ? v.w : 1;
99

100 101
		return this;

102
	},
103

104 105 106 107 108 109 110 111 112 113 114
	addScalar: function ( s ) {

		this.x += s;
		this.y += s;
		this.z += s;
		this.w += s;

		return this;

	},

M
Mr.doob 已提交
115
	add: function ( a, b ) {
M
Mr.doob 已提交
116

M
Mr.doob 已提交
117 118 119 120
		this.x = a.x + b.x;
		this.y = a.y + b.y;
		this.z = a.z + b.z;
		this.w = a.w + b.w;
121

122 123
		return this;

124
	},
125

126
	addSelf: function ( v ) {
M
Mr.doob 已提交
127

M
Mr.doob 已提交
128 129 130 131
		this.x += v.x;
		this.y += v.y;
		this.z += v.z;
		this.w += v.w;
132

M
Mr.doob 已提交
133
		return this;
M
Mr.doob 已提交
134

M
Mr.doob 已提交
135 136
	},

M
Mr.doob 已提交
137
	sub: function ( a, b ) {
M
Mr.doob 已提交
138

M
Mr.doob 已提交
139 140 141 142
		this.x = a.x - b.x;
		this.y = a.y - b.y;
		this.z = a.z - b.z;
		this.w = a.w - b.w;
143

B
Ben Nolan 已提交
144 145
		return this;

146
	},
147

148
	subSelf: function ( v ) {
M
Mr.doob 已提交
149 150 151 152 153

		this.x -= v.x;
		this.y -= v.y;
		this.z -= v.z;
		this.w -= v.w;
M
Mr.doob 已提交
154

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

M
Mr.doob 已提交
157
	},
M
Mr.doob 已提交
158

159
	multiplyScalar: function ( s ) {
M
Mr.doob 已提交
160 161 162 163 164

		this.x *= s;
		this.y *= s;
		this.z *= s;
		this.w *= s;
165

166 167
		return this;

168
	},
169

170
	applyMatrix4: function ( m ) {
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

		var x = this.x;
		var y = this.y;
		var z = this.z;
		var w = this.w;

		var e = m.elements;

		this.x = e[0] * x + e[4] * y + e[8] * z + e[12] * w;
		this.y = e[1] * x + e[5] * y + e[9] * z + e[13] * w;
		this.z = e[2] * x + e[6] * y + e[10] * z + e[14] * w;
		this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w;

		return this;

	},

188
	divideScalar: function ( s ) {
M
Mr.doob 已提交
189

B
Ben Houston 已提交
190
		if ( s !== 0 ) {
M
Mr.doob 已提交
191

M
Mr.doob 已提交
192 193 194 195
			this.x /= s;
			this.y /= s;
			this.z /= s;
			this.w /= s;
196

M
Mr.doob 已提交
197 198
		} else {

199 200 201 202
			this.x = 0;
			this.y = 0;
			this.z = 0;
			this.w = 1;
M
Mr.doob 已提交
203 204

		}
205

B
Ben Nolan 已提交
206 207
		return this;

208
	},
M
Mr.doob 已提交
209

210 211
	minSelf: function ( v ) {

A
alteredq 已提交
212 213
		if ( this.x > v.x ) {

214
			this.x = v.x;
A
alteredq 已提交
215

216
		}
A
alteredq 已提交
217 218 219

		if ( this.y > v.y ) {

220
			this.y = v.y;
A
alteredq 已提交
221

222
		}
A
alteredq 已提交
223 224 225

		if ( this.z > v.z ) {

226
			this.z = v.z;
A
alteredq 已提交
227

228
		}
A
alteredq 已提交
229 230 231

		if ( this.w > v.w ) {

232
			this.w = v.w;
A
alteredq 已提交
233

234 235 236 237 238 239 240 241
		}

		return this;

	},

	maxSelf: function ( v ) {

A
alteredq 已提交
242 243
		if ( this.x < v.x ) {

244
			this.x = v.x;
A
alteredq 已提交
245

246
		}
A
alteredq 已提交
247 248 249

		if ( this.y < v.y ) {

250
			this.y = v.y;
A
alteredq 已提交
251

252
		}
A
alteredq 已提交
253 254 255

		if ( this.z < v.z ) {

256
			this.z = v.z;
A
alteredq 已提交
257

258
		}
A
alteredq 已提交
259 260 261

		if ( this.w < v.w ) {

262
			this.w = v.w;
A
alteredq 已提交
263

264 265 266 267 268 269 270 271 272 273
		}

		return this;

	},

	clampSelf: function ( min, max ) {

		// This function assumes min < max, if this assumption isn't true it will not operate correctly

A
alteredq 已提交
274 275
		if ( this.x < min.x ) {

276
			this.x = min.x;
A
alteredq 已提交
277 278 279

		} else if ( this.x > max.x ) {

280
			this.x = max.x;
A
alteredq 已提交
281

282 283
		}

A
alteredq 已提交
284 285
		if ( this.y < min.y ) {

286
			this.y = min.y;
A
alteredq 已提交
287 288 289

		} else if ( this.y > max.y ) {

290
			this.y = max.y;
A
alteredq 已提交
291

292 293
		}

A
alteredq 已提交
294 295
		if ( this.z < min.z ) {

296
			this.z = min.z;
A
alteredq 已提交
297 298 299

		} else if ( this.z > max.z ) {

300
			this.z = max.z;
A
alteredq 已提交
301

302 303
		}

A
alteredq 已提交
304 305
		if ( this.w < min.w ) {

306
			this.w = min.w;
A
alteredq 已提交
307 308 309

		} else if ( this.w > max.w ) {

310
			this.w = max.w;
A
alteredq 已提交
311

312 313 314
		}

		return this;
A
alteredq 已提交
315

316
	},
M
Mr.doob 已提交
317

318
	negate: function() {
M
Mr.doob 已提交
319

M
Mr.doob 已提交
320
		return this.multiplyScalar( -1 );
M
Mr.doob 已提交
321

M
Mr.doob 已提交
322
	},
M
Mr.doob 已提交
323

324
	dot: function ( v ) {
M
Mr.doob 已提交
325 326

		return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
M
Mr.doob 已提交
327 328 329

	},

330
	lengthSq: function () {
M
Mr.doob 已提交
331

332
		return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
M
Mr.doob 已提交
333

M
Mr.doob 已提交
334
	},
M
Mr.doob 已提交
335

336
	length: function () {
M
Mr.doob 已提交
337

338
		return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
M
Mr.doob 已提交
339 340

	},
M
Mr.doob 已提交
341

342 343 344 345 346
	lengthManhattan: function () {

		return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );

	},
M
Mr.doob 已提交
347

348
	normalize: function () {
M
Mr.doob 已提交
349 350

		return this.divideScalar( this.length() );
M
Mr.doob 已提交
351

M
Mr.doob 已提交
352
	},
M
Mr.doob 已提交
353

354
	setLength: function ( l ) {
M
Mr.doob 已提交
355

356
		var oldLength = this.length();
M
Mr.doob 已提交
357 358

		if ( oldLength !== 0 && l !== oldLength ) {
359

360 361 362 363
			this.multiplyScalar( l / oldLength );
		}

		return this;
M
Mr.doob 已提交
364

M
Mr.doob 已提交
365
	},
366

367
	lerpSelf: function ( v, alpha ) {
M
Mr.doob 已提交
368

369 370 371 372
		this.x += ( v.x - this.x ) * alpha;
		this.y += ( v.y - this.y ) * alpha;
		this.z += ( v.z - this.z ) * alpha;
		this.w += ( v.w - this.w ) * alpha;
373

M
Mr.doob 已提交
374 375
		return this;

M
Mr.doob 已提交
376 377
	},

378 379 380 381 382 383
	equals: function ( v ) {

		return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );

	},

M
Mr.doob 已提交
384 385 386 387
	clone: function () {

		return new THREE.Vector4( this.x, this.y, this.z, this.w );

W
WestLangley 已提交
388 389 390 391 392
	},

	setAxisAngleFromQuaternion: function ( q ) {

		// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
M
Mr.doob 已提交
393

W
WestLangley 已提交
394
		// q is assumed to be normalized
M
Mr.doob 已提交
395

W
WestLangley 已提交
396
		this.w = 2 * Math.acos( q.w );
M
Mr.doob 已提交
397

W
WestLangley 已提交
398
		var s = Math.sqrt( 1 - q.w * q.w );
M
Mr.doob 已提交
399

W
WestLangley 已提交
400
		if ( s < 0.0001 ) {
M
Mr.doob 已提交
401

W
WestLangley 已提交
402 403 404
			 this.x = 1;
			 this.y = 0;
			 this.z = 0;
M
Mr.doob 已提交
405

W
WestLangley 已提交
406
		} else {
M
Mr.doob 已提交
407

W
WestLangley 已提交
408 409 410
			 this.x = q.x / s;
			 this.y = q.y / s;
			 this.z = q.z / s;
M
Mr.doob 已提交
411

W
WestLangley 已提交
412
		}
M
Mr.doob 已提交
413

W
WestLangley 已提交
414 415 416 417 418 419 420
		return this;

	},

	setAxisAngleFromRotationMatrix: function ( m ) {

		// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
M
Mr.doob 已提交
421

W
WestLangley 已提交
422
		// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
M
Mr.doob 已提交
423

W
WestLangley 已提交
424 425 426
		var angle, x, y, z,		// variables for result
			epsilon = 0.01,		// margin to allow for rounding errors
			epsilon2 = 0.1,		// margin to distinguish between 0 and 180 degrees
M
Mr.doob 已提交
427

W
WestLangley 已提交
428
			te = m.elements,
M
Mr.doob 已提交
429

W
WestLangley 已提交
430 431 432 433 434 435 436
			m11 = te[0], m12 = te[4], m13 = te[8],
			m21 = te[1], m22 = te[5], m23 = te[9],
			m31 = te[2], m32 = te[6], m33 = te[10];

		if ( ( Math.abs( m12 - m21 ) < epsilon )
		  && ( Math.abs( m13 - m31 ) < epsilon )
		  && ( Math.abs( m23 - m32 ) < epsilon ) ) {
M
Mr.doob 已提交
437

W
WestLangley 已提交
438 439 440
			// singularity found
			// first check for identity matrix which must have +1 for all terms
			// in leading diagonal and zero in other terms
M
Mr.doob 已提交
441

W
WestLangley 已提交
442 443 444 445
			if ( ( Math.abs( m12 + m21 ) < epsilon2 )
			  && ( Math.abs( m13 + m31 ) < epsilon2 )
			  && ( Math.abs( m23 + m32 ) < epsilon2 )
			  && ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {
M
Mr.doob 已提交
446

W
WestLangley 已提交
447
				// this singularity is identity matrix so angle = 0
M
Mr.doob 已提交
448

W
WestLangley 已提交
449
				this.set( 1, 0, 0, 0 );
M
Mr.doob 已提交
450

W
WestLangley 已提交
451
				return this; // zero angle, arbitrary axis
M
Mr.doob 已提交
452

W
WestLangley 已提交
453
			}
M
Mr.doob 已提交
454

W
WestLangley 已提交
455
			// otherwise this singularity is angle = 180
M
Mr.doob 已提交
456

W
WestLangley 已提交
457
			angle = Math.PI;
M
Mr.doob 已提交
458

W
WestLangley 已提交
459 460 461 462 463 464
			var xx = ( m11 + 1 ) / 2;
			var yy = ( m22 + 1 ) / 2;
			var zz = ( m33 + 1 ) / 2;
			var xy = ( m12 + m21 ) / 4;
			var xz = ( m13 + m31 ) / 4;
			var yz = ( m23 + m32 ) / 4;
M
Mr.doob 已提交
465

W
WestLangley 已提交
466
			if ( ( xx > yy ) && ( xx > zz ) ) { // m11 is the largest diagonal term
M
Mr.doob 已提交
467

W
WestLangley 已提交
468
				if ( xx < epsilon ) {
M
Mr.doob 已提交
469

W
WestLangley 已提交
470 471 472
					x = 0;
					y = 0.707106781;
					z = 0.707106781;
M
Mr.doob 已提交
473

W
WestLangley 已提交
474
				} else {
M
Mr.doob 已提交
475

W
WestLangley 已提交
476 477 478
					x = Math.sqrt( xx );
					y = xy / x;
					z = xz / x;
M
Mr.doob 已提交
479

W
WestLangley 已提交
480
				}
M
Mr.doob 已提交
481

W
WestLangley 已提交
482
			} else if ( yy > zz ) { // m22 is the largest diagonal term
M
Mr.doob 已提交
483

W
WestLangley 已提交
484
				if ( yy < epsilon ) {
M
Mr.doob 已提交
485

W
WestLangley 已提交
486 487 488
					x = 0.707106781;
					y = 0;
					z = 0.707106781;
M
Mr.doob 已提交
489

W
WestLangley 已提交
490
				} else {
M
Mr.doob 已提交
491

W
WestLangley 已提交
492 493 494
					y = Math.sqrt( yy );
					x = xy / y;
					z = yz / y;
M
Mr.doob 已提交
495 496 497

				}

W
WestLangley 已提交
498
			} else { // m33 is the largest diagonal term so base result on this
M
Mr.doob 已提交
499

W
WestLangley 已提交
500
				if ( zz < epsilon ) {
M
Mr.doob 已提交
501

W
WestLangley 已提交
502 503 504
					x = 0.707106781;
					y = 0.707106781;
					z = 0;
M
Mr.doob 已提交
505

W
WestLangley 已提交
506
				} else {
M
Mr.doob 已提交
507

W
WestLangley 已提交
508 509 510
					z = Math.sqrt( zz );
					x = xz / z;
					y = yz / z;
M
Mr.doob 已提交
511

W
WestLangley 已提交
512
				}
M
Mr.doob 已提交
513

W
WestLangley 已提交
514
			}
M
Mr.doob 已提交
515

W
WestLangley 已提交
516
			this.set( x, y, z, angle );
M
Mr.doob 已提交
517

W
WestLangley 已提交
518
			return this; // return 180 deg rotation
M
Mr.doob 已提交
519

W
WestLangley 已提交
520
		}
M
Mr.doob 已提交
521

W
WestLangley 已提交
522
		// as we have reached here there are no singularities so we can handle normally
M
Mr.doob 已提交
523

W
WestLangley 已提交
524 525 526
		var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 )
						 + ( m13 - m31 ) * ( m13 - m31 )
						 + ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize
M
Mr.doob 已提交
527

A
alteredq 已提交
528
		if ( Math.abs( s ) < 0.001 ) s = 1;
M
Mr.doob 已提交
529

W
WestLangley 已提交
530 531
		// prevent divide by zero, should not happen if matrix is orthogonal and should be
		// caught by singularity test above, but I've left it in just in case
M
Mr.doob 已提交
532

W
WestLangley 已提交
533 534 535 536
		this.x = ( m32 - m23 ) / s;
		this.y = ( m13 - m31 ) / s;
		this.z = ( m21 - m12 ) / s;
		this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );
M
Mr.doob 已提交
537

W
WestLangley 已提交
538 539
		return this;

540
	}
541

M
Mr.doob 已提交
542
};