@threepipe/plugin-blend-importer 0.0.4 → 0.0.6
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/BlendLoadPlugin.d.ts +1 -1
- package/dist/BlendLoadPlugin.d.ts.map +1 -1
- package/dist/dependencies.txt +32 -1
- package/dist/index.js +2179 -82
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2179 -81
- package/dist/index.mjs.map +1 -1
- package/dist/loader/bakeGetters.d.ts +2 -0
- package/dist/loader/bakeGetters.d.ts.map +1 -0
- package/dist/loader/camera.d.ts +4 -0
- package/dist/loader/camera.d.ts.map +1 -0
- package/dist/loader/ctx.d.ts +16 -0
- package/dist/loader/ctx.d.ts.map +1 -0
- package/dist/loader/geometry.d.ts +3 -2
- package/dist/loader/geometry.d.ts.map +1 -1
- package/dist/loader/index.d.ts +2 -1
- package/dist/loader/index.d.ts.map +1 -1
- package/dist/loader/light.d.ts +3 -2
- package/dist/loader/light.d.ts.map +1 -1
- package/dist/loader/material.d.ts +2 -2
- package/dist/loader/material.d.ts.map +1 -1
- package/dist/loader/mesh.d.ts +2 -2
- package/dist/loader/mesh.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/BlendLoadPlugin.ts +42 -3
- package/src/js-blend/main.js +3 -2
- package/src/js-blend/parser/parser.js +152 -24
- package/src/js-blend/threejs/blend_three.js +1 -1
- package/src/js-blend/threejs/light.js +1 -1
- package/src/js-blend/threejs/material.js +1 -1
- package/src/loader/bakeGetters.ts +63 -0
- package/src/loader/camera.ts +55 -0
- package/src/loader/ctx.ts +29 -0
- package/src/loader/geometry.ts +236 -13
- package/src/loader/index.ts +95 -6
- package/src/loader/light.ts +18 -13
- package/src/loader/material.ts +7 -5
- package/src/loader/mesh.ts +14 -13
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* @threepipe/plugin-blend-importer v0.0.
|
|
3
|
+
* @threepipe/plugin-blend-importer v0.0.6
|
|
4
4
|
* Copyright 2022-2025 repalash <palash@shaders.app>
|
|
5
5
|
* Apache-2.0 License
|
|
6
6
|
* See ./dependencies.txt for any bundled third-party dependencies and licenses.
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
const ENDB = 1111772741;
|
|
8
|
+
import { BaseImporterPlugin, Importer, FileLoader, Object3D, Object3D2, PerspectiveCamera0, OrthographicCamera0, PointLight2, PhysicalMaterial, Mesh2, BufferGeometry2, BufferAttribute } from "threepipe";
|
|
9
|
+
import { Quaternion as Quaternion$1, Vector3 as Vector3$1 } from "threepipe";
|
|
11
10
|
let worker = null;
|
|
12
11
|
const return_object = {
|
|
13
12
|
loadBlendFromArrayBuffer: function(array_buffer) {
|
|
@@ -48,7 +47,7 @@ function worker_code() {
|
|
|
48
47
|
self.postMessage(FILE, ERROR);
|
|
49
48
|
}
|
|
50
49
|
}
|
|
51
|
-
|
|
50
|
+
const BLENDER_FILE = function(AB2) {
|
|
52
51
|
this.AB = AB2;
|
|
53
52
|
this.byte = new Uint8Array(AB2);
|
|
54
53
|
this.dv = new DataView(AB2);
|
|
@@ -87,7 +86,9 @@ function worker_code() {
|
|
|
87
86
|
else {
|
|
88
87
|
this.__blender_file__.dv.setFloat64(this.__data_address__ + offset2, float, this.__blender_file__.template.endianess);
|
|
89
88
|
}
|
|
90
|
-
}
|
|
89
|
+
},
|
|
90
|
+
enumerable: true,
|
|
91
|
+
configurable: true
|
|
91
92
|
};
|
|
92
93
|
}
|
|
93
94
|
function floatProp(offset2, Blender_Array_Length, length) {
|
|
@@ -100,7 +101,9 @@ function worker_code() {
|
|
|
100
101
|
else {
|
|
101
102
|
this.__blender_file__.dv.setFloat32(this.__data_address__ + offset2, float, this.__blender_file__.template.endianess);
|
|
102
103
|
}
|
|
103
|
-
}
|
|
104
|
+
},
|
|
105
|
+
enumerable: true,
|
|
106
|
+
configurable: true
|
|
104
107
|
};
|
|
105
108
|
}
|
|
106
109
|
function intProp(offset2, Blender_Array_Length, length) {
|
|
@@ -113,7 +116,9 @@ function worker_code() {
|
|
|
113
116
|
else {
|
|
114
117
|
this.__blender_file__.dv.setInt32(this.__data_address__ + offset2, float, this.__blender_file__.template.endianess);
|
|
115
118
|
}
|
|
116
|
-
}
|
|
119
|
+
},
|
|
120
|
+
enumerable: true,
|
|
121
|
+
configurable: true
|
|
117
122
|
};
|
|
118
123
|
}
|
|
119
124
|
function shortProp(offset2, Blender_Array_Length, length) {
|
|
@@ -126,9 +131,26 @@ function worker_code() {
|
|
|
126
131
|
else {
|
|
127
132
|
this.__blender_file__.dv.setInt16(this.__data_address__ + offset2, float, this.__blender_file__.template.endianess);
|
|
128
133
|
}
|
|
129
|
-
}
|
|
134
|
+
},
|
|
135
|
+
enumerable: true,
|
|
136
|
+
configurable: true
|
|
130
137
|
};
|
|
131
138
|
}
|
|
139
|
+
const uShortProp = (offset2, Blender_Array_Length, length) => {
|
|
140
|
+
return {
|
|
141
|
+
get: function() {
|
|
142
|
+
return Blender_Array_Length > 1 ? new Uint16Array(this.__blender_file__.AB, this.__data_address__ + offset2, length) : this.__blender_file__.dv.getUint16(this.__data_address__ + offset2, this.__blender_file__.template.endianess);
|
|
143
|
+
},
|
|
144
|
+
set: function(float) {
|
|
145
|
+
if (Blender_Array_Length > 1) ;
|
|
146
|
+
else {
|
|
147
|
+
this.__blender_file__.dv.setUint16(this.__data_address__ + offset2, float, this.__blender_file__.template.endianess);
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
enumerable: true,
|
|
151
|
+
configurable: true
|
|
152
|
+
};
|
|
153
|
+
};
|
|
132
154
|
function charProp(offset2, Blender_Array_Length, length) {
|
|
133
155
|
return {
|
|
134
156
|
get: function() {
|
|
@@ -157,7 +179,9 @@ function worker_code() {
|
|
|
157
179
|
} else {
|
|
158
180
|
this.__blender_file__.byte[this.__data_address__ + offset2] = byte | 0;
|
|
159
181
|
}
|
|
160
|
-
}
|
|
182
|
+
},
|
|
183
|
+
enumerable: true,
|
|
184
|
+
configurable: true
|
|
161
185
|
};
|
|
162
186
|
}
|
|
163
187
|
function pointerProp2(offset2) {
|
|
@@ -180,7 +204,9 @@ function worker_code() {
|
|
|
180
204
|
return results;
|
|
181
205
|
},
|
|
182
206
|
set: function() {
|
|
183
|
-
}
|
|
207
|
+
},
|
|
208
|
+
enumerable: true,
|
|
209
|
+
configurable: true
|
|
184
210
|
};
|
|
185
211
|
}
|
|
186
212
|
function pointerProp(offset2, Blender_Array_Length, length) {
|
|
@@ -203,7 +229,9 @@ function worker_code() {
|
|
|
203
229
|
}
|
|
204
230
|
},
|
|
205
231
|
set: function() {
|
|
206
|
-
}
|
|
232
|
+
},
|
|
233
|
+
enumerable: true,
|
|
234
|
+
configurable: true
|
|
207
235
|
};
|
|
208
236
|
}
|
|
209
237
|
function compileProp(obj, name, type, offset2, array_size, IS_POINTER, pointer_size2, length) {
|
|
@@ -219,9 +247,11 @@ function worker_code() {
|
|
|
219
247
|
Object.defineProperty(obj, name, intProp(offset2, array_size, length >> 2));
|
|
220
248
|
break;
|
|
221
249
|
case "short":
|
|
222
|
-
case "ushort":
|
|
223
250
|
Object.defineProperty(obj, name, shortProp(offset2, array_size, length >> 1));
|
|
224
251
|
break;
|
|
252
|
+
case "ushort":
|
|
253
|
+
Object.defineProperty(obj, name, uShortProp(offset2, array_size, length >> 1));
|
|
254
|
+
break;
|
|
225
255
|
case "char":
|
|
226
256
|
case "uchar":
|
|
227
257
|
Object.defineProperty(obj, name, charProp(offset2, array_size, length));
|
|
@@ -234,6 +264,7 @@ function worker_code() {
|
|
|
234
264
|
offset2 += length;
|
|
235
265
|
} else {
|
|
236
266
|
Object.defineProperty(obj, name, pointerProp(offset2, array_size, pointer_size2));
|
|
267
|
+
obj._length += pointer_size2 * array_size;
|
|
237
268
|
offset2 += pointer_size2 * array_size;
|
|
238
269
|
}
|
|
239
270
|
return offset2;
|
|
@@ -250,19 +281,20 @@ function worker_code() {
|
|
|
250
281
|
MASTER_SDNA_SCHEMA.prototype = {
|
|
251
282
|
getSDNAStructureConstructor: function(name, struct) {
|
|
252
283
|
if (struct) {
|
|
253
|
-
const
|
|
284
|
+
const jsName = name === "void" ? "void_" : name;
|
|
285
|
+
const blen_struct = Function("function " + jsName + "(){}; return " + jsName)();
|
|
254
286
|
blen_struct.prototype = new BLENDER_STRUCTURE();
|
|
255
287
|
blen_struct.prototype.blender_name = name;
|
|
256
288
|
blen_struct.prototype.__pointers = [];
|
|
257
289
|
blen_struct.prototype.__list__ = [];
|
|
290
|
+
const DNA = this.SDNA[name] = {
|
|
291
|
+
constructor: blen_struct
|
|
292
|
+
};
|
|
258
293
|
let offset2 = 0;
|
|
259
294
|
for (let i = 0; i < struct.length; i += 3) {
|
|
260
295
|
let _name = struct[i];
|
|
261
296
|
const n = _name, type = struct[i + 1];
|
|
262
297
|
let length = struct[i + 2], array_length = 0, match = null, Blender_Array_Length = 1, Suparray_match = 1, PointerToArray = false, Pointer_Match = 0;
|
|
263
|
-
const DNA = this.SDNA[name] = {
|
|
264
|
-
constructor: blen_struct
|
|
265
|
-
};
|
|
266
298
|
if (match = _name.match(/(\*?)(\*?)(\w+)(\[(\w*)\])?(\[(\w*)\])?/)) {
|
|
267
299
|
_name = match[3];
|
|
268
300
|
if (match[1]) {
|
|
@@ -307,7 +339,9 @@ function worker_code() {
|
|
|
307
339
|
}
|
|
308
340
|
return array;
|
|
309
341
|
};
|
|
310
|
-
}(array_names)
|
|
342
|
+
}(array_names),
|
|
343
|
+
enumerable: true,
|
|
344
|
+
configurable: true
|
|
311
345
|
});
|
|
312
346
|
} else {
|
|
313
347
|
offset2 = compileProp(blen_struct.prototype, _name, type, offset2, Blender_Array_Length, Pointer_Match, pointer_size, length);
|
|
@@ -322,7 +356,7 @@ function worker_code() {
|
|
|
322
356
|
}
|
|
323
357
|
}
|
|
324
358
|
};
|
|
325
|
-
|
|
359
|
+
const BLENDER_STRUCTURE = function() {
|
|
326
360
|
this.__blender_file__ = null;
|
|
327
361
|
this.__list__ = null;
|
|
328
362
|
this.__super_array_list__ = null;
|
|
@@ -390,7 +424,8 @@ function worker_code() {
|
|
|
390
424
|
FILE.memory_lookup = {};
|
|
391
425
|
struct_names = [];
|
|
392
426
|
offset = 0;
|
|
393
|
-
|
|
427
|
+
const magic = toString(_data, offset, 7);
|
|
428
|
+
if (magic !== "BLENDER") return ERROR = "File supplied is not a .blend compatible Blender file.";
|
|
394
429
|
offset += 7;
|
|
395
430
|
pointer_size = toString(_data, offset++, offset) == "_" ? 4 : 8;
|
|
396
431
|
BIG_ENDIAN = toString(_data, offset++, offset) !== "V";
|
|
@@ -427,9 +462,17 @@ function worker_code() {
|
|
|
427
462
|
offset2++;
|
|
428
463
|
curr_count++;
|
|
429
464
|
}
|
|
430
|
-
if (offset2
|
|
465
|
+
if (toString(_data, offset2, offset2 + 4) !== "TYPE") {
|
|
466
|
+
for (let j = 0; j < 8; j++) {
|
|
467
|
+
if (toString(_data, offset2, offset2 + 4) === "TYPE") break;
|
|
468
|
+
offset2++;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
if (toString(_data, offset2, offset2 + 4) !== "TYPE") {
|
|
472
|
+
debugger;
|
|
473
|
+
}
|
|
431
474
|
offset2 += 4;
|
|
432
|
-
count = data.
|
|
475
|
+
count = data.getUint32(offset2, true);
|
|
433
476
|
offset2 += 4;
|
|
434
477
|
curr_count = 0;
|
|
435
478
|
while (curr_count < count) {
|
|
@@ -442,7 +485,15 @@ function worker_code() {
|
|
|
442
485
|
offset2++;
|
|
443
486
|
curr_count++;
|
|
444
487
|
}
|
|
445
|
-
if (offset2
|
|
488
|
+
if (toString(_data, offset2, offset2 + 4) !== "TLEN") {
|
|
489
|
+
for (let j = 0; j < 8; j++) {
|
|
490
|
+
if (toString(_data, offset2, offset2 + 4) === "TLEN") break;
|
|
491
|
+
offset2++;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
if (toString(_data, offset2, offset2 + 4) !== "TLEN") {
|
|
495
|
+
debugger;
|
|
496
|
+
}
|
|
446
497
|
offset2 += 4;
|
|
447
498
|
curr_count = 0;
|
|
448
499
|
while (curr_count < count) {
|
|
@@ -450,7 +501,15 @@ function worker_code() {
|
|
|
450
501
|
offset2 += 2;
|
|
451
502
|
curr_count++;
|
|
452
503
|
}
|
|
453
|
-
if (offset2
|
|
504
|
+
if (toString(_data, offset2, offset2 + 4) !== "STRC") {
|
|
505
|
+
for (let j = 0; j < 8; j++) {
|
|
506
|
+
if (toString(_data, offset2, offset2 + 4) === "STRC") break;
|
|
507
|
+
offset2++;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
if (toString(_data, offset2, offset2 + 4) !== "STRC") {
|
|
511
|
+
debugger;
|
|
512
|
+
}
|
|
454
513
|
offset2 += 4;
|
|
455
514
|
const structure_count = data.getInt32(offset2, BIG_ENDIAN);
|
|
456
515
|
offset2 += 4;
|
|
@@ -479,22 +538,56 @@ function worker_code() {
|
|
|
479
538
|
}
|
|
480
539
|
}
|
|
481
540
|
while (true) {
|
|
482
|
-
|
|
483
|
-
|
|
541
|
+
for (let j = 0; j < 8; j++) {
|
|
542
|
+
if (data.getInt8(offset) === 0) {
|
|
543
|
+
offset++;
|
|
544
|
+
continue;
|
|
545
|
+
}
|
|
546
|
+
break;
|
|
547
|
+
}
|
|
548
|
+
if (data.getInt8(offset) === 0) {
|
|
549
|
+
debugger;
|
|
484
550
|
}
|
|
485
551
|
data_offset = offset;
|
|
552
|
+
if (offset + pointer_size + 12 >= data.byteLength) {
|
|
553
|
+
ERROR = "Unexpected end of file while parsing";
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
486
556
|
sdna_index = data.getInt32(offset + pointer_size + 8, BIG_ENDIAN);
|
|
487
|
-
|
|
557
|
+
const code_str = toString(_data, offset, offset + 4);
|
|
488
558
|
offset2 = offset + 16 + pointer_size;
|
|
489
|
-
|
|
490
|
-
if (
|
|
491
|
-
|
|
492
|
-
|
|
559
|
+
const blockLength = data.getInt32(offset + 4, true);
|
|
560
|
+
if (blockLength < 0 || offset + blockLength + 16 + pointer_size > data.byteLength) {
|
|
561
|
+
ERROR = "Invalid block length detected";
|
|
562
|
+
break;
|
|
563
|
+
}
|
|
564
|
+
offset += blockLength + 16 + pointer_size;
|
|
565
|
+
if (code_str === "DNA1") ;
|
|
566
|
+
else if (code_str === "ENDB") break;
|
|
567
|
+
else if (code_str === "TEST") {
|
|
568
|
+
const data_start = data_offset + pointer_size + 16;
|
|
569
|
+
const width = data.getInt32(data_start, BIG_ENDIAN);
|
|
570
|
+
const height = data.getInt32(data_start + 4, BIG_ENDIAN);
|
|
571
|
+
if (width * height > 0) {
|
|
572
|
+
const data_len = width * height * 4;
|
|
573
|
+
if (blockLength < data_len + 8) {
|
|
574
|
+
ERROR = "Invalid TEST block length detected";
|
|
575
|
+
break;
|
|
576
|
+
}
|
|
577
|
+
const image_data = new Uint32Array(_data, data_start + 8, data_len >> 2);
|
|
578
|
+
const image = {
|
|
579
|
+
width,
|
|
580
|
+
height,
|
|
581
|
+
data: image_data
|
|
582
|
+
};
|
|
583
|
+
FILE.thumbnail = image;
|
|
584
|
+
}
|
|
585
|
+
} else {
|
|
493
586
|
const data_start = data_offset + pointer_size + 16;
|
|
494
587
|
const constructor = current_SDNA_template.getSDNAStructureConstructor(current_SDNA_template.SDNA_NAMES[sdna_index]);
|
|
495
588
|
const size = data.getInt32(data_offset + 4, BIG_ENDIAN);
|
|
496
589
|
count = data.getInt32(data_offset + 12 + pointer_size, BIG_ENDIAN);
|
|
497
|
-
if (count > 0) {
|
|
590
|
+
if (count > 0 && constructor) {
|
|
498
591
|
let obj = new constructor();
|
|
499
592
|
const length = constructor.prototype._length;
|
|
500
593
|
const address = FILE.getPointer(data_offset + 8);
|
|
@@ -518,8 +611,8 @@ function worker_code() {
|
|
|
518
611
|
}
|
|
519
612
|
}
|
|
520
613
|
worker = new worker_code();
|
|
521
|
-
worker.postMessage = function(message) {
|
|
522
|
-
return_object.onParseReady(message);
|
|
614
|
+
worker.postMessage = function(message, err) {
|
|
615
|
+
return_object.onParseReady(message, err);
|
|
523
616
|
};
|
|
524
617
|
/**
|
|
525
618
|
* JS.Blend
|
|
@@ -533,49 +626,200 @@ worker.postMessage = function(message) {
|
|
|
533
626
|
async function parseBlend(buffer, name = "") {
|
|
534
627
|
return new Promise((res, rej) => {
|
|
535
628
|
return_object.onParseReady = (file, error) => {
|
|
536
|
-
if (error)
|
|
537
|
-
|
|
629
|
+
if (error) console.error(error);
|
|
630
|
+
res(file);
|
|
538
631
|
};
|
|
539
632
|
return_object.loadBlendFromArrayBuffer(buffer, name);
|
|
540
633
|
});
|
|
541
634
|
}
|
|
635
|
+
function createCamera(object, ctx) {
|
|
636
|
+
const cdata = object.data;
|
|
637
|
+
if (!cdata) return void 0;
|
|
638
|
+
const type = cdata.type;
|
|
639
|
+
let camera;
|
|
640
|
+
if (type === 0) {
|
|
641
|
+
const sensorWidth = cdata.sensor_x || 36;
|
|
642
|
+
const sensorHeight = cdata.sensor_y || 24;
|
|
643
|
+
const lens = cdata.lens || 50;
|
|
644
|
+
const fov = 2 * Math.atan(sensorHeight / (2 * lens)) * (180 / Math.PI);
|
|
645
|
+
camera = new ctx.PerspectiveCamera(
|
|
646
|
+
fov,
|
|
647
|
+
sensorWidth / sensorHeight,
|
|
648
|
+
cdata.clipsta || 0.1,
|
|
649
|
+
cdata.clipend || 1e3
|
|
650
|
+
);
|
|
651
|
+
if ("shiftx" in cdata) camera.userData.shiftX = cdata.shiftx;
|
|
652
|
+
if ("shiftx" in cdata) camera.userData.shiftX = cdata.shiftx;
|
|
653
|
+
if ("shifty" in cdata) camera.userData.shiftY = cdata.shifty;
|
|
654
|
+
} else if (type === 1) {
|
|
655
|
+
const scale = cdata.ortho_scale || 1;
|
|
656
|
+
const aspect = (cdata.sensor_x || 36) / (cdata.sensor_y || 24);
|
|
657
|
+
const left = -scale * aspect / 2;
|
|
658
|
+
const right = scale * aspect / 2;
|
|
659
|
+
const top = scale / 2;
|
|
660
|
+
const bottom = -scale / 2;
|
|
661
|
+
camera = new ctx.OrthographicCamera(
|
|
662
|
+
left,
|
|
663
|
+
right,
|
|
664
|
+
top,
|
|
665
|
+
bottom,
|
|
666
|
+
cdata.clipsta || 0.1,
|
|
667
|
+
cdata.clipend || 1e3
|
|
668
|
+
);
|
|
669
|
+
if ("shiftx" in cdata) camera.userData.shiftX = cdata.shiftx;
|
|
670
|
+
if ("shifty" in cdata) camera.userData.shiftY = cdata.shifty;
|
|
671
|
+
} else {
|
|
672
|
+
camera = new ctx.PerspectiveCamera();
|
|
673
|
+
console.warn("Unsupported camera type", type);
|
|
674
|
+
}
|
|
675
|
+
return camera;
|
|
676
|
+
}
|
|
542
677
|
const blenderLightTypes = {
|
|
543
678
|
point: 0,
|
|
544
|
-
sun: 1
|
|
545
|
-
spot: 0,
|
|
546
|
-
hemi: 0,
|
|
547
|
-
area: 0
|
|
679
|
+
sun: 1
|
|
548
680
|
};
|
|
549
|
-
function createLight(lamp) {
|
|
681
|
+
function createLight(lamp, ctx) {
|
|
550
682
|
const ldata = lamp.data;
|
|
551
683
|
const position = [lamp.loc[0], lamp.loc[2], -lamp.loc[1]];
|
|
552
684
|
const color = ldata.r * 255 << 16 | ldata.g * 255 << 8 | ldata.b * 255 << 0;
|
|
553
685
|
const intensity = ldata.energy;
|
|
554
686
|
const distance = 0;
|
|
555
|
-
let light =
|
|
687
|
+
let light = void 0;
|
|
556
688
|
switch (ldata.type) {
|
|
557
689
|
case blenderLightTypes.point:
|
|
558
|
-
light = new PointLight(color, intensity, distance);
|
|
690
|
+
light = new ctx.PointLight(color, intensity, distance);
|
|
559
691
|
light.position.fromArray(position, 0);
|
|
560
692
|
light.castShadow = true;
|
|
561
693
|
break;
|
|
562
694
|
case blenderLightTypes.sun:
|
|
563
|
-
light = new PointLight(color, intensity, distance);
|
|
695
|
+
light = new ctx.PointLight(color, intensity, distance);
|
|
564
696
|
light.position.fromArray(position, 0);
|
|
565
697
|
light.castShadow = true;
|
|
566
|
-
light.shadow
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
698
|
+
if (light.shadow) {
|
|
699
|
+
light.shadow.mapSize.width = 1024;
|
|
700
|
+
light.shadow.mapSize.height = 1024;
|
|
701
|
+
light.shadow.camera.near = 0.01;
|
|
702
|
+
light.shadow.camera.far = 500;
|
|
703
|
+
}
|
|
570
704
|
break;
|
|
571
705
|
default:
|
|
572
706
|
console.warn("Unsupported light type", ldata.type);
|
|
573
707
|
}
|
|
574
708
|
return light;
|
|
575
709
|
}
|
|
576
|
-
function
|
|
710
|
+
function getLayer(layers, i) {
|
|
711
|
+
if (!Array.isArray(layers)) return layers;
|
|
712
|
+
return layers[i];
|
|
713
|
+
}
|
|
714
|
+
function createBufferGeometry(meshData, ctx) {
|
|
715
|
+
var _a;
|
|
716
|
+
if (meshData.mpoly) return createBufferGeometryOld(meshData, ctx);
|
|
717
|
+
const geometry = new ctx.BufferGeometry();
|
|
718
|
+
geometry.name = meshData.aname || "";
|
|
719
|
+
let vertices;
|
|
720
|
+
let indices;
|
|
721
|
+
if (meshData.vdata && meshData.vdata.layers && meshData.vdata.totlayer > 0) {
|
|
722
|
+
for (let i = 0; i < meshData.vdata.totlayer; i++) {
|
|
723
|
+
const layer = getLayer(meshData.vdata.layers, i);
|
|
724
|
+
const data = layer.data || [];
|
|
725
|
+
if (data.length === meshData.totvert) {
|
|
726
|
+
if (vertices && (layer.name !== "position" || vertices.name === "position")) {
|
|
727
|
+
continue;
|
|
728
|
+
}
|
|
729
|
+
vertices = layer;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
if (meshData.ldata && meshData.ldata.layers) {
|
|
734
|
+
for (let i = 0; i < meshData.ldata.totlayer; i++) {
|
|
735
|
+
const layer = getLayer(meshData.ldata.layers, i);
|
|
736
|
+
const data = layer.data || [];
|
|
737
|
+
if (data.length === meshData.totloop) {
|
|
738
|
+
if (indices && (layer.name !== ".corner_vert" || indices.name === ".corner_vert")) {
|
|
739
|
+
continue;
|
|
740
|
+
}
|
|
741
|
+
indices = layer;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
let faceIndices = [];
|
|
746
|
+
if (meshData.poly_offset_indices && meshData.totpoly > 0) {
|
|
747
|
+
faceIndices = [...new Int32Array(meshData.poly_offset_indices.__blender_file__.AB, meshData.poly_offset_indices.__data_address__, meshData.totpoly + 1)];
|
|
748
|
+
}
|
|
749
|
+
if ((vertices == null ? void 0 : vertices.data) && vertices.data.length > 0) {
|
|
750
|
+
const positions = new Float32Array(vertices.data.length * 3);
|
|
751
|
+
for (let j = 0; j < vertices.data.length; j++) {
|
|
752
|
+
const vertex = vertices.data[j];
|
|
753
|
+
if (vertex.x !== void 0) {
|
|
754
|
+
positions[j * 3] = vertex.x;
|
|
755
|
+
positions[j * 3 + 1] = vertex.z;
|
|
756
|
+
positions[j * 3 + 2] = -vertex.y;
|
|
757
|
+
} else if (vertex.co !== void 0) {
|
|
758
|
+
positions[j * 3] = vertex.co[0];
|
|
759
|
+
positions[j * 3 + 1] = vertex.co[2];
|
|
760
|
+
positions[j * 3 + 2] = -vertex.co[1];
|
|
761
|
+
} else {
|
|
762
|
+
console.error("BlendLoader - unknown vertex", vertex);
|
|
763
|
+
break;
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
geometry.setAttribute("position", new ctx.BufferAttribute(positions, 3));
|
|
767
|
+
}
|
|
768
|
+
if ((indices == null ? void 0 : indices.data) && indices.data.length > 0 && ((_a = vertices == null ? void 0 : vertices.data) == null ? void 0 : _a.length)) {
|
|
769
|
+
const faceSize = meshData.totloop / meshData.totpoly;
|
|
770
|
+
if (faceIndices.length > 0) {
|
|
771
|
+
let totalTriangles = 0;
|
|
772
|
+
for (let i = 0; i < faceIndices.length - 1; i++) {
|
|
773
|
+
const faceVertCount = faceIndices[i + 1] - faceIndices[i];
|
|
774
|
+
totalTriangles += Math.max(0, faceVertCount - 2);
|
|
775
|
+
}
|
|
776
|
+
const indexes = new Uint32Array(totalTriangles * 3);
|
|
777
|
+
let t = 0;
|
|
778
|
+
for (let i = 0; i < faceIndices.length - 1; i++) {
|
|
779
|
+
const faceStart = faceIndices[i];
|
|
780
|
+
const faceEnd = faceIndices[i + 1];
|
|
781
|
+
const faceVertCount = faceEnd - faceStart;
|
|
782
|
+
if (faceVertCount >= 3) {
|
|
783
|
+
const firstVert = indices.data[faceStart].i;
|
|
784
|
+
for (let k = 1; k < faceVertCount - 1; k++) {
|
|
785
|
+
indexes[t++] = firstVert;
|
|
786
|
+
indexes[t++] = indices.data[faceStart + k].i;
|
|
787
|
+
indexes[t++] = indices.data[faceStart + k + 1].i;
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
geometry.setIndex(new ctx.BufferAttribute(indexes, 1));
|
|
792
|
+
} else if (faceSize === 3 || faceSize === 4) {
|
|
793
|
+
const isQuad = faceSize === 4;
|
|
794
|
+
const faceCount = indices.length / faceSize;
|
|
795
|
+
const indexes = new Uint32Array(faceCount * 3 * (isQuad ? 2 : 1));
|
|
796
|
+
if (faceSize !== 3 && faceSize !== 4) return geometry;
|
|
797
|
+
for (let j = 0, t = 0; j < indices.length; j += faceSize) {
|
|
798
|
+
const a = indices[j].i;
|
|
799
|
+
const b = indices[j + 1].i;
|
|
800
|
+
const c = indices[j + 2].i;
|
|
801
|
+
indexes[t++] = a;
|
|
802
|
+
indexes[t++] = b;
|
|
803
|
+
indexes[t++] = c;
|
|
804
|
+
if (isQuad) {
|
|
805
|
+
const d = indices[j + 3].i;
|
|
806
|
+
indexes[t++] = a;
|
|
807
|
+
indexes[t++] = c;
|
|
808
|
+
indexes[t++] = d;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
geometry.setIndex(new ctx.BufferAttribute(indexes, 1));
|
|
812
|
+
}
|
|
813
|
+
} else if (faceIndices) {
|
|
814
|
+
console.error("BlendLoader - no indices data found, but face indices are present", faceIndices);
|
|
815
|
+
}
|
|
816
|
+
if (geometry.attributes.position && !geometry.attributes.normal)
|
|
817
|
+
geometry.computeVertexNormals();
|
|
818
|
+
return geometry;
|
|
819
|
+
}
|
|
820
|
+
function createBufferGeometryOld(mesh, ctx) {
|
|
577
821
|
const faces = Array.isArray(mesh.mpoly) ? mesh.mpoly : [mesh.mpoly], loops = mesh.mloop, uv = mesh.mloopuv, vertices = mesh.mvert;
|
|
578
|
-
const geometry = new BufferGeometry();
|
|
822
|
+
const geometry = new ctx.BufferGeometry();
|
|
579
823
|
if (!faces) return geometry;
|
|
580
824
|
const size = faces.reduce((acc, face) => acc + Math.floor(face.totloop * 3 / 2), 0);
|
|
581
825
|
const indices = new Uint32Array(size);
|
|
@@ -583,6 +827,7 @@ function createBufferGeometry(mesh, origin) {
|
|
|
583
827
|
const normals = new Float32Array(size * 3);
|
|
584
828
|
const positions = new Float32Array(size * 3);
|
|
585
829
|
let currentIndex = 0;
|
|
830
|
+
let computeNormals = false;
|
|
586
831
|
for (const face of faces) {
|
|
587
832
|
const len = face.totloop;
|
|
588
833
|
const start = face.loopstart;
|
|
@@ -596,12 +841,16 @@ function createBufferGeometry(mesh, origin) {
|
|
|
596
841
|
const loop = loops[index];
|
|
597
842
|
const vert = vertices[loop.v];
|
|
598
843
|
indices[currentIndex] = currentIndex;
|
|
599
|
-
positions[currentIndex * 3 + 0] = vert.co[0]
|
|
600
|
-
positions[currentIndex * 3 + 1] = vert.co[2]
|
|
601
|
-
positions[currentIndex * 3 + 2] = -vert.co[1]
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
844
|
+
positions[currentIndex * 3 + 0] = vert.co[0];
|
|
845
|
+
positions[currentIndex * 3 + 1] = vert.co[2];
|
|
846
|
+
positions[currentIndex * 3 + 2] = -vert.co[1];
|
|
847
|
+
if (vert.no) {
|
|
848
|
+
normals[currentIndex * 3 + 0] = vert.no[0];
|
|
849
|
+
normals[currentIndex * 3 + 1] = vert.no[2];
|
|
850
|
+
normals[currentIndex * 3 + 2] = -vert.no[1];
|
|
851
|
+
} else {
|
|
852
|
+
computeNormals = true;
|
|
853
|
+
}
|
|
605
854
|
if (uv) {
|
|
606
855
|
uvs[currentIndex * 2 + 0] = uv[index].uv[0];
|
|
607
856
|
uvs[currentIndex * 2 + 1] = uv[index].uv[1];
|
|
@@ -611,57 +860,1891 @@ function createBufferGeometry(mesh, origin) {
|
|
|
611
860
|
indexi += 2;
|
|
612
861
|
}
|
|
613
862
|
}
|
|
614
|
-
geometry.setAttribute("position", new BufferAttribute(positions, 3));
|
|
615
|
-
geometry.setIndex(new BufferAttribute(indices, 1));
|
|
616
|
-
geometry.setAttribute("normal", new BufferAttribute(normals, 3));
|
|
617
|
-
geometry.setAttribute("uv", new BufferAttribute(uvs, 2));
|
|
863
|
+
geometry.setAttribute("position", new ctx.BufferAttribute(positions, 3));
|
|
864
|
+
geometry.setIndex(new ctx.BufferAttribute(indices, 1));
|
|
865
|
+
geometry.setAttribute("normal", new ctx.BufferAttribute(normals, 3));
|
|
866
|
+
geometry.setAttribute("uv", new ctx.BufferAttribute(uvs, 2));
|
|
867
|
+
if (computeNormals) {
|
|
868
|
+
geometry.computeVertexNormals();
|
|
869
|
+
}
|
|
618
870
|
return geometry;
|
|
619
871
|
}
|
|
620
|
-
function createMaterial(mat) {
|
|
621
|
-
const material = new MeshPhysicalMaterial();
|
|
872
|
+
function createMaterial(mat, ctx) {
|
|
873
|
+
const material = new ctx.MeshPhysicalMaterial();
|
|
622
874
|
material.color.setRGB(mat.r, mat.g, mat.b);
|
|
623
875
|
material.roughness = mat.roughness !== void 0 ? mat.roughness : 0.4;
|
|
624
876
|
material.metalness = mat.metallic !== void 0 ? mat.metallic : 0;
|
|
625
|
-
material.opacity =
|
|
877
|
+
material.opacity = 1;
|
|
626
878
|
material.transparent = material.opacity < 1;
|
|
627
879
|
return material;
|
|
628
880
|
}
|
|
629
|
-
function createMesh(object) {
|
|
630
|
-
if (!object.data)
|
|
631
|
-
|
|
881
|
+
function createMesh(object, loaded, ctx) {
|
|
882
|
+
if (!object.data) {
|
|
883
|
+
return void 0;
|
|
884
|
+
}
|
|
885
|
+
const geometry = loaded.get(object.data) ?? createBufferGeometry(object.data, ctx);
|
|
886
|
+
loaded.set(object.data, geometry);
|
|
632
887
|
const mat = object.data.mat[0];
|
|
633
|
-
const material = mat ? createMaterial(mat) :
|
|
634
|
-
|
|
888
|
+
const material = mat ? loaded.get(mat) ?? createMaterial(mat, ctx) : new ctx.MeshPhysicalMaterial();
|
|
889
|
+
if (mat) loaded.set(mat, material);
|
|
890
|
+
const mesh = new ctx.Mesh(geometry, material);
|
|
635
891
|
mesh.castShadow = true;
|
|
636
892
|
mesh.receiveShadow = true;
|
|
637
|
-
mesh.rotateZ(object.rot[2]);
|
|
638
|
-
mesh.rotateY(object.rot[1]);
|
|
639
|
-
mesh.rotateX(object.rot[0]);
|
|
640
|
-
mesh.scale.fromArray(object.size, 0);
|
|
641
|
-
mesh.position.fromArray([object.loc[0], object.loc[2], -object.loc[1]], 0);
|
|
642
893
|
return mesh;
|
|
643
894
|
}
|
|
895
|
+
function clamp(value, min, max) {
|
|
896
|
+
return Math.max(min, Math.min(max, value));
|
|
897
|
+
}
|
|
898
|
+
class Quaternion {
|
|
899
|
+
constructor(x = 0, y = 0, z = 0, w = 1) {
|
|
900
|
+
this.isQuaternion = true;
|
|
901
|
+
this._x = x;
|
|
902
|
+
this._y = y;
|
|
903
|
+
this._z = z;
|
|
904
|
+
this._w = w;
|
|
905
|
+
}
|
|
906
|
+
static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) {
|
|
907
|
+
let x0 = src0[srcOffset0 + 0], y0 = src0[srcOffset0 + 1], z0 = src0[srcOffset0 + 2], w0 = src0[srcOffset0 + 3];
|
|
908
|
+
const x1 = src1[srcOffset1 + 0], y1 = src1[srcOffset1 + 1], z1 = src1[srcOffset1 + 2], w1 = src1[srcOffset1 + 3];
|
|
909
|
+
if (t === 0) {
|
|
910
|
+
dst[dstOffset + 0] = x0;
|
|
911
|
+
dst[dstOffset + 1] = y0;
|
|
912
|
+
dst[dstOffset + 2] = z0;
|
|
913
|
+
dst[dstOffset + 3] = w0;
|
|
914
|
+
return;
|
|
915
|
+
}
|
|
916
|
+
if (t === 1) {
|
|
917
|
+
dst[dstOffset + 0] = x1;
|
|
918
|
+
dst[dstOffset + 1] = y1;
|
|
919
|
+
dst[dstOffset + 2] = z1;
|
|
920
|
+
dst[dstOffset + 3] = w1;
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) {
|
|
924
|
+
let s = 1 - t;
|
|
925
|
+
const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, dir = cos >= 0 ? 1 : -1, sqrSin = 1 - cos * cos;
|
|
926
|
+
if (sqrSin > Number.EPSILON) {
|
|
927
|
+
const sin = Math.sqrt(sqrSin), len = Math.atan2(sin, cos * dir);
|
|
928
|
+
s = Math.sin(s * len) / sin;
|
|
929
|
+
t = Math.sin(t * len) / sin;
|
|
930
|
+
}
|
|
931
|
+
const tDir = t * dir;
|
|
932
|
+
x0 = x0 * s + x1 * tDir;
|
|
933
|
+
y0 = y0 * s + y1 * tDir;
|
|
934
|
+
z0 = z0 * s + z1 * tDir;
|
|
935
|
+
w0 = w0 * s + w1 * tDir;
|
|
936
|
+
if (s === 1 - t) {
|
|
937
|
+
const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0);
|
|
938
|
+
x0 *= f;
|
|
939
|
+
y0 *= f;
|
|
940
|
+
z0 *= f;
|
|
941
|
+
w0 *= f;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
dst[dstOffset] = x0;
|
|
945
|
+
dst[dstOffset + 1] = y0;
|
|
946
|
+
dst[dstOffset + 2] = z0;
|
|
947
|
+
dst[dstOffset + 3] = w0;
|
|
948
|
+
}
|
|
949
|
+
static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) {
|
|
950
|
+
const x0 = src0[srcOffset0];
|
|
951
|
+
const y0 = src0[srcOffset0 + 1];
|
|
952
|
+
const z0 = src0[srcOffset0 + 2];
|
|
953
|
+
const w0 = src0[srcOffset0 + 3];
|
|
954
|
+
const x1 = src1[srcOffset1];
|
|
955
|
+
const y1 = src1[srcOffset1 + 1];
|
|
956
|
+
const z1 = src1[srcOffset1 + 2];
|
|
957
|
+
const w1 = src1[srcOffset1 + 3];
|
|
958
|
+
dst[dstOffset] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;
|
|
959
|
+
dst[dstOffset + 1] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;
|
|
960
|
+
dst[dstOffset + 2] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;
|
|
961
|
+
dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;
|
|
962
|
+
return dst;
|
|
963
|
+
}
|
|
964
|
+
get x() {
|
|
965
|
+
return this._x;
|
|
966
|
+
}
|
|
967
|
+
set x(value) {
|
|
968
|
+
this._x = value;
|
|
969
|
+
this._onChangeCallback();
|
|
970
|
+
}
|
|
971
|
+
get y() {
|
|
972
|
+
return this._y;
|
|
973
|
+
}
|
|
974
|
+
set y(value) {
|
|
975
|
+
this._y = value;
|
|
976
|
+
this._onChangeCallback();
|
|
977
|
+
}
|
|
978
|
+
get z() {
|
|
979
|
+
return this._z;
|
|
980
|
+
}
|
|
981
|
+
set z(value) {
|
|
982
|
+
this._z = value;
|
|
983
|
+
this._onChangeCallback();
|
|
984
|
+
}
|
|
985
|
+
get w() {
|
|
986
|
+
return this._w;
|
|
987
|
+
}
|
|
988
|
+
set w(value) {
|
|
989
|
+
this._w = value;
|
|
990
|
+
this._onChangeCallback();
|
|
991
|
+
}
|
|
992
|
+
set(x, y, z, w) {
|
|
993
|
+
this._x = x;
|
|
994
|
+
this._y = y;
|
|
995
|
+
this._z = z;
|
|
996
|
+
this._w = w;
|
|
997
|
+
this._onChangeCallback();
|
|
998
|
+
return this;
|
|
999
|
+
}
|
|
1000
|
+
clone() {
|
|
1001
|
+
return new this.constructor(this._x, this._y, this._z, this._w);
|
|
1002
|
+
}
|
|
1003
|
+
copy(quaternion) {
|
|
1004
|
+
this._x = quaternion.x;
|
|
1005
|
+
this._y = quaternion.y;
|
|
1006
|
+
this._z = quaternion.z;
|
|
1007
|
+
this._w = quaternion.w;
|
|
1008
|
+
this._onChangeCallback();
|
|
1009
|
+
return this;
|
|
1010
|
+
}
|
|
1011
|
+
setFromEuler(euler, update = true) {
|
|
1012
|
+
const x = euler._x, y = euler._y, z = euler._z, order = euler._order;
|
|
1013
|
+
const cos = Math.cos;
|
|
1014
|
+
const sin = Math.sin;
|
|
1015
|
+
const c1 = cos(x / 2);
|
|
1016
|
+
const c2 = cos(y / 2);
|
|
1017
|
+
const c3 = cos(z / 2);
|
|
1018
|
+
const s1 = sin(x / 2);
|
|
1019
|
+
const s2 = sin(y / 2);
|
|
1020
|
+
const s3 = sin(z / 2);
|
|
1021
|
+
switch (order) {
|
|
1022
|
+
case "XYZ":
|
|
1023
|
+
this._x = s1 * c2 * c3 + c1 * s2 * s3;
|
|
1024
|
+
this._y = c1 * s2 * c3 - s1 * c2 * s3;
|
|
1025
|
+
this._z = c1 * c2 * s3 + s1 * s2 * c3;
|
|
1026
|
+
this._w = c1 * c2 * c3 - s1 * s2 * s3;
|
|
1027
|
+
break;
|
|
1028
|
+
case "YXZ":
|
|
1029
|
+
this._x = s1 * c2 * c3 + c1 * s2 * s3;
|
|
1030
|
+
this._y = c1 * s2 * c3 - s1 * c2 * s3;
|
|
1031
|
+
this._z = c1 * c2 * s3 - s1 * s2 * c3;
|
|
1032
|
+
this._w = c1 * c2 * c3 + s1 * s2 * s3;
|
|
1033
|
+
break;
|
|
1034
|
+
case "ZXY":
|
|
1035
|
+
this._x = s1 * c2 * c3 - c1 * s2 * s3;
|
|
1036
|
+
this._y = c1 * s2 * c3 + s1 * c2 * s3;
|
|
1037
|
+
this._z = c1 * c2 * s3 + s1 * s2 * c3;
|
|
1038
|
+
this._w = c1 * c2 * c3 - s1 * s2 * s3;
|
|
1039
|
+
break;
|
|
1040
|
+
case "ZYX":
|
|
1041
|
+
this._x = s1 * c2 * c3 - c1 * s2 * s3;
|
|
1042
|
+
this._y = c1 * s2 * c3 + s1 * c2 * s3;
|
|
1043
|
+
this._z = c1 * c2 * s3 - s1 * s2 * c3;
|
|
1044
|
+
this._w = c1 * c2 * c3 + s1 * s2 * s3;
|
|
1045
|
+
break;
|
|
1046
|
+
case "YZX":
|
|
1047
|
+
this._x = s1 * c2 * c3 + c1 * s2 * s3;
|
|
1048
|
+
this._y = c1 * s2 * c3 + s1 * c2 * s3;
|
|
1049
|
+
this._z = c1 * c2 * s3 - s1 * s2 * c3;
|
|
1050
|
+
this._w = c1 * c2 * c3 - s1 * s2 * s3;
|
|
1051
|
+
break;
|
|
1052
|
+
case "XZY":
|
|
1053
|
+
this._x = s1 * c2 * c3 - c1 * s2 * s3;
|
|
1054
|
+
this._y = c1 * s2 * c3 - s1 * c2 * s3;
|
|
1055
|
+
this._z = c1 * c2 * s3 + s1 * s2 * c3;
|
|
1056
|
+
this._w = c1 * c2 * c3 + s1 * s2 * s3;
|
|
1057
|
+
break;
|
|
1058
|
+
default:
|
|
1059
|
+
console.warn("THREE.Quaternion: .setFromEuler() encountered an unknown order: " + order);
|
|
1060
|
+
}
|
|
1061
|
+
if (update === true) this._onChangeCallback();
|
|
1062
|
+
return this;
|
|
1063
|
+
}
|
|
1064
|
+
setFromAxisAngle(axis, angle) {
|
|
1065
|
+
const halfAngle = angle / 2, s = Math.sin(halfAngle);
|
|
1066
|
+
this._x = axis.x * s;
|
|
1067
|
+
this._y = axis.y * s;
|
|
1068
|
+
this._z = axis.z * s;
|
|
1069
|
+
this._w = Math.cos(halfAngle);
|
|
1070
|
+
this._onChangeCallback();
|
|
1071
|
+
return this;
|
|
1072
|
+
}
|
|
1073
|
+
setFromRotationMatrix(m) {
|
|
1074
|
+
const te = m.elements, 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], trace = m11 + m22 + m33;
|
|
1075
|
+
if (trace > 0) {
|
|
1076
|
+
const s = 0.5 / Math.sqrt(trace + 1);
|
|
1077
|
+
this._w = 0.25 / s;
|
|
1078
|
+
this._x = (m32 - m23) * s;
|
|
1079
|
+
this._y = (m13 - m31) * s;
|
|
1080
|
+
this._z = (m21 - m12) * s;
|
|
1081
|
+
} else if (m11 > m22 && m11 > m33) {
|
|
1082
|
+
const s = 2 * Math.sqrt(1 + m11 - m22 - m33);
|
|
1083
|
+
this._w = (m32 - m23) / s;
|
|
1084
|
+
this._x = 0.25 * s;
|
|
1085
|
+
this._y = (m12 + m21) / s;
|
|
1086
|
+
this._z = (m13 + m31) / s;
|
|
1087
|
+
} else if (m22 > m33) {
|
|
1088
|
+
const s = 2 * Math.sqrt(1 + m22 - m11 - m33);
|
|
1089
|
+
this._w = (m13 - m31) / s;
|
|
1090
|
+
this._x = (m12 + m21) / s;
|
|
1091
|
+
this._y = 0.25 * s;
|
|
1092
|
+
this._z = (m23 + m32) / s;
|
|
1093
|
+
} else {
|
|
1094
|
+
const s = 2 * Math.sqrt(1 + m33 - m11 - m22);
|
|
1095
|
+
this._w = (m21 - m12) / s;
|
|
1096
|
+
this._x = (m13 + m31) / s;
|
|
1097
|
+
this._y = (m23 + m32) / s;
|
|
1098
|
+
this._z = 0.25 * s;
|
|
1099
|
+
}
|
|
1100
|
+
this._onChangeCallback();
|
|
1101
|
+
return this;
|
|
1102
|
+
}
|
|
1103
|
+
setFromUnitVectors(vFrom, vTo) {
|
|
1104
|
+
let r = vFrom.dot(vTo) + 1;
|
|
1105
|
+
if (r < Number.EPSILON) {
|
|
1106
|
+
r = 0;
|
|
1107
|
+
if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) {
|
|
1108
|
+
this._x = -vFrom.y;
|
|
1109
|
+
this._y = vFrom.x;
|
|
1110
|
+
this._z = 0;
|
|
1111
|
+
this._w = r;
|
|
1112
|
+
} else {
|
|
1113
|
+
this._x = 0;
|
|
1114
|
+
this._y = -vFrom.z;
|
|
1115
|
+
this._z = vFrom.y;
|
|
1116
|
+
this._w = r;
|
|
1117
|
+
}
|
|
1118
|
+
} else {
|
|
1119
|
+
this._x = vFrom.y * vTo.z - vFrom.z * vTo.y;
|
|
1120
|
+
this._y = vFrom.z * vTo.x - vFrom.x * vTo.z;
|
|
1121
|
+
this._z = vFrom.x * vTo.y - vFrom.y * vTo.x;
|
|
1122
|
+
this._w = r;
|
|
1123
|
+
}
|
|
1124
|
+
return this.normalize();
|
|
1125
|
+
}
|
|
1126
|
+
angleTo(q) {
|
|
1127
|
+
return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1)));
|
|
1128
|
+
}
|
|
1129
|
+
rotateTowards(q, step) {
|
|
1130
|
+
const angle = this.angleTo(q);
|
|
1131
|
+
if (angle === 0) return this;
|
|
1132
|
+
const t = Math.min(1, step / angle);
|
|
1133
|
+
this.slerp(q, t);
|
|
1134
|
+
return this;
|
|
1135
|
+
}
|
|
1136
|
+
identity() {
|
|
1137
|
+
return this.set(0, 0, 0, 1);
|
|
1138
|
+
}
|
|
1139
|
+
invert() {
|
|
1140
|
+
return this.conjugate();
|
|
1141
|
+
}
|
|
1142
|
+
conjugate() {
|
|
1143
|
+
this._x *= -1;
|
|
1144
|
+
this._y *= -1;
|
|
1145
|
+
this._z *= -1;
|
|
1146
|
+
this._onChangeCallback();
|
|
1147
|
+
return this;
|
|
1148
|
+
}
|
|
1149
|
+
dot(v) {
|
|
1150
|
+
return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
|
|
1151
|
+
}
|
|
1152
|
+
lengthSq() {
|
|
1153
|
+
return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
|
|
1154
|
+
}
|
|
1155
|
+
length() {
|
|
1156
|
+
return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w);
|
|
1157
|
+
}
|
|
1158
|
+
normalize() {
|
|
1159
|
+
let l = this.length();
|
|
1160
|
+
if (l === 0) {
|
|
1161
|
+
this._x = 0;
|
|
1162
|
+
this._y = 0;
|
|
1163
|
+
this._z = 0;
|
|
1164
|
+
this._w = 1;
|
|
1165
|
+
} else {
|
|
1166
|
+
l = 1 / l;
|
|
1167
|
+
this._x = this._x * l;
|
|
1168
|
+
this._y = this._y * l;
|
|
1169
|
+
this._z = this._z * l;
|
|
1170
|
+
this._w = this._w * l;
|
|
1171
|
+
}
|
|
1172
|
+
this._onChangeCallback();
|
|
1173
|
+
return this;
|
|
1174
|
+
}
|
|
1175
|
+
multiply(q) {
|
|
1176
|
+
return this.multiplyQuaternions(this, q);
|
|
1177
|
+
}
|
|
1178
|
+
premultiply(q) {
|
|
1179
|
+
return this.multiplyQuaternions(q, this);
|
|
1180
|
+
}
|
|
1181
|
+
multiplyQuaternions(a, b) {
|
|
1182
|
+
const qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;
|
|
1183
|
+
const qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;
|
|
1184
|
+
this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
|
|
1185
|
+
this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
|
|
1186
|
+
this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
|
|
1187
|
+
this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
|
|
1188
|
+
this._onChangeCallback();
|
|
1189
|
+
return this;
|
|
1190
|
+
}
|
|
1191
|
+
slerp(qb, t) {
|
|
1192
|
+
if (t === 0) return this;
|
|
1193
|
+
if (t === 1) return this.copy(qb);
|
|
1194
|
+
const x = this._x, y = this._y, z = this._z, w = this._w;
|
|
1195
|
+
let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
|
|
1196
|
+
if (cosHalfTheta < 0) {
|
|
1197
|
+
this._w = -qb._w;
|
|
1198
|
+
this._x = -qb._x;
|
|
1199
|
+
this._y = -qb._y;
|
|
1200
|
+
this._z = -qb._z;
|
|
1201
|
+
cosHalfTheta = -cosHalfTheta;
|
|
1202
|
+
} else {
|
|
1203
|
+
this.copy(qb);
|
|
1204
|
+
}
|
|
1205
|
+
if (cosHalfTheta >= 1) {
|
|
1206
|
+
this._w = w;
|
|
1207
|
+
this._x = x;
|
|
1208
|
+
this._y = y;
|
|
1209
|
+
this._z = z;
|
|
1210
|
+
return this;
|
|
1211
|
+
}
|
|
1212
|
+
const sqrSinHalfTheta = 1 - cosHalfTheta * cosHalfTheta;
|
|
1213
|
+
if (sqrSinHalfTheta <= Number.EPSILON) {
|
|
1214
|
+
const s = 1 - t;
|
|
1215
|
+
this._w = s * w + t * this._w;
|
|
1216
|
+
this._x = s * x + t * this._x;
|
|
1217
|
+
this._y = s * y + t * this._y;
|
|
1218
|
+
this._z = s * z + t * this._z;
|
|
1219
|
+
this.normalize();
|
|
1220
|
+
return this;
|
|
1221
|
+
}
|
|
1222
|
+
const sinHalfTheta = Math.sqrt(sqrSinHalfTheta);
|
|
1223
|
+
const halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta);
|
|
1224
|
+
const ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta, ratioB = Math.sin(t * halfTheta) / sinHalfTheta;
|
|
1225
|
+
this._w = w * ratioA + this._w * ratioB;
|
|
1226
|
+
this._x = x * ratioA + this._x * ratioB;
|
|
1227
|
+
this._y = y * ratioA + this._y * ratioB;
|
|
1228
|
+
this._z = z * ratioA + this._z * ratioB;
|
|
1229
|
+
this._onChangeCallback();
|
|
1230
|
+
return this;
|
|
1231
|
+
}
|
|
1232
|
+
slerpQuaternions(qa, qb, t) {
|
|
1233
|
+
return this.copy(qa).slerp(qb, t);
|
|
1234
|
+
}
|
|
1235
|
+
random() {
|
|
1236
|
+
const u1 = Math.random();
|
|
1237
|
+
const sqrt1u1 = Math.sqrt(1 - u1);
|
|
1238
|
+
const sqrtu1 = Math.sqrt(u1);
|
|
1239
|
+
const u2 = 2 * Math.PI * Math.random();
|
|
1240
|
+
const u3 = 2 * Math.PI * Math.random();
|
|
1241
|
+
return this.set(
|
|
1242
|
+
sqrt1u1 * Math.cos(u2),
|
|
1243
|
+
sqrtu1 * Math.sin(u3),
|
|
1244
|
+
sqrtu1 * Math.cos(u3),
|
|
1245
|
+
sqrt1u1 * Math.sin(u2)
|
|
1246
|
+
);
|
|
1247
|
+
}
|
|
1248
|
+
equals(quaternion) {
|
|
1249
|
+
return quaternion._x === this._x && quaternion._y === this._y && quaternion._z === this._z && quaternion._w === this._w;
|
|
1250
|
+
}
|
|
1251
|
+
fromArray(array, offset = 0) {
|
|
1252
|
+
this._x = array[offset];
|
|
1253
|
+
this._y = array[offset + 1];
|
|
1254
|
+
this._z = array[offset + 2];
|
|
1255
|
+
this._w = array[offset + 3];
|
|
1256
|
+
this._onChangeCallback();
|
|
1257
|
+
return this;
|
|
1258
|
+
}
|
|
1259
|
+
toArray(array = [], offset = 0) {
|
|
1260
|
+
array[offset] = this._x;
|
|
1261
|
+
array[offset + 1] = this._y;
|
|
1262
|
+
array[offset + 2] = this._z;
|
|
1263
|
+
array[offset + 3] = this._w;
|
|
1264
|
+
return array;
|
|
1265
|
+
}
|
|
1266
|
+
fromBufferAttribute(attribute, index) {
|
|
1267
|
+
this._x = attribute.getX(index);
|
|
1268
|
+
this._y = attribute.getY(index);
|
|
1269
|
+
this._z = attribute.getZ(index);
|
|
1270
|
+
this._w = attribute.getW(index);
|
|
1271
|
+
this._onChangeCallback();
|
|
1272
|
+
return this;
|
|
1273
|
+
}
|
|
1274
|
+
toJSON() {
|
|
1275
|
+
return this.toArray();
|
|
1276
|
+
}
|
|
1277
|
+
_onChange(callback) {
|
|
1278
|
+
this._onChangeCallback = callback;
|
|
1279
|
+
return this;
|
|
1280
|
+
}
|
|
1281
|
+
_onChangeCallback() {
|
|
1282
|
+
}
|
|
1283
|
+
*[Symbol.iterator]() {
|
|
1284
|
+
yield this._x;
|
|
1285
|
+
yield this._y;
|
|
1286
|
+
yield this._z;
|
|
1287
|
+
yield this._w;
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
const WebGLCoordinateSystem = 2e3;
|
|
1291
|
+
const WebGPUCoordinateSystem = 2001;
|
|
1292
|
+
class Vector3 {
|
|
1293
|
+
constructor(x = 0, y = 0, z = 0) {
|
|
1294
|
+
Vector3.prototype.isVector3 = true;
|
|
1295
|
+
this.x = x;
|
|
1296
|
+
this.y = y;
|
|
1297
|
+
this.z = z;
|
|
1298
|
+
}
|
|
1299
|
+
set(x, y, z) {
|
|
1300
|
+
if (z === void 0) z = this.z;
|
|
1301
|
+
this.x = x;
|
|
1302
|
+
this.y = y;
|
|
1303
|
+
this.z = z;
|
|
1304
|
+
return this;
|
|
1305
|
+
}
|
|
1306
|
+
setScalar(scalar) {
|
|
1307
|
+
this.x = scalar;
|
|
1308
|
+
this.y = scalar;
|
|
1309
|
+
this.z = scalar;
|
|
1310
|
+
return this;
|
|
1311
|
+
}
|
|
1312
|
+
setX(x) {
|
|
1313
|
+
this.x = x;
|
|
1314
|
+
return this;
|
|
1315
|
+
}
|
|
1316
|
+
setY(y) {
|
|
1317
|
+
this.y = y;
|
|
1318
|
+
return this;
|
|
1319
|
+
}
|
|
1320
|
+
setZ(z) {
|
|
1321
|
+
this.z = z;
|
|
1322
|
+
return this;
|
|
1323
|
+
}
|
|
1324
|
+
setComponent(index, value) {
|
|
1325
|
+
switch (index) {
|
|
1326
|
+
case 0:
|
|
1327
|
+
this.x = value;
|
|
1328
|
+
break;
|
|
1329
|
+
case 1:
|
|
1330
|
+
this.y = value;
|
|
1331
|
+
break;
|
|
1332
|
+
case 2:
|
|
1333
|
+
this.z = value;
|
|
1334
|
+
break;
|
|
1335
|
+
default:
|
|
1336
|
+
throw new Error("index is out of range: " + index);
|
|
1337
|
+
}
|
|
1338
|
+
return this;
|
|
1339
|
+
}
|
|
1340
|
+
getComponent(index) {
|
|
1341
|
+
switch (index) {
|
|
1342
|
+
case 0:
|
|
1343
|
+
return this.x;
|
|
1344
|
+
case 1:
|
|
1345
|
+
return this.y;
|
|
1346
|
+
case 2:
|
|
1347
|
+
return this.z;
|
|
1348
|
+
default:
|
|
1349
|
+
throw new Error("index is out of range: " + index);
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
clone() {
|
|
1353
|
+
return new this.constructor(this.x, this.y, this.z);
|
|
1354
|
+
}
|
|
1355
|
+
copy(v) {
|
|
1356
|
+
this.x = v.x;
|
|
1357
|
+
this.y = v.y;
|
|
1358
|
+
this.z = v.z;
|
|
1359
|
+
return this;
|
|
1360
|
+
}
|
|
1361
|
+
add(v) {
|
|
1362
|
+
this.x += v.x;
|
|
1363
|
+
this.y += v.y;
|
|
1364
|
+
this.z += v.z;
|
|
1365
|
+
return this;
|
|
1366
|
+
}
|
|
1367
|
+
addScalar(s) {
|
|
1368
|
+
this.x += s;
|
|
1369
|
+
this.y += s;
|
|
1370
|
+
this.z += s;
|
|
1371
|
+
return this;
|
|
1372
|
+
}
|
|
1373
|
+
addVectors(a, b) {
|
|
1374
|
+
this.x = a.x + b.x;
|
|
1375
|
+
this.y = a.y + b.y;
|
|
1376
|
+
this.z = a.z + b.z;
|
|
1377
|
+
return this;
|
|
1378
|
+
}
|
|
1379
|
+
addScaledVector(v, s) {
|
|
1380
|
+
this.x += v.x * s;
|
|
1381
|
+
this.y += v.y * s;
|
|
1382
|
+
this.z += v.z * s;
|
|
1383
|
+
return this;
|
|
1384
|
+
}
|
|
1385
|
+
sub(v) {
|
|
1386
|
+
this.x -= v.x;
|
|
1387
|
+
this.y -= v.y;
|
|
1388
|
+
this.z -= v.z;
|
|
1389
|
+
return this;
|
|
1390
|
+
}
|
|
1391
|
+
subScalar(s) {
|
|
1392
|
+
this.x -= s;
|
|
1393
|
+
this.y -= s;
|
|
1394
|
+
this.z -= s;
|
|
1395
|
+
return this;
|
|
1396
|
+
}
|
|
1397
|
+
subVectors(a, b) {
|
|
1398
|
+
this.x = a.x - b.x;
|
|
1399
|
+
this.y = a.y - b.y;
|
|
1400
|
+
this.z = a.z - b.z;
|
|
1401
|
+
return this;
|
|
1402
|
+
}
|
|
1403
|
+
multiply(v) {
|
|
1404
|
+
this.x *= v.x;
|
|
1405
|
+
this.y *= v.y;
|
|
1406
|
+
this.z *= v.z;
|
|
1407
|
+
return this;
|
|
1408
|
+
}
|
|
1409
|
+
multiplyScalar(scalar) {
|
|
1410
|
+
this.x *= scalar;
|
|
1411
|
+
this.y *= scalar;
|
|
1412
|
+
this.z *= scalar;
|
|
1413
|
+
return this;
|
|
1414
|
+
}
|
|
1415
|
+
multiplyVectors(a, b) {
|
|
1416
|
+
this.x = a.x * b.x;
|
|
1417
|
+
this.y = a.y * b.y;
|
|
1418
|
+
this.z = a.z * b.z;
|
|
1419
|
+
return this;
|
|
1420
|
+
}
|
|
1421
|
+
applyEuler(euler) {
|
|
1422
|
+
return this.applyQuaternion(_quaternion$1.setFromEuler(euler));
|
|
1423
|
+
}
|
|
1424
|
+
applyAxisAngle(axis, angle) {
|
|
1425
|
+
return this.applyQuaternion(_quaternion$1.setFromAxisAngle(axis, angle));
|
|
1426
|
+
}
|
|
1427
|
+
applyMatrix3(m) {
|
|
1428
|
+
const x = this.x, y = this.y, z = this.z;
|
|
1429
|
+
const e = m.elements;
|
|
1430
|
+
this.x = e[0] * x + e[3] * y + e[6] * z;
|
|
1431
|
+
this.y = e[1] * x + e[4] * y + e[7] * z;
|
|
1432
|
+
this.z = e[2] * x + e[5] * y + e[8] * z;
|
|
1433
|
+
return this;
|
|
1434
|
+
}
|
|
1435
|
+
applyNormalMatrix(m) {
|
|
1436
|
+
return this.applyMatrix3(m).normalize();
|
|
1437
|
+
}
|
|
1438
|
+
applyMatrix4(m) {
|
|
1439
|
+
const x = this.x, y = this.y, z = this.z;
|
|
1440
|
+
const e = m.elements;
|
|
1441
|
+
const w = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]);
|
|
1442
|
+
this.x = (e[0] * x + e[4] * y + e[8] * z + e[12]) * w;
|
|
1443
|
+
this.y = (e[1] * x + e[5] * y + e[9] * z + e[13]) * w;
|
|
1444
|
+
this.z = (e[2] * x + e[6] * y + e[10] * z + e[14]) * w;
|
|
1445
|
+
return this;
|
|
1446
|
+
}
|
|
1447
|
+
applyQuaternion(q) {
|
|
1448
|
+
const vx = this.x, vy = this.y, vz = this.z;
|
|
1449
|
+
const qx = q.x, qy = q.y, qz = q.z, qw = q.w;
|
|
1450
|
+
const tx = 2 * (qy * vz - qz * vy);
|
|
1451
|
+
const ty = 2 * (qz * vx - qx * vz);
|
|
1452
|
+
const tz = 2 * (qx * vy - qy * vx);
|
|
1453
|
+
this.x = vx + qw * tx + qy * tz - qz * ty;
|
|
1454
|
+
this.y = vy + qw * ty + qz * tx - qx * tz;
|
|
1455
|
+
this.z = vz + qw * tz + qx * ty - qy * tx;
|
|
1456
|
+
return this;
|
|
1457
|
+
}
|
|
1458
|
+
project(camera) {
|
|
1459
|
+
return this.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix);
|
|
1460
|
+
}
|
|
1461
|
+
unproject(camera) {
|
|
1462
|
+
return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld);
|
|
1463
|
+
}
|
|
1464
|
+
transformDirection(m) {
|
|
1465
|
+
const x = this.x, y = this.y, z = this.z;
|
|
1466
|
+
const e = m.elements;
|
|
1467
|
+
this.x = e[0] * x + e[4] * y + e[8] * z;
|
|
1468
|
+
this.y = e[1] * x + e[5] * y + e[9] * z;
|
|
1469
|
+
this.z = e[2] * x + e[6] * y + e[10] * z;
|
|
1470
|
+
return this.normalize();
|
|
1471
|
+
}
|
|
1472
|
+
divide(v) {
|
|
1473
|
+
this.x /= v.x;
|
|
1474
|
+
this.y /= v.y;
|
|
1475
|
+
this.z /= v.z;
|
|
1476
|
+
return this;
|
|
1477
|
+
}
|
|
1478
|
+
divideScalar(scalar) {
|
|
1479
|
+
return this.multiplyScalar(1 / scalar);
|
|
1480
|
+
}
|
|
1481
|
+
min(v) {
|
|
1482
|
+
this.x = Math.min(this.x, v.x);
|
|
1483
|
+
this.y = Math.min(this.y, v.y);
|
|
1484
|
+
this.z = Math.min(this.z, v.z);
|
|
1485
|
+
return this;
|
|
1486
|
+
}
|
|
1487
|
+
max(v) {
|
|
1488
|
+
this.x = Math.max(this.x, v.x);
|
|
1489
|
+
this.y = Math.max(this.y, v.y);
|
|
1490
|
+
this.z = Math.max(this.z, v.z);
|
|
1491
|
+
return this;
|
|
1492
|
+
}
|
|
1493
|
+
clamp(min, max) {
|
|
1494
|
+
this.x = Math.max(min.x, Math.min(max.x, this.x));
|
|
1495
|
+
this.y = Math.max(min.y, Math.min(max.y, this.y));
|
|
1496
|
+
this.z = Math.max(min.z, Math.min(max.z, this.z));
|
|
1497
|
+
return this;
|
|
1498
|
+
}
|
|
1499
|
+
clampScalar(minVal, maxVal) {
|
|
1500
|
+
this.x = Math.max(minVal, Math.min(maxVal, this.x));
|
|
1501
|
+
this.y = Math.max(minVal, Math.min(maxVal, this.y));
|
|
1502
|
+
this.z = Math.max(minVal, Math.min(maxVal, this.z));
|
|
1503
|
+
return this;
|
|
1504
|
+
}
|
|
1505
|
+
clampLength(min, max) {
|
|
1506
|
+
const length = this.length();
|
|
1507
|
+
return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length)));
|
|
1508
|
+
}
|
|
1509
|
+
floor() {
|
|
1510
|
+
this.x = Math.floor(this.x);
|
|
1511
|
+
this.y = Math.floor(this.y);
|
|
1512
|
+
this.z = Math.floor(this.z);
|
|
1513
|
+
return this;
|
|
1514
|
+
}
|
|
1515
|
+
ceil() {
|
|
1516
|
+
this.x = Math.ceil(this.x);
|
|
1517
|
+
this.y = Math.ceil(this.y);
|
|
1518
|
+
this.z = Math.ceil(this.z);
|
|
1519
|
+
return this;
|
|
1520
|
+
}
|
|
1521
|
+
round() {
|
|
1522
|
+
this.x = Math.round(this.x);
|
|
1523
|
+
this.y = Math.round(this.y);
|
|
1524
|
+
this.z = Math.round(this.z);
|
|
1525
|
+
return this;
|
|
1526
|
+
}
|
|
1527
|
+
roundToZero() {
|
|
1528
|
+
this.x = Math.trunc(this.x);
|
|
1529
|
+
this.y = Math.trunc(this.y);
|
|
1530
|
+
this.z = Math.trunc(this.z);
|
|
1531
|
+
return this;
|
|
1532
|
+
}
|
|
1533
|
+
negate() {
|
|
1534
|
+
this.x = -this.x;
|
|
1535
|
+
this.y = -this.y;
|
|
1536
|
+
this.z = -this.z;
|
|
1537
|
+
return this;
|
|
1538
|
+
}
|
|
1539
|
+
dot(v) {
|
|
1540
|
+
return this.x * v.x + this.y * v.y + this.z * v.z;
|
|
1541
|
+
}
|
|
1542
|
+
// TODO lengthSquared?
|
|
1543
|
+
lengthSq() {
|
|
1544
|
+
return this.x * this.x + this.y * this.y + this.z * this.z;
|
|
1545
|
+
}
|
|
1546
|
+
length() {
|
|
1547
|
+
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
|
|
1548
|
+
}
|
|
1549
|
+
manhattanLength() {
|
|
1550
|
+
return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z);
|
|
1551
|
+
}
|
|
1552
|
+
normalize() {
|
|
1553
|
+
return this.divideScalar(this.length() || 1);
|
|
1554
|
+
}
|
|
1555
|
+
setLength(length) {
|
|
1556
|
+
return this.normalize().multiplyScalar(length);
|
|
1557
|
+
}
|
|
1558
|
+
lerp(v, alpha) {
|
|
1559
|
+
this.x += (v.x - this.x) * alpha;
|
|
1560
|
+
this.y += (v.y - this.y) * alpha;
|
|
1561
|
+
this.z += (v.z - this.z) * alpha;
|
|
1562
|
+
return this;
|
|
1563
|
+
}
|
|
1564
|
+
lerpVectors(v1, v2, alpha) {
|
|
1565
|
+
this.x = v1.x + (v2.x - v1.x) * alpha;
|
|
1566
|
+
this.y = v1.y + (v2.y - v1.y) * alpha;
|
|
1567
|
+
this.z = v1.z + (v2.z - v1.z) * alpha;
|
|
1568
|
+
return this;
|
|
1569
|
+
}
|
|
1570
|
+
cross(v) {
|
|
1571
|
+
return this.crossVectors(this, v);
|
|
1572
|
+
}
|
|
1573
|
+
crossVectors(a, b) {
|
|
1574
|
+
const ax = a.x, ay = a.y, az = a.z;
|
|
1575
|
+
const bx = b.x, by = b.y, bz = b.z;
|
|
1576
|
+
this.x = ay * bz - az * by;
|
|
1577
|
+
this.y = az * bx - ax * bz;
|
|
1578
|
+
this.z = ax * by - ay * bx;
|
|
1579
|
+
return this;
|
|
1580
|
+
}
|
|
1581
|
+
projectOnVector(v) {
|
|
1582
|
+
const denominator = v.lengthSq();
|
|
1583
|
+
if (denominator === 0) return this.set(0, 0, 0);
|
|
1584
|
+
const scalar = v.dot(this) / denominator;
|
|
1585
|
+
return this.copy(v).multiplyScalar(scalar);
|
|
1586
|
+
}
|
|
1587
|
+
projectOnPlane(planeNormal) {
|
|
1588
|
+
_vector.copy(this).projectOnVector(planeNormal);
|
|
1589
|
+
return this.sub(_vector);
|
|
1590
|
+
}
|
|
1591
|
+
reflect(normal) {
|
|
1592
|
+
return this.sub(_vector.copy(normal).multiplyScalar(2 * this.dot(normal)));
|
|
1593
|
+
}
|
|
1594
|
+
angleTo(v) {
|
|
1595
|
+
const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());
|
|
1596
|
+
if (denominator === 0) return Math.PI / 2;
|
|
1597
|
+
const theta = this.dot(v) / denominator;
|
|
1598
|
+
return Math.acos(clamp(theta, -1, 1));
|
|
1599
|
+
}
|
|
1600
|
+
distanceTo(v) {
|
|
1601
|
+
return Math.sqrt(this.distanceToSquared(v));
|
|
1602
|
+
}
|
|
1603
|
+
distanceToSquared(v) {
|
|
1604
|
+
const dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
|
|
1605
|
+
return dx * dx + dy * dy + dz * dz;
|
|
1606
|
+
}
|
|
1607
|
+
manhattanDistanceTo(v) {
|
|
1608
|
+
return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z);
|
|
1609
|
+
}
|
|
1610
|
+
setFromSpherical(s) {
|
|
1611
|
+
return this.setFromSphericalCoords(s.radius, s.phi, s.theta);
|
|
1612
|
+
}
|
|
1613
|
+
setFromSphericalCoords(radius, phi, theta) {
|
|
1614
|
+
const sinPhiRadius = Math.sin(phi) * radius;
|
|
1615
|
+
this.x = sinPhiRadius * Math.sin(theta);
|
|
1616
|
+
this.y = Math.cos(phi) * radius;
|
|
1617
|
+
this.z = sinPhiRadius * Math.cos(theta);
|
|
1618
|
+
return this;
|
|
1619
|
+
}
|
|
1620
|
+
setFromCylindrical(c) {
|
|
1621
|
+
return this.setFromCylindricalCoords(c.radius, c.theta, c.y);
|
|
1622
|
+
}
|
|
1623
|
+
setFromCylindricalCoords(radius, theta, y) {
|
|
1624
|
+
this.x = radius * Math.sin(theta);
|
|
1625
|
+
this.y = y;
|
|
1626
|
+
this.z = radius * Math.cos(theta);
|
|
1627
|
+
return this;
|
|
1628
|
+
}
|
|
1629
|
+
setFromMatrixPosition(m) {
|
|
1630
|
+
const e = m.elements;
|
|
1631
|
+
this.x = e[12];
|
|
1632
|
+
this.y = e[13];
|
|
1633
|
+
this.z = e[14];
|
|
1634
|
+
return this;
|
|
1635
|
+
}
|
|
1636
|
+
setFromMatrixScale(m) {
|
|
1637
|
+
const sx = this.setFromMatrixColumn(m, 0).length();
|
|
1638
|
+
const sy = this.setFromMatrixColumn(m, 1).length();
|
|
1639
|
+
const sz = this.setFromMatrixColumn(m, 2).length();
|
|
1640
|
+
this.x = sx;
|
|
1641
|
+
this.y = sy;
|
|
1642
|
+
this.z = sz;
|
|
1643
|
+
return this;
|
|
1644
|
+
}
|
|
1645
|
+
setFromMatrixColumn(m, index) {
|
|
1646
|
+
return this.fromArray(m.elements, index * 4);
|
|
1647
|
+
}
|
|
1648
|
+
setFromMatrix3Column(m, index) {
|
|
1649
|
+
return this.fromArray(m.elements, index * 3);
|
|
1650
|
+
}
|
|
1651
|
+
setFromEuler(e) {
|
|
1652
|
+
this.x = e._x;
|
|
1653
|
+
this.y = e._y;
|
|
1654
|
+
this.z = e._z;
|
|
1655
|
+
return this;
|
|
1656
|
+
}
|
|
1657
|
+
setFromColor(c) {
|
|
1658
|
+
this.x = c.r;
|
|
1659
|
+
this.y = c.g;
|
|
1660
|
+
this.z = c.b;
|
|
1661
|
+
return this;
|
|
1662
|
+
}
|
|
1663
|
+
equals(v) {
|
|
1664
|
+
return v.x === this.x && v.y === this.y && v.z === this.z;
|
|
1665
|
+
}
|
|
1666
|
+
fromArray(array, offset = 0) {
|
|
1667
|
+
this.x = array[offset];
|
|
1668
|
+
this.y = array[offset + 1];
|
|
1669
|
+
this.z = array[offset + 2];
|
|
1670
|
+
return this;
|
|
1671
|
+
}
|
|
1672
|
+
toArray(array = [], offset = 0) {
|
|
1673
|
+
array[offset] = this.x;
|
|
1674
|
+
array[offset + 1] = this.y;
|
|
1675
|
+
array[offset + 2] = this.z;
|
|
1676
|
+
return array;
|
|
1677
|
+
}
|
|
1678
|
+
fromBufferAttribute(attribute, index) {
|
|
1679
|
+
this.x = attribute.getX(index);
|
|
1680
|
+
this.y = attribute.getY(index);
|
|
1681
|
+
this.z = attribute.getZ(index);
|
|
1682
|
+
return this;
|
|
1683
|
+
}
|
|
1684
|
+
random() {
|
|
1685
|
+
this.x = Math.random();
|
|
1686
|
+
this.y = Math.random();
|
|
1687
|
+
this.z = Math.random();
|
|
1688
|
+
return this;
|
|
1689
|
+
}
|
|
1690
|
+
randomDirection() {
|
|
1691
|
+
const u = (Math.random() - 0.5) * 2;
|
|
1692
|
+
const t = Math.random() * Math.PI * 2;
|
|
1693
|
+
const f = Math.sqrt(1 - u ** 2);
|
|
1694
|
+
this.x = f * Math.cos(t);
|
|
1695
|
+
this.y = f * Math.sin(t);
|
|
1696
|
+
this.z = u;
|
|
1697
|
+
return this;
|
|
1698
|
+
}
|
|
1699
|
+
*[Symbol.iterator]() {
|
|
1700
|
+
yield this.x;
|
|
1701
|
+
yield this.y;
|
|
1702
|
+
yield this.z;
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
const _vector = /* @__PURE__ */ new Vector3();
|
|
1706
|
+
const _quaternion$1 = /* @__PURE__ */ new Quaternion();
|
|
1707
|
+
class Matrix4 {
|
|
1708
|
+
constructor(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) {
|
|
1709
|
+
Matrix4.prototype.isMatrix4 = true;
|
|
1710
|
+
this.elements = [
|
|
1711
|
+
1,
|
|
1712
|
+
0,
|
|
1713
|
+
0,
|
|
1714
|
+
0,
|
|
1715
|
+
0,
|
|
1716
|
+
1,
|
|
1717
|
+
0,
|
|
1718
|
+
0,
|
|
1719
|
+
0,
|
|
1720
|
+
0,
|
|
1721
|
+
1,
|
|
1722
|
+
0,
|
|
1723
|
+
0,
|
|
1724
|
+
0,
|
|
1725
|
+
0,
|
|
1726
|
+
1
|
|
1727
|
+
];
|
|
1728
|
+
if (n11 !== void 0) {
|
|
1729
|
+
this.set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44);
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) {
|
|
1733
|
+
const te = this.elements;
|
|
1734
|
+
te[0] = n11;
|
|
1735
|
+
te[4] = n12;
|
|
1736
|
+
te[8] = n13;
|
|
1737
|
+
te[12] = n14;
|
|
1738
|
+
te[1] = n21;
|
|
1739
|
+
te[5] = n22;
|
|
1740
|
+
te[9] = n23;
|
|
1741
|
+
te[13] = n24;
|
|
1742
|
+
te[2] = n31;
|
|
1743
|
+
te[6] = n32;
|
|
1744
|
+
te[10] = n33;
|
|
1745
|
+
te[14] = n34;
|
|
1746
|
+
te[3] = n41;
|
|
1747
|
+
te[7] = n42;
|
|
1748
|
+
te[11] = n43;
|
|
1749
|
+
te[15] = n44;
|
|
1750
|
+
return this;
|
|
1751
|
+
}
|
|
1752
|
+
identity() {
|
|
1753
|
+
this.set(
|
|
1754
|
+
1,
|
|
1755
|
+
0,
|
|
1756
|
+
0,
|
|
1757
|
+
0,
|
|
1758
|
+
0,
|
|
1759
|
+
1,
|
|
1760
|
+
0,
|
|
1761
|
+
0,
|
|
1762
|
+
0,
|
|
1763
|
+
0,
|
|
1764
|
+
1,
|
|
1765
|
+
0,
|
|
1766
|
+
0,
|
|
1767
|
+
0,
|
|
1768
|
+
0,
|
|
1769
|
+
1
|
|
1770
|
+
);
|
|
1771
|
+
return this;
|
|
1772
|
+
}
|
|
1773
|
+
clone() {
|
|
1774
|
+
return new Matrix4().fromArray(this.elements);
|
|
1775
|
+
}
|
|
1776
|
+
copy(m) {
|
|
1777
|
+
const te = this.elements;
|
|
1778
|
+
const me = m.elements;
|
|
1779
|
+
te[0] = me[0];
|
|
1780
|
+
te[1] = me[1];
|
|
1781
|
+
te[2] = me[2];
|
|
1782
|
+
te[3] = me[3];
|
|
1783
|
+
te[4] = me[4];
|
|
1784
|
+
te[5] = me[5];
|
|
1785
|
+
te[6] = me[6];
|
|
1786
|
+
te[7] = me[7];
|
|
1787
|
+
te[8] = me[8];
|
|
1788
|
+
te[9] = me[9];
|
|
1789
|
+
te[10] = me[10];
|
|
1790
|
+
te[11] = me[11];
|
|
1791
|
+
te[12] = me[12];
|
|
1792
|
+
te[13] = me[13];
|
|
1793
|
+
te[14] = me[14];
|
|
1794
|
+
te[15] = me[15];
|
|
1795
|
+
return this;
|
|
1796
|
+
}
|
|
1797
|
+
copyPosition(m) {
|
|
1798
|
+
const te = this.elements, me = m.elements;
|
|
1799
|
+
te[12] = me[12];
|
|
1800
|
+
te[13] = me[13];
|
|
1801
|
+
te[14] = me[14];
|
|
1802
|
+
return this;
|
|
1803
|
+
}
|
|
1804
|
+
setFromMatrix3(m) {
|
|
1805
|
+
const me = m.elements;
|
|
1806
|
+
this.set(
|
|
1807
|
+
me[0],
|
|
1808
|
+
me[3],
|
|
1809
|
+
me[6],
|
|
1810
|
+
0,
|
|
1811
|
+
me[1],
|
|
1812
|
+
me[4],
|
|
1813
|
+
me[7],
|
|
1814
|
+
0,
|
|
1815
|
+
me[2],
|
|
1816
|
+
me[5],
|
|
1817
|
+
me[8],
|
|
1818
|
+
0,
|
|
1819
|
+
0,
|
|
1820
|
+
0,
|
|
1821
|
+
0,
|
|
1822
|
+
1
|
|
1823
|
+
);
|
|
1824
|
+
return this;
|
|
1825
|
+
}
|
|
1826
|
+
extractBasis(xAxis, yAxis, zAxis) {
|
|
1827
|
+
xAxis.setFromMatrixColumn(this, 0);
|
|
1828
|
+
yAxis.setFromMatrixColumn(this, 1);
|
|
1829
|
+
zAxis.setFromMatrixColumn(this, 2);
|
|
1830
|
+
return this;
|
|
1831
|
+
}
|
|
1832
|
+
makeBasis(xAxis, yAxis, zAxis) {
|
|
1833
|
+
this.set(
|
|
1834
|
+
xAxis.x,
|
|
1835
|
+
yAxis.x,
|
|
1836
|
+
zAxis.x,
|
|
1837
|
+
0,
|
|
1838
|
+
xAxis.y,
|
|
1839
|
+
yAxis.y,
|
|
1840
|
+
zAxis.y,
|
|
1841
|
+
0,
|
|
1842
|
+
xAxis.z,
|
|
1843
|
+
yAxis.z,
|
|
1844
|
+
zAxis.z,
|
|
1845
|
+
0,
|
|
1846
|
+
0,
|
|
1847
|
+
0,
|
|
1848
|
+
0,
|
|
1849
|
+
1
|
|
1850
|
+
);
|
|
1851
|
+
return this;
|
|
1852
|
+
}
|
|
1853
|
+
extractRotation(m) {
|
|
1854
|
+
const te = this.elements;
|
|
1855
|
+
const me = m.elements;
|
|
1856
|
+
const scaleX = 1 / _v1.setFromMatrixColumn(m, 0).length();
|
|
1857
|
+
const scaleY = 1 / _v1.setFromMatrixColumn(m, 1).length();
|
|
1858
|
+
const scaleZ = 1 / _v1.setFromMatrixColumn(m, 2).length();
|
|
1859
|
+
te[0] = me[0] * scaleX;
|
|
1860
|
+
te[1] = me[1] * scaleX;
|
|
1861
|
+
te[2] = me[2] * scaleX;
|
|
1862
|
+
te[3] = 0;
|
|
1863
|
+
te[4] = me[4] * scaleY;
|
|
1864
|
+
te[5] = me[5] * scaleY;
|
|
1865
|
+
te[6] = me[6] * scaleY;
|
|
1866
|
+
te[7] = 0;
|
|
1867
|
+
te[8] = me[8] * scaleZ;
|
|
1868
|
+
te[9] = me[9] * scaleZ;
|
|
1869
|
+
te[10] = me[10] * scaleZ;
|
|
1870
|
+
te[11] = 0;
|
|
1871
|
+
te[12] = 0;
|
|
1872
|
+
te[13] = 0;
|
|
1873
|
+
te[14] = 0;
|
|
1874
|
+
te[15] = 1;
|
|
1875
|
+
return this;
|
|
1876
|
+
}
|
|
1877
|
+
makeRotationFromEuler(euler) {
|
|
1878
|
+
const te = this.elements;
|
|
1879
|
+
const x = euler.x, y = euler.y, z = euler.z;
|
|
1880
|
+
const a = Math.cos(x), b = Math.sin(x);
|
|
1881
|
+
const c = Math.cos(y), d = Math.sin(y);
|
|
1882
|
+
const e = Math.cos(z), f = Math.sin(z);
|
|
1883
|
+
if (euler.order === "XYZ") {
|
|
1884
|
+
const ae = a * e, af = a * f, be = b * e, bf = b * f;
|
|
1885
|
+
te[0] = c * e;
|
|
1886
|
+
te[4] = -c * f;
|
|
1887
|
+
te[8] = d;
|
|
1888
|
+
te[1] = af + be * d;
|
|
1889
|
+
te[5] = ae - bf * d;
|
|
1890
|
+
te[9] = -b * c;
|
|
1891
|
+
te[2] = bf - ae * d;
|
|
1892
|
+
te[6] = be + af * d;
|
|
1893
|
+
te[10] = a * c;
|
|
1894
|
+
} else if (euler.order === "YXZ") {
|
|
1895
|
+
const ce = c * e, cf = c * f, de = d * e, df = d * f;
|
|
1896
|
+
te[0] = ce + df * b;
|
|
1897
|
+
te[4] = de * b - cf;
|
|
1898
|
+
te[8] = a * d;
|
|
1899
|
+
te[1] = a * f;
|
|
1900
|
+
te[5] = a * e;
|
|
1901
|
+
te[9] = -b;
|
|
1902
|
+
te[2] = cf * b - de;
|
|
1903
|
+
te[6] = df + ce * b;
|
|
1904
|
+
te[10] = a * c;
|
|
1905
|
+
} else if (euler.order === "ZXY") {
|
|
1906
|
+
const ce = c * e, cf = c * f, de = d * e, df = d * f;
|
|
1907
|
+
te[0] = ce - df * b;
|
|
1908
|
+
te[4] = -a * f;
|
|
1909
|
+
te[8] = de + cf * b;
|
|
1910
|
+
te[1] = cf + de * b;
|
|
1911
|
+
te[5] = a * e;
|
|
1912
|
+
te[9] = df - ce * b;
|
|
1913
|
+
te[2] = -a * d;
|
|
1914
|
+
te[6] = b;
|
|
1915
|
+
te[10] = a * c;
|
|
1916
|
+
} else if (euler.order === "ZYX") {
|
|
1917
|
+
const ae = a * e, af = a * f, be = b * e, bf = b * f;
|
|
1918
|
+
te[0] = c * e;
|
|
1919
|
+
te[4] = be * d - af;
|
|
1920
|
+
te[8] = ae * d + bf;
|
|
1921
|
+
te[1] = c * f;
|
|
1922
|
+
te[5] = bf * d + ae;
|
|
1923
|
+
te[9] = af * d - be;
|
|
1924
|
+
te[2] = -d;
|
|
1925
|
+
te[6] = b * c;
|
|
1926
|
+
te[10] = a * c;
|
|
1927
|
+
} else if (euler.order === "YZX") {
|
|
1928
|
+
const ac = a * c, ad = a * d, bc = b * c, bd = b * d;
|
|
1929
|
+
te[0] = c * e;
|
|
1930
|
+
te[4] = bd - ac * f;
|
|
1931
|
+
te[8] = bc * f + ad;
|
|
1932
|
+
te[1] = f;
|
|
1933
|
+
te[5] = a * e;
|
|
1934
|
+
te[9] = -b * e;
|
|
1935
|
+
te[2] = -d * e;
|
|
1936
|
+
te[6] = ad * f + bc;
|
|
1937
|
+
te[10] = ac - bd * f;
|
|
1938
|
+
} else if (euler.order === "XZY") {
|
|
1939
|
+
const ac = a * c, ad = a * d, bc = b * c, bd = b * d;
|
|
1940
|
+
te[0] = c * e;
|
|
1941
|
+
te[4] = -f;
|
|
1942
|
+
te[8] = d * e;
|
|
1943
|
+
te[1] = ac * f + bd;
|
|
1944
|
+
te[5] = a * e;
|
|
1945
|
+
te[9] = ad * f - bc;
|
|
1946
|
+
te[2] = bc * f - ad;
|
|
1947
|
+
te[6] = b * e;
|
|
1948
|
+
te[10] = bd * f + ac;
|
|
1949
|
+
}
|
|
1950
|
+
te[3] = 0;
|
|
1951
|
+
te[7] = 0;
|
|
1952
|
+
te[11] = 0;
|
|
1953
|
+
te[12] = 0;
|
|
1954
|
+
te[13] = 0;
|
|
1955
|
+
te[14] = 0;
|
|
1956
|
+
te[15] = 1;
|
|
1957
|
+
return this;
|
|
1958
|
+
}
|
|
1959
|
+
makeRotationFromQuaternion(q) {
|
|
1960
|
+
return this.compose(_zero, q, _one);
|
|
1961
|
+
}
|
|
1962
|
+
lookAt(eye, target, up) {
|
|
1963
|
+
const te = this.elements;
|
|
1964
|
+
_z.subVectors(eye, target);
|
|
1965
|
+
if (_z.lengthSq() === 0) {
|
|
1966
|
+
_z.z = 1;
|
|
1967
|
+
}
|
|
1968
|
+
_z.normalize();
|
|
1969
|
+
_x.crossVectors(up, _z);
|
|
1970
|
+
if (_x.lengthSq() === 0) {
|
|
1971
|
+
if (Math.abs(up.z) === 1) {
|
|
1972
|
+
_z.x += 1e-4;
|
|
1973
|
+
} else {
|
|
1974
|
+
_z.z += 1e-4;
|
|
1975
|
+
}
|
|
1976
|
+
_z.normalize();
|
|
1977
|
+
_x.crossVectors(up, _z);
|
|
1978
|
+
}
|
|
1979
|
+
_x.normalize();
|
|
1980
|
+
_y.crossVectors(_z, _x);
|
|
1981
|
+
te[0] = _x.x;
|
|
1982
|
+
te[4] = _y.x;
|
|
1983
|
+
te[8] = _z.x;
|
|
1984
|
+
te[1] = _x.y;
|
|
1985
|
+
te[5] = _y.y;
|
|
1986
|
+
te[9] = _z.y;
|
|
1987
|
+
te[2] = _x.z;
|
|
1988
|
+
te[6] = _y.z;
|
|
1989
|
+
te[10] = _z.z;
|
|
1990
|
+
return this;
|
|
1991
|
+
}
|
|
1992
|
+
multiply(m) {
|
|
1993
|
+
return this.multiplyMatrices(this, m);
|
|
1994
|
+
}
|
|
1995
|
+
premultiply(m) {
|
|
1996
|
+
return this.multiplyMatrices(m, this);
|
|
1997
|
+
}
|
|
1998
|
+
multiplyMatrices(a, b) {
|
|
1999
|
+
const ae = a.elements;
|
|
2000
|
+
const be = b.elements;
|
|
2001
|
+
const te = this.elements;
|
|
2002
|
+
const a11 = ae[0], a12 = ae[4], a13 = ae[8], a14 = ae[12];
|
|
2003
|
+
const a21 = ae[1], a22 = ae[5], a23 = ae[9], a24 = ae[13];
|
|
2004
|
+
const a31 = ae[2], a32 = ae[6], a33 = ae[10], a34 = ae[14];
|
|
2005
|
+
const a41 = ae[3], a42 = ae[7], a43 = ae[11], a44 = ae[15];
|
|
2006
|
+
const b11 = be[0], b12 = be[4], b13 = be[8], b14 = be[12];
|
|
2007
|
+
const b21 = be[1], b22 = be[5], b23 = be[9], b24 = be[13];
|
|
2008
|
+
const b31 = be[2], b32 = be[6], b33 = be[10], b34 = be[14];
|
|
2009
|
+
const b41 = be[3], b42 = be[7], b43 = be[11], b44 = be[15];
|
|
2010
|
+
te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
|
|
2011
|
+
te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
|
|
2012
|
+
te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
|
|
2013
|
+
te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
|
|
2014
|
+
te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
|
|
2015
|
+
te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
|
|
2016
|
+
te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
|
|
2017
|
+
te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
|
|
2018
|
+
te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
|
|
2019
|
+
te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
|
|
2020
|
+
te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
|
|
2021
|
+
te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
|
|
2022
|
+
te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
|
|
2023
|
+
te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
|
|
2024
|
+
te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
|
|
2025
|
+
te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
|
|
2026
|
+
return this;
|
|
2027
|
+
}
|
|
2028
|
+
multiplyScalar(s) {
|
|
2029
|
+
const te = this.elements;
|
|
2030
|
+
te[0] *= s;
|
|
2031
|
+
te[4] *= s;
|
|
2032
|
+
te[8] *= s;
|
|
2033
|
+
te[12] *= s;
|
|
2034
|
+
te[1] *= s;
|
|
2035
|
+
te[5] *= s;
|
|
2036
|
+
te[9] *= s;
|
|
2037
|
+
te[13] *= s;
|
|
2038
|
+
te[2] *= s;
|
|
2039
|
+
te[6] *= s;
|
|
2040
|
+
te[10] *= s;
|
|
2041
|
+
te[14] *= s;
|
|
2042
|
+
te[3] *= s;
|
|
2043
|
+
te[7] *= s;
|
|
2044
|
+
te[11] *= s;
|
|
2045
|
+
te[15] *= s;
|
|
2046
|
+
return this;
|
|
2047
|
+
}
|
|
2048
|
+
determinant() {
|
|
2049
|
+
const te = this.elements;
|
|
2050
|
+
const n11 = te[0], n12 = te[4], n13 = te[8], n14 = te[12];
|
|
2051
|
+
const n21 = te[1], n22 = te[5], n23 = te[9], n24 = te[13];
|
|
2052
|
+
const n31 = te[2], n32 = te[6], n33 = te[10], n34 = te[14];
|
|
2053
|
+
const n41 = te[3], n42 = te[7], n43 = te[11], n44 = te[15];
|
|
2054
|
+
return n41 * (+n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34) + n42 * (+n11 * n23 * n34 - n11 * n24 * n33 + n14 * n21 * n33 - n13 * n21 * n34 + n13 * n24 * n31 - n14 * n23 * n31) + n43 * (+n11 * n24 * n32 - n11 * n22 * n34 - n14 * n21 * n32 + n12 * n21 * n34 + n14 * n22 * n31 - n12 * n24 * n31) + n44 * (-n13 * n22 * n31 - n11 * n23 * n32 + n11 * n22 * n33 + n13 * n21 * n32 - n12 * n21 * n33 + n12 * n23 * n31);
|
|
2055
|
+
}
|
|
2056
|
+
transpose() {
|
|
2057
|
+
const te = this.elements;
|
|
2058
|
+
let tmp;
|
|
2059
|
+
tmp = te[1];
|
|
2060
|
+
te[1] = te[4];
|
|
2061
|
+
te[4] = tmp;
|
|
2062
|
+
tmp = te[2];
|
|
2063
|
+
te[2] = te[8];
|
|
2064
|
+
te[8] = tmp;
|
|
2065
|
+
tmp = te[6];
|
|
2066
|
+
te[6] = te[9];
|
|
2067
|
+
te[9] = tmp;
|
|
2068
|
+
tmp = te[3];
|
|
2069
|
+
te[3] = te[12];
|
|
2070
|
+
te[12] = tmp;
|
|
2071
|
+
tmp = te[7];
|
|
2072
|
+
te[7] = te[13];
|
|
2073
|
+
te[13] = tmp;
|
|
2074
|
+
tmp = te[11];
|
|
2075
|
+
te[11] = te[14];
|
|
2076
|
+
te[14] = tmp;
|
|
2077
|
+
return this;
|
|
2078
|
+
}
|
|
2079
|
+
setPosition(x, y, z) {
|
|
2080
|
+
const te = this.elements;
|
|
2081
|
+
if (x.isVector3) {
|
|
2082
|
+
te[12] = x.x;
|
|
2083
|
+
te[13] = x.y;
|
|
2084
|
+
te[14] = x.z;
|
|
2085
|
+
} else {
|
|
2086
|
+
te[12] = x;
|
|
2087
|
+
te[13] = y;
|
|
2088
|
+
te[14] = z;
|
|
2089
|
+
}
|
|
2090
|
+
return this;
|
|
2091
|
+
}
|
|
2092
|
+
invert() {
|
|
2093
|
+
const te = this.elements, n11 = te[0], n21 = te[1], n31 = te[2], n41 = te[3], n12 = te[4], n22 = te[5], n32 = te[6], n42 = te[7], n13 = te[8], n23 = te[9], n33 = te[10], n43 = te[11], n14 = te[12], n24 = te[13], n34 = te[14], n44 = te[15], t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
|
|
2094
|
+
const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
|
|
2095
|
+
if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
2096
|
+
const detInv = 1 / det;
|
|
2097
|
+
te[0] = t11 * detInv;
|
|
2098
|
+
te[1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * detInv;
|
|
2099
|
+
te[2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * detInv;
|
|
2100
|
+
te[3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * detInv;
|
|
2101
|
+
te[4] = t12 * detInv;
|
|
2102
|
+
te[5] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * detInv;
|
|
2103
|
+
te[6] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * detInv;
|
|
2104
|
+
te[7] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * detInv;
|
|
2105
|
+
te[8] = t13 * detInv;
|
|
2106
|
+
te[9] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * detInv;
|
|
2107
|
+
te[10] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * detInv;
|
|
2108
|
+
te[11] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * detInv;
|
|
2109
|
+
te[12] = t14 * detInv;
|
|
2110
|
+
te[13] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * detInv;
|
|
2111
|
+
te[14] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * detInv;
|
|
2112
|
+
te[15] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * detInv;
|
|
2113
|
+
return this;
|
|
2114
|
+
}
|
|
2115
|
+
scale(v) {
|
|
2116
|
+
const te = this.elements;
|
|
2117
|
+
const x = v.x, y = v.y, z = v.z;
|
|
2118
|
+
te[0] *= x;
|
|
2119
|
+
te[4] *= y;
|
|
2120
|
+
te[8] *= z;
|
|
2121
|
+
te[1] *= x;
|
|
2122
|
+
te[5] *= y;
|
|
2123
|
+
te[9] *= z;
|
|
2124
|
+
te[2] *= x;
|
|
2125
|
+
te[6] *= y;
|
|
2126
|
+
te[10] *= z;
|
|
2127
|
+
te[3] *= x;
|
|
2128
|
+
te[7] *= y;
|
|
2129
|
+
te[11] *= z;
|
|
2130
|
+
return this;
|
|
2131
|
+
}
|
|
2132
|
+
getMaxScaleOnAxis() {
|
|
2133
|
+
const te = this.elements;
|
|
2134
|
+
const scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2];
|
|
2135
|
+
const scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6];
|
|
2136
|
+
const scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10];
|
|
2137
|
+
return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq));
|
|
2138
|
+
}
|
|
2139
|
+
makeTranslation(x, y, z) {
|
|
2140
|
+
if (x.isVector3) {
|
|
2141
|
+
this.set(
|
|
2142
|
+
1,
|
|
2143
|
+
0,
|
|
2144
|
+
0,
|
|
2145
|
+
x.x,
|
|
2146
|
+
0,
|
|
2147
|
+
1,
|
|
2148
|
+
0,
|
|
2149
|
+
x.y,
|
|
2150
|
+
0,
|
|
2151
|
+
0,
|
|
2152
|
+
1,
|
|
2153
|
+
x.z,
|
|
2154
|
+
0,
|
|
2155
|
+
0,
|
|
2156
|
+
0,
|
|
2157
|
+
1
|
|
2158
|
+
);
|
|
2159
|
+
} else {
|
|
2160
|
+
this.set(
|
|
2161
|
+
1,
|
|
2162
|
+
0,
|
|
2163
|
+
0,
|
|
2164
|
+
x,
|
|
2165
|
+
0,
|
|
2166
|
+
1,
|
|
2167
|
+
0,
|
|
2168
|
+
y,
|
|
2169
|
+
0,
|
|
2170
|
+
0,
|
|
2171
|
+
1,
|
|
2172
|
+
z,
|
|
2173
|
+
0,
|
|
2174
|
+
0,
|
|
2175
|
+
0,
|
|
2176
|
+
1
|
|
2177
|
+
);
|
|
2178
|
+
}
|
|
2179
|
+
return this;
|
|
2180
|
+
}
|
|
2181
|
+
makeRotationX(theta) {
|
|
2182
|
+
const c = Math.cos(theta), s = Math.sin(theta);
|
|
2183
|
+
this.set(
|
|
2184
|
+
1,
|
|
2185
|
+
0,
|
|
2186
|
+
0,
|
|
2187
|
+
0,
|
|
2188
|
+
0,
|
|
2189
|
+
c,
|
|
2190
|
+
-s,
|
|
2191
|
+
0,
|
|
2192
|
+
0,
|
|
2193
|
+
s,
|
|
2194
|
+
c,
|
|
2195
|
+
0,
|
|
2196
|
+
0,
|
|
2197
|
+
0,
|
|
2198
|
+
0,
|
|
2199
|
+
1
|
|
2200
|
+
);
|
|
2201
|
+
return this;
|
|
2202
|
+
}
|
|
2203
|
+
makeRotationY(theta) {
|
|
2204
|
+
const c = Math.cos(theta), s = Math.sin(theta);
|
|
2205
|
+
this.set(
|
|
2206
|
+
c,
|
|
2207
|
+
0,
|
|
2208
|
+
s,
|
|
2209
|
+
0,
|
|
2210
|
+
0,
|
|
2211
|
+
1,
|
|
2212
|
+
0,
|
|
2213
|
+
0,
|
|
2214
|
+
-s,
|
|
2215
|
+
0,
|
|
2216
|
+
c,
|
|
2217
|
+
0,
|
|
2218
|
+
0,
|
|
2219
|
+
0,
|
|
2220
|
+
0,
|
|
2221
|
+
1
|
|
2222
|
+
);
|
|
2223
|
+
return this;
|
|
2224
|
+
}
|
|
2225
|
+
makeRotationZ(theta) {
|
|
2226
|
+
const c = Math.cos(theta), s = Math.sin(theta);
|
|
2227
|
+
this.set(
|
|
2228
|
+
c,
|
|
2229
|
+
-s,
|
|
2230
|
+
0,
|
|
2231
|
+
0,
|
|
2232
|
+
s,
|
|
2233
|
+
c,
|
|
2234
|
+
0,
|
|
2235
|
+
0,
|
|
2236
|
+
0,
|
|
2237
|
+
0,
|
|
2238
|
+
1,
|
|
2239
|
+
0,
|
|
2240
|
+
0,
|
|
2241
|
+
0,
|
|
2242
|
+
0,
|
|
2243
|
+
1
|
|
2244
|
+
);
|
|
2245
|
+
return this;
|
|
2246
|
+
}
|
|
2247
|
+
makeRotationAxis(axis, angle) {
|
|
2248
|
+
const c = Math.cos(angle);
|
|
2249
|
+
const s = Math.sin(angle);
|
|
2250
|
+
const t = 1 - c;
|
|
2251
|
+
const x = axis.x, y = axis.y, z = axis.z;
|
|
2252
|
+
const tx = t * x, ty = t * y;
|
|
2253
|
+
this.set(
|
|
2254
|
+
tx * x + c,
|
|
2255
|
+
tx * y - s * z,
|
|
2256
|
+
tx * z + s * y,
|
|
2257
|
+
0,
|
|
2258
|
+
tx * y + s * z,
|
|
2259
|
+
ty * y + c,
|
|
2260
|
+
ty * z - s * x,
|
|
2261
|
+
0,
|
|
2262
|
+
tx * z - s * y,
|
|
2263
|
+
ty * z + s * x,
|
|
2264
|
+
t * z * z + c,
|
|
2265
|
+
0,
|
|
2266
|
+
0,
|
|
2267
|
+
0,
|
|
2268
|
+
0,
|
|
2269
|
+
1
|
|
2270
|
+
);
|
|
2271
|
+
return this;
|
|
2272
|
+
}
|
|
2273
|
+
makeScale(x, y, z) {
|
|
2274
|
+
this.set(
|
|
2275
|
+
x,
|
|
2276
|
+
0,
|
|
2277
|
+
0,
|
|
2278
|
+
0,
|
|
2279
|
+
0,
|
|
2280
|
+
y,
|
|
2281
|
+
0,
|
|
2282
|
+
0,
|
|
2283
|
+
0,
|
|
2284
|
+
0,
|
|
2285
|
+
z,
|
|
2286
|
+
0,
|
|
2287
|
+
0,
|
|
2288
|
+
0,
|
|
2289
|
+
0,
|
|
2290
|
+
1
|
|
2291
|
+
);
|
|
2292
|
+
return this;
|
|
2293
|
+
}
|
|
2294
|
+
makeShear(xy, xz, yx, yz, zx, zy) {
|
|
2295
|
+
this.set(
|
|
2296
|
+
1,
|
|
2297
|
+
yx,
|
|
2298
|
+
zx,
|
|
2299
|
+
0,
|
|
2300
|
+
xy,
|
|
2301
|
+
1,
|
|
2302
|
+
zy,
|
|
2303
|
+
0,
|
|
2304
|
+
xz,
|
|
2305
|
+
yz,
|
|
2306
|
+
1,
|
|
2307
|
+
0,
|
|
2308
|
+
0,
|
|
2309
|
+
0,
|
|
2310
|
+
0,
|
|
2311
|
+
1
|
|
2312
|
+
);
|
|
2313
|
+
return this;
|
|
2314
|
+
}
|
|
2315
|
+
compose(position, quaternion, scale) {
|
|
2316
|
+
const te = this.elements;
|
|
2317
|
+
const x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w;
|
|
2318
|
+
const x2 = x + x, y2 = y + y, z2 = z + z;
|
|
2319
|
+
const xx = x * x2, xy = x * y2, xz = x * z2;
|
|
2320
|
+
const yy = y * y2, yz = y * z2, zz = z * z2;
|
|
2321
|
+
const wx = w * x2, wy = w * y2, wz = w * z2;
|
|
2322
|
+
const sx = scale.x, sy = scale.y, sz = scale.z;
|
|
2323
|
+
te[0] = (1 - (yy + zz)) * sx;
|
|
2324
|
+
te[1] = (xy + wz) * sx;
|
|
2325
|
+
te[2] = (xz - wy) * sx;
|
|
2326
|
+
te[3] = 0;
|
|
2327
|
+
te[4] = (xy - wz) * sy;
|
|
2328
|
+
te[5] = (1 - (xx + zz)) * sy;
|
|
2329
|
+
te[6] = (yz + wx) * sy;
|
|
2330
|
+
te[7] = 0;
|
|
2331
|
+
te[8] = (xz + wy) * sz;
|
|
2332
|
+
te[9] = (yz - wx) * sz;
|
|
2333
|
+
te[10] = (1 - (xx + yy)) * sz;
|
|
2334
|
+
te[11] = 0;
|
|
2335
|
+
te[12] = position.x;
|
|
2336
|
+
te[13] = position.y;
|
|
2337
|
+
te[14] = position.z;
|
|
2338
|
+
te[15] = 1;
|
|
2339
|
+
return this;
|
|
2340
|
+
}
|
|
2341
|
+
decompose(position, quaternion, scale) {
|
|
2342
|
+
const te = this.elements;
|
|
2343
|
+
let sx = _v1.set(te[0], te[1], te[2]).length();
|
|
2344
|
+
const sy = _v1.set(te[4], te[5], te[6]).length();
|
|
2345
|
+
const sz = _v1.set(te[8], te[9], te[10]).length();
|
|
2346
|
+
const det = this.determinant();
|
|
2347
|
+
if (det < 0) sx = -sx;
|
|
2348
|
+
position.x = te[12];
|
|
2349
|
+
position.y = te[13];
|
|
2350
|
+
position.z = te[14];
|
|
2351
|
+
_m1.copy(this);
|
|
2352
|
+
const invSX = 1 / sx;
|
|
2353
|
+
const invSY = 1 / sy;
|
|
2354
|
+
const invSZ = 1 / sz;
|
|
2355
|
+
_m1.elements[0] *= invSX;
|
|
2356
|
+
_m1.elements[1] *= invSX;
|
|
2357
|
+
_m1.elements[2] *= invSX;
|
|
2358
|
+
_m1.elements[4] *= invSY;
|
|
2359
|
+
_m1.elements[5] *= invSY;
|
|
2360
|
+
_m1.elements[6] *= invSY;
|
|
2361
|
+
_m1.elements[8] *= invSZ;
|
|
2362
|
+
_m1.elements[9] *= invSZ;
|
|
2363
|
+
_m1.elements[10] *= invSZ;
|
|
2364
|
+
quaternion.setFromRotationMatrix(_m1);
|
|
2365
|
+
scale.x = sx;
|
|
2366
|
+
scale.y = sy;
|
|
2367
|
+
scale.z = sz;
|
|
2368
|
+
return this;
|
|
2369
|
+
}
|
|
2370
|
+
makePerspective(left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem) {
|
|
2371
|
+
const te = this.elements;
|
|
2372
|
+
const x = 2 * near / (right - left);
|
|
2373
|
+
const y = 2 * near / (top - bottom);
|
|
2374
|
+
const a = (right + left) / (right - left);
|
|
2375
|
+
const b = (top + bottom) / (top - bottom);
|
|
2376
|
+
let c, d;
|
|
2377
|
+
if (coordinateSystem === WebGLCoordinateSystem) {
|
|
2378
|
+
c = -(far + near) / (far - near);
|
|
2379
|
+
d = -2 * far * near / (far - near);
|
|
2380
|
+
} else if (coordinateSystem === WebGPUCoordinateSystem) {
|
|
2381
|
+
c = -far / (far - near);
|
|
2382
|
+
d = -far * near / (far - near);
|
|
2383
|
+
} else {
|
|
2384
|
+
throw new Error("THREE.Matrix4.makePerspective(): Invalid coordinate system: " + coordinateSystem);
|
|
2385
|
+
}
|
|
2386
|
+
te[0] = x;
|
|
2387
|
+
te[4] = 0;
|
|
2388
|
+
te[8] = a;
|
|
2389
|
+
te[12] = 0;
|
|
2390
|
+
te[1] = 0;
|
|
2391
|
+
te[5] = y;
|
|
2392
|
+
te[9] = b;
|
|
2393
|
+
te[13] = 0;
|
|
2394
|
+
te[2] = 0;
|
|
2395
|
+
te[6] = 0;
|
|
2396
|
+
te[10] = c;
|
|
2397
|
+
te[14] = d;
|
|
2398
|
+
te[3] = 0;
|
|
2399
|
+
te[7] = 0;
|
|
2400
|
+
te[11] = -1;
|
|
2401
|
+
te[15] = 0;
|
|
2402
|
+
return this;
|
|
2403
|
+
}
|
|
2404
|
+
makeOrthographic(left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem) {
|
|
2405
|
+
const te = this.elements;
|
|
2406
|
+
const w = 1 / (right - left);
|
|
2407
|
+
const h = 1 / (top - bottom);
|
|
2408
|
+
const p = 1 / (far - near);
|
|
2409
|
+
const x = (right + left) * w;
|
|
2410
|
+
const y = (top + bottom) * h;
|
|
2411
|
+
let z, zInv;
|
|
2412
|
+
if (coordinateSystem === WebGLCoordinateSystem) {
|
|
2413
|
+
z = (far + near) * p;
|
|
2414
|
+
zInv = -2 * p;
|
|
2415
|
+
} else if (coordinateSystem === WebGPUCoordinateSystem) {
|
|
2416
|
+
z = near * p;
|
|
2417
|
+
zInv = -1 * p;
|
|
2418
|
+
} else {
|
|
2419
|
+
throw new Error("THREE.Matrix4.makeOrthographic(): Invalid coordinate system: " + coordinateSystem);
|
|
2420
|
+
}
|
|
2421
|
+
te[0] = 2 * w;
|
|
2422
|
+
te[4] = 0;
|
|
2423
|
+
te[8] = 0;
|
|
2424
|
+
te[12] = -x;
|
|
2425
|
+
te[1] = 0;
|
|
2426
|
+
te[5] = 2 * h;
|
|
2427
|
+
te[9] = 0;
|
|
2428
|
+
te[13] = -y;
|
|
2429
|
+
te[2] = 0;
|
|
2430
|
+
te[6] = 0;
|
|
2431
|
+
te[10] = zInv;
|
|
2432
|
+
te[14] = -z;
|
|
2433
|
+
te[3] = 0;
|
|
2434
|
+
te[7] = 0;
|
|
2435
|
+
te[11] = 0;
|
|
2436
|
+
te[15] = 1;
|
|
2437
|
+
return this;
|
|
2438
|
+
}
|
|
2439
|
+
equals(matrix) {
|
|
2440
|
+
const te = this.elements;
|
|
2441
|
+
const me = matrix.elements;
|
|
2442
|
+
for (let i = 0; i < 16; i++) {
|
|
2443
|
+
if (te[i] !== me[i]) return false;
|
|
2444
|
+
}
|
|
2445
|
+
return true;
|
|
2446
|
+
}
|
|
2447
|
+
fromArray(array, offset = 0) {
|
|
2448
|
+
for (let i = 0; i < 16; i++) {
|
|
2449
|
+
this.elements[i] = array[i + offset];
|
|
2450
|
+
}
|
|
2451
|
+
return this;
|
|
2452
|
+
}
|
|
2453
|
+
toArray(array = [], offset = 0) {
|
|
2454
|
+
const te = this.elements;
|
|
2455
|
+
array[offset] = te[0];
|
|
2456
|
+
array[offset + 1] = te[1];
|
|
2457
|
+
array[offset + 2] = te[2];
|
|
2458
|
+
array[offset + 3] = te[3];
|
|
2459
|
+
array[offset + 4] = te[4];
|
|
2460
|
+
array[offset + 5] = te[5];
|
|
2461
|
+
array[offset + 6] = te[6];
|
|
2462
|
+
array[offset + 7] = te[7];
|
|
2463
|
+
array[offset + 8] = te[8];
|
|
2464
|
+
array[offset + 9] = te[9];
|
|
2465
|
+
array[offset + 10] = te[10];
|
|
2466
|
+
array[offset + 11] = te[11];
|
|
2467
|
+
array[offset + 12] = te[12];
|
|
2468
|
+
array[offset + 13] = te[13];
|
|
2469
|
+
array[offset + 14] = te[14];
|
|
2470
|
+
array[offset + 15] = te[15];
|
|
2471
|
+
return array;
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
const _v1 = /* @__PURE__ */ new Vector3();
|
|
2475
|
+
const _m1 = /* @__PURE__ */ new Matrix4();
|
|
2476
|
+
const _zero = /* @__PURE__ */ new Vector3(0, 0, 0);
|
|
2477
|
+
const _one = /* @__PURE__ */ new Vector3(1, 1, 1);
|
|
2478
|
+
const _x = /* @__PURE__ */ new Vector3();
|
|
2479
|
+
const _y = /* @__PURE__ */ new Vector3();
|
|
2480
|
+
const _z = /* @__PURE__ */ new Vector3();
|
|
2481
|
+
const _matrix = /* @__PURE__ */ new Matrix4();
|
|
2482
|
+
const _quaternion = /* @__PURE__ */ new Quaternion();
|
|
2483
|
+
class Euler {
|
|
2484
|
+
constructor(x = 0, y = 0, z = 0, order = Euler.DEFAULT_ORDER) {
|
|
2485
|
+
this.isEuler = true;
|
|
2486
|
+
this._x = x;
|
|
2487
|
+
this._y = y;
|
|
2488
|
+
this._z = z;
|
|
2489
|
+
this._order = order;
|
|
2490
|
+
}
|
|
2491
|
+
get x() {
|
|
2492
|
+
return this._x;
|
|
2493
|
+
}
|
|
2494
|
+
set x(value) {
|
|
2495
|
+
this._x = value;
|
|
2496
|
+
this._onChangeCallback();
|
|
2497
|
+
}
|
|
2498
|
+
get y() {
|
|
2499
|
+
return this._y;
|
|
2500
|
+
}
|
|
2501
|
+
set y(value) {
|
|
2502
|
+
this._y = value;
|
|
2503
|
+
this._onChangeCallback();
|
|
2504
|
+
}
|
|
2505
|
+
get z() {
|
|
2506
|
+
return this._z;
|
|
2507
|
+
}
|
|
2508
|
+
set z(value) {
|
|
2509
|
+
this._z = value;
|
|
2510
|
+
this._onChangeCallback();
|
|
2511
|
+
}
|
|
2512
|
+
get order() {
|
|
2513
|
+
return this._order;
|
|
2514
|
+
}
|
|
2515
|
+
set order(value) {
|
|
2516
|
+
this._order = value;
|
|
2517
|
+
this._onChangeCallback();
|
|
2518
|
+
}
|
|
2519
|
+
set(x, y, z, order = this._order) {
|
|
2520
|
+
this._x = x;
|
|
2521
|
+
this._y = y;
|
|
2522
|
+
this._z = z;
|
|
2523
|
+
this._order = order;
|
|
2524
|
+
this._onChangeCallback();
|
|
2525
|
+
return this;
|
|
2526
|
+
}
|
|
2527
|
+
clone() {
|
|
2528
|
+
return new this.constructor(this._x, this._y, this._z, this._order);
|
|
2529
|
+
}
|
|
2530
|
+
copy(euler) {
|
|
2531
|
+
this._x = euler._x;
|
|
2532
|
+
this._y = euler._y;
|
|
2533
|
+
this._z = euler._z;
|
|
2534
|
+
this._order = euler._order;
|
|
2535
|
+
this._onChangeCallback();
|
|
2536
|
+
return this;
|
|
2537
|
+
}
|
|
2538
|
+
setFromRotationMatrix(m, order = this._order, update = true) {
|
|
2539
|
+
const te = m.elements;
|
|
2540
|
+
const m11 = te[0], m12 = te[4], m13 = te[8];
|
|
2541
|
+
const m21 = te[1], m22 = te[5], m23 = te[9];
|
|
2542
|
+
const m31 = te[2], m32 = te[6], m33 = te[10];
|
|
2543
|
+
switch (order) {
|
|
2544
|
+
case "XYZ":
|
|
2545
|
+
this._y = Math.asin(clamp(m13, -1, 1));
|
|
2546
|
+
if (Math.abs(m13) < 0.9999999) {
|
|
2547
|
+
this._x = Math.atan2(-m23, m33);
|
|
2548
|
+
this._z = Math.atan2(-m12, m11);
|
|
2549
|
+
} else {
|
|
2550
|
+
this._x = Math.atan2(m32, m22);
|
|
2551
|
+
this._z = 0;
|
|
2552
|
+
}
|
|
2553
|
+
break;
|
|
2554
|
+
case "YXZ":
|
|
2555
|
+
this._x = Math.asin(-clamp(m23, -1, 1));
|
|
2556
|
+
if (Math.abs(m23) < 0.9999999) {
|
|
2557
|
+
this._y = Math.atan2(m13, m33);
|
|
2558
|
+
this._z = Math.atan2(m21, m22);
|
|
2559
|
+
} else {
|
|
2560
|
+
this._y = Math.atan2(-m31, m11);
|
|
2561
|
+
this._z = 0;
|
|
2562
|
+
}
|
|
2563
|
+
break;
|
|
2564
|
+
case "ZXY":
|
|
2565
|
+
this._x = Math.asin(clamp(m32, -1, 1));
|
|
2566
|
+
if (Math.abs(m32) < 0.9999999) {
|
|
2567
|
+
this._y = Math.atan2(-m31, m33);
|
|
2568
|
+
this._z = Math.atan2(-m12, m22);
|
|
2569
|
+
} else {
|
|
2570
|
+
this._y = 0;
|
|
2571
|
+
this._z = Math.atan2(m21, m11);
|
|
2572
|
+
}
|
|
2573
|
+
break;
|
|
2574
|
+
case "ZYX":
|
|
2575
|
+
this._y = Math.asin(-clamp(m31, -1, 1));
|
|
2576
|
+
if (Math.abs(m31) < 0.9999999) {
|
|
2577
|
+
this._x = Math.atan2(m32, m33);
|
|
2578
|
+
this._z = Math.atan2(m21, m11);
|
|
2579
|
+
} else {
|
|
2580
|
+
this._x = 0;
|
|
2581
|
+
this._z = Math.atan2(-m12, m22);
|
|
2582
|
+
}
|
|
2583
|
+
break;
|
|
2584
|
+
case "YZX":
|
|
2585
|
+
this._z = Math.asin(clamp(m21, -1, 1));
|
|
2586
|
+
if (Math.abs(m21) < 0.9999999) {
|
|
2587
|
+
this._x = Math.atan2(-m23, m22);
|
|
2588
|
+
this._y = Math.atan2(-m31, m11);
|
|
2589
|
+
} else {
|
|
2590
|
+
this._x = 0;
|
|
2591
|
+
this._y = Math.atan2(m13, m33);
|
|
2592
|
+
}
|
|
2593
|
+
break;
|
|
2594
|
+
case "XZY":
|
|
2595
|
+
this._z = Math.asin(-clamp(m12, -1, 1));
|
|
2596
|
+
if (Math.abs(m12) < 0.9999999) {
|
|
2597
|
+
this._x = Math.atan2(m32, m22);
|
|
2598
|
+
this._y = Math.atan2(m13, m11);
|
|
2599
|
+
} else {
|
|
2600
|
+
this._x = Math.atan2(-m23, m33);
|
|
2601
|
+
this._y = 0;
|
|
2602
|
+
}
|
|
2603
|
+
break;
|
|
2604
|
+
default:
|
|
2605
|
+
console.warn("THREE.Euler: .setFromRotationMatrix() encountered an unknown order: " + order);
|
|
2606
|
+
}
|
|
2607
|
+
this._order = order;
|
|
2608
|
+
if (update === true) this._onChangeCallback();
|
|
2609
|
+
return this;
|
|
2610
|
+
}
|
|
2611
|
+
setFromQuaternion(q, order, update) {
|
|
2612
|
+
_matrix.makeRotationFromQuaternion(q);
|
|
2613
|
+
return this.setFromRotationMatrix(_matrix, order, update);
|
|
2614
|
+
}
|
|
2615
|
+
setFromVector3(v, order = this._order) {
|
|
2616
|
+
return this.set(v.x, v.y, v.z, order);
|
|
2617
|
+
}
|
|
2618
|
+
reorder(newOrder) {
|
|
2619
|
+
_quaternion.setFromEuler(this);
|
|
2620
|
+
return this.setFromQuaternion(_quaternion, newOrder);
|
|
2621
|
+
}
|
|
2622
|
+
equals(euler) {
|
|
2623
|
+
return euler._x === this._x && euler._y === this._y && euler._z === this._z && euler._order === this._order;
|
|
2624
|
+
}
|
|
2625
|
+
fromArray(array) {
|
|
2626
|
+
this._x = array[0];
|
|
2627
|
+
this._y = array[1];
|
|
2628
|
+
this._z = array[2];
|
|
2629
|
+
if (array[3] !== void 0) this._order = array[3];
|
|
2630
|
+
this._onChangeCallback();
|
|
2631
|
+
return this;
|
|
2632
|
+
}
|
|
2633
|
+
toArray(array = [], offset = 0) {
|
|
2634
|
+
array[offset] = this._x;
|
|
2635
|
+
array[offset + 1] = this._y;
|
|
2636
|
+
array[offset + 2] = this._z;
|
|
2637
|
+
array[offset + 3] = this._order;
|
|
2638
|
+
return array;
|
|
2639
|
+
}
|
|
2640
|
+
_onChange(callback) {
|
|
2641
|
+
this._onChangeCallback = callback;
|
|
2642
|
+
return this;
|
|
2643
|
+
}
|
|
2644
|
+
_onChangeCallback() {
|
|
2645
|
+
}
|
|
2646
|
+
*[Symbol.iterator]() {
|
|
2647
|
+
yield this._x;
|
|
2648
|
+
yield this._y;
|
|
2649
|
+
yield this._z;
|
|
2650
|
+
yield this._order;
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
Euler.DEFAULT_ORDER = "XYZ";
|
|
644
2654
|
const blenderObjectTypes = {
|
|
2655
|
+
empty: 0,
|
|
645
2656
|
mesh: 1,
|
|
646
|
-
lamp: 10
|
|
2657
|
+
lamp: 10,
|
|
2658
|
+
camera: 11
|
|
647
2659
|
};
|
|
648
|
-
async function createObjects(file) {
|
|
2660
|
+
async function createObjects(file, ctx) {
|
|
649
2661
|
const objects = [];
|
|
650
|
-
const
|
|
2662
|
+
const childMap = /* @__PURE__ */ new Map();
|
|
2663
|
+
const objMap = /* @__PURE__ */ new Map();
|
|
2664
|
+
const blendObjects = file.objects.Object ?? [];
|
|
2665
|
+
const loaded = /* @__PURE__ */ new WeakMap();
|
|
651
2666
|
for (const object of blendObjects) {
|
|
2667
|
+
if (loaded.has(object)) {
|
|
2668
|
+
console.warn("BlendLoader - duplicate object");
|
|
2669
|
+
continue;
|
|
2670
|
+
}
|
|
2671
|
+
let obj = void 0;
|
|
652
2672
|
switch (object.type) {
|
|
2673
|
+
case blenderObjectTypes.empty:
|
|
2674
|
+
obj = new ctx.Object3D();
|
|
2675
|
+
break;
|
|
653
2676
|
case blenderObjectTypes.mesh:
|
|
654
|
-
|
|
2677
|
+
obj = createMesh(object, loaded, ctx);
|
|
655
2678
|
break;
|
|
656
2679
|
case blenderObjectTypes.lamp:
|
|
657
|
-
|
|
2680
|
+
obj = createLight(object, ctx);
|
|
2681
|
+
break;
|
|
2682
|
+
case blenderObjectTypes.camera:
|
|
2683
|
+
obj = createCamera(object, ctx);
|
|
658
2684
|
break;
|
|
659
2685
|
default:
|
|
660
|
-
|
|
2686
|
+
obj = new ctx.Object3D();
|
|
2687
|
+
console.warn("Unsupported object type", object.type, object, obj);
|
|
2688
|
+
}
|
|
2689
|
+
if (obj) {
|
|
2690
|
+
setTransform(object, obj);
|
|
2691
|
+
const exChildren = childMap.get(object);
|
|
2692
|
+
if (exChildren) {
|
|
2693
|
+
for (const exChild of exChildren) {
|
|
2694
|
+
obj.add(exChild);
|
|
2695
|
+
}
|
|
2696
|
+
childMap.delete(object);
|
|
2697
|
+
}
|
|
2698
|
+
objMap.set(object, obj);
|
|
2699
|
+
if (object.parent === object) {
|
|
2700
|
+
console.error("BlendLoader - invalid, parent same as object, adding to root", object);
|
|
2701
|
+
objects.push(obj);
|
|
2702
|
+
} else if (!object.parent) {
|
|
2703
|
+
objects.push(obj);
|
|
2704
|
+
} else {
|
|
2705
|
+
const parent = objMap.get(object.parent);
|
|
2706
|
+
if (!parent) {
|
|
2707
|
+
const chi = childMap.get(object.parent) ?? [];
|
|
2708
|
+
chi.push(obj);
|
|
2709
|
+
childMap.set(object, chi);
|
|
2710
|
+
} else {
|
|
2711
|
+
parent.add(obj);
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2714
|
+
loaded.set(object, obj);
|
|
661
2715
|
}
|
|
662
2716
|
}
|
|
2717
|
+
if (childMap.size) {
|
|
2718
|
+
const vals = [...childMap.values()].flat();
|
|
2719
|
+
console.warn("BlendLoader - unknown objects with parents, adding to root", vals, childMap);
|
|
2720
|
+
objects.push(...vals);
|
|
2721
|
+
}
|
|
663
2722
|
return objects.filter((o) => !!o);
|
|
664
2723
|
}
|
|
2724
|
+
const eulerModes = {
|
|
2725
|
+
[1]: "XYZ",
|
|
2726
|
+
[2]: "XZY",
|
|
2727
|
+
[3]: "YXZ",
|
|
2728
|
+
[4]: "YZX",
|
|
2729
|
+
[5]: "ZXY",
|
|
2730
|
+
[6]: "ZYX"
|
|
2731
|
+
};
|
|
2732
|
+
function setTransform(object, obj) {
|
|
2733
|
+
obj.name = object.aname;
|
|
2734
|
+
obj.scale.set(object.size[0], object.size[2], object.size[1]);
|
|
2735
|
+
obj.position.set(object.loc[0], object.loc[2], -object.loc[1]);
|
|
2736
|
+
if (!object.rotmode || object.rotmode === 0) {
|
|
2737
|
+
obj.quaternion.set(object.quat[1], object.quat[3], -object.quat[2], object.quat[0]);
|
|
2738
|
+
} else {
|
|
2739
|
+
const order = eulerModes[object.rotmode] ?? "XYZ";
|
|
2740
|
+
const quat = new Quaternion$1().setFromEuler(new Euler(object.rot[0], object.rot[1], object.rot[2], order.split("").reverse().join("")));
|
|
2741
|
+
obj.quaternion.set(quat.x, quat.z, -quat.y, quat.w);
|
|
2742
|
+
}
|
|
2743
|
+
if (object.type === blenderObjectTypes.camera)
|
|
2744
|
+
obj.quaternion.multiply(new Quaternion$1().setFromAxisAngle(new Vector3$1(1, 0, 0), -Math.PI / 2));
|
|
2745
|
+
obj.updateMatrix();
|
|
2746
|
+
if (obj.setDirty) obj.setDirty();
|
|
2747
|
+
}
|
|
665
2748
|
const _BlendLoadPlugin = class _BlendLoadPlugin extends BaseImporterPlugin {
|
|
666
2749
|
constructor() {
|
|
667
2750
|
super();
|
|
@@ -670,13 +2753,28 @@ const _BlendLoadPlugin = class _BlendLoadPlugin extends BaseImporterPlugin {
|
|
|
670
2753
|
this.setResponseType("arraybuffer");
|
|
671
2754
|
const res = await super.loadAsync(url, onProgress);
|
|
672
2755
|
const blend = await parseBlend(res);
|
|
673
|
-
const
|
|
2756
|
+
const ctx = {
|
|
2757
|
+
Object3D: Object3D2,
|
|
2758
|
+
Mesh: Mesh2,
|
|
2759
|
+
MeshPhysicalMaterial: PhysicalMaterial,
|
|
2760
|
+
PerspectiveCamera: PerspectiveCamera0,
|
|
2761
|
+
OrthographicCamera: OrthographicCamera0,
|
|
2762
|
+
PointLight: PointLight2,
|
|
2763
|
+
BufferGeometry: BufferGeometry2,
|
|
2764
|
+
BufferAttribute
|
|
2765
|
+
};
|
|
2766
|
+
const objects = await createObjects(blend, ctx);
|
|
674
2767
|
const root = new Object3D();
|
|
675
2768
|
root.add(...objects);
|
|
2769
|
+
root.userData.autoScaled = true;
|
|
2770
|
+
root.userData.autoCentered = true;
|
|
676
2771
|
blend.scene = root;
|
|
677
2772
|
return blend;
|
|
678
2773
|
}
|
|
679
|
-
transform(res,
|
|
2774
|
+
transform(res, options) {
|
|
2775
|
+
if (typeof options.onBlendLoad === "function") {
|
|
2776
|
+
options.onBlendLoad(res);
|
|
2777
|
+
}
|
|
680
2778
|
return res.scene;
|
|
681
2779
|
}
|
|
682
2780
|
}, ["blend"], ["application/x-blender"], true);
|