poly-extrude 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,688 @@
1
+ // code copy from https://github.com/mrdoob/three.js/blob/dev/src/math/Quaternion.js
2
+
3
+ // import { clamp } from './MathUtils.js';
4
+
5
+ class Quaternion {
6
+
7
+ constructor(x = 0, y = 0, z = 0, w = 1) {
8
+
9
+ this.isQuaternion = true;
10
+
11
+ this._x = x;
12
+ this._y = y;
13
+ this._z = z;
14
+ this._w = w;
15
+
16
+ }
17
+
18
+ static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) {
19
+
20
+ // fuzz-free, array-based Quaternion SLERP operation
21
+
22
+ let x0 = src0[srcOffset0 + 0],
23
+ y0 = src0[srcOffset0 + 1],
24
+ z0 = src0[srcOffset0 + 2],
25
+ w0 = src0[srcOffset0 + 3];
26
+
27
+ const x1 = src1[srcOffset1 + 0],
28
+ y1 = src1[srcOffset1 + 1],
29
+ z1 = src1[srcOffset1 + 2],
30
+ w1 = src1[srcOffset1 + 3];
31
+
32
+ if (t === 0) {
33
+
34
+ dst[dstOffset + 0] = x0;
35
+ dst[dstOffset + 1] = y0;
36
+ dst[dstOffset + 2] = z0;
37
+ dst[dstOffset + 3] = w0;
38
+ return;
39
+
40
+ }
41
+
42
+ if (t === 1) {
43
+
44
+ dst[dstOffset + 0] = x1;
45
+ dst[dstOffset + 1] = y1;
46
+ dst[dstOffset + 2] = z1;
47
+ dst[dstOffset + 3] = w1;
48
+ return;
49
+
50
+ }
51
+
52
+ if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) {
53
+
54
+ let s = 1 - t;
55
+ const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,
56
+ dir = (cos >= 0 ? 1 : -1),
57
+ sqrSin = 1 - cos * cos;
58
+
59
+ // Skip the Slerp for tiny steps to avoid numeric problems:
60
+ if (sqrSin > Number.EPSILON) {
61
+
62
+ const sin = Math.sqrt(sqrSin),
63
+ len = Math.atan2(sin, cos * dir);
64
+
65
+ s = Math.sin(s * len) / sin;
66
+ t = Math.sin(t * len) / sin;
67
+
68
+ }
69
+
70
+ const tDir = t * dir;
71
+
72
+ x0 = x0 * s + x1 * tDir;
73
+ y0 = y0 * s + y1 * tDir;
74
+ z0 = z0 * s + z1 * tDir;
75
+ w0 = w0 * s + w1 * tDir;
76
+
77
+ // Normalize in case we just did a lerp:
78
+ if (s === 1 - t) {
79
+
80
+ const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0);
81
+
82
+ x0 *= f;
83
+ y0 *= f;
84
+ z0 *= f;
85
+ w0 *= f;
86
+
87
+ }
88
+
89
+ }
90
+
91
+ dst[dstOffset] = x0;
92
+ dst[dstOffset + 1] = y0;
93
+ dst[dstOffset + 2] = z0;
94
+ dst[dstOffset + 3] = w0;
95
+
96
+ }
97
+
98
+ static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) {
99
+
100
+ const x0 = src0[srcOffset0];
101
+ const y0 = src0[srcOffset0 + 1];
102
+ const z0 = src0[srcOffset0 + 2];
103
+ const w0 = src0[srcOffset0 + 3];
104
+
105
+ const x1 = src1[srcOffset1];
106
+ const y1 = src1[srcOffset1 + 1];
107
+ const z1 = src1[srcOffset1 + 2];
108
+ const w1 = src1[srcOffset1 + 3];
109
+
110
+ dst[dstOffset] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;
111
+ dst[dstOffset + 1] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;
112
+ dst[dstOffset + 2] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;
113
+ dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;
114
+
115
+ return dst;
116
+
117
+ }
118
+
119
+ get x() {
120
+
121
+ return this._x;
122
+
123
+ }
124
+
125
+ set x(value) {
126
+
127
+ this._x = value;
128
+ this._onChangeCallback();
129
+
130
+ }
131
+
132
+ get y() {
133
+
134
+ return this._y;
135
+
136
+ }
137
+
138
+ set y(value) {
139
+
140
+ this._y = value;
141
+ this._onChangeCallback();
142
+
143
+ }
144
+
145
+ get z() {
146
+
147
+ return this._z;
148
+
149
+ }
150
+
151
+ set z(value) {
152
+
153
+ this._z = value;
154
+ this._onChangeCallback();
155
+
156
+ }
157
+
158
+ get w() {
159
+
160
+ return this._w;
161
+
162
+ }
163
+
164
+ set w(value) {
165
+
166
+ this._w = value;
167
+ this._onChangeCallback();
168
+
169
+ }
170
+
171
+ set(x, y, z, w) {
172
+
173
+ this._x = x;
174
+ this._y = y;
175
+ this._z = z;
176
+ this._w = w;
177
+
178
+ this._onChangeCallback();
179
+
180
+ return this;
181
+
182
+ }
183
+
184
+ clone() {
185
+
186
+ return new this.constructor(this._x, this._y, this._z, this._w);
187
+
188
+ }
189
+
190
+ copy(quaternion) {
191
+
192
+ this._x = quaternion.x;
193
+ this._y = quaternion.y;
194
+ this._z = quaternion.z;
195
+ this._w = quaternion.w;
196
+
197
+ this._onChangeCallback();
198
+
199
+ return this;
200
+
201
+ }
202
+
203
+ setFromEuler(euler, update = true) {
204
+
205
+ const x = euler._x, y = euler._y, z = euler._z, order = euler._order;
206
+
207
+ // http://www.mathworks.com/matlabcentral/fileexchange/
208
+ // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
209
+ // content/SpinCalc.m
210
+
211
+ const cos = Math.cos;
212
+ const sin = Math.sin;
213
+
214
+ const c1 = cos(x / 2);
215
+ const c2 = cos(y / 2);
216
+ const c3 = cos(z / 2);
217
+
218
+ const s1 = sin(x / 2);
219
+ const s2 = sin(y / 2);
220
+ const s3 = sin(z / 2);
221
+
222
+ switch (order) {
223
+
224
+ case 'XYZ':
225
+ this._x = s1 * c2 * c3 + c1 * s2 * s3;
226
+ this._y = c1 * s2 * c3 - s1 * c2 * s3;
227
+ this._z = c1 * c2 * s3 + s1 * s2 * c3;
228
+ this._w = c1 * c2 * c3 - s1 * s2 * s3;
229
+ break;
230
+
231
+ case 'YXZ':
232
+ this._x = s1 * c2 * c3 + c1 * s2 * s3;
233
+ this._y = c1 * s2 * c3 - s1 * c2 * s3;
234
+ this._z = c1 * c2 * s3 - s1 * s2 * c3;
235
+ this._w = c1 * c2 * c3 + s1 * s2 * s3;
236
+ break;
237
+
238
+ case 'ZXY':
239
+ this._x = s1 * c2 * c3 - c1 * s2 * s3;
240
+ this._y = c1 * s2 * c3 + s1 * c2 * s3;
241
+ this._z = c1 * c2 * s3 + s1 * s2 * c3;
242
+ this._w = c1 * c2 * c3 - s1 * s2 * s3;
243
+ break;
244
+
245
+ case 'ZYX':
246
+ this._x = s1 * c2 * c3 - c1 * s2 * s3;
247
+ this._y = c1 * s2 * c3 + s1 * c2 * s3;
248
+ this._z = c1 * c2 * s3 - s1 * s2 * c3;
249
+ this._w = c1 * c2 * c3 + s1 * s2 * s3;
250
+ break;
251
+
252
+ case 'YZX':
253
+ this._x = s1 * c2 * c3 + c1 * s2 * s3;
254
+ this._y = c1 * s2 * c3 + s1 * c2 * s3;
255
+ this._z = c1 * c2 * s3 - s1 * s2 * c3;
256
+ this._w = c1 * c2 * c3 - s1 * s2 * s3;
257
+ break;
258
+
259
+ case 'XZY':
260
+ this._x = s1 * c2 * c3 - c1 * s2 * s3;
261
+ this._y = c1 * s2 * c3 - s1 * c2 * s3;
262
+ this._z = c1 * c2 * s3 + s1 * s2 * c3;
263
+ this._w = c1 * c2 * c3 + s1 * s2 * s3;
264
+ break;
265
+
266
+ default:
267
+ console.warn('THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order);
268
+
269
+ }
270
+
271
+ if (update === true) this._onChangeCallback();
272
+
273
+ return this;
274
+
275
+ }
276
+
277
+ setFromAxisAngle(axis, angle) {
278
+
279
+ // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
280
+
281
+ // assumes axis is normalized
282
+
283
+ const halfAngle = angle / 2, s = Math.sin(halfAngle);
284
+
285
+ this._x = axis.x * s;
286
+ this._y = axis.y * s;
287
+ this._z = axis.z * s;
288
+ this._w = Math.cos(halfAngle);
289
+
290
+ this._onChangeCallback();
291
+
292
+ return this;
293
+
294
+ }
295
+
296
+ setFromRotationMatrix(m) {
297
+
298
+ // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
299
+
300
+ // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
301
+
302
+ const te = m.elements,
303
+
304
+ m11 = te[0], m12 = te[4], m13 = te[8],
305
+ m21 = te[1], m22 = te[5], m23 = te[9],
306
+ m31 = te[2], m32 = te[6], m33 = te[10],
307
+
308
+ trace = m11 + m22 + m33;
309
+
310
+ if (trace > 0) {
311
+
312
+ const s = 0.5 / Math.sqrt(trace + 1.0);
313
+
314
+ this._w = 0.25 / s;
315
+ this._x = (m32 - m23) * s;
316
+ this._y = (m13 - m31) * s;
317
+ this._z = (m21 - m12) * s;
318
+
319
+ } else if (m11 > m22 && m11 > m33) {
320
+
321
+ const s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);
322
+
323
+ this._w = (m32 - m23) / s;
324
+ this._x = 0.25 * s;
325
+ this._y = (m12 + m21) / s;
326
+ this._z = (m13 + m31) / s;
327
+
328
+ } else if (m22 > m33) {
329
+
330
+ const s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);
331
+
332
+ this._w = (m13 - m31) / s;
333
+ this._x = (m12 + m21) / s;
334
+ this._y = 0.25 * s;
335
+ this._z = (m23 + m32) / s;
336
+
337
+ } else {
338
+
339
+ const s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);
340
+
341
+ this._w = (m21 - m12) / s;
342
+ this._x = (m13 + m31) / s;
343
+ this._y = (m23 + m32) / s;
344
+ this._z = 0.25 * s;
345
+
346
+ }
347
+
348
+ this._onChangeCallback();
349
+
350
+ return this;
351
+
352
+ }
353
+
354
+ setFromUnitVectors(vFrom, vTo) {
355
+
356
+ // assumes direction vectors vFrom and vTo are normalized
357
+
358
+ let r = vFrom.dot(vTo) + 1;
359
+
360
+ if (r < Number.EPSILON) {
361
+
362
+ // vFrom and vTo point in opposite directions
363
+
364
+ r = 0;
365
+
366
+ if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) {
367
+
368
+ this._x = -vFrom.y;
369
+ this._y = vFrom.x;
370
+ this._z = 0;
371
+ this._w = r;
372
+
373
+ } else {
374
+
375
+ this._x = 0;
376
+ this._y = -vFrom.z;
377
+ this._z = vFrom.y;
378
+ this._w = r;
379
+
380
+ }
381
+
382
+ } else {
383
+
384
+ // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3
385
+
386
+ this._x = vFrom.y * vTo.z - vFrom.z * vTo.y;
387
+ this._y = vFrom.z * vTo.x - vFrom.x * vTo.z;
388
+ this._z = vFrom.x * vTo.y - vFrom.y * vTo.x;
389
+ this._w = r;
390
+
391
+ }
392
+
393
+ return this.normalize();
394
+
395
+ }
396
+
397
+ // angleTo(q) {
398
+
399
+ // return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1)));
400
+
401
+ // }
402
+
403
+ rotateTowards(q, step) {
404
+
405
+ const angle = this.angleTo(q);
406
+
407
+ if (angle === 0) return this;
408
+
409
+ const t = Math.min(1, step / angle);
410
+
411
+ this.slerp(q, t);
412
+
413
+ return this;
414
+
415
+ }
416
+
417
+ identity() {
418
+
419
+ return this.set(0, 0, 0, 1);
420
+
421
+ }
422
+
423
+ invert() {
424
+
425
+ // quaternion is assumed to have unit length
426
+
427
+ return this.conjugate();
428
+
429
+ }
430
+
431
+ conjugate() {
432
+
433
+ this._x *= -1;
434
+ this._y *= -1;
435
+ this._z *= -1;
436
+
437
+ this._onChangeCallback();
438
+
439
+ return this;
440
+
441
+ }
442
+
443
+ dot(v) {
444
+
445
+ return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
446
+
447
+ }
448
+
449
+ lengthSq() {
450
+
451
+ return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
452
+
453
+ }
454
+
455
+ length() {
456
+
457
+ return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w);
458
+
459
+ }
460
+
461
+ normalize() {
462
+
463
+ let l = this.length();
464
+
465
+ if (l === 0) {
466
+
467
+ this._x = 0;
468
+ this._y = 0;
469
+ this._z = 0;
470
+ this._w = 1;
471
+
472
+ } else {
473
+
474
+ l = 1 / l;
475
+
476
+ this._x = this._x * l;
477
+ this._y = this._y * l;
478
+ this._z = this._z * l;
479
+ this._w = this._w * l;
480
+
481
+ }
482
+
483
+ this._onChangeCallback();
484
+
485
+ return this;
486
+
487
+ }
488
+
489
+ multiply(q) {
490
+
491
+ return this.multiplyQuaternions(this, q);
492
+
493
+ }
494
+
495
+ premultiply(q) {
496
+
497
+ return this.multiplyQuaternions(q, this);
498
+
499
+ }
500
+
501
+ multiplyQuaternions(a, b) {
502
+
503
+ // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
504
+
505
+ const qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;
506
+ const qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;
507
+
508
+ this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
509
+ this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
510
+ this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
511
+ this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
512
+
513
+ this._onChangeCallback();
514
+
515
+ return this;
516
+
517
+ }
518
+
519
+ slerp(qb, t) {
520
+
521
+ if (t === 0) return this;
522
+ if (t === 1) return this.copy(qb);
523
+
524
+ const x = this._x, y = this._y, z = this._z, w = this._w;
525
+
526
+ // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
527
+
528
+ let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
529
+
530
+ if (cosHalfTheta < 0) {
531
+
532
+ this._w = -qb._w;
533
+ this._x = -qb._x;
534
+ this._y = -qb._y;
535
+ this._z = -qb._z;
536
+
537
+ cosHalfTheta = -cosHalfTheta;
538
+
539
+ } else {
540
+
541
+ this.copy(qb);
542
+
543
+ }
544
+
545
+ if (cosHalfTheta >= 1.0) {
546
+
547
+ this._w = w;
548
+ this._x = x;
549
+ this._y = y;
550
+ this._z = z;
551
+
552
+ return this;
553
+
554
+ }
555
+
556
+ const sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;
557
+
558
+ if (sqrSinHalfTheta <= Number.EPSILON) {
559
+
560
+ const s = 1 - t;
561
+ this._w = s * w + t * this._w;
562
+ this._x = s * x + t * this._x;
563
+ this._y = s * y + t * this._y;
564
+ this._z = s * z + t * this._z;
565
+
566
+ this.normalize(); // normalize calls _onChangeCallback()
567
+
568
+ return this;
569
+
570
+ }
571
+
572
+ const sinHalfTheta = Math.sqrt(sqrSinHalfTheta);
573
+ const halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta);
574
+ const ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta,
575
+ ratioB = Math.sin(t * halfTheta) / sinHalfTheta;
576
+
577
+ this._w = (w * ratioA + this._w * ratioB);
578
+ this._x = (x * ratioA + this._x * ratioB);
579
+ this._y = (y * ratioA + this._y * ratioB);
580
+ this._z = (z * ratioA + this._z * ratioB);
581
+
582
+ this._onChangeCallback();
583
+
584
+ return this;
585
+
586
+ }
587
+
588
+ slerpQuaternions(qa, qb, t) {
589
+
590
+ return this.copy(qa).slerp(qb, t);
591
+
592
+ }
593
+
594
+ random() {
595
+
596
+ // sets this quaternion to a uniform random unit quaternnion
597
+
598
+ // Ken Shoemake
599
+ // Uniform random rotations
600
+ // D. Kirk, editor, Graphics Gems III, pages 124-132. Academic Press, New York, 1992.
601
+
602
+ const theta1 = 2 * Math.PI * Math.random();
603
+ const theta2 = 2 * Math.PI * Math.random();
604
+
605
+ const x0 = Math.random();
606
+ const r1 = Math.sqrt(1 - x0);
607
+ const r2 = Math.sqrt(x0);
608
+
609
+ return this.set(
610
+ r1 * Math.sin(theta1),
611
+ r1 * Math.cos(theta1),
612
+ r2 * Math.sin(theta2),
613
+ r2 * Math.cos(theta2)
614
+ );
615
+
616
+ }
617
+
618
+ equals(quaternion) {
619
+
620
+ return (quaternion._x === this._x) && (quaternion._y === this._y) && (quaternion._z === this._z) && (quaternion._w === this._w);
621
+
622
+ }
623
+
624
+ fromArray(array, offset = 0) {
625
+
626
+ this._x = array[offset];
627
+ this._y = array[offset + 1];
628
+ this._z = array[offset + 2];
629
+ this._w = array[offset + 3];
630
+
631
+ this._onChangeCallback();
632
+
633
+ return this;
634
+
635
+ }
636
+
637
+ toArray(array = [], offset = 0) {
638
+
639
+ array[offset] = this._x;
640
+ array[offset + 1] = this._y;
641
+ array[offset + 2] = this._z;
642
+ array[offset + 3] = this._w;
643
+
644
+ return array;
645
+
646
+ }
647
+
648
+ fromBufferAttribute(attribute, index) {
649
+
650
+ this._x = attribute.getX(index);
651
+ this._y = attribute.getY(index);
652
+ this._z = attribute.getZ(index);
653
+ this._w = attribute.getW(index);
654
+
655
+ this._onChangeCallback();
656
+
657
+ return this;
658
+
659
+ }
660
+
661
+ toJSON() {
662
+
663
+ return this.toArray();
664
+
665
+ }
666
+
667
+ _onChange(callback) {
668
+
669
+ this._onChangeCallback = callback;
670
+
671
+ return this;
672
+
673
+ }
674
+
675
+ _onChangeCallback() { }
676
+
677
+ * [Symbol.iterator]() {
678
+
679
+ yield this._x;
680
+ yield this._y;
681
+ yield this._z;
682
+ yield this._w;
683
+
684
+ }
685
+
686
+ }
687
+
688
+ export { Quaternion };