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.
- package/dist/poly-extrude.js +1183 -42
- package/dist/poly-extrude.js.map +1 -1
- package/dist/poly-extrude.min.js +4 -2
- package/dist/poly-extrude.mjs +1183 -43
- package/index.js +2 -1
- package/package.json +1 -1
- package/readme.md +172 -170
- package/src/math/Quaternion.js +688 -0
- package/src/math/Vector3.js +21 -17
- package/src/polyline.js +43 -3
- package/src/tube.js +146 -0
@@ -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 };
|