UNPKG

12.3 kBJavaScriptView Raw
1import { _Math } from './Math.js';
2import { Matrix4 } from './Matrix4.js';
3import { Quaternion } from './Quaternion.js';
4
5/**
6 * @author mrdoob / http://mrdoob.com/
7 * @author kile / http://kile.stravaganza.org/
8 * @author philogb / http://blog.thejit.org/
9 * @author mikael emtinger / http://gomo.se/
10 * @author egraether / http://egraether.com/
11 * @author WestLangley / http://github.com/WestLangley
12 */
13
14function Vector3( x, y, z ) {
15
16 this.x = x || 0;
17 this.y = y || 0;
18 this.z = z || 0;
19
20}
21
22Object.assign( Vector3.prototype, {
23
24 isVector3: true,
25
26 set: function ( x, y, z ) {
27
28 this.x = x;
29 this.y = y;
30 this.z = z;
31
32 return this;
33
34 },
35
36 setScalar: function ( scalar ) {
37
38 this.x = scalar;
39 this.y = scalar;
40 this.z = scalar;
41
42 return this;
43
44 },
45
46 setX: function ( x ) {
47
48 this.x = x;
49
50 return this;
51
52 },
53
54 setY: function ( y ) {
55
56 this.y = y;
57
58 return this;
59
60 },
61
62 setZ: function ( z ) {
63
64 this.z = z;
65
66 return this;
67
68 },
69
70 setComponent: function ( index, value ) {
71
72 switch ( index ) {
73
74 case 0: this.x = value; break;
75 case 1: this.y = value; break;
76 case 2: this.z = value; break;
77 default: throw new Error( 'index is out of range: ' + index );
78
79 }
80
81 return this;
82
83 },
84
85 getComponent: function ( index ) {
86
87 switch ( index ) {
88
89 case 0: return this.x;
90 case 1: return this.y;
91 case 2: return this.z;
92 default: throw new Error( 'index is out of range: ' + index );
93
94 }
95
96 },
97
98 clone: function () {
99
100 return new this.constructor( this.x, this.y, this.z );
101
102 },
103
104 copy: function ( v ) {
105
106 this.x = v.x;
107 this.y = v.y;
108 this.z = v.z;
109
110 return this;
111
112 },
113
114 add: function ( v, w ) {
115
116 if ( w !== undefined ) {
117
118 console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
119 return this.addVectors( v, w );
120
121 }
122
123 this.x += v.x;
124 this.y += v.y;
125 this.z += v.z;
126
127 return this;
128
129 },
130
131 addScalar: function ( s ) {
132
133 this.x += s;
134 this.y += s;
135 this.z += s;
136
137 return this;
138
139 },
140
141 addVectors: function ( a, b ) {
142
143 this.x = a.x + b.x;
144 this.y = a.y + b.y;
145 this.z = a.z + b.z;
146
147 return this;
148
149 },
150
151 addScaledVector: function ( v, s ) {
152
153 this.x += v.x * s;
154 this.y += v.y * s;
155 this.z += v.z * s;
156
157 return this;
158
159 },
160
161 sub: function ( v, w ) {
162
163 if ( w !== undefined ) {
164
165 console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
166 return this.subVectors( v, w );
167
168 }
169
170 this.x -= v.x;
171 this.y -= v.y;
172 this.z -= v.z;
173
174 return this;
175
176 },
177
178 subScalar: function ( s ) {
179
180 this.x -= s;
181 this.y -= s;
182 this.z -= s;
183
184 return this;
185
186 },
187
188 subVectors: function ( a, b ) {
189
190 this.x = a.x - b.x;
191 this.y = a.y - b.y;
192 this.z = a.z - b.z;
193
194 return this;
195
196 },
197
198 multiply: function ( v, w ) {
199
200 if ( w !== undefined ) {
201
202 console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );
203 return this.multiplyVectors( v, w );
204
205 }
206
207 this.x *= v.x;
208 this.y *= v.y;
209 this.z *= v.z;
210
211 return this;
212
213 },
214
215 multiplyScalar: function ( scalar ) {
216
217 this.x *= scalar;
218 this.y *= scalar;
219 this.z *= scalar;
220
221 return this;
222
223 },
224
225 multiplyVectors: function ( a, b ) {
226
227 this.x = a.x * b.x;
228 this.y = a.y * b.y;
229 this.z = a.z * b.z;
230
231 return this;
232
233 },
234
235 applyEuler: function () {
236
237 var quaternion = new Quaternion();
238
239 return function applyEuler( euler ) {
240
241 if ( ! ( euler && euler.isEuler ) ) {
242
243 console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );
244
245 }
246
247 return this.applyQuaternion( quaternion.setFromEuler( euler ) );
248
249 };
250
251 }(),
252
253 applyAxisAngle: function () {
254
255 var quaternion = new Quaternion();
256
257 return function applyAxisAngle( axis, angle ) {
258
259 return this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );
260
261 };
262
263 }(),
264
265 applyMatrix3: function ( m ) {
266
267 var x = this.x, y = this.y, z = this.z;
268 var e = m.elements;
269
270 this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;
271 this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;
272 this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;
273
274 return this;
275
276 },
277
278 applyMatrix4: function ( m ) {
279
280 var x = this.x, y = this.y, z = this.z;
281 var e = m.elements;
282
283 var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] );
284
285 this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w;
286 this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w;
287 this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w;
288
289 return this;
290
291 },
292
293 applyQuaternion: function ( q ) {
294
295 var x = this.x, y = this.y, z = this.z;
296 var qx = q.x, qy = q.y, qz = q.z, qw = q.w;
297
298 // calculate quat * vector
299
300 var ix = qw * x + qy * z - qz * y;
301 var iy = qw * y + qz * x - qx * z;
302 var iz = qw * z + qx * y - qy * x;
303 var iw = - qx * x - qy * y - qz * z;
304
305 // calculate result * inverse quat
306
307 this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
308 this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
309 this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
310
311 return this;
312
313 },
314
315 project: function () {
316
317 var matrix = new Matrix4();
318
319 return function project( camera ) {
320
321 matrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );
322 return this.applyMatrix4( matrix );
323
324 };
325
326 }(),
327
328 unproject: function () {
329
330 var matrix = new Matrix4();
331
332 return function unproject( camera ) {
333
334 matrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );
335 return this.applyMatrix4( matrix );
336
337 };
338
339 }(),
340
341 transformDirection: function ( m ) {
342
343 // input: THREE.Matrix4 affine matrix
344 // vector interpreted as a direction
345
346 var x = this.x, y = this.y, z = this.z;
347 var e = m.elements;
348
349 this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;
350 this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;
351 this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;
352
353 return this.normalize();
354
355 },
356
357 divide: function ( v ) {
358
359 this.x /= v.x;
360 this.y /= v.y;
361 this.z /= v.z;
362
363 return this;
364
365 },
366
367 divideScalar: function ( scalar ) {
368
369 return this.multiplyScalar( 1 / scalar );
370
371 },
372
373 min: function ( v ) {
374
375 this.x = Math.min( this.x, v.x );
376 this.y = Math.min( this.y, v.y );
377 this.z = Math.min( this.z, v.z );
378
379 return this;
380
381 },
382
383 max: function ( v ) {
384
385 this.x = Math.max( this.x, v.x );
386 this.y = Math.max( this.y, v.y );
387 this.z = Math.max( this.z, v.z );
388
389 return this;
390
391 },
392
393 clamp: function ( min, max ) {
394
395 // assumes min < max, componentwise
396
397 this.x = Math.max( min.x, Math.min( max.x, this.x ) );
398 this.y = Math.max( min.y, Math.min( max.y, this.y ) );
399 this.z = Math.max( min.z, Math.min( max.z, this.z ) );
400
401 return this;
402
403 },
404
405 clampScalar: function () {
406
407 var min = new Vector3();
408 var max = new Vector3();
409
410 return function clampScalar( minVal, maxVal ) {
411
412 min.set( minVal, minVal, minVal );
413 max.set( maxVal, maxVal, maxVal );
414
415 return this.clamp( min, max );
416
417 };
418
419 }(),
420
421 clampLength: function ( min, max ) {
422
423 var length = this.length();
424
425 return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
426
427 },
428
429 floor: function () {
430
431 this.x = Math.floor( this.x );
432 this.y = Math.floor( this.y );
433 this.z = Math.floor( this.z );
434
435 return this;
436
437 },
438
439 ceil: function () {
440
441 this.x = Math.ceil( this.x );
442 this.y = Math.ceil( this.y );
443 this.z = Math.ceil( this.z );
444
445 return this;
446
447 },
448
449 round: function () {
450
451 this.x = Math.round( this.x );
452 this.y = Math.round( this.y );
453 this.z = Math.round( this.z );
454
455 return this;
456
457 },
458
459 roundToZero: function () {
460
461 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
462 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
463 this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
464
465 return this;
466
467 },
468
469 negate: function () {
470
471 this.x = - this.x;
472 this.y = - this.y;
473 this.z = - this.z;
474
475 return this;
476
477 },
478
479 dot: function ( v ) {
480
481 return this.x * v.x + this.y * v.y + this.z * v.z;
482
483 },
484
485 // TODO lengthSquared?
486
487 lengthSq: function () {
488
489 return this.x * this.x + this.y * this.y + this.z * this.z;
490
491 },
492
493 length: function () {
494
495 return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
496
497 },
498
499 manhattanLength: function () {
500
501 return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
502
503 },
504
505 normalize: function () {
506
507 return this.divideScalar( this.length() || 1 );
508
509 },
510
511 setLength: function ( length ) {
512
513 return this.normalize().multiplyScalar( length );
514
515 },
516
517 lerp: function ( v, alpha ) {
518
519 this.x += ( v.x - this.x ) * alpha;
520 this.y += ( v.y - this.y ) * alpha;
521 this.z += ( v.z - this.z ) * alpha;
522
523 return this;
524
525 },
526
527 lerpVectors: function ( v1, v2, alpha ) {
528
529 return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );
530
531 },
532
533 cross: function ( v, w ) {
534
535 if ( w !== undefined ) {
536
537 console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );
538 return this.crossVectors( v, w );
539
540 }
541
542 return this.crossVectors( this, v );
543
544 },
545
546 crossVectors: function ( a, b ) {
547
548 var ax = a.x, ay = a.y, az = a.z;
549 var bx = b.x, by = b.y, bz = b.z;
550
551 this.x = ay * bz - az * by;
552 this.y = az * bx - ax * bz;
553 this.z = ax * by - ay * bx;
554
555 return this;
556
557 },
558
559 projectOnVector: function ( vector ) {
560
561 var scalar = vector.dot( this ) / vector.lengthSq();
562
563 return this.copy( vector ).multiplyScalar( scalar );
564
565 },
566
567 projectOnPlane: function () {
568
569 var v1 = new Vector3();
570
571 return function projectOnPlane( planeNormal ) {
572
573 v1.copy( this ).projectOnVector( planeNormal );
574
575 return this.sub( v1 );
576
577 };
578
579 }(),
580
581 reflect: function () {
582
583 // reflect incident vector off plane orthogonal to normal
584 // normal is assumed to have unit length
585
586 var v1 = new Vector3();
587
588 return function reflect( normal ) {
589
590 return this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );
591
592 };
593
594 }(),
595
596 angleTo: function ( v ) {
597
598 var theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );
599
600 // clamp, to handle numerical problems
601
602 return Math.acos( _Math.clamp( theta, - 1, 1 ) );
603
604 },
605
606 distanceTo: function ( v ) {
607
608 return Math.sqrt( this.distanceToSquared( v ) );
609
610 },
611
612 distanceToSquared: function ( v ) {
613
614 var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
615
616 return dx * dx + dy * dy + dz * dz;
617
618 },
619
620 manhattanDistanceTo: function ( v ) {
621
622 return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );
623
624 },
625
626 setFromSpherical: function ( s ) {
627
628 var sinPhiRadius = Math.sin( s.phi ) * s.radius;
629
630 this.x = sinPhiRadius * Math.sin( s.theta );
631 this.y = Math.cos( s.phi ) * s.radius;
632 this.z = sinPhiRadius * Math.cos( s.theta );
633
634 return this;
635
636 },
637
638 setFromCylindrical: function ( c ) {
639
640 this.x = c.radius * Math.sin( c.theta );
641 this.y = c.y;
642 this.z = c.radius * Math.cos( c.theta );
643
644 return this;
645
646 },
647
648 setFromMatrixPosition: function ( m ) {
649
650 var e = m.elements;
651
652 this.x = e[ 12 ];
653 this.y = e[ 13 ];
654 this.z = e[ 14 ];
655
656 return this;
657
658 },
659
660 setFromMatrixScale: function ( m ) {
661
662 var sx = this.setFromMatrixColumn( m, 0 ).length();
663 var sy = this.setFromMatrixColumn( m, 1 ).length();
664 var sz = this.setFromMatrixColumn( m, 2 ).length();
665
666 this.x = sx;
667 this.y = sy;
668 this.z = sz;
669
670 return this;
671
672 },
673
674 setFromMatrixColumn: function ( m, index ) {
675
676 return this.fromArray( m.elements, index * 4 );
677
678 },
679
680 equals: function ( v ) {
681
682 return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );
683
684 },
685
686 fromArray: function ( array, offset ) {
687
688 if ( offset === undefined ) offset = 0;
689
690 this.x = array[ offset ];
691 this.y = array[ offset + 1 ];
692 this.z = array[ offset + 2 ];
693
694 return this;
695
696 },
697
698 toArray: function ( array, offset ) {
699
700 if ( array === undefined ) array = [];
701 if ( offset === undefined ) offset = 0;
702
703 array[ offset ] = this.x;
704 array[ offset + 1 ] = this.y;
705 array[ offset + 2 ] = this.z;
706
707 return array;
708
709 },
710
711 fromBufferAttribute: function ( attribute, index, offset ) {
712
713 if ( offset !== undefined ) {
714
715 console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );
716
717 }
718
719 this.x = attribute.getX( index );
720 this.y = attribute.getY( index );
721 this.z = attribute.getZ( index );
722
723 return this;
724
725 }
726
727} );
728
729
730export { Vector3 };