@inweb/viewer-three 27.4.7 → 27.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/extensions/components/AxesHelperComponent.js +3 -0
- package/dist/extensions/components/AxesHelperComponent.js.map +1 -1
- package/dist/extensions/components/AxesHelperComponent.min.js +1 -1
- package/dist/extensions/components/AxesHelperComponent.module.js +3 -0
- package/dist/extensions/components/AxesHelperComponent.module.js.map +1 -1
- package/dist/extensions/components/ExtentsHelperComponent.js +6 -2
- package/dist/extensions/components/ExtentsHelperComponent.js.map +1 -1
- package/dist/extensions/components/ExtentsHelperComponent.min.js +1 -1
- package/dist/extensions/components/ExtentsHelperComponent.module.js +6 -2
- package/dist/extensions/components/ExtentsHelperComponent.module.js.map +1 -1
- package/dist/extensions/components/GridHelperComponent.js +1 -0
- package/dist/extensions/components/GridHelperComponent.js.map +1 -1
- package/dist/extensions/components/GridHelperComponent.min.js +1 -1
- package/dist/extensions/components/GridHelperComponent.module.js +1 -0
- package/dist/extensions/components/GridHelperComponent.module.js.map +1 -1
- package/dist/extensions/components/LightHelperComponent.js +2 -1
- package/dist/extensions/components/LightHelperComponent.js.map +1 -1
- package/dist/extensions/components/LightHelperComponent.min.js +1 -1
- package/dist/extensions/components/LightHelperComponent.module.js +2 -1
- package/dist/extensions/components/LightHelperComponent.module.js.map +1 -1
- package/dist/extensions/components/StatsPanelComponent.js +0 -1
- package/dist/extensions/components/StatsPanelComponent.js.map +1 -1
- package/dist/extensions/components/StatsPanelComponent.min.js +1 -1
- package/dist/extensions/components/StatsPanelComponent.module.js +0 -1
- package/dist/extensions/components/StatsPanelComponent.module.js.map +1 -1
- package/dist/extensions/loaders/GLTFCloudLoader.js +7 -2
- package/dist/extensions/loaders/GLTFCloudLoader.js.map +1 -1
- package/dist/extensions/loaders/GLTFCloudLoader.min.js +1 -1
- package/dist/extensions/loaders/GLTFCloudLoader.module.js +7 -2
- package/dist/extensions/loaders/GLTFCloudLoader.module.js.map +1 -1
- package/dist/extensions/loaders/GLTFFileLoader.js +2 -1
- package/dist/extensions/loaders/GLTFFileLoader.js.map +1 -1
- package/dist/extensions/loaders/GLTFFileLoader.min.js +1 -1
- package/dist/extensions/loaders/GLTFFileLoader.module.js +2 -1
- package/dist/extensions/loaders/GLTFFileLoader.module.js.map +1 -1
- package/dist/extensions/loaders/IFCXLoader.js +10 -5
- package/dist/extensions/loaders/IFCXLoader.js.map +1 -1
- package/dist/extensions/loaders/IFCXLoader.min.js +1 -1
- package/dist/extensions/loaders/IFCXLoader.module.js +10 -5
- package/dist/extensions/loaders/IFCXLoader.module.js.map +1 -1
- package/dist/viewer-three.js +1901 -569
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +4 -4
- package/dist/viewer-three.module.js +1366 -451
- package/dist/viewer-three.module.js.map +1 -1
- package/extensions/components/AxesHelperComponent.ts +3 -0
- package/extensions/components/ExtentsHelperComponent.ts +5 -2
- package/extensions/components/GridHelperComponent.ts +1 -0
- package/extensions/components/LightHelperComponent.ts +2 -1
- package/extensions/components/StatsPanelComponent.ts +0 -1
- package/extensions/loaders/GLTFCloudLoader.ts +8 -2
- package/extensions/loaders/GLTFFileLoader.ts +3 -2
- package/extensions/loaders/IFCX/IFCXFileLoader.ts +11 -5
- package/lib/Viewer/Viewer.d.ts +6 -8
- package/lib/Viewer/components/CameraComponent.d.ts +1 -1
- package/lib/Viewer/components/ClippingPlaneComponent.d.ts +8 -0
- package/lib/Viewer/components/HighlighterComponent.d.ts +2 -2
- package/lib/Viewer/components/InfoComponent.d.ts +1 -1
- package/lib/Viewer/components/SectionsComponent.d.ts +15 -0
- package/lib/Viewer/components/WCSHelperComponent.d.ts +2 -2
- package/lib/Viewer/draggers/CuttingPlaneDragger.d.ts +6 -6
- package/lib/Viewer/draggers/OrbitDragger.d.ts +1 -1
- package/lib/Viewer/measurement/Snapper.d.ts +4 -4
- package/package.json +5 -5
- package/src/Viewer/Viewer.ts +59 -48
- package/src/Viewer/commands/GetSelected2.ts +1 -1
- package/src/Viewer/commands/SetSelected.ts +1 -1
- package/src/Viewer/commands/index.ts +1 -1
- package/src/Viewer/components/BackgroundComponent.ts +2 -1
- package/src/Viewer/components/CameraComponent.ts +6 -7
- package/src/Viewer/components/CanvasRemoveComponent.ts +0 -1
- package/src/Viewer/{scenes/Helpers.ts → components/ClippingPlaneComponent.ts} +22 -12
- package/src/Viewer/components/HighlighterComponent.ts +9 -5
- package/src/Viewer/components/HighlighterUtils.ts +2 -2
- package/src/Viewer/components/InfoComponent.ts +4 -4
- package/src/Viewer/components/SectionsComponent.ts +119 -0
- package/src/Viewer/components/SelectionComponent.ts +5 -3
- package/src/Viewer/components/WCSHelperComponent.ts +8 -6
- package/src/Viewer/components/index.ts +4 -0
- package/src/Viewer/draggers/CuttingPlaneDragger.ts +57 -34
- package/src/Viewer/draggers/MeasureLineDragger.ts +1 -1
- package/src/Viewer/draggers/OrbitDragger.ts +3 -3
- package/src/Viewer/helpers/SectionsHelper.js +1061 -0
- package/src/Viewer/helpers/WCSHelper.ts +31 -5
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +417 -92
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.ts +19 -14
- package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +76 -9
- package/src/Viewer/loaders/GLTFBinaryParser.ts +2 -2
- package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +3 -2
- package/src/Viewer/loaders/GLTFFileDynamicLoader.ts +6 -4
- package/src/Viewer/measurement/Snapper.ts +6 -7
- package/src/Viewer/models/ModelImpl.ts +65 -28
- package/lib/Viewer/scenes/Helpers.d.ts +0 -7
- package/src/Viewer/postprocessing/SSAARenderPass.js +0 -245
package/dist/viewer-three.js
CHANGED
|
@@ -159,8 +159,7 @@
|
|
|
159
159
|
this.abortController = new AbortController();
|
|
160
160
|
}
|
|
161
161
|
dispose() {
|
|
162
|
-
this.
|
|
163
|
-
this.abortController = undefined;
|
|
162
|
+
this.cancel();
|
|
164
163
|
}
|
|
165
164
|
isSupport(file, format) {
|
|
166
165
|
return false;
|
|
@@ -179,10 +178,10 @@
|
|
|
179
178
|
extractFileName(file) {
|
|
180
179
|
const regex = /[^/\\?#:]+(?=\?|#|$)/;
|
|
181
180
|
if (typeof file === "string")
|
|
182
|
-
return (file.match(regex) || [])[0];
|
|
181
|
+
return (file.match(regex) || [])[0] || "";
|
|
183
182
|
else if (file instanceof globalThis.File)
|
|
184
|
-
return (file.name.match(regex) || [])[0];
|
|
185
|
-
return
|
|
183
|
+
return (file.name.match(regex) || [])[0] || "";
|
|
184
|
+
return "";
|
|
186
185
|
}
|
|
187
186
|
};
|
|
188
187
|
class Loaders {
|
|
@@ -235,6 +234,15 @@
|
|
|
235
234
|
enablePartialMode: false,
|
|
236
235
|
memoryLimit: 3294967296,
|
|
237
236
|
cuttingPlaneFillColor: { red: 0xff, green: 0x98, blue: 0x00 },
|
|
237
|
+
enableSectionFill: true,
|
|
238
|
+
sectionFillColor: { r: 0xff, g: 0x98, b: 0x00 },
|
|
239
|
+
sectionUseObjectColor: false,
|
|
240
|
+
enableSectionHatch: true,
|
|
241
|
+
sectionHatchColor: { r: 0, g: 0, b: 0 },
|
|
242
|
+
sectionHatchScale: 8,
|
|
243
|
+
enableSectionOutline: true,
|
|
244
|
+
sectionOutlineColor: { r: 0, g: 0, b: 0 },
|
|
245
|
+
sectionOutlineWidth: 2,
|
|
238
246
|
edgesColor: { r: 0xff, g: 0x98, b: 0x00 },
|
|
239
247
|
facesColor: { r: 0xff, g: 0x98, b: 0x00 },
|
|
240
248
|
edgesVisibility: true,
|
|
@@ -293,230 +301,301 @@
|
|
|
293
301
|
}
|
|
294
302
|
}
|
|
295
303
|
resetToDefaults(fields) {
|
|
304
|
+
const defaults = Options.defaults();
|
|
296
305
|
if (fields !== undefined) {
|
|
297
|
-
const
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
302
|
-
this.data =
|
|
306
|
+
const resetData = {};
|
|
307
|
+
for (const field of fields) {
|
|
308
|
+
if (field in defaults)
|
|
309
|
+
resetData[field] = defaults[field];
|
|
310
|
+
}
|
|
311
|
+
this.data = resetData;
|
|
303
312
|
}
|
|
304
313
|
else {
|
|
305
|
-
this.data =
|
|
314
|
+
this.data = defaults;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
setProperty(key, value = Options.defaults()[key]) {
|
|
318
|
+
if (this._data[key] !== value) {
|
|
319
|
+
this._data[key] = value;
|
|
320
|
+
this.change();
|
|
306
321
|
}
|
|
307
322
|
}
|
|
308
323
|
get data() {
|
|
309
324
|
return this._data;
|
|
310
325
|
}
|
|
311
326
|
set data(value) {
|
|
312
|
-
const
|
|
313
|
-
const
|
|
314
|
-
|
|
327
|
+
const defaults = Options.defaults();
|
|
328
|
+
const merged = { ...defaults, ...this._data, ...value };
|
|
329
|
+
for (const key of Object.keys(defaults)) {
|
|
330
|
+
if (merged[key] === undefined)
|
|
331
|
+
merged[key] = defaults[key];
|
|
332
|
+
}
|
|
333
|
+
this._data = merged;
|
|
334
|
+
if (this._data.enablePartialMode) {
|
|
335
|
+
this._data.enableStreamingMode = true;
|
|
336
|
+
this._data.sceneGraph = false;
|
|
337
|
+
}
|
|
338
|
+
if (!value.sectionFillColor && value.cuttingPlaneFillColor)
|
|
339
|
+
this._data.sectionFillColor = {
|
|
340
|
+
r: value.cuttingPlaneFillColor.red,
|
|
341
|
+
g: value.cuttingPlaneFillColor.green,
|
|
342
|
+
b: value.cuttingPlaneFillColor.blue,
|
|
343
|
+
};
|
|
315
344
|
this.change();
|
|
316
345
|
}
|
|
317
346
|
get showWCS() {
|
|
318
347
|
return this._data.showWCS;
|
|
319
348
|
}
|
|
320
349
|
set showWCS(value) {
|
|
321
|
-
this.
|
|
322
|
-
this.change();
|
|
350
|
+
this.setProperty("showWCS", value);
|
|
323
351
|
}
|
|
324
352
|
get cameraAnimation() {
|
|
325
353
|
return this._data.cameraAnimation;
|
|
326
354
|
}
|
|
327
355
|
set cameraAnimation(value) {
|
|
328
|
-
this.
|
|
329
|
-
this.change();
|
|
356
|
+
this.setProperty("cameraAnimation", value);
|
|
330
357
|
}
|
|
331
358
|
get antialiasing() {
|
|
332
359
|
return this._data.antialiasing;
|
|
333
360
|
}
|
|
334
361
|
set antialiasing(value) {
|
|
335
|
-
this.
|
|
336
|
-
this.change();
|
|
362
|
+
this.setProperty("antialiasing", value);
|
|
337
363
|
}
|
|
338
364
|
get groundShadow() {
|
|
339
365
|
return this._data.groundShadow;
|
|
340
366
|
}
|
|
341
367
|
set groundShadow(value) {
|
|
342
|
-
this.
|
|
343
|
-
this.change();
|
|
368
|
+
this.setProperty("groundShadow", value);
|
|
344
369
|
}
|
|
345
370
|
get shadows() {
|
|
346
371
|
return this._data.shadows;
|
|
347
372
|
}
|
|
348
373
|
set shadows(value) {
|
|
349
|
-
this.
|
|
350
|
-
this.change();
|
|
374
|
+
this.setProperty("shadows", value);
|
|
351
375
|
}
|
|
352
376
|
get cameraAxisXSpeed() {
|
|
353
377
|
return this._data.cameraAxisXSpeed;
|
|
354
378
|
}
|
|
355
379
|
set cameraAxisXSpeed(value) {
|
|
356
|
-
this.
|
|
357
|
-
this.change();
|
|
380
|
+
this.setProperty("cameraAxisXSpeed", value);
|
|
358
381
|
}
|
|
359
382
|
get cameraAxisYSpeed() {
|
|
360
383
|
return this._data.cameraAxisYSpeed;
|
|
361
384
|
}
|
|
362
385
|
set cameraAxisYSpeed(value) {
|
|
363
|
-
this.cameraAxisYSpeed
|
|
364
|
-
this.change();
|
|
386
|
+
this.setProperty("cameraAxisYSpeed", value);
|
|
365
387
|
}
|
|
366
388
|
get ambientOcclusion() {
|
|
367
389
|
return this._data.ambientOcclusion;
|
|
368
390
|
}
|
|
369
391
|
set ambientOcclusion(value) {
|
|
370
|
-
this.
|
|
371
|
-
this.change();
|
|
392
|
+
this.setProperty("ambientOcclusion", value);
|
|
372
393
|
}
|
|
373
394
|
get enableStreamingMode() {
|
|
374
395
|
return this._data.enableStreamingMode;
|
|
375
396
|
}
|
|
376
397
|
set enableStreamingMode(value) {
|
|
377
|
-
this.
|
|
378
|
-
if (!value)
|
|
379
|
-
this.
|
|
380
|
-
|
|
398
|
+
this.setProperty("enableStreamingMode", value);
|
|
399
|
+
if (!value) {
|
|
400
|
+
this.setProperty("enablePartialMode", false);
|
|
401
|
+
}
|
|
381
402
|
}
|
|
382
403
|
get enablePartialMode() {
|
|
383
404
|
return this._data.enablePartialMode;
|
|
384
405
|
}
|
|
385
406
|
set enablePartialMode(value) {
|
|
386
|
-
this.
|
|
407
|
+
this.setProperty("enablePartialMode", value);
|
|
387
408
|
if (value) {
|
|
388
|
-
this.
|
|
389
|
-
this.
|
|
409
|
+
this.setProperty("enableStreamingMode", true);
|
|
410
|
+
this.setProperty("sceneGraph", false);
|
|
390
411
|
}
|
|
391
|
-
this.change();
|
|
392
412
|
}
|
|
393
413
|
get memoryLimit() {
|
|
394
414
|
return this._data.memoryLimit;
|
|
395
415
|
}
|
|
396
416
|
set memoryLimit(value) {
|
|
397
|
-
this.
|
|
398
|
-
this.change();
|
|
417
|
+
this.setProperty("memoryLimit", value);
|
|
399
418
|
}
|
|
400
419
|
get cuttingPlaneFillColor() {
|
|
401
|
-
|
|
420
|
+
console.warn("Options.cuttingPlaneFillColor has been deprecated since 27.5 and will be removed in a future release, use sectionFillColor instead");
|
|
421
|
+
return {
|
|
422
|
+
red: this._data.sectionFillColor.r,
|
|
423
|
+
green: this._data.sectionFillColor.g,
|
|
424
|
+
blue: this._data.sectionFillColor.b,
|
|
425
|
+
};
|
|
402
426
|
}
|
|
403
427
|
set cuttingPlaneFillColor(value) {
|
|
404
|
-
|
|
405
|
-
this.
|
|
428
|
+
console.warn("Options.cuttingPlaneFillColor has been deprecated since 27.5 and will be removed in a future release, use sectionFillColor instead");
|
|
429
|
+
this.setProperty("sectionFillColor", {
|
|
430
|
+
r: value.red,
|
|
431
|
+
g: value.green,
|
|
432
|
+
b: value.blue,
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
get enableSectionFill() {
|
|
436
|
+
return this._data.enableSectionFill;
|
|
437
|
+
}
|
|
438
|
+
set enableSectionFill(value) {
|
|
439
|
+
this.setProperty("enableSectionFill", value);
|
|
440
|
+
}
|
|
441
|
+
get sectionFillColor() {
|
|
442
|
+
return this._data.sectionFillColor;
|
|
443
|
+
}
|
|
444
|
+
set sectionFillColor(value) {
|
|
445
|
+
this.setProperty("sectionFillColor", value);
|
|
446
|
+
}
|
|
447
|
+
get sectionUseObjectColor() {
|
|
448
|
+
return this._data.sectionUseObjectColor;
|
|
449
|
+
}
|
|
450
|
+
set sectionUseObjectColor(value) {
|
|
451
|
+
this.setProperty("sectionUseObjectColor", value);
|
|
452
|
+
}
|
|
453
|
+
get enableSectionHatch() {
|
|
454
|
+
return this._data.enableSectionHatch;
|
|
455
|
+
}
|
|
456
|
+
set enableSectionHatch(value) {
|
|
457
|
+
this.setProperty("enableSectionHatch", value);
|
|
458
|
+
}
|
|
459
|
+
get sectionHatchColor() {
|
|
460
|
+
return this._data.sectionHatchColor;
|
|
461
|
+
}
|
|
462
|
+
set sectionHatchColor(value) {
|
|
463
|
+
this.setProperty("sectionHatchColor", value);
|
|
464
|
+
}
|
|
465
|
+
get sectionHatchScale() {
|
|
466
|
+
return this._data.sectionHatchScale;
|
|
467
|
+
}
|
|
468
|
+
set sectionHatchScale(value) {
|
|
469
|
+
this.setProperty("sectionHatchScale", value);
|
|
470
|
+
}
|
|
471
|
+
get enableSectionOutline() {
|
|
472
|
+
return this._data.enableSectionOutline;
|
|
473
|
+
}
|
|
474
|
+
set enableSectionOutline(value) {
|
|
475
|
+
this.setProperty("enableSectionOutline", value);
|
|
476
|
+
}
|
|
477
|
+
get sectionOutlineColor() {
|
|
478
|
+
return this._data.sectionOutlineColor;
|
|
479
|
+
}
|
|
480
|
+
set sectionOutlineColor(value) {
|
|
481
|
+
this.setProperty("sectionOutlineColor", value);
|
|
482
|
+
}
|
|
483
|
+
get sectionOutlineWidth() {
|
|
484
|
+
return this._data.sectionOutlineWidth;
|
|
485
|
+
}
|
|
486
|
+
set sectionOutlineWidth(value) {
|
|
487
|
+
this.setProperty("sectionOutlineWidth", value);
|
|
406
488
|
}
|
|
407
489
|
get edgesColor() {
|
|
408
490
|
return this._data.edgesColor;
|
|
409
491
|
}
|
|
410
492
|
set edgesColor(value) {
|
|
411
|
-
this.
|
|
412
|
-
this.change();
|
|
493
|
+
this.setProperty("edgesColor", value);
|
|
413
494
|
}
|
|
414
495
|
get facesColor() {
|
|
415
496
|
return this._data.facesColor;
|
|
416
497
|
}
|
|
417
498
|
set facesColor(value) {
|
|
418
|
-
this.
|
|
419
|
-
this.change();
|
|
499
|
+
this.setProperty("facesColor", value);
|
|
420
500
|
}
|
|
421
501
|
get edgesVisibility() {
|
|
422
502
|
return this._data.edgesVisibility;
|
|
423
503
|
}
|
|
424
504
|
set edgesVisibility(value) {
|
|
425
|
-
this.
|
|
426
|
-
this.change();
|
|
505
|
+
this.setProperty("edgesVisibility", value);
|
|
427
506
|
}
|
|
428
507
|
get edgesOverlap() {
|
|
429
508
|
return this._data.edgesOverlap;
|
|
430
509
|
}
|
|
431
510
|
set edgesOverlap(value) {
|
|
432
|
-
this.
|
|
433
|
-
this.change();
|
|
511
|
+
this.setProperty("edgesOverlap", value);
|
|
434
512
|
}
|
|
435
513
|
get facesOverlap() {
|
|
436
514
|
return this._data.facesOverlap;
|
|
437
515
|
}
|
|
438
516
|
set facesOverlap(value) {
|
|
439
|
-
this.
|
|
440
|
-
this.change();
|
|
517
|
+
this.setProperty("facesOverlap", value);
|
|
441
518
|
}
|
|
442
519
|
get facesTransparancy() {
|
|
443
520
|
return this._data.facesTransparancy;
|
|
444
521
|
}
|
|
445
522
|
set facesTransparancy(value) {
|
|
446
|
-
this.
|
|
447
|
-
this.change();
|
|
523
|
+
this.setProperty("facesTransparancy", value);
|
|
448
524
|
}
|
|
449
525
|
get enableCustomHighlight() {
|
|
450
526
|
return this._data.enableCustomHighlight;
|
|
451
527
|
}
|
|
452
528
|
set enableCustomHighlight(value) {
|
|
453
|
-
this.
|
|
454
|
-
this.change();
|
|
529
|
+
this.setProperty("enableCustomHighlight", value);
|
|
455
530
|
}
|
|
456
531
|
get sceneGraph() {
|
|
457
532
|
return this._data.sceneGraph;
|
|
458
533
|
}
|
|
459
534
|
set sceneGraph(value) {
|
|
460
|
-
this.
|
|
461
|
-
if (value)
|
|
462
|
-
this.
|
|
463
|
-
|
|
535
|
+
this.setProperty("sceneGraph", value);
|
|
536
|
+
if (value) {
|
|
537
|
+
this.setProperty("enablePartialMode", false);
|
|
538
|
+
}
|
|
464
539
|
}
|
|
465
540
|
get edgeModel() {
|
|
466
541
|
return Boolean(this._data.edgeModel);
|
|
467
542
|
}
|
|
468
543
|
set edgeModel(value) {
|
|
469
|
-
this.
|
|
470
|
-
this.change();
|
|
544
|
+
this.setProperty("edgeModel", value);
|
|
471
545
|
}
|
|
472
546
|
get reverseZoomWheel() {
|
|
473
547
|
return this._data.reverseZoomWheel;
|
|
474
548
|
}
|
|
475
549
|
set reverseZoomWheel(value) {
|
|
476
|
-
this.
|
|
477
|
-
this.change();
|
|
550
|
+
this.setProperty("reverseZoomWheel", value);
|
|
478
551
|
}
|
|
479
552
|
get enableZoomWheel() {
|
|
480
553
|
return this._data.enableZoomWheel;
|
|
481
554
|
}
|
|
482
555
|
set enableZoomWheel(value) {
|
|
483
|
-
this.
|
|
484
|
-
this.change();
|
|
556
|
+
this.setProperty("enableZoomWheel", value);
|
|
485
557
|
}
|
|
486
558
|
get enableGestures() {
|
|
487
559
|
return this._data.enableGestures;
|
|
488
560
|
}
|
|
489
561
|
set enableGestures(value) {
|
|
490
|
-
this.
|
|
491
|
-
this.change();
|
|
562
|
+
this.setProperty("enableGestures", value);
|
|
492
563
|
}
|
|
493
564
|
get geometryType() {
|
|
494
565
|
return this._data.geometryType;
|
|
495
566
|
}
|
|
496
567
|
set geometryType(value) {
|
|
497
|
-
this.
|
|
498
|
-
this.change();
|
|
568
|
+
this.setProperty("geometryType", value);
|
|
499
569
|
}
|
|
500
570
|
get rulerUnit() {
|
|
501
571
|
return this._data.rulerUnit;
|
|
502
572
|
}
|
|
503
573
|
set rulerUnit(value) {
|
|
504
|
-
this.
|
|
505
|
-
this.change();
|
|
574
|
+
this.setProperty("rulerUnit", value);
|
|
506
575
|
}
|
|
507
576
|
get rulerPrecision() {
|
|
508
577
|
return this._data.rulerPrecision;
|
|
509
578
|
}
|
|
510
579
|
set rulerPrecision(value) {
|
|
511
|
-
this.
|
|
512
|
-
this.change();
|
|
580
|
+
this.setProperty("rulerPrecision", value);
|
|
513
581
|
}
|
|
514
582
|
get cameraMode() {
|
|
515
583
|
return this._data.cameraMode || "perspective";
|
|
516
584
|
}
|
|
517
585
|
set cameraMode(value) {
|
|
518
|
-
this.
|
|
519
|
-
|
|
586
|
+
this.setProperty("cameraMode", value);
|
|
587
|
+
}
|
|
588
|
+
get snapshotMimeType() {
|
|
589
|
+
return this._data.snapshotMimeType;
|
|
590
|
+
}
|
|
591
|
+
set snapshotMimeType(value) {
|
|
592
|
+
this.setProperty("snapshotMimeType", value);
|
|
593
|
+
}
|
|
594
|
+
get snapshotQuality() {
|
|
595
|
+
return this._data.snapshotQuality;
|
|
596
|
+
}
|
|
597
|
+
set snapshotQuality(value) {
|
|
598
|
+
this.setProperty("snapshotQuality", value);
|
|
520
599
|
}
|
|
521
600
|
}
|
|
522
601
|
const CanvasEvents = [
|
|
@@ -9820,7 +9899,7 @@
|
|
|
9820
9899
|
const _whiteColor = new Color( 1, 1, 1 );
|
|
9821
9900
|
const _frustum = new Frustum();
|
|
9822
9901
|
const _frustumArray = new FrustumArray();
|
|
9823
|
-
const _box$1 = new Box3();
|
|
9902
|
+
const _box$1$1 = new Box3();
|
|
9824
9903
|
const _sphere$2 = new Sphere();
|
|
9825
9904
|
const _vector$5 = new Vector3();
|
|
9826
9905
|
const _forward$1 = new Vector3();
|
|
@@ -9983,8 +10062,8 @@
|
|
|
9983
10062
|
if ( instanceInfo[ i ].active === false ) continue;
|
|
9984
10063
|
const geometryId = instanceInfo[ i ].geometryIndex;
|
|
9985
10064
|
this.getMatrixAt( i, _matrix$1 );
|
|
9986
|
-
this.getBoundingBoxAt( geometryId, _box$1 ).applyMatrix4( _matrix$1 );
|
|
9987
|
-
boundingBox.union( _box$1 );
|
|
10065
|
+
this.getBoundingBoxAt( geometryId, _box$1$1 ).applyMatrix4( _matrix$1 );
|
|
10066
|
+
boundingBox.union( _box$1$1 );
|
|
9988
10067
|
}
|
|
9989
10068
|
}
|
|
9990
10069
|
computeBoundingSphere() {
|
|
@@ -10244,8 +10323,8 @@
|
|
|
10244
10323
|
const geometryInfo = this._geometryInfo[ geometryId ];
|
|
10245
10324
|
if ( geometryInfo.boundingSphere === null ) {
|
|
10246
10325
|
const sphere = new Sphere();
|
|
10247
|
-
this.getBoundingBoxAt( geometryId, _box$1 );
|
|
10248
|
-
_box$1.getCenter( sphere.center );
|
|
10326
|
+
this.getBoundingBoxAt( geometryId, _box$1$1 );
|
|
10327
|
+
_box$1$1.getCenter( sphere.center );
|
|
10249
10328
|
const index = geometry.index;
|
|
10250
10329
|
const position = geometry.attributes.position;
|
|
10251
10330
|
let maxRadiusSq = 0;
|
|
@@ -10713,8 +10792,8 @@
|
|
|
10713
10792
|
object: object
|
|
10714
10793
|
};
|
|
10715
10794
|
}
|
|
10716
|
-
const _start$
|
|
10717
|
-
const _end$
|
|
10795
|
+
const _start$3 = new Vector3();
|
|
10796
|
+
const _end$3 = new Vector3();
|
|
10718
10797
|
class LineSegments extends Line$1 {
|
|
10719
10798
|
constructor( geometry, material ) {
|
|
10720
10799
|
super( geometry, material );
|
|
@@ -10727,10 +10806,10 @@
|
|
|
10727
10806
|
const positionAttribute = geometry.attributes.position;
|
|
10728
10807
|
const lineDistances = [];
|
|
10729
10808
|
for ( let i = 0, l = positionAttribute.count; i < l; i += 2 ) {
|
|
10730
|
-
_start$
|
|
10731
|
-
_end$
|
|
10809
|
+
_start$3.fromBufferAttribute( positionAttribute, i );
|
|
10810
|
+
_end$3.fromBufferAttribute( positionAttribute, i + 1 );
|
|
10732
10811
|
lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ];
|
|
10733
|
-
lineDistances[ i + 1 ] = lineDistances[ i ] + _start$
|
|
10812
|
+
lineDistances[ i + 1 ] = lineDistances[ i ] + _start$3.distanceTo( _end$3 );
|
|
10734
10813
|
}
|
|
10735
10814
|
geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) );
|
|
10736
10815
|
} else {
|
|
@@ -10771,8 +10850,8 @@
|
|
|
10771
10850
|
}
|
|
10772
10851
|
}
|
|
10773
10852
|
const _inverseMatrix = new Matrix4();
|
|
10774
|
-
const _ray = new Ray();
|
|
10775
|
-
const _sphere = new Sphere();
|
|
10853
|
+
const _ray$4 = new Ray();
|
|
10854
|
+
const _sphere$7 = new Sphere();
|
|
10776
10855
|
const _position$2 = new Vector3();
|
|
10777
10856
|
class Points extends Object3D {
|
|
10778
10857
|
constructor( geometry = new BufferGeometry(), material = new PointsMaterial() ) {
|
|
@@ -10797,12 +10876,12 @@
|
|
|
10797
10876
|
const threshold = raycaster.params.Points.threshold;
|
|
10798
10877
|
const drawRange = geometry.drawRange;
|
|
10799
10878
|
if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
|
|
10800
|
-
_sphere.copy( geometry.boundingSphere );
|
|
10801
|
-
_sphere.applyMatrix4( matrixWorld );
|
|
10802
|
-
_sphere.radius += threshold;
|
|
10803
|
-
if ( raycaster.ray.intersectsSphere( _sphere ) === false ) return;
|
|
10879
|
+
_sphere$7.copy( geometry.boundingSphere );
|
|
10880
|
+
_sphere$7.applyMatrix4( matrixWorld );
|
|
10881
|
+
_sphere$7.radius += threshold;
|
|
10882
|
+
if ( raycaster.ray.intersectsSphere( _sphere$7 ) === false ) return;
|
|
10804
10883
|
_inverseMatrix.copy( matrixWorld ).invert();
|
|
10805
|
-
_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
|
|
10884
|
+
_ray$4.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
|
|
10806
10885
|
const localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
|
|
10807
10886
|
const localThresholdSq = localThreshold * localThreshold;
|
|
10808
10887
|
const index = geometry.index;
|
|
@@ -10844,10 +10923,10 @@
|
|
|
10844
10923
|
}
|
|
10845
10924
|
}
|
|
10846
10925
|
function testPoint( point, index, localThresholdSq, matrixWorld, raycaster, intersects, object ) {
|
|
10847
|
-
const rayPointDistanceSq = _ray.distanceSqToPoint( point );
|
|
10926
|
+
const rayPointDistanceSq = _ray$4.distanceSqToPoint( point );
|
|
10848
10927
|
if ( rayPointDistanceSq < localThresholdSq ) {
|
|
10849
10928
|
const intersectPoint = new Vector3();
|
|
10850
|
-
_ray.closestPointToPoint( point, intersectPoint );
|
|
10929
|
+
_ray$4.closestPointToPoint( point, intersectPoint );
|
|
10851
10930
|
intersectPoint.applyMatrix4( matrixWorld );
|
|
10852
10931
|
const distance = raycaster.ray.origin.distanceTo( intersectPoint );
|
|
10853
10932
|
if ( distance < raycaster.near || distance > raycaster.far ) return;
|
|
@@ -34348,15 +34427,15 @@ void main() {
|
|
|
34348
34427
|
const DESKTOP_SNAP_DISTANCE = 10;
|
|
34349
34428
|
const MOBILE_SNAP_DISTANCE = 50;
|
|
34350
34429
|
const _vertex = new Vector3();
|
|
34351
|
-
const _start$
|
|
34352
|
-
const _end$
|
|
34353
|
-
const _line = new Line3();
|
|
34430
|
+
const _start$2 = new Vector3();
|
|
34431
|
+
const _end$2 = new Vector3();
|
|
34432
|
+
const _line$1 = new Line3();
|
|
34354
34433
|
const _center = new Vector3();
|
|
34355
34434
|
const _projection = new Vector3();
|
|
34356
34435
|
class Snapper {
|
|
34357
|
-
constructor(camera,
|
|
34436
|
+
constructor(camera, clippingPlanes, canvas) {
|
|
34358
34437
|
this.camera = camera;
|
|
34359
|
-
this.
|
|
34438
|
+
this.clippingPlanes = clippingPlanes;
|
|
34360
34439
|
this.canvas = canvas;
|
|
34361
34440
|
this.threshold = 0.0001;
|
|
34362
34441
|
this.raycaster = new Raycaster();
|
|
@@ -34387,7 +34466,7 @@ void main() {
|
|
|
34387
34466
|
};
|
|
34388
34467
|
let intersects = this.raycaster.intersectObjects(objects, recursive);
|
|
34389
34468
|
if (clip) {
|
|
34390
|
-
const clippingPlanes = this.
|
|
34469
|
+
const clippingPlanes = this.clippingPlanes;
|
|
34391
34470
|
clippingPlanes.forEach((plane) => {
|
|
34392
34471
|
intersects = intersects.filter((intersect) => plane.distanceToPoint(intersect.point) >= 0);
|
|
34393
34472
|
});
|
|
@@ -34418,7 +34497,7 @@ void main() {
|
|
|
34418
34497
|
const object = intersections[0].object;
|
|
34419
34498
|
const intersectionPoint = intersections[0].point;
|
|
34420
34499
|
const localPoint = object.worldToLocal(intersectionPoint.clone());
|
|
34421
|
-
let snapPoint;
|
|
34500
|
+
let snapPoint = undefined;
|
|
34422
34501
|
let snapDistance = this.getDetectRadius(intersectionPoint);
|
|
34423
34502
|
const geometry = object.geometry;
|
|
34424
34503
|
const positions = geometry.attributes.position.array;
|
|
@@ -34439,17 +34518,17 @@ void main() {
|
|
|
34439
34518
|
}
|
|
34440
34519
|
const edgePositions = edges.attributes.position.array;
|
|
34441
34520
|
for (let i = 0; i < edgePositions.length; i += 6) {
|
|
34442
|
-
_start$
|
|
34443
|
-
_end$
|
|
34444
|
-
_line.set(_start$
|
|
34445
|
-
_line.getCenter(_center);
|
|
34521
|
+
_start$2.set(edgePositions[i], edgePositions[i + 1], edgePositions[i + 2]);
|
|
34522
|
+
_end$2.set(edgePositions[i + 3], edgePositions[i + 4], edgePositions[i + 5]);
|
|
34523
|
+
_line$1.set(_start$2, _end$2);
|
|
34524
|
+
_line$1.getCenter(_center);
|
|
34446
34525
|
const centerDistance = _center.distanceTo(localPoint);
|
|
34447
34526
|
if (centerDistance < snapDistance) {
|
|
34448
34527
|
snapDistance = centerDistance;
|
|
34449
34528
|
snapPoint = _center.clone();
|
|
34450
34529
|
continue;
|
|
34451
34530
|
}
|
|
34452
|
-
_line.closestPointToPoint(localPoint, true, _projection);
|
|
34531
|
+
_line$1.closestPointToPoint(localPoint, true, _projection);
|
|
34453
34532
|
const lineDistance = _projection.distanceTo(localPoint);
|
|
34454
34533
|
if (lineDistance < snapDistance) {
|
|
34455
34534
|
snapDistance = lineDistance;
|
|
@@ -34474,7 +34553,7 @@ void main() {
|
|
|
34474
34553
|
this.orbit.object = this.viewer.camera;
|
|
34475
34554
|
this.orbit.update();
|
|
34476
34555
|
};
|
|
34477
|
-
this.
|
|
34556
|
+
this.updateZoomSpeed = ({ data: options }) => {
|
|
34478
34557
|
this.orbit.zoomSpeed = Math.abs(this.orbit.zoomSpeed) * (options.reverseZoomWheel ? -1 : 1);
|
|
34479
34558
|
};
|
|
34480
34559
|
this.controlsStart = () => {
|
|
@@ -34533,7 +34612,7 @@ void main() {
|
|
|
34533
34612
|
this.viewer.addEventListener("zoom", this.updateControls);
|
|
34534
34613
|
this.viewer.addEventListener("drawviewpoint", this.updateControls);
|
|
34535
34614
|
this.viewer.addEventListener("changecameramode", this.updateControlsCamera);
|
|
34536
|
-
this.viewer.addEventListener("optionschange", this.
|
|
34615
|
+
this.viewer.addEventListener("optionschange", this.updateZoomSpeed);
|
|
34537
34616
|
this.viewer.addEventListener("contextmenu", this.stopContextMenu);
|
|
34538
34617
|
this.updateControls();
|
|
34539
34618
|
this.updateControlsCamera();
|
|
@@ -34545,7 +34624,7 @@ void main() {
|
|
|
34545
34624
|
this.viewer.removeEventListener("zoom", this.updateControls);
|
|
34546
34625
|
this.viewer.removeEventListener("drawviewpoint", this.updateControls);
|
|
34547
34626
|
this.viewer.removeEventListener("changecameramode", this.updateControlsCamera);
|
|
34548
|
-
this.viewer.removeEventListener("optionschange", this.
|
|
34627
|
+
this.viewer.removeEventListener("optionschange", this.updateZoomSpeed);
|
|
34549
34628
|
this.viewer.removeEventListener("contextmenu", this.stopContextMenu);
|
|
34550
34629
|
this.orbit.removeEventListener("start", this.controlsStart);
|
|
34551
34630
|
this.orbit.removeEventListener("change", this.controlsChange);
|
|
@@ -34557,13 +34636,17 @@ void main() {
|
|
|
34557
34636
|
constructor(viewer) {
|
|
34558
34637
|
super(viewer);
|
|
34559
34638
|
this.helpers = [];
|
|
34560
|
-
this.activeHelper =
|
|
34639
|
+
this.activeHelper = undefined;
|
|
34640
|
+
this.transformUpdate = () => {
|
|
34641
|
+
this.viewer.update();
|
|
34642
|
+
};
|
|
34561
34643
|
this.transformChange = () => {
|
|
34562
34644
|
if (!this.activeHelper)
|
|
34563
34645
|
return;
|
|
34564
34646
|
const plane = this.activeHelper.plane;
|
|
34565
34647
|
plane.normal.copy(new Vector3(0, 0, -1)).applyQuaternion(this.activeHelper.quaternion);
|
|
34566
34648
|
plane.constant = -this.activeHelper.position.dot(plane.normal);
|
|
34649
|
+
this.viewer.emitEvent({ type: "changecuttingplanes" });
|
|
34567
34650
|
this.viewer.update();
|
|
34568
34651
|
this.changed = true;
|
|
34569
34652
|
};
|
|
@@ -34575,25 +34658,29 @@ void main() {
|
|
|
34575
34658
|
this.orbit.enabled = !event.value;
|
|
34576
34659
|
this.translate.enabled = !event.value;
|
|
34577
34660
|
};
|
|
34578
|
-
this.
|
|
34661
|
+
this.syncHelpers = () => {
|
|
34579
34662
|
const extentsSize = this.viewer.extents.getSize(new Vector3()).length() || 1;
|
|
34580
|
-
this.
|
|
34663
|
+
const extentsCenter = this.viewer.extents.getCenter(new Vector3());
|
|
34664
|
+
this.helpers.forEach((planeHelper) => {
|
|
34665
|
+
planeHelper.size = extentsSize;
|
|
34666
|
+
planeHelper.position.copy(planeHelper.plane.projectPoint(extentsCenter, new Vector3()));
|
|
34667
|
+
});
|
|
34581
34668
|
this.viewer.update();
|
|
34582
34669
|
};
|
|
34583
|
-
this.updateTransformCamera = () => {
|
|
34584
|
-
this.translate.camera = this.viewer.camera;
|
|
34585
|
-
this.rotate.camera = this.viewer.camera;
|
|
34586
|
-
this.snapper.camera = this.viewer.camera;
|
|
34587
|
-
};
|
|
34588
34670
|
this.clearHelpers = () => {
|
|
34589
34671
|
this.setActiveHelper();
|
|
34590
34672
|
this.helpers.forEach((helper) => {
|
|
34591
34673
|
helper.removeFromParent();
|
|
34592
34674
|
helper.dispose();
|
|
34593
34675
|
});
|
|
34594
|
-
this.helpers =
|
|
34676
|
+
this.helpers.length = 0;
|
|
34595
34677
|
this.viewer.update();
|
|
34596
34678
|
};
|
|
34679
|
+
this.updateTransformCamera = () => {
|
|
34680
|
+
this.translate.camera = this.viewer.camera;
|
|
34681
|
+
this.rotate.camera = this.viewer.camera;
|
|
34682
|
+
this.snapper.camera = this.viewer.camera;
|
|
34683
|
+
};
|
|
34597
34684
|
this.onKeyDown = (event) => {
|
|
34598
34685
|
if (event.key === "Shift")
|
|
34599
34686
|
this.rotate.setRotationSnap(Math.PI / 4);
|
|
@@ -34637,12 +34724,9 @@ void main() {
|
|
|
34637
34724
|
this.transformChange();
|
|
34638
34725
|
event.stopPropagation();
|
|
34639
34726
|
};
|
|
34640
|
-
|
|
34641
|
-
viewer.renderer.clippingPlanes = [];
|
|
34642
|
-
this.clippingPlanes = viewer.renderer.clippingPlanes;
|
|
34643
|
-
this.clippingPlanes.forEach((plane) => this.addHelper(plane));
|
|
34727
|
+
viewer.clippingPlanes.forEach((plane) => this.addHelper(plane));
|
|
34644
34728
|
const extentsSize = viewer.extents.getSize(new Vector3()).length() || 1;
|
|
34645
|
-
this.snapper = new Snapper(viewer.camera, viewer.
|
|
34729
|
+
this.snapper = new Snapper(viewer.camera, viewer.clippingPlanes, viewer.canvas);
|
|
34646
34730
|
this.snapper.threshold = extentsSize / 10000;
|
|
34647
34731
|
this.downPosition = new Vector2();
|
|
34648
34732
|
this.position0 = new Vector3();
|
|
@@ -34653,7 +34737,8 @@ void main() {
|
|
|
34653
34737
|
this.translate.showX = false;
|
|
34654
34738
|
this.translate.showY = false;
|
|
34655
34739
|
this.translate.showZ = true;
|
|
34656
|
-
this.translate.addEventListener("change", this.
|
|
34740
|
+
this.translate.addEventListener("change", this.transformUpdate);
|
|
34741
|
+
this.translate.addEventListener("objectChange", this.transformChange);
|
|
34657
34742
|
this.translate.addEventListener("dragging-changed", this.translateDrag);
|
|
34658
34743
|
this.viewer.helpers.add(this.translate.getHelper());
|
|
34659
34744
|
this.rotate = new TransformControls(viewer.camera, viewer.canvas);
|
|
@@ -34662,15 +34747,18 @@ void main() {
|
|
|
34662
34747
|
this.rotate.showX = true;
|
|
34663
34748
|
this.rotate.showY = true;
|
|
34664
34749
|
this.rotate.showZ = false;
|
|
34665
|
-
this.rotate.addEventListener("change", this.
|
|
34750
|
+
this.rotate.addEventListener("change", this.transformUpdate);
|
|
34751
|
+
this.rotate.addEventListener("objectChange", this.transformChange);
|
|
34666
34752
|
this.rotate.addEventListener("dragging-changed", this.rotateDrag);
|
|
34667
34753
|
this.viewer.helpers.add(this.rotate.getHelper());
|
|
34668
34754
|
this.setActiveHelper(this.helpers[this.helpers.length - 1]);
|
|
34669
|
-
this.viewer.addEventListener("explode", this.
|
|
34670
|
-
this.viewer.addEventListener("
|
|
34671
|
-
this.viewer.addEventListener("
|
|
34672
|
-
this.viewer.addEventListener("
|
|
34755
|
+
this.viewer.addEventListener("explode", this.syncHelpers);
|
|
34756
|
+
this.viewer.addEventListener("hide", this.syncHelpers);
|
|
34757
|
+
this.viewer.addEventListener("isolate", this.syncHelpers);
|
|
34758
|
+
this.viewer.addEventListener("show", this.syncHelpers);
|
|
34759
|
+
this.viewer.addEventListener("showall", this.syncHelpers);
|
|
34673
34760
|
this.viewer.addEventListener("clearslices", this.clearHelpers);
|
|
34761
|
+
this.viewer.addEventListener("changecameramode", this.updateTransformCamera);
|
|
34674
34762
|
this.viewer.canvas.addEventListener("pointerdown", this.onPointerDown, true);
|
|
34675
34763
|
this.viewer.canvas.addEventListener("pointerup", this.onPointerUp, true);
|
|
34676
34764
|
this.viewer.canvas.addEventListener("pointercancel", this.onPointerCancel, true);
|
|
@@ -34680,23 +34768,27 @@ void main() {
|
|
|
34680
34768
|
this.viewer.update();
|
|
34681
34769
|
}
|
|
34682
34770
|
dispose() {
|
|
34683
|
-
this.viewer.removeEventListener("explode", this.
|
|
34684
|
-
this.viewer.removeEventListener("
|
|
34685
|
-
this.viewer.removeEventListener("
|
|
34686
|
-
this.viewer.removeEventListener("
|
|
34771
|
+
this.viewer.removeEventListener("explode", this.syncHelpers);
|
|
34772
|
+
this.viewer.removeEventListener("hide", this.syncHelpers);
|
|
34773
|
+
this.viewer.removeEventListener("isolate", this.syncHelpers);
|
|
34774
|
+
this.viewer.removeEventListener("show", this.syncHelpers);
|
|
34775
|
+
this.viewer.removeEventListener("showall", this.syncHelpers);
|
|
34687
34776
|
this.viewer.removeEventListener("clearslices", this.clearHelpers);
|
|
34777
|
+
this.viewer.removeEventListener("changecameramode", this.updateTransformCamera);
|
|
34688
34778
|
this.viewer.canvas.removeEventListener("pointerdown", this.onPointerDown, true);
|
|
34689
34779
|
this.viewer.canvas.removeEventListener("pointerup", this.onPointerUp, true);
|
|
34690
34780
|
this.viewer.canvas.removeEventListener("pointercancel", this.onPointerCancel, true);
|
|
34691
34781
|
this.viewer.canvas.removeEventListener("dblclick", this.onDoubleClick, true);
|
|
34692
34782
|
window.removeEventListener("keydown", this.onKeyDown);
|
|
34693
34783
|
window.removeEventListener("keyup", this.onKeyUp);
|
|
34694
|
-
this.translate.removeEventListener("change", this.
|
|
34784
|
+
this.translate.removeEventListener("change", this.transformUpdate);
|
|
34785
|
+
this.translate.removeEventListener("objectChange", this.transformChange);
|
|
34695
34786
|
this.translate.removeEventListener("dragging-changed", this.translateDrag);
|
|
34696
34787
|
this.translate.getHelper().removeFromParent();
|
|
34697
34788
|
this.translate.detach();
|
|
34698
34789
|
this.translate.dispose();
|
|
34699
|
-
this.rotate.removeEventListener("change", this.
|
|
34790
|
+
this.rotate.removeEventListener("change", this.transformUpdate);
|
|
34791
|
+
this.rotate.removeEventListener("objectChange", this.transformChange);
|
|
34700
34792
|
this.rotate.removeEventListener("dragging-changed", this.rotateDrag);
|
|
34701
34793
|
this.rotate.getHelper().removeFromParent();
|
|
34702
34794
|
this.rotate.detach();
|
|
@@ -34705,8 +34797,8 @@ void main() {
|
|
|
34705
34797
|
helper.removeFromParent();
|
|
34706
34798
|
helper.dispose();
|
|
34707
34799
|
});
|
|
34708
|
-
this.helpers =
|
|
34709
|
-
this.activeHelper =
|
|
34800
|
+
this.helpers.length = 0;
|
|
34801
|
+
this.activeHelper = undefined;
|
|
34710
34802
|
super.dispose();
|
|
34711
34803
|
}
|
|
34712
34804
|
addHelper(plane) {
|
|
@@ -34758,9 +34850,10 @@ void main() {
|
|
|
34758
34850
|
const extentsCenter = this.viewer.extents.getCenter(new Vector3());
|
|
34759
34851
|
const constant = -extentsCenter.dot(normal);
|
|
34760
34852
|
const plane = new Plane(normal, constant);
|
|
34761
|
-
this.clippingPlanes.push(plane);
|
|
34853
|
+
this.viewer.clippingPlanes.push(plane);
|
|
34762
34854
|
const helper = this.addHelper(plane);
|
|
34763
34855
|
this.setActiveHelper(helper);
|
|
34856
|
+
this.viewer.emitEvent({ type: "changecuttingplanes" });
|
|
34764
34857
|
}
|
|
34765
34858
|
addPlaneX() {
|
|
34766
34859
|
this.addPlane(new Vector3(-1, 0, 0));
|
|
@@ -34775,13 +34868,14 @@ void main() {
|
|
|
34775
34868
|
if (!this.activeHelper)
|
|
34776
34869
|
return;
|
|
34777
34870
|
const helper = this.activeHelper;
|
|
34778
|
-
const index = this.clippingPlanes.indexOf(helper.plane);
|
|
34871
|
+
const index = this.viewer.clippingPlanes.indexOf(helper.plane);
|
|
34779
34872
|
if (index !== -1)
|
|
34780
|
-
this.clippingPlanes.splice(index, 1);
|
|
34873
|
+
this.viewer.clippingPlanes.splice(index, 1);
|
|
34781
34874
|
this.helpers = this.helpers.filter((x) => x !== helper);
|
|
34782
34875
|
helper.removeFromParent();
|
|
34783
34876
|
helper.dispose();
|
|
34784
34877
|
this.setActiveHelper(this.helpers[this.helpers.length - 1]);
|
|
34878
|
+
this.viewer.emitEvent({ type: "changecuttingplanes" });
|
|
34785
34879
|
}
|
|
34786
34880
|
}
|
|
34787
34881
|
|
|
@@ -34975,7 +35069,7 @@ void main() {
|
|
|
34975
35069
|
this.line = new MeasureLine(this.overlay, this.scale, this.units, this.precision);
|
|
34976
35070
|
this.overlay.addLine(this.line);
|
|
34977
35071
|
const extentsSize = this.viewer.extents.getSize(new Vector3()).length() || 1;
|
|
34978
|
-
this.snapper = new Snapper(viewer.camera, viewer.
|
|
35072
|
+
this.snapper = new Snapper(viewer.camera, viewer.clippingPlanes, viewer.canvas);
|
|
34979
35073
|
this.snapper.threshold = extentsSize / 10000;
|
|
34980
35074
|
this.objects = [];
|
|
34981
35075
|
this.updateObjects();
|
|
@@ -36254,8 +36348,8 @@ void main() {
|
|
|
36254
36348
|
commands.registerCommand("right", (viewer) => setDefaultViewPosition(viewer, "right"));
|
|
36255
36349
|
commands.registerCommand("front", (viewer) => setDefaultViewPosition(viewer, "front"));
|
|
36256
36350
|
commands.registerCommand("back", (viewer) => setDefaultViewPosition(viewer, "back"));
|
|
36257
|
-
commands.registerCommand("sw", (viewer) => setDefaultViewPosition(viewer, "sw"));
|
|
36258
36351
|
commands.registerCommand("se", (viewer) => setDefaultViewPosition(viewer, "se"));
|
|
36352
|
+
commands.registerCommand("sw", (viewer) => setDefaultViewPosition(viewer, "sw"));
|
|
36259
36353
|
commands.registerCommand("ne", (viewer) => setDefaultViewPosition(viewer, "ne"));
|
|
36260
36354
|
commands.registerCommand("nw", (viewer) => setDefaultViewPosition(viewer, "nw"));
|
|
36261
36355
|
commands.registerCommandAlias("clearMarkup", "clearOverlay");
|
|
@@ -36278,6 +36372,7 @@ void main() {
|
|
|
36278
36372
|
this.syncOptions = () => {
|
|
36279
36373
|
this.backgroundColor.setHex(0xffffff);
|
|
36280
36374
|
this.viewer.renderer.setClearColor(this.backgroundColor);
|
|
36375
|
+
this.viewer.update();
|
|
36281
36376
|
};
|
|
36282
36377
|
this.viewer = viewer;
|
|
36283
36378
|
this.backgroundColor = new Color(0xffffff);
|
|
@@ -36287,13 +36382,13 @@ void main() {
|
|
|
36287
36382
|
}
|
|
36288
36383
|
dispose() {
|
|
36289
36384
|
this.viewer.removeEventListener("optionschange", this.syncOptions);
|
|
36290
|
-
this.viewer.scene.background =
|
|
36385
|
+
this.viewer.scene.background = null;
|
|
36291
36386
|
}
|
|
36292
36387
|
}
|
|
36293
36388
|
|
|
36294
36389
|
class CameraComponent {
|
|
36295
36390
|
constructor(viewer) {
|
|
36296
|
-
this.
|
|
36391
|
+
this.syncOptions = () => {
|
|
36297
36392
|
this.switchCameraMode(this.viewer.options.cameraMode);
|
|
36298
36393
|
};
|
|
36299
36394
|
this.geometryEnd = () => {
|
|
@@ -36324,13 +36419,13 @@ void main() {
|
|
|
36324
36419
|
};
|
|
36325
36420
|
this.viewer = viewer;
|
|
36326
36421
|
this.viewer.addEventListener("databasechunk", this.geometryEnd);
|
|
36327
|
-
this.viewer.addEventListener("optionschange", this.
|
|
36328
|
-
this.viewer.addEventListener("initialize", this.
|
|
36422
|
+
this.viewer.addEventListener("optionschange", this.syncOptions);
|
|
36423
|
+
this.viewer.addEventListener("initialize", this.syncOptions);
|
|
36329
36424
|
}
|
|
36330
36425
|
dispose() {
|
|
36331
36426
|
this.viewer.removeEventListener("databasechunk", this.geometryEnd);
|
|
36332
|
-
this.viewer.removeEventListener("optionschange", this.
|
|
36333
|
-
this.viewer.removeEventListener("initialize", this.
|
|
36427
|
+
this.viewer.removeEventListener("optionschange", this.syncOptions);
|
|
36428
|
+
this.viewer.removeEventListener("initialize", this.syncOptions);
|
|
36334
36429
|
}
|
|
36335
36430
|
getCameraMode(camera) {
|
|
36336
36431
|
return camera.isOrthographicCamera ? "orthographic" : "perspective";
|
|
@@ -36353,7 +36448,6 @@ void main() {
|
|
|
36353
36448
|
camera.updateProjectionMatrix();
|
|
36354
36449
|
this.viewer.camera = camera;
|
|
36355
36450
|
this.viewer.renderPass.camera = camera;
|
|
36356
|
-
this.viewer.helpersPass.camera = camera;
|
|
36357
36451
|
this.viewer.ssaaRenderPass.camera = camera;
|
|
36358
36452
|
this.viewer.update();
|
|
36359
36453
|
}
|
|
@@ -36364,7 +36458,7 @@ void main() {
|
|
|
36364
36458
|
if (mode === this.getCameraMode(currentCamera))
|
|
36365
36459
|
return;
|
|
36366
36460
|
const target = this.viewer.target.clone();
|
|
36367
|
-
let camera;
|
|
36461
|
+
let camera = null;
|
|
36368
36462
|
if (currentCamera.isOrthographicCamera) {
|
|
36369
36463
|
const fov = currentCamera.userData.fov || 45;
|
|
36370
36464
|
const fieldHeight = (currentCamera.top - currentCamera.bottom) / currentCamera.zoom;
|
|
@@ -36497,7 +36591,7 @@ void main() {
|
|
|
36497
36591
|
console.log("WebGL Renderer:", this.viewer.info.system.webglRenderer);
|
|
36498
36592
|
console.log("WebGL Vendor:", this.viewer.info.system.webglVendor);
|
|
36499
36593
|
this.resize();
|
|
36500
|
-
this.
|
|
36594
|
+
this.syncOptions({ data: this.viewer.options });
|
|
36501
36595
|
};
|
|
36502
36596
|
this.clear = () => {
|
|
36503
36597
|
this.viewer.info.performance.timeToFirstRender = 0;
|
|
@@ -36521,7 +36615,7 @@ void main() {
|
|
|
36521
36615
|
this.viewer.info.memory.totalEstimatedGpuBytes = 0;
|
|
36522
36616
|
this.viewer.info.memory.usedJSHeapSize = 0;
|
|
36523
36617
|
};
|
|
36524
|
-
this.
|
|
36618
|
+
this.syncOptions = ({ data: options }) => {
|
|
36525
36619
|
if (options.antialiasing === false)
|
|
36526
36620
|
this.viewer.info.render.antialiasing = "";
|
|
36527
36621
|
else if (options.antialiasing === true)
|
|
@@ -36596,7 +36690,7 @@ void main() {
|
|
|
36596
36690
|
this.frames = 0;
|
|
36597
36691
|
this.viewer.addEventListener("initialize", this.initialize);
|
|
36598
36692
|
this.viewer.addEventListener("clear", this.clear);
|
|
36599
|
-
this.viewer.addEventListener("optionschange", this.
|
|
36693
|
+
this.viewer.addEventListener("optionschange", this.syncOptions);
|
|
36600
36694
|
this.viewer.addEventListener("geometrystart", this.geometryStart);
|
|
36601
36695
|
this.viewer.addEventListener("databasechunk", this.databaseChunk);
|
|
36602
36696
|
this.viewer.addEventListener("geometryend", this.geometryEnd);
|
|
@@ -36607,7 +36701,7 @@ void main() {
|
|
|
36607
36701
|
dispose() {
|
|
36608
36702
|
this.viewer.removeEventListener("initialize", this.initialize);
|
|
36609
36703
|
this.viewer.removeEventListener("clear", this.clear);
|
|
36610
|
-
this.viewer.removeEventListener("optionschange", this.
|
|
36704
|
+
this.viewer.removeEventListener("optionschange", this.syncOptions);
|
|
36611
36705
|
this.viewer.removeEventListener("geometrystart", this.geometryStart);
|
|
36612
36706
|
this.viewer.removeEventListener("databasechunk", this.databaseChunk);
|
|
36613
36707
|
this.viewer.removeEventListener("geometryend", this.geometryEnd);
|
|
@@ -36655,7 +36749,6 @@ void main() {
|
|
|
36655
36749
|
}
|
|
36656
36750
|
dispose() {
|
|
36657
36751
|
this.mutationObserver.disconnect();
|
|
36658
|
-
this.mutationObserver = undefined;
|
|
36659
36752
|
}
|
|
36660
36753
|
}
|
|
36661
36754
|
|
|
@@ -36674,7 +36767,7 @@ void main() {
|
|
|
36674
36767
|
}
|
|
36675
36768
|
}
|
|
36676
36769
|
|
|
36677
|
-
const _box = new Box3();
|
|
36770
|
+
const _box$1 = new Box3();
|
|
36678
36771
|
const _vector = new Vector3();
|
|
36679
36772
|
class LineSegmentsGeometry extends InstancedBufferGeometry {
|
|
36680
36773
|
constructor() {
|
|
@@ -36756,8 +36849,8 @@ void main() {
|
|
|
36756
36849
|
const end = this.attributes.instanceEnd;
|
|
36757
36850
|
if ( start !== undefined && end !== undefined ) {
|
|
36758
36851
|
this.boundingBox.setFromBufferAttribute( start );
|
|
36759
|
-
_box.setFromBufferAttribute( end );
|
|
36760
|
-
this.boundingBox.union( _box );
|
|
36852
|
+
_box$1.setFromBufferAttribute( end );
|
|
36853
|
+
this.boundingBox.union( _box$1 );
|
|
36761
36854
|
}
|
|
36762
36855
|
}
|
|
36763
36856
|
computeBoundingSphere() {
|
|
@@ -37279,9 +37372,9 @@ void main() {
|
|
|
37279
37372
|
}
|
|
37280
37373
|
}
|
|
37281
37374
|
|
|
37282
|
-
const _start = new Vector3();
|
|
37283
|
-
const _end = new Vector3();
|
|
37284
|
-
const _viewport = new Vector4();
|
|
37375
|
+
const _start$1 = new Vector3();
|
|
37376
|
+
const _end$1 = new Vector3();
|
|
37377
|
+
const _viewport$1 = new Vector4();
|
|
37285
37378
|
class Wireframe extends Mesh {
|
|
37286
37379
|
constructor( geometry = new LineSegmentsGeometry(), material = new LineMaterial( { color: Math.random() * 0xffffff } ) ) {
|
|
37287
37380
|
super( geometry, material );
|
|
@@ -37294,10 +37387,10 @@ void main() {
|
|
|
37294
37387
|
const instanceEnd = geometry.attributes.instanceEnd;
|
|
37295
37388
|
const lineDistances = new Float32Array( 2 * instanceStart.count );
|
|
37296
37389
|
for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
|
|
37297
|
-
_start.fromBufferAttribute( instanceStart, i );
|
|
37298
|
-
_end.fromBufferAttribute( instanceEnd, i );
|
|
37390
|
+
_start$1.fromBufferAttribute( instanceStart, i );
|
|
37391
|
+
_end$1.fromBufferAttribute( instanceEnd, i );
|
|
37299
37392
|
lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
|
|
37300
|
-
lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
|
|
37393
|
+
lineDistances[ j + 1 ] = lineDistances[ j ] + _start$1.distanceTo( _end$1 );
|
|
37301
37394
|
}
|
|
37302
37395
|
const instanceDistanceBuffer = new InstancedInterleavedBuffer( lineDistances, 2, 1 );
|
|
37303
37396
|
geometry.setAttribute( 'instanceDistanceStart', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) );
|
|
@@ -37307,8 +37400,8 @@ void main() {
|
|
|
37307
37400
|
onBeforeRender( renderer ) {
|
|
37308
37401
|
const uniforms = this.material.uniforms;
|
|
37309
37402
|
if ( uniforms && uniforms.resolution ) {
|
|
37310
|
-
renderer.getViewport( _viewport );
|
|
37311
|
-
this.material.uniforms.resolution.value.set( _viewport.z, _viewport.w );
|
|
37403
|
+
renderer.getViewport( _viewport$1 );
|
|
37404
|
+
this.material.uniforms.resolution.value.set( _viewport$1.z, _viewport$1.w );
|
|
37312
37405
|
}
|
|
37313
37406
|
}
|
|
37314
37407
|
}
|
|
@@ -37384,28 +37477,38 @@ void main() {
|
|
|
37384
37477
|
polygonOffset: true,
|
|
37385
37478
|
polygonOffsetFactor: 1,
|
|
37386
37479
|
polygonOffsetUnits: 1,
|
|
37480
|
+
clippingPlanes: this.viewer.clippingPlanes,
|
|
37387
37481
|
});
|
|
37388
37482
|
this.edgesMaterial = new LineMaterial({
|
|
37389
37483
|
linewidth: 1.5,
|
|
37390
37484
|
resolution: new Vector2(window.innerWidth, window.innerHeight),
|
|
37485
|
+
clippingPlanes: this.viewer.clippingPlanes,
|
|
37391
37486
|
});
|
|
37392
37487
|
this.lineMaterial = new LineBasicMaterial({
|
|
37393
37488
|
transparent: true,
|
|
37394
37489
|
depthTest: true,
|
|
37395
37490
|
depthWrite: true,
|
|
37491
|
+
clippingPlanes: this.viewer.clippingPlanes,
|
|
37396
37492
|
});
|
|
37397
37493
|
this.lineGlowMaterial = new LineMaterial({
|
|
37398
37494
|
linewidth: 1.5,
|
|
37399
37495
|
transparent: true,
|
|
37400
37496
|
opacity: 0.8,
|
|
37401
37497
|
resolution: new Vector2(window.innerWidth, window.innerHeight),
|
|
37498
|
+
clippingPlanes: this.viewer.clippingPlanes,
|
|
37402
37499
|
});
|
|
37403
37500
|
this.syncHighlightColors();
|
|
37404
37501
|
};
|
|
37405
|
-
this.
|
|
37502
|
+
this.syncOptions = () => {
|
|
37406
37503
|
this.syncHighlightColors();
|
|
37407
37504
|
this.viewer.update();
|
|
37408
37505
|
};
|
|
37506
|
+
this.viewerResize = (event) => {
|
|
37507
|
+
var _a, _b, _c;
|
|
37508
|
+
(_a = this.renderTarget) === null || _a === void 0 ? void 0 : _a.setSize(event.width, event.height);
|
|
37509
|
+
(_b = this.edgesMaterial) === null || _b === void 0 ? void 0 : _b.resolution.set(event.width, event.height);
|
|
37510
|
+
(_c = this.lineGlowMaterial) === null || _c === void 0 ? void 0 : _c.resolution.set(event.width, event.height);
|
|
37511
|
+
};
|
|
37409
37512
|
this.viewer = viewer;
|
|
37410
37513
|
const gl2 = viewer.canvas.getContext("webgl2");
|
|
37411
37514
|
if (gl2) {
|
|
@@ -37418,13 +37521,13 @@ void main() {
|
|
|
37418
37521
|
});
|
|
37419
37522
|
}
|
|
37420
37523
|
this.viewer.addEventListener("databasechunk", this.geometryEnd);
|
|
37421
|
-
this.viewer.addEventListener("optionschange", this.
|
|
37524
|
+
this.viewer.addEventListener("optionschange", this.syncOptions);
|
|
37422
37525
|
this.viewer.addEventListener("resize", this.viewerResize);
|
|
37423
37526
|
this.geometryEnd();
|
|
37424
37527
|
}
|
|
37425
37528
|
dispose() {
|
|
37426
37529
|
this.viewer.removeEventListener("databasechunk", this.geometryEnd);
|
|
37427
|
-
this.viewer.removeEventListener("optionschange", this.
|
|
37530
|
+
this.viewer.removeEventListener("optionschange", this.syncOptions);
|
|
37428
37531
|
this.viewer.removeEventListener("resize", this.viewerResize);
|
|
37429
37532
|
}
|
|
37430
37533
|
highlight(objects) {
|
|
@@ -37503,12 +37606,6 @@ void main() {
|
|
|
37503
37606
|
wireframe.visible = edgesVisibility;
|
|
37504
37607
|
});
|
|
37505
37608
|
}
|
|
37506
|
-
viewerResize(event) {
|
|
37507
|
-
var _a, _b, _c;
|
|
37508
|
-
(_a = this.renderTarget) === null || _a === void 0 ? void 0 : _a.setSize(event.width, event.height);
|
|
37509
|
-
(_b = this.edgesMaterial) === null || _b === void 0 ? void 0 : _b.resolution.set(event.width, event.height);
|
|
37510
|
-
(_c = this.lineGlowMaterial) === null || _c === void 0 ? void 0 : _c.resolution.set(event.width, event.height);
|
|
37511
|
-
}
|
|
37512
37609
|
}
|
|
37513
37610
|
|
|
37514
37611
|
class SelectionComponent {
|
|
@@ -37525,7 +37622,7 @@ void main() {
|
|
|
37525
37622
|
if (upPosition.distanceTo(this.downPosition) !== 0)
|
|
37526
37623
|
return;
|
|
37527
37624
|
const extentsSize = this.viewer.extents.getSize(new Vector3()).length() || 1;
|
|
37528
|
-
const snapper = new Snapper(this.viewer.camera, this.viewer.
|
|
37625
|
+
const snapper = new Snapper(this.viewer.camera, this.viewer.clippingPlanes, this.viewer.canvas);
|
|
37529
37626
|
snapper.threshold = extentsSize / 10000;
|
|
37530
37627
|
let intersections = [];
|
|
37531
37628
|
this.viewer.models.forEach((model) => {
|
|
@@ -37622,9 +37719,1032 @@ void main() {
|
|
|
37622
37719
|
}
|
|
37623
37720
|
}
|
|
37624
37721
|
|
|
37722
|
+
class ClippingPlaneComponent {
|
|
37723
|
+
constructor(viewer) {
|
|
37724
|
+
this.applyClippingPlanes = () => {
|
|
37725
|
+
this.viewer.models.forEach((model) => {
|
|
37726
|
+
model.scene.traverse((object) => {
|
|
37727
|
+
if (object.material) {
|
|
37728
|
+
const materials = Array.isArray(object.material) ? object.material : [object.material];
|
|
37729
|
+
materials.forEach((material) => (material.clippingPlanes = this.viewer.clippingPlanes));
|
|
37730
|
+
}
|
|
37731
|
+
});
|
|
37732
|
+
});
|
|
37733
|
+
};
|
|
37734
|
+
this.viewer = viewer;
|
|
37735
|
+
this.viewer.addEventListener("geometryend", this.applyClippingPlanes);
|
|
37736
|
+
this.viewer.addEventListener("changecuttingplanes", this.applyClippingPlanes);
|
|
37737
|
+
}
|
|
37738
|
+
dispose() {
|
|
37739
|
+
this.viewer.removeEventListener("geometryend", this.applyClippingPlanes);
|
|
37740
|
+
this.viewer.removeEventListener("changecuttingplanes", this.applyClippingPlanes);
|
|
37741
|
+
}
|
|
37742
|
+
}
|
|
37743
|
+
|
|
37744
|
+
const _viewport = new Vector4();
|
|
37745
|
+
const _start = new Vector3();
|
|
37746
|
+
const _end = new Vector3();
|
|
37747
|
+
const _start4 = new Vector4();
|
|
37748
|
+
const _end4 = new Vector4();
|
|
37749
|
+
const _ssOrigin = new Vector4();
|
|
37750
|
+
const _ssOrigin3 = new Vector3();
|
|
37751
|
+
const _mvMatrix = new Matrix4();
|
|
37752
|
+
const _line = new Line3();
|
|
37753
|
+
const _closestPoint = new Vector3();
|
|
37754
|
+
const _box = new Box3();
|
|
37755
|
+
const _sphere = new Sphere();
|
|
37756
|
+
const _clipToWorldVector = new Vector4();
|
|
37757
|
+
let _ray, _lineWidth;
|
|
37758
|
+
function getWorldSpaceHalfWidth( camera, distance, resolution ) {
|
|
37759
|
+
_clipToWorldVector.set( 0, 0, - distance, 1.0 ).applyMatrix4( camera.projectionMatrix );
|
|
37760
|
+
_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
|
|
37761
|
+
_clipToWorldVector.x = _lineWidth / resolution.width;
|
|
37762
|
+
_clipToWorldVector.y = _lineWidth / resolution.height;
|
|
37763
|
+
_clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse );
|
|
37764
|
+
_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
|
|
37765
|
+
return Math.abs( Math.max( _clipToWorldVector.x, _clipToWorldVector.y ) );
|
|
37766
|
+
}
|
|
37767
|
+
function raycastWorldUnits( lineSegments, intersects ) {
|
|
37768
|
+
const matrixWorld = lineSegments.matrixWorld;
|
|
37769
|
+
const geometry = lineSegments.geometry;
|
|
37770
|
+
const instanceStart = geometry.attributes.instanceStart;
|
|
37771
|
+
const instanceEnd = geometry.attributes.instanceEnd;
|
|
37772
|
+
const segmentCount = Math.min( geometry.instanceCount, instanceStart.count );
|
|
37773
|
+
for ( let i = 0, l = segmentCount; i < l; i ++ ) {
|
|
37774
|
+
_line.start.fromBufferAttribute( instanceStart, i );
|
|
37775
|
+
_line.end.fromBufferAttribute( instanceEnd, i );
|
|
37776
|
+
_line.applyMatrix4( matrixWorld );
|
|
37777
|
+
const pointOnLine = new Vector3();
|
|
37778
|
+
const point = new Vector3();
|
|
37779
|
+
_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
|
|
37780
|
+
const isInside = point.distanceTo( pointOnLine ) < _lineWidth * 0.5;
|
|
37781
|
+
if ( isInside ) {
|
|
37782
|
+
intersects.push( {
|
|
37783
|
+
point,
|
|
37784
|
+
pointOnLine,
|
|
37785
|
+
distance: _ray.origin.distanceTo( point ),
|
|
37786
|
+
object: lineSegments,
|
|
37787
|
+
face: null,
|
|
37788
|
+
faceIndex: i,
|
|
37789
|
+
uv: null,
|
|
37790
|
+
uv1: null,
|
|
37791
|
+
} );
|
|
37792
|
+
}
|
|
37793
|
+
}
|
|
37794
|
+
}
|
|
37795
|
+
function raycastScreenSpace( lineSegments, camera, intersects ) {
|
|
37796
|
+
const projectionMatrix = camera.projectionMatrix;
|
|
37797
|
+
const material = lineSegments.material;
|
|
37798
|
+
const resolution = material.resolution;
|
|
37799
|
+
const matrixWorld = lineSegments.matrixWorld;
|
|
37800
|
+
const geometry = lineSegments.geometry;
|
|
37801
|
+
const instanceStart = geometry.attributes.instanceStart;
|
|
37802
|
+
const instanceEnd = geometry.attributes.instanceEnd;
|
|
37803
|
+
const segmentCount = Math.min( geometry.instanceCount, instanceStart.count );
|
|
37804
|
+
const near = - camera.near;
|
|
37805
|
+
_ray.at( 1, _ssOrigin );
|
|
37806
|
+
_ssOrigin.w = 1;
|
|
37807
|
+
_ssOrigin.applyMatrix4( camera.matrixWorldInverse );
|
|
37808
|
+
_ssOrigin.applyMatrix4( projectionMatrix );
|
|
37809
|
+
_ssOrigin.multiplyScalar( 1 / _ssOrigin.w );
|
|
37810
|
+
_ssOrigin.x *= resolution.x / 2;
|
|
37811
|
+
_ssOrigin.y *= resolution.y / 2;
|
|
37812
|
+
_ssOrigin.z = 0;
|
|
37813
|
+
_ssOrigin3.copy( _ssOrigin );
|
|
37814
|
+
_mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
|
|
37815
|
+
for ( let i = 0, l = segmentCount; i < l; i ++ ) {
|
|
37816
|
+
_start4.fromBufferAttribute( instanceStart, i );
|
|
37817
|
+
_end4.fromBufferAttribute( instanceEnd, i );
|
|
37818
|
+
_start4.w = 1;
|
|
37819
|
+
_end4.w = 1;
|
|
37820
|
+
_start4.applyMatrix4( _mvMatrix );
|
|
37821
|
+
_end4.applyMatrix4( _mvMatrix );
|
|
37822
|
+
const isBehindCameraNear = _start4.z > near && _end4.z > near;
|
|
37823
|
+
if ( isBehindCameraNear ) {
|
|
37824
|
+
continue;
|
|
37825
|
+
}
|
|
37826
|
+
if ( _start4.z > near ) {
|
|
37827
|
+
const deltaDist = _start4.z - _end4.z;
|
|
37828
|
+
const t = ( _start4.z - near ) / deltaDist;
|
|
37829
|
+
_start4.lerp( _end4, t );
|
|
37830
|
+
} else if ( _end4.z > near ) {
|
|
37831
|
+
const deltaDist = _end4.z - _start4.z;
|
|
37832
|
+
const t = ( _end4.z - near ) / deltaDist;
|
|
37833
|
+
_end4.lerp( _start4, t );
|
|
37834
|
+
}
|
|
37835
|
+
_start4.applyMatrix4( projectionMatrix );
|
|
37836
|
+
_end4.applyMatrix4( projectionMatrix );
|
|
37837
|
+
_start4.multiplyScalar( 1 / _start4.w );
|
|
37838
|
+
_end4.multiplyScalar( 1 / _end4.w );
|
|
37839
|
+
_start4.x *= resolution.x / 2;
|
|
37840
|
+
_start4.y *= resolution.y / 2;
|
|
37841
|
+
_end4.x *= resolution.x / 2;
|
|
37842
|
+
_end4.y *= resolution.y / 2;
|
|
37843
|
+
_line.start.copy( _start4 );
|
|
37844
|
+
_line.start.z = 0;
|
|
37845
|
+
_line.end.copy( _end4 );
|
|
37846
|
+
_line.end.z = 0;
|
|
37847
|
+
const param = _line.closestPointToPointParameter( _ssOrigin3, true );
|
|
37848
|
+
_line.at( param, _closestPoint );
|
|
37849
|
+
const zPos = MathUtils.lerp( _start4.z, _end4.z, param );
|
|
37850
|
+
const isInClipSpace = zPos >= -1 && zPos <= 1;
|
|
37851
|
+
const isInside = _ssOrigin3.distanceTo( _closestPoint ) < _lineWidth * 0.5;
|
|
37852
|
+
if ( isInClipSpace && isInside ) {
|
|
37853
|
+
_line.start.fromBufferAttribute( instanceStart, i );
|
|
37854
|
+
_line.end.fromBufferAttribute( instanceEnd, i );
|
|
37855
|
+
_line.start.applyMatrix4( matrixWorld );
|
|
37856
|
+
_line.end.applyMatrix4( matrixWorld );
|
|
37857
|
+
const pointOnLine = new Vector3();
|
|
37858
|
+
const point = new Vector3();
|
|
37859
|
+
_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
|
|
37860
|
+
intersects.push( {
|
|
37861
|
+
point: point,
|
|
37862
|
+
pointOnLine: pointOnLine,
|
|
37863
|
+
distance: _ray.origin.distanceTo( point ),
|
|
37864
|
+
object: lineSegments,
|
|
37865
|
+
face: null,
|
|
37866
|
+
faceIndex: i,
|
|
37867
|
+
uv: null,
|
|
37868
|
+
uv1: null,
|
|
37869
|
+
} );
|
|
37870
|
+
}
|
|
37871
|
+
}
|
|
37872
|
+
}
|
|
37873
|
+
class LineSegments2 extends Mesh {
|
|
37874
|
+
constructor( geometry = new LineSegmentsGeometry(), material = new LineMaterial( { color: Math.random() * 0xffffff } ) ) {
|
|
37875
|
+
super( geometry, material );
|
|
37876
|
+
this.isLineSegments2 = true;
|
|
37877
|
+
this.type = 'LineSegments2';
|
|
37878
|
+
}
|
|
37879
|
+
computeLineDistances() {
|
|
37880
|
+
const geometry = this.geometry;
|
|
37881
|
+
const instanceStart = geometry.attributes.instanceStart;
|
|
37882
|
+
const instanceEnd = geometry.attributes.instanceEnd;
|
|
37883
|
+
const lineDistances = new Float32Array( 2 * instanceStart.count );
|
|
37884
|
+
for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
|
|
37885
|
+
_start.fromBufferAttribute( instanceStart, i );
|
|
37886
|
+
_end.fromBufferAttribute( instanceEnd, i );
|
|
37887
|
+
lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
|
|
37888
|
+
lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
|
|
37889
|
+
}
|
|
37890
|
+
const instanceDistanceBuffer = new InstancedInterleavedBuffer( lineDistances, 2, 1 );
|
|
37891
|
+
geometry.setAttribute( 'instanceDistanceStart', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) );
|
|
37892
|
+
geometry.setAttribute( 'instanceDistanceEnd', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) );
|
|
37893
|
+
return this;
|
|
37894
|
+
}
|
|
37895
|
+
raycast( raycaster, intersects ) {
|
|
37896
|
+
const worldUnits = this.material.worldUnits;
|
|
37897
|
+
const camera = raycaster.camera;
|
|
37898
|
+
if ( camera === null && ! worldUnits ) {
|
|
37899
|
+
console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2 while worldUnits is set to false.' );
|
|
37900
|
+
}
|
|
37901
|
+
const threshold = ( raycaster.params.Line2 !== undefined ) ? raycaster.params.Line2.threshold || 0 : 0;
|
|
37902
|
+
_ray = raycaster.ray;
|
|
37903
|
+
const matrixWorld = this.matrixWorld;
|
|
37904
|
+
const geometry = this.geometry;
|
|
37905
|
+
const material = this.material;
|
|
37906
|
+
_lineWidth = material.linewidth + threshold;
|
|
37907
|
+
if ( geometry.boundingSphere === null ) {
|
|
37908
|
+
geometry.computeBoundingSphere();
|
|
37909
|
+
}
|
|
37910
|
+
_sphere.copy( geometry.boundingSphere ).applyMatrix4( matrixWorld );
|
|
37911
|
+
let sphereMargin;
|
|
37912
|
+
if ( worldUnits ) {
|
|
37913
|
+
sphereMargin = _lineWidth * 0.5;
|
|
37914
|
+
} else {
|
|
37915
|
+
const distanceToSphere = Math.max( camera.near, _sphere.distanceToPoint( _ray.origin ) );
|
|
37916
|
+
sphereMargin = getWorldSpaceHalfWidth( camera, distanceToSphere, material.resolution );
|
|
37917
|
+
}
|
|
37918
|
+
_sphere.radius += sphereMargin;
|
|
37919
|
+
if ( _ray.intersectsSphere( _sphere ) === false ) {
|
|
37920
|
+
return;
|
|
37921
|
+
}
|
|
37922
|
+
if ( geometry.boundingBox === null ) {
|
|
37923
|
+
geometry.computeBoundingBox();
|
|
37924
|
+
}
|
|
37925
|
+
_box.copy( geometry.boundingBox ).applyMatrix4( matrixWorld );
|
|
37926
|
+
let boxMargin;
|
|
37927
|
+
if ( worldUnits ) {
|
|
37928
|
+
boxMargin = _lineWidth * 0.5;
|
|
37929
|
+
} else {
|
|
37930
|
+
const distanceToBox = Math.max( camera.near, _box.distanceToPoint( _ray.origin ) );
|
|
37931
|
+
boxMargin = getWorldSpaceHalfWidth( camera, distanceToBox, material.resolution );
|
|
37932
|
+
}
|
|
37933
|
+
_box.expandByScalar( boxMargin );
|
|
37934
|
+
if ( _ray.intersectsBox( _box ) === false ) {
|
|
37935
|
+
return;
|
|
37936
|
+
}
|
|
37937
|
+
if ( worldUnits ) {
|
|
37938
|
+
raycastWorldUnits( this, intersects );
|
|
37939
|
+
} else {
|
|
37940
|
+
raycastScreenSpace( this, camera, intersects );
|
|
37941
|
+
}
|
|
37942
|
+
}
|
|
37943
|
+
onBeforeRender( renderer ) {
|
|
37944
|
+
const uniforms = this.material.uniforms;
|
|
37945
|
+
if ( uniforms && uniforms.resolution ) {
|
|
37946
|
+
renderer.getViewport( _viewport );
|
|
37947
|
+
this.material.uniforms.resolution.value.set( _viewport.z, _viewport.w );
|
|
37948
|
+
}
|
|
37949
|
+
}
|
|
37950
|
+
}
|
|
37951
|
+
|
|
37952
|
+
class PointHashGrid {
|
|
37953
|
+
constructor(tolerance = 1e-5) {
|
|
37954
|
+
this.tolerance = tolerance;
|
|
37955
|
+
this.points = [];
|
|
37956
|
+
this.grid = new Map();
|
|
37957
|
+
}
|
|
37958
|
+
_hash(hx, hy, hz) {
|
|
37959
|
+
return `${hx},${hy},${hz}`;
|
|
37960
|
+
}
|
|
37961
|
+
add(v) {
|
|
37962
|
+
const hx = Math.round(v.x / this.tolerance);
|
|
37963
|
+
const hy = Math.round(v.y / this.tolerance);
|
|
37964
|
+
const hz = Math.round(v.z / this.tolerance);
|
|
37965
|
+
for (let i = -1; i <= 1; i++) {
|
|
37966
|
+
for (let j = -1; j <= 1; j++) {
|
|
37967
|
+
for (let k = -1; k <= 1; k++) {
|
|
37968
|
+
const hash = this._hash(hx + i, hy + j, hz + k);
|
|
37969
|
+
const cell = this.grid.get(hash);
|
|
37970
|
+
if (cell) {
|
|
37971
|
+
for (const id of cell) {
|
|
37972
|
+
if (this.points[id].distanceTo(v) <= this.tolerance) return id;
|
|
37973
|
+
}
|
|
37974
|
+
}
|
|
37975
|
+
}
|
|
37976
|
+
}
|
|
37977
|
+
}
|
|
37978
|
+
const id = this.points.length;
|
|
37979
|
+
this.points.push(v.clone());
|
|
37980
|
+
const centerHash = this._hash(hx, hy, hz);
|
|
37981
|
+
if (!this.grid.has(centerHash)) this.grid.set(centerHash, []);
|
|
37982
|
+
this.grid.get(centerHash).push(id);
|
|
37983
|
+
return id;
|
|
37984
|
+
}
|
|
37985
|
+
}
|
|
37986
|
+
class SectionsHelper extends Object3D {
|
|
37987
|
+
constructor() {
|
|
37988
|
+
super();
|
|
37989
|
+
this.type = "SectionsHelper";
|
|
37990
|
+
this.flags = {
|
|
37991
|
+
fillEnabled: true,
|
|
37992
|
+
fillColor: "#fffde7",
|
|
37993
|
+
hatchEnabled: true,
|
|
37994
|
+
hatchColor: "#000000",
|
|
37995
|
+
hatchScale: 8.0,
|
|
37996
|
+
outlineEnabled: true,
|
|
37997
|
+
outlineColor: "#000000",
|
|
37998
|
+
outlineWidth: 2,
|
|
37999
|
+
boundaryOnly: true,
|
|
38000
|
+
showDebugSeams: false,
|
|
38001
|
+
showDebugPoints: false,
|
|
38002
|
+
showDebugSegments: false,
|
|
38003
|
+
showDebugGaps: false,
|
|
38004
|
+
showDebugInfo: false,
|
|
38005
|
+
useObjFillColor: false,
|
|
38006
|
+
useObjOutlineColor: false,
|
|
38007
|
+
};
|
|
38008
|
+
this._caps = [];
|
|
38009
|
+
this._outlines = [];
|
|
38010
|
+
this._debugPoints = [];
|
|
38011
|
+
this._debugSegments = [];
|
|
38012
|
+
this._debugGaps = [];
|
|
38013
|
+
this._vA = new Vector3();
|
|
38014
|
+
this._vB = new Vector3();
|
|
38015
|
+
this._vC = new Vector3();
|
|
38016
|
+
this._worldBox = new Box3();
|
|
38017
|
+
}
|
|
38018
|
+
dispose() {
|
|
38019
|
+
const disposeMesh = (item) => {
|
|
38020
|
+
if (item.geometry) item.geometry.dispose();
|
|
38021
|
+
if (item.material) item.material.dispose();
|
|
38022
|
+
this.remove(item);
|
|
38023
|
+
};
|
|
38024
|
+
this._caps.forEach(disposeMesh);
|
|
38025
|
+
this._outlines.forEach(disposeMesh);
|
|
38026
|
+
this._debugPoints.forEach(disposeMesh);
|
|
38027
|
+
this._debugSegments.forEach(disposeMesh);
|
|
38028
|
+
this._debugGaps.forEach(disposeMesh);
|
|
38029
|
+
this._caps.length = 0;
|
|
38030
|
+
this._outlines.length = 0;
|
|
38031
|
+
this._debugPoints.length = 0;
|
|
38032
|
+
this._debugSegments.length = 0;
|
|
38033
|
+
this._debugGaps.length = 0;
|
|
38034
|
+
}
|
|
38035
|
+
setSize(width, height) {
|
|
38036
|
+
this._outlines.forEach((o) => {
|
|
38037
|
+
if (o.material.resolution) o.material.resolution.set(width, height);
|
|
38038
|
+
});
|
|
38039
|
+
this._debugSegments.forEach((s) => {
|
|
38040
|
+
if (s.material.resolution) s.material.resolution.set(width, height);
|
|
38041
|
+
});
|
|
38042
|
+
}
|
|
38043
|
+
_ensureHelpersCount(count) {
|
|
38044
|
+
const hatchVertexShader = `
|
|
38045
|
+
#include <common>
|
|
38046
|
+
#include <logdepthbuf_pars_vertex>
|
|
38047
|
+
#include <clipping_planes_pars_vertex>
|
|
38048
|
+
|
|
38049
|
+
attribute float aHatchDir;
|
|
38050
|
+
attribute vec3 aFillColor;
|
|
38051
|
+
|
|
38052
|
+
varying vec3 vWP;
|
|
38053
|
+
varying float vHatchDir;
|
|
38054
|
+
varying vec3 vFillColor;
|
|
38055
|
+
|
|
38056
|
+
void main() {
|
|
38057
|
+
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
|
|
38058
|
+
#include <clipping_planes_vertex>
|
|
38059
|
+
|
|
38060
|
+
vWP = (modelMatrix * vec4(position, 1.0)).xyz;
|
|
38061
|
+
vHatchDir = aHatchDir;
|
|
38062
|
+
vFillColor = aFillColor;
|
|
38063
|
+
|
|
38064
|
+
gl_Position = projectionMatrix * mvPosition;
|
|
38065
|
+
#include <logdepthbuf_vertex>
|
|
38066
|
+
}
|
|
38067
|
+
`;
|
|
38068
|
+
const hatchFragmentShader = `
|
|
38069
|
+
#include <common>
|
|
38070
|
+
#include <logdepthbuf_pars_fragment>
|
|
38071
|
+
#include <clipping_planes_pars_fragment>
|
|
38072
|
+
|
|
38073
|
+
uniform vec3 lineColor;
|
|
38074
|
+
uniform float uHatchScale;
|
|
38075
|
+
uniform float uHatchEnabled;
|
|
38076
|
+
|
|
38077
|
+
varying vec3 vWP;
|
|
38078
|
+
varying float vHatchDir;
|
|
38079
|
+
varying vec3 vFillColor;
|
|
38080
|
+
|
|
38081
|
+
void main() {
|
|
38082
|
+
#include <clipping_planes_fragment>
|
|
38083
|
+
#include <logdepthbuf_fragment>
|
|
38084
|
+
|
|
38085
|
+
float v1 = mod(gl_FragCoord.x + gl_FragCoord.y, uHatchScale);
|
|
38086
|
+
float v2 = mod(gl_FragCoord.x - gl_FragCoord.y, uHatchScale);
|
|
38087
|
+
float v = mix(v1, v2, vHatchDir);
|
|
38088
|
+
|
|
38089
|
+
float hatchMask = step(v, 1.5) * uHatchEnabled;
|
|
38090
|
+
gl_FragColor = vec4(mix(vFillColor, lineColor, hatchMask), 1.0);
|
|
38091
|
+
}
|
|
38092
|
+
`;
|
|
38093
|
+
while (this._caps.length < count) {
|
|
38094
|
+
const capMat = new ShaderMaterial({
|
|
38095
|
+
uniforms: {
|
|
38096
|
+
lineColor: { value: new Color() },
|
|
38097
|
+
uHatchScale: { value: 10.0 },
|
|
38098
|
+
uHatchEnabled: { value: 1.0 },
|
|
38099
|
+
},
|
|
38100
|
+
vertexShader: hatchVertexShader,
|
|
38101
|
+
fragmentShader: hatchFragmentShader,
|
|
38102
|
+
side: DoubleSide,
|
|
38103
|
+
clipping: true,
|
|
38104
|
+
depthTest: true,
|
|
38105
|
+
depthWrite: false,
|
|
38106
|
+
});
|
|
38107
|
+
const capMesh = new Mesh(new BufferGeometry(), capMat);
|
|
38108
|
+
capMesh.renderOrder = 5;
|
|
38109
|
+
this.add(capMesh);
|
|
38110
|
+
this._caps.push(capMesh);
|
|
38111
|
+
const lineMat = new LineMaterial({
|
|
38112
|
+
color: 0xffffff,
|
|
38113
|
+
linewidth: 2,
|
|
38114
|
+
resolution: new Vector2(window.innerWidth, window.innerHeight),
|
|
38115
|
+
depthTest: true,
|
|
38116
|
+
clipping: true,
|
|
38117
|
+
vertexColors: true,
|
|
38118
|
+
});
|
|
38119
|
+
const lineObj = new LineSegments2(new LineSegmentsGeometry(), lineMat);
|
|
38120
|
+
lineObj.renderOrder = 100;
|
|
38121
|
+
this.add(lineObj);
|
|
38122
|
+
this._outlines.push(lineObj);
|
|
38123
|
+
const ptsMat = new PointsMaterial({
|
|
38124
|
+
color: 0x00aaff,
|
|
38125
|
+
size: 6,
|
|
38126
|
+
sizeAttenuation: false,
|
|
38127
|
+
depthTest: false,
|
|
38128
|
+
transparent: true,
|
|
38129
|
+
depthWrite: false,
|
|
38130
|
+
});
|
|
38131
|
+
const pointsObj = new Points(new BufferGeometry(), ptsMat);
|
|
38132
|
+
pointsObj.renderOrder = 200;
|
|
38133
|
+
this.add(pointsObj);
|
|
38134
|
+
this._debugPoints.push(pointsObj);
|
|
38135
|
+
const debugSegMat = new LineMaterial({
|
|
38136
|
+
color: 0x00ff00,
|
|
38137
|
+
linewidth: 4,
|
|
38138
|
+
resolution: new Vector2(window.innerWidth, window.innerHeight),
|
|
38139
|
+
depthTest: false,
|
|
38140
|
+
transparent: true,
|
|
38141
|
+
depthWrite: false,
|
|
38142
|
+
clipping: true,
|
|
38143
|
+
});
|
|
38144
|
+
const debugSegObj = new LineSegments2(new LineSegmentsGeometry(), debugSegMat);
|
|
38145
|
+
debugSegObj.renderOrder = 150;
|
|
38146
|
+
this.add(debugSegObj);
|
|
38147
|
+
this._debugSegments.push(debugSegObj);
|
|
38148
|
+
const gapPtsMat = new PointsMaterial({
|
|
38149
|
+
size: 6,
|
|
38150
|
+
sizeAttenuation: false,
|
|
38151
|
+
depthTest: false,
|
|
38152
|
+
transparent: true,
|
|
38153
|
+
depthWrite: false,
|
|
38154
|
+
vertexColors: true,
|
|
38155
|
+
});
|
|
38156
|
+
const gapsObj = new Points(new BufferGeometry(), gapPtsMat);
|
|
38157
|
+
gapsObj.renderOrder = 250;
|
|
38158
|
+
this.add(gapsObj);
|
|
38159
|
+
this._debugGaps.push(gapsObj);
|
|
38160
|
+
}
|
|
38161
|
+
for (let i = count; i < this._caps.length; i++) {
|
|
38162
|
+
this._caps[i].visible = false;
|
|
38163
|
+
this._outlines[i].visible = false;
|
|
38164
|
+
this._debugPoints[i].visible = false;
|
|
38165
|
+
this._debugSegments[i].visible = false;
|
|
38166
|
+
this._debugGaps[i].visible = false;
|
|
38167
|
+
}
|
|
38168
|
+
}
|
|
38169
|
+
update(objects, extents, planes) {
|
|
38170
|
+
const t0 = performance.now();
|
|
38171
|
+
this._ensureHelpersCount(planes.length);
|
|
38172
|
+
if (planes.length === 0) return;
|
|
38173
|
+
const sphere = extents.getBoundingSphere(new Sphere());
|
|
38174
|
+
const globalRadius = Math.max(sphere.radius, 1e-3);
|
|
38175
|
+
const clippingBias = globalRadius * 1e-4;
|
|
38176
|
+
const biasedPlanes = planes.map((p) => {
|
|
38177
|
+
const bp = p.clone();
|
|
38178
|
+
bp.constant += clippingBias;
|
|
38179
|
+
return bp;
|
|
38180
|
+
});
|
|
38181
|
+
const targetMeshes = [];
|
|
38182
|
+
objects.forEach((obj) => {
|
|
38183
|
+
if (obj.isMesh && obj.material) {
|
|
38184
|
+
const mats = Array.isArray(obj.material) ? obj.material : [obj.material];
|
|
38185
|
+
if (mats.some((m) => m.clippingPlanes)) targetMeshes.push(obj);
|
|
38186
|
+
}
|
|
38187
|
+
});
|
|
38188
|
+
planes.forEach((plane, pIdx) => {
|
|
38189
|
+
const capMesh = this._caps[pIdx];
|
|
38190
|
+
const outlineMesh = this._outlines[pIdx];
|
|
38191
|
+
const debugPtsMesh = this._debugPoints[pIdx];
|
|
38192
|
+
const debugSegsMesh = this._debugSegments[pIdx];
|
|
38193
|
+
const debugGapsMesh = this._debugGaps[pIdx];
|
|
38194
|
+
const hatchColor = new Color(this.flags.hatchColor);
|
|
38195
|
+
hatchColor.convertLinearToSRGB();
|
|
38196
|
+
capMesh.material.uniforms.lineColor.value.set(hatchColor);
|
|
38197
|
+
capMesh.material.uniforms.uHatchScale.value = this.flags.hatchScale;
|
|
38198
|
+
capMesh.material.uniforms.uHatchEnabled.value = this.flags.hatchEnabled ? 1.0 : 0.0;
|
|
38199
|
+
outlineMesh.material.linewidth = this.flags.outlineWidth;
|
|
38200
|
+
const otherBiasedPlanes = biasedPlanes.filter((_, i) => i !== pIdx);
|
|
38201
|
+
capMesh.material.clippingPlanes = otherBiasedPlanes;
|
|
38202
|
+
outlineMesh.material.clippingPlanes = otherBiasedPlanes;
|
|
38203
|
+
debugSegsMesh.material.clippingPlanes = otherBiasedPlanes;
|
|
38204
|
+
const n = plane.normal;
|
|
38205
|
+
const planeOrigin = n.clone().multiplyScalar(-plane.constant);
|
|
38206
|
+
const up = new Vector3(0, 1, 0);
|
|
38207
|
+
if (Math.abs(n.dot(up)) > 0.999) up.set(1, 0, 0);
|
|
38208
|
+
const uAxis = new Vector3().crossVectors(up, n).normalize();
|
|
38209
|
+
const vAxis = new Vector3().crossVectors(n, uAxis).normalize();
|
|
38210
|
+
const positions = [];
|
|
38211
|
+
const indices = [];
|
|
38212
|
+
const hatchDirs = [];
|
|
38213
|
+
const fillColors = [];
|
|
38214
|
+
const combinedOutlinePoints = [];
|
|
38215
|
+
const combinedOutlineColors = [];
|
|
38216
|
+
const rawPts = [];
|
|
38217
|
+
const rawSegs = [];
|
|
38218
|
+
const rawGaps = [];
|
|
38219
|
+
const rawGapColors = [];
|
|
38220
|
+
targetMeshes.forEach((mesh, meshIndex) => {
|
|
38221
|
+
if (!mesh.geometry.boundingBox) mesh.geometry.computeBoundingBox();
|
|
38222
|
+
if (!mesh.geometry.boundingSphere) mesh.geometry.computeBoundingSphere();
|
|
38223
|
+
this._worldBox.copy(mesh.geometry.boundingBox).applyMatrix4(mesh.matrixWorld);
|
|
38224
|
+
if (!plane.intersectsBox(this._worldBox)) return;
|
|
38225
|
+
const localScale = new Vector3().setFromMatrixScale(mesh.matrixWorld);
|
|
38226
|
+
const maxScale = Math.max(localScale.x, localScale.y, localScale.z);
|
|
38227
|
+
const localRadius = Math.max(mesh.geometry.boundingSphere.radius * maxScale, 1e-3);
|
|
38228
|
+
const localHashTolerance = Math.max(localRadius * 1e-4, 1e-6);
|
|
38229
|
+
const localEps = Math.max(localRadius * 1e-5, 1e-7);
|
|
38230
|
+
const baseColor = new Color(0xffffff);
|
|
38231
|
+
const om = mesh.userData.originalMaterial;
|
|
38232
|
+
const mm = om ?? (Array.isArray(mesh.material) ? mesh.material[0] : mesh.material);
|
|
38233
|
+
if (mm.color) baseColor.copy(mm.color);
|
|
38234
|
+
const objFillColor = baseColor.clone().lerp(new Color(0x000000), 0.2);
|
|
38235
|
+
const objOutlineColor = baseColor.clone().lerp(new Color(0x000000), 0.85);
|
|
38236
|
+
const hue = ((meshIndex * 137.5) % 360) / 360;
|
|
38237
|
+
const meshGapColor = new Color().setHSL(hue, 1.0, 0.5);
|
|
38238
|
+
const currentHatchDir = meshIndex % 2 === 0 ? 0.0 : 1.0;
|
|
38239
|
+
const fillColor = this.flags.useObjFillColor ? objFillColor : new Color(this.flags.fillColor);
|
|
38240
|
+
const outlineColor = this.flags.useObjOutlineColor ? objOutlineColor : new Color(this.flags.outlineColor);
|
|
38241
|
+
meshGapColor.convertLinearToSRGB();
|
|
38242
|
+
fillColor.convertLinearToSRGB();
|
|
38243
|
+
outlineColor.convertLinearToSRGB();
|
|
38244
|
+
const localEdgeStats = new Map();
|
|
38245
|
+
const localPointGrid = new PointHashGrid(localHashTolerance);
|
|
38246
|
+
this._calculateMeshSegmentsUndirected(mesh, plane, localEdgeStats, localPointGrid, localEps);
|
|
38247
|
+
if (localEdgeStats.size > 0) {
|
|
38248
|
+
const boundaryEdges = [];
|
|
38249
|
+
for (const [key, stat] of localEdgeStats.entries()) {
|
|
38250
|
+
const isBoundary = stat.count % 2 !== 0;
|
|
38251
|
+
const ids = key.split("-");
|
|
38252
|
+
const id0 = Number(ids[0]);
|
|
38253
|
+
const id1 = Number(ids[1]);
|
|
38254
|
+
const p1 = localPointGrid.points[id0];
|
|
38255
|
+
const p2 = localPointGrid.points[id1];
|
|
38256
|
+
if (this.flags.showDebugSeams || (this.flags.boundaryOnly ? isBoundary : true)) {
|
|
38257
|
+
combinedOutlinePoints.push(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);
|
|
38258
|
+
combinedOutlineColors.push(outlineColor.r, outlineColor.g, outlineColor.b);
|
|
38259
|
+
combinedOutlineColors.push(outlineColor.r, outlineColor.g, outlineColor.b);
|
|
38260
|
+
}
|
|
38261
|
+
if (isBoundary) boundaryEdges.push([id0, id1]);
|
|
38262
|
+
if (this.flags.showDebugSegments) rawSegs.push(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);
|
|
38263
|
+
}
|
|
38264
|
+
if (this.flags.showDebugPoints) {
|
|
38265
|
+
for (const p of localPointGrid.points) rawPts.push(p.x, p.y, p.z);
|
|
38266
|
+
}
|
|
38267
|
+
if (this.flags.fillEnabled && boundaryEdges.length >= 3) {
|
|
38268
|
+
const currentAdj = new Map();
|
|
38269
|
+
for (const edge of boundaryEdges) {
|
|
38270
|
+
const a = edge[0];
|
|
38271
|
+
const b = edge[1];
|
|
38272
|
+
if (!currentAdj.has(a)) currentAdj.set(a, []);
|
|
38273
|
+
if (!currentAdj.has(b)) currentAdj.set(b, []);
|
|
38274
|
+
currentAdj.get(a).push(b);
|
|
38275
|
+
currentAdj.get(b).push(a);
|
|
38276
|
+
}
|
|
38277
|
+
const degree1 = [];
|
|
38278
|
+
for (const [node, neighbors] of currentAdj.entries()) {
|
|
38279
|
+
if (neighbors.length === 1) degree1.push(node);
|
|
38280
|
+
}
|
|
38281
|
+
const stitchTol = Math.max(localRadius * 0.05, 1e-4);
|
|
38282
|
+
for (let i = 0; i < degree1.length; i++) {
|
|
38283
|
+
const n1 = degree1[i];
|
|
38284
|
+
if (currentAdj.get(n1).length !== 1) continue;
|
|
38285
|
+
const p1 = localPointGrid.points[n1];
|
|
38286
|
+
let bestEdgeIdx = -1;
|
|
38287
|
+
let bestProj = null;
|
|
38288
|
+
let bestT = 0;
|
|
38289
|
+
let minDist = stitchTol;
|
|
38290
|
+
const edgeCount = boundaryEdges.length;
|
|
38291
|
+
for (let eIdx = 0; eIdx < edgeCount; eIdx++) {
|
|
38292
|
+
const edge = boundaryEdges[eIdx];
|
|
38293
|
+
const eA = edge[0];
|
|
38294
|
+
const eB = edge[1];
|
|
38295
|
+
if (eA === n1 || eB === n1) continue;
|
|
38296
|
+
const pA = localPointGrid.points[eA];
|
|
38297
|
+
const pB = localPointGrid.points[eB];
|
|
38298
|
+
const lineVec = new Vector3().subVectors(pB, pA);
|
|
38299
|
+
const lineLenSq = lineVec.lengthSq();
|
|
38300
|
+
let proj;
|
|
38301
|
+
let t;
|
|
38302
|
+
if (lineLenSq < 1e-12) {
|
|
38303
|
+
proj = pA.clone();
|
|
38304
|
+
t = 0;
|
|
38305
|
+
} else {
|
|
38306
|
+
const ptVec = new Vector3().subVectors(p1, pA);
|
|
38307
|
+
t = ptVec.dot(lineVec) / lineLenSq;
|
|
38308
|
+
t = Math.max(0, Math.min(1, t));
|
|
38309
|
+
proj = new Vector3().copy(pA).addScaledVector(lineVec, t);
|
|
38310
|
+
}
|
|
38311
|
+
const dist = p1.distanceTo(proj);
|
|
38312
|
+
if (dist < minDist) {
|
|
38313
|
+
minDist = dist;
|
|
38314
|
+
bestEdgeIdx = eIdx;
|
|
38315
|
+
bestProj = proj;
|
|
38316
|
+
bestT = t;
|
|
38317
|
+
}
|
|
38318
|
+
}
|
|
38319
|
+
if (bestEdgeIdx !== -1) {
|
|
38320
|
+
const edge = boundaryEdges[bestEdgeIdx];
|
|
38321
|
+
const eA = edge[0];
|
|
38322
|
+
const eB = edge[1];
|
|
38323
|
+
if (bestT < 0.001) {
|
|
38324
|
+
boundaryEdges.push([n1, eA]);
|
|
38325
|
+
currentAdj.get(n1).push(eA);
|
|
38326
|
+
currentAdj.get(eA).push(n1);
|
|
38327
|
+
p1.copy(localPointGrid.points[eA]);
|
|
38328
|
+
} else if (bestT > 0.999) {
|
|
38329
|
+
boundaryEdges.push([n1, eB]);
|
|
38330
|
+
currentAdj.get(n1).push(eB);
|
|
38331
|
+
currentAdj.get(eB).push(n1);
|
|
38332
|
+
p1.copy(localPointGrid.points[eB]);
|
|
38333
|
+
} else {
|
|
38334
|
+
const newNodeId = localPointGrid.add(bestProj);
|
|
38335
|
+
edge[1] = newNodeId;
|
|
38336
|
+
boundaryEdges.push([newNodeId, eB]);
|
|
38337
|
+
boundaryEdges.push([n1, newNodeId]);
|
|
38338
|
+
const neighborsA = currentAdj.get(eA);
|
|
38339
|
+
neighborsA[neighborsA.indexOf(eB)] = newNodeId;
|
|
38340
|
+
const neighborsB = currentAdj.get(eB);
|
|
38341
|
+
neighborsB[neighborsB.indexOf(eA)] = newNodeId;
|
|
38342
|
+
if (!currentAdj.has(newNodeId)) currentAdj.set(newNodeId, []);
|
|
38343
|
+
currentAdj.get(newNodeId).push(eA, eB, n1);
|
|
38344
|
+
currentAdj.get(n1).push(newNodeId);
|
|
38345
|
+
p1.copy(bestProj);
|
|
38346
|
+
}
|
|
38347
|
+
}
|
|
38348
|
+
}
|
|
38349
|
+
if (this.flags.showDebugGaps) {
|
|
38350
|
+
for (const [node, neighbors] of currentAdj.entries()) {
|
|
38351
|
+
if (neighbors.length !== 2) {
|
|
38352
|
+
const p = localPointGrid.points[node];
|
|
38353
|
+
rawGaps.push(p.x, p.y, p.z);
|
|
38354
|
+
rawGapColors.push(meshGapColor.r, meshGapColor.g, meshGapColor.b);
|
|
38355
|
+
}
|
|
38356
|
+
}
|
|
38357
|
+
}
|
|
38358
|
+
const loops = this._assembleLoopsUndirected(boundaryEdges, localPointGrid, uAxis, vAxis);
|
|
38359
|
+
if (loops.length > 0) {
|
|
38360
|
+
this._triangulateTreeOptimized(
|
|
38361
|
+
loops,
|
|
38362
|
+
planeOrigin,
|
|
38363
|
+
uAxis,
|
|
38364
|
+
vAxis,
|
|
38365
|
+
positions,
|
|
38366
|
+
indices,
|
|
38367
|
+
localRadius,
|
|
38368
|
+
fillColor,
|
|
38369
|
+
currentHatchDir,
|
|
38370
|
+
hatchDirs,
|
|
38371
|
+
fillColors
|
|
38372
|
+
);
|
|
38373
|
+
}
|
|
38374
|
+
}
|
|
38375
|
+
}
|
|
38376
|
+
});
|
|
38377
|
+
if (indices.length > 0) {
|
|
38378
|
+
capMesh.geometry.dispose();
|
|
38379
|
+
capMesh.geometry = new BufferGeometry();
|
|
38380
|
+
capMesh.geometry.setAttribute("position", new Float32BufferAttribute(positions, 3));
|
|
38381
|
+
capMesh.geometry.setAttribute("aHatchDir", new Float32BufferAttribute(hatchDirs, 1));
|
|
38382
|
+
capMesh.geometry.setAttribute("aFillColor", new Float32BufferAttribute(fillColors, 3));
|
|
38383
|
+
capMesh.geometry.setIndex(indices);
|
|
38384
|
+
capMesh.geometry.computeVertexNormals();
|
|
38385
|
+
capMesh.visible = this.flags.fillEnabled;
|
|
38386
|
+
} else {
|
|
38387
|
+
capMesh.visible = false;
|
|
38388
|
+
}
|
|
38389
|
+
if (outlineMesh.geometry) outlineMesh.geometry.dispose();
|
|
38390
|
+
outlineMesh.geometry = new LineSegmentsGeometry();
|
|
38391
|
+
if (this.flags.outlineEnabled && combinedOutlinePoints.length >= 6) {
|
|
38392
|
+
outlineMesh.geometry.setPositions(new Float32Array(combinedOutlinePoints));
|
|
38393
|
+
outlineMesh.geometry.setColors(new Float32Array(combinedOutlineColors));
|
|
38394
|
+
outlineMesh.visible = true;
|
|
38395
|
+
} else {
|
|
38396
|
+
outlineMesh.visible = false;
|
|
38397
|
+
}
|
|
38398
|
+
if (this.flags.showDebugPoints && rawPts.length > 0) {
|
|
38399
|
+
debugPtsMesh.geometry.setAttribute("position", new Float32BufferAttribute(rawPts, 3));
|
|
38400
|
+
debugPtsMesh.visible = true;
|
|
38401
|
+
} else {
|
|
38402
|
+
debugPtsMesh.visible = false;
|
|
38403
|
+
}
|
|
38404
|
+
if (debugSegsMesh.geometry) debugSegsMesh.geometry.dispose();
|
|
38405
|
+
debugSegsMesh.geometry = new LineSegmentsGeometry();
|
|
38406
|
+
if (this.flags.showDebugSegments && rawSegs.length >= 6) {
|
|
38407
|
+
debugSegsMesh.geometry.setPositions(new Float32Array(rawSegs));
|
|
38408
|
+
debugSegsMesh.visible = true;
|
|
38409
|
+
} else {
|
|
38410
|
+
debugSegsMesh.visible = false;
|
|
38411
|
+
}
|
|
38412
|
+
if (debugGapsMesh.geometry) debugGapsMesh.geometry.dispose();
|
|
38413
|
+
debugGapsMesh.geometry = new BufferGeometry();
|
|
38414
|
+
if (this.flags.showDebugGaps && rawGaps.length > 0) {
|
|
38415
|
+
debugGapsMesh.geometry.setAttribute("position", new Float32BufferAttribute(rawGaps, 3));
|
|
38416
|
+
debugGapsMesh.geometry.setAttribute("color", new Float32BufferAttribute(rawGapColors, 3));
|
|
38417
|
+
debugGapsMesh.visible = true;
|
|
38418
|
+
} else {
|
|
38419
|
+
debugGapsMesh.visible = false;
|
|
38420
|
+
}
|
|
38421
|
+
});
|
|
38422
|
+
if (this.flags.showDebugInfo) {
|
|
38423
|
+
console.log(`[SectionsHelper] v7.00 Updated in ${(performance.now() - t0).toFixed(2)} ms`);
|
|
38424
|
+
}
|
|
38425
|
+
}
|
|
38426
|
+
_assembleLoopsUndirected(edges, pointGrid, uAxis, vAxis) {
|
|
38427
|
+
const adj = new Map();
|
|
38428
|
+
for (const edge of edges) {
|
|
38429
|
+
const a = edge[0];
|
|
38430
|
+
const b = edge[1];
|
|
38431
|
+
if (!adj.has(a)) adj.set(a, []);
|
|
38432
|
+
if (!adj.has(b)) adj.set(b, []);
|
|
38433
|
+
adj.get(a).push(b);
|
|
38434
|
+
adj.get(b).push(a);
|
|
38435
|
+
}
|
|
38436
|
+
const loops = [];
|
|
38437
|
+
while (adj.size > 0) {
|
|
38438
|
+
let startNode = -1;
|
|
38439
|
+
for (const key of adj.keys()) {
|
|
38440
|
+
if (adj.get(key).length > 0) {
|
|
38441
|
+
startNode = key;
|
|
38442
|
+
break;
|
|
38443
|
+
}
|
|
38444
|
+
}
|
|
38445
|
+
if (startNode === -1) break;
|
|
38446
|
+
let current = startNode;
|
|
38447
|
+
let prev = -1;
|
|
38448
|
+
const path = [];
|
|
38449
|
+
const pathIndices = new Map();
|
|
38450
|
+
while (true) {
|
|
38451
|
+
path.push(current);
|
|
38452
|
+
pathIndices.set(current, path.length - 1);
|
|
38453
|
+
const neighbors = adj.get(current);
|
|
38454
|
+
if (!neighbors || neighbors.length === 0) break;
|
|
38455
|
+
let nextIdx = 0;
|
|
38456
|
+
if (neighbors.length > 1 && prev !== -1) {
|
|
38457
|
+
const pPrev = pointGrid.points[prev];
|
|
38458
|
+
const pCurr = pointGrid.points[current];
|
|
38459
|
+
const vIn = new Vector3().subVectors(pCurr, pPrev);
|
|
38460
|
+
const in2d = new Vector2(vIn.dot(uAxis), vIn.dot(vAxis));
|
|
38461
|
+
if (in2d.lengthSq() > 1e-10) {
|
|
38462
|
+
in2d.normalize();
|
|
38463
|
+
let minAngle = Infinity;
|
|
38464
|
+
for (let i = 0; i < neighbors.length; i++) {
|
|
38465
|
+
const pNext = pointGrid.points[neighbors[i]];
|
|
38466
|
+
const vOut = new Vector3().subVectors(pNext, pCurr);
|
|
38467
|
+
const out2d = new Vector2(vOut.dot(uAxis), vOut.dot(vAxis));
|
|
38468
|
+
if (out2d.lengthSq() > 1e-10) {
|
|
38469
|
+
out2d.normalize();
|
|
38470
|
+
const angle = Math.atan2(in2d.cross(out2d), in2d.dot(out2d));
|
|
38471
|
+
if (angle < minAngle) {
|
|
38472
|
+
minAngle = angle;
|
|
38473
|
+
nextIdx = i;
|
|
38474
|
+
}
|
|
38475
|
+
}
|
|
38476
|
+
}
|
|
38477
|
+
}
|
|
38478
|
+
}
|
|
38479
|
+
const next = neighbors[nextIdx];
|
|
38480
|
+
neighbors.splice(nextIdx, 1);
|
|
38481
|
+
const nextNeighbors = adj.get(next);
|
|
38482
|
+
if (nextNeighbors) {
|
|
38483
|
+
const revIdx = nextNeighbors.indexOf(current);
|
|
38484
|
+
if (revIdx !== -1) nextNeighbors.splice(revIdx, 1);
|
|
38485
|
+
}
|
|
38486
|
+
prev = current;
|
|
38487
|
+
current = next;
|
|
38488
|
+
if (pathIndices.has(current)) {
|
|
38489
|
+
const loopStartIdx = pathIndices.get(current);
|
|
38490
|
+
const loopNodes = path.slice(loopStartIdx);
|
|
38491
|
+
if (loopNodes.length >= 3) loops.push(loopNodes.map((id) => pointGrid.points[id]));
|
|
38492
|
+
for (let i = loopStartIdx; i < path.length; i++) pathIndices.delete(path[i]);
|
|
38493
|
+
path.length = loopStartIdx;
|
|
38494
|
+
prev = path.length > 1 ? path[path.length - 2] : -1;
|
|
38495
|
+
}
|
|
38496
|
+
}
|
|
38497
|
+
for (const key of adj.keys()) {
|
|
38498
|
+
if (adj.get(key).length === 0) adj.delete(key);
|
|
38499
|
+
}
|
|
38500
|
+
}
|
|
38501
|
+
return loops;
|
|
38502
|
+
}
|
|
38503
|
+
_triangulateTreeOptimized(
|
|
38504
|
+
loops,
|
|
38505
|
+
planeOrigin,
|
|
38506
|
+
uAxis,
|
|
38507
|
+
vAxis,
|
|
38508
|
+
positionsBuffer,
|
|
38509
|
+
indicesBuffer,
|
|
38510
|
+
localRadius,
|
|
38511
|
+
fillColor,
|
|
38512
|
+
hatchDir,
|
|
38513
|
+
hatchDirsBuffer,
|
|
38514
|
+
fillColorsBuffer
|
|
38515
|
+
) {
|
|
38516
|
+
const shapesData = [];
|
|
38517
|
+
const minArea = localRadius * 1e-5 * (localRadius * 1e-5);
|
|
38518
|
+
loops.forEach((loop) => {
|
|
38519
|
+
const pts2d = loop.map((p) => {
|
|
38520
|
+
const pv = p.clone().sub(planeOrigin);
|
|
38521
|
+
return new Vector2(pv.dot(uAxis), pv.dot(vAxis));
|
|
38522
|
+
});
|
|
38523
|
+
const cleaned = [];
|
|
38524
|
+
for (let k = 0; k < pts2d.length; k++) {
|
|
38525
|
+
const prev = k === 0 ? pts2d[pts2d.length - 1] : pts2d[k - 1];
|
|
38526
|
+
if (pts2d[k].distanceTo(prev) > 1e-5) cleaned.push(pts2d[k]);
|
|
38527
|
+
}
|
|
38528
|
+
if (cleaned.length < 3) return;
|
|
38529
|
+
const area = ShapeUtils.area(cleaned);
|
|
38530
|
+
if (Math.abs(area) > minArea) {
|
|
38531
|
+
shapesData.push({ pts2d: cleaned, absArea: Math.abs(area), depth: 0, parent: -1, holes: [] });
|
|
38532
|
+
}
|
|
38533
|
+
});
|
|
38534
|
+
shapesData.sort((a, b) => b.absArea - a.absArea);
|
|
38535
|
+
for (let i = 0; i < shapesData.length; i++) {
|
|
38536
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
38537
|
+
if (shapesData[i].absArea > shapesData[j].absArea * 0.98) continue;
|
|
38538
|
+
if (this._isLoopInside(shapesData[i].pts2d, shapesData[j].pts2d, localRadius)) {
|
|
38539
|
+
shapesData[i].parent = j;
|
|
38540
|
+
shapesData[i].depth = shapesData[j].depth + 1;
|
|
38541
|
+
break;
|
|
38542
|
+
}
|
|
38543
|
+
}
|
|
38544
|
+
}
|
|
38545
|
+
for (let i = 0; i < shapesData.length; i++) {
|
|
38546
|
+
const shape = shapesData[i];
|
|
38547
|
+
if (shape.depth % 2 === 1 && shape.parent !== -1) {
|
|
38548
|
+
shapesData[shape.parent].holes.push(shape.pts2d);
|
|
38549
|
+
}
|
|
38550
|
+
}
|
|
38551
|
+
for (let i = 0; i < shapesData.length; i++) {
|
|
38552
|
+
const shapeData = shapesData[i];
|
|
38553
|
+
if (shapeData.depth % 2 !== 0) continue;
|
|
38554
|
+
if (ShapeUtils.area(shapeData.pts2d) < 0) {
|
|
38555
|
+
shapeData.pts2d.reverse();
|
|
38556
|
+
}
|
|
38557
|
+
shapeData.holes.forEach((h) => {
|
|
38558
|
+
if (ShapeUtils.area(h) > 0) h.reverse();
|
|
38559
|
+
});
|
|
38560
|
+
const allPoints = [...shapeData.pts2d];
|
|
38561
|
+
shapeData.holes.forEach((h) => allPoints.push(...h));
|
|
38562
|
+
const faces = ShapeUtils.triangulateShape(shapeData.pts2d, shapeData.holes);
|
|
38563
|
+
const vertexOffset = positionsBuffer.length / 3;
|
|
38564
|
+
for (const pt of allPoints) {
|
|
38565
|
+
const p3d = planeOrigin.clone().addScaledVector(uAxis, pt.x).addScaledVector(vAxis, pt.y);
|
|
38566
|
+
positionsBuffer.push(p3d.x, p3d.y, p3d.z);
|
|
38567
|
+
hatchDirsBuffer.push(hatchDir);
|
|
38568
|
+
fillColorsBuffer.push(fillColor.r, fillColor.g, fillColor.b);
|
|
38569
|
+
}
|
|
38570
|
+
for (let f = 0; f < faces.length; f++) {
|
|
38571
|
+
indicesBuffer.push(vertexOffset + faces[f][0], vertexOffset + faces[f][1], vertexOffset + faces[f][2]);
|
|
38572
|
+
}
|
|
38573
|
+
}
|
|
38574
|
+
}
|
|
38575
|
+
_isPointInPoly(pt, poly) {
|
|
38576
|
+
let inside = false;
|
|
38577
|
+
const py = pt.y + 1.119e-7;
|
|
38578
|
+
const px = pt.x;
|
|
38579
|
+
for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {
|
|
38580
|
+
if (
|
|
38581
|
+
poly[i].y > py !== poly[j].y > py &&
|
|
38582
|
+
px < ((poly[j].x - poly[i].x) * (py - poly[i].y)) / (poly[j].y - poly[i].y) + poly[i].x
|
|
38583
|
+
) {
|
|
38584
|
+
inside = !inside;
|
|
38585
|
+
}
|
|
38586
|
+
}
|
|
38587
|
+
return inside;
|
|
38588
|
+
}
|
|
38589
|
+
_isLoopInside(child, parent, localRadius) {
|
|
38590
|
+
let minX1 = Infinity;
|
|
38591
|
+
let maxX1 = -Infinity;
|
|
38592
|
+
let minY1 = Infinity;
|
|
38593
|
+
let maxY1 = -Infinity;
|
|
38594
|
+
for (const p of child) {
|
|
38595
|
+
if (p.x < minX1) minX1 = p.x;
|
|
38596
|
+
if (p.x > maxX1) maxX1 = p.x;
|
|
38597
|
+
if (p.y < minY1) minY1 = p.y;
|
|
38598
|
+
if (p.y > maxY1) maxY1 = p.y;
|
|
38599
|
+
}
|
|
38600
|
+
let minX2 = Infinity;
|
|
38601
|
+
let maxX2 = -Infinity;
|
|
38602
|
+
let minY2 = Infinity;
|
|
38603
|
+
let maxY2 = -Infinity;
|
|
38604
|
+
for (const p of parent) {
|
|
38605
|
+
if (p.x < minX2) minX2 = p.x;
|
|
38606
|
+
if (p.x > maxX2) maxX2 = p.x;
|
|
38607
|
+
if (p.y < minY2) minY2 = p.y;
|
|
38608
|
+
if (p.y > maxY2) maxY2 = p.y;
|
|
38609
|
+
}
|
|
38610
|
+
const margin = Math.max(localRadius * 1e-4, 1e-5);
|
|
38611
|
+
if (minX1 < minX2 - margin || maxX1 > maxX2 + margin || minY1 < minY2 - margin || maxY1 > maxY2 + margin) {
|
|
38612
|
+
return false;
|
|
38613
|
+
}
|
|
38614
|
+
let insideCount = 0;
|
|
38615
|
+
for (let i = 0; i < child.length; i++) {
|
|
38616
|
+
if (this._isPointInPoly(child[i], parent)) {
|
|
38617
|
+
insideCount++;
|
|
38618
|
+
}
|
|
38619
|
+
}
|
|
38620
|
+
return insideCount >= child.length * 0.85;
|
|
38621
|
+
}
|
|
38622
|
+
_calculateMeshSegmentsUndirected(mesh, plane, edgeStats, grid, eps) {
|
|
38623
|
+
const geom = mesh.geometry;
|
|
38624
|
+
const pos = geom.attributes.position;
|
|
38625
|
+
const index = geom.index;
|
|
38626
|
+
const world = mesh.matrixWorld;
|
|
38627
|
+
const count = index ? index.count : pos.count;
|
|
38628
|
+
for (let i = 0; i < count; i += 3) {
|
|
38629
|
+
const i1 = index ? index.getX(i) : i;
|
|
38630
|
+
const i2 = index ? index.getX(i + 1) : i + 1;
|
|
38631
|
+
const i3 = index ? index.getX(i + 2) : i + 2;
|
|
38632
|
+
const v1 = this._vA.fromBufferAttribute(pos, i1).applyMatrix4(world);
|
|
38633
|
+
const v2 = this._vB.fromBufferAttribute(pos, i2).applyMatrix4(world);
|
|
38634
|
+
const v3 = this._vC.fromBufferAttribute(pos, i3).applyMatrix4(world);
|
|
38635
|
+
let d1 = plane.distanceToPoint(v1);
|
|
38636
|
+
let d2 = plane.distanceToPoint(v2);
|
|
38637
|
+
let d3 = plane.distanceToPoint(v3);
|
|
38638
|
+
if (Math.abs(d1) <= eps) d1 = eps;
|
|
38639
|
+
if (Math.abs(d2) <= eps) d2 = eps;
|
|
38640
|
+
if (Math.abs(d3) <= eps) d3 = eps;
|
|
38641
|
+
const s1 = d1 > 0 ? 1 : -1;
|
|
38642
|
+
const s2 = d2 > 0 ? 1 : -1;
|
|
38643
|
+
const s3 = d3 > 0 ? 1 : -1;
|
|
38644
|
+
if (s1 === s2 && s2 === s3) continue;
|
|
38645
|
+
const intersections = [];
|
|
38646
|
+
if (s1 !== s2) {
|
|
38647
|
+
intersections.push(new Vector3().lerpVectors(v1, v2, Math.abs(d1) / (Math.abs(d1) + Math.abs(d2))));
|
|
38648
|
+
}
|
|
38649
|
+
if (s2 !== s3) {
|
|
38650
|
+
intersections.push(new Vector3().lerpVectors(v2, v3, Math.abs(d2) / (Math.abs(d2) + Math.abs(d3))));
|
|
38651
|
+
}
|
|
38652
|
+
if (s3 !== s1) {
|
|
38653
|
+
intersections.push(new Vector3().lerpVectors(v3, v1, Math.abs(d3) / (Math.abs(d3) + Math.abs(d1))));
|
|
38654
|
+
}
|
|
38655
|
+
if (intersections.length >= 2) {
|
|
38656
|
+
const id1 = grid.add(intersections[0]);
|
|
38657
|
+
const id2 = grid.add(intersections[1]);
|
|
38658
|
+
if (id1 !== id2) {
|
|
38659
|
+
const key = id1 < id2 ? `${id1}-${id2}` : `${id2}-${id1}`;
|
|
38660
|
+
const stat = edgeStats.get(key) || { count: 0 };
|
|
38661
|
+
stat.count++;
|
|
38662
|
+
edgeStats.set(key, stat);
|
|
38663
|
+
}
|
|
38664
|
+
}
|
|
38665
|
+
}
|
|
38666
|
+
}
|
|
38667
|
+
}
|
|
38668
|
+
|
|
38669
|
+
class SectionsComponent {
|
|
38670
|
+
constructor(viewer) {
|
|
38671
|
+
this.updateTimerId = 0;
|
|
38672
|
+
this.updateDelay = 250;
|
|
38673
|
+
this.syncOptions = () => {
|
|
38674
|
+
function rgbToHex(c) {
|
|
38675
|
+
const hex = (v = 0) => v.toString(16).padStart(2, "0");
|
|
38676
|
+
return "#" + hex(c.r) + hex(c.g) + hex(c.b);
|
|
38677
|
+
}
|
|
38678
|
+
const options = this.viewer.options;
|
|
38679
|
+
const flags = this.sectionsHelper.flags;
|
|
38680
|
+
flags.fillEnabled = options.enableSectionFill;
|
|
38681
|
+
flags.fillColor = rgbToHex(options.sectionFillColor);
|
|
38682
|
+
flags.useObjFillColor = options.sectionUseObjectColor;
|
|
38683
|
+
flags.hatchEnabled = options.enableSectionHatch;
|
|
38684
|
+
flags.hatchColor = rgbToHex(options.sectionHatchColor);
|
|
38685
|
+
flags.hatchScale = options.sectionHatchScale;
|
|
38686
|
+
flags.outlineEnabled = options.enableSectionOutline;
|
|
38687
|
+
flags.outlineColor = rgbToHex(options.sectionOutlineColor);
|
|
38688
|
+
flags.outlineWidth = options.sectionOutlineWidth;
|
|
38689
|
+
this.syncSections();
|
|
38690
|
+
};
|
|
38691
|
+
this.syncHelper = () => {
|
|
38692
|
+
this.sectionsHelper.removeFromParent();
|
|
38693
|
+
this.viewer.helpers.add(this.sectionsHelper);
|
|
38694
|
+
};
|
|
38695
|
+
this.syncSections = () => {
|
|
38696
|
+
this.sectionsHelper.visible = false;
|
|
38697
|
+
clearTimeout(this.updateTimerId);
|
|
38698
|
+
this.updateTimerId = window.setTimeout(this.updateSections, this.updateDelay);
|
|
38699
|
+
};
|
|
38700
|
+
this.viewerResize = (event) => {
|
|
38701
|
+
this.sectionsHelper.setSize(event.width, event.height);
|
|
38702
|
+
};
|
|
38703
|
+
this.updateSections = () => {
|
|
38704
|
+
const objects = [];
|
|
38705
|
+
this.viewer.models.forEach((model) => objects.push(model.getVisibleObjects()));
|
|
38706
|
+
const objects2 = objects.flat();
|
|
38707
|
+
this.sectionsHelper.update(objects2, this.viewer.extents, this.viewer.clippingPlanes);
|
|
38708
|
+
this.sectionsHelper.visible = true;
|
|
38709
|
+
this.viewer.update();
|
|
38710
|
+
};
|
|
38711
|
+
this.sectionsHelper = new SectionsHelper();
|
|
38712
|
+
this.viewer = viewer;
|
|
38713
|
+
this.viewer.addEventListener("initialize", this.syncHelper);
|
|
38714
|
+
this.viewer.addEventListener("databasechunk", this.syncHelper);
|
|
38715
|
+
this.viewer.addEventListener("drawviewpoint", this.syncHelper);
|
|
38716
|
+
this.viewer.addEventListener("changecuttingplanes", this.syncSections);
|
|
38717
|
+
this.viewer.addEventListener("explode", this.syncSections);
|
|
38718
|
+
this.viewer.addEventListener("hide", this.syncSections);
|
|
38719
|
+
this.viewer.addEventListener("isolate", this.syncSections);
|
|
38720
|
+
this.viewer.addEventListener("show", this.syncSections);
|
|
38721
|
+
this.viewer.addEventListener("showall", this.syncSections);
|
|
38722
|
+
this.viewer.addEventListener("resize", this.viewerResize);
|
|
38723
|
+
this.viewer.addEventListener("optionschange", this.syncOptions);
|
|
38724
|
+
this.syncOptions();
|
|
38725
|
+
}
|
|
38726
|
+
dispose() {
|
|
38727
|
+
clearTimeout(this.updateTimerId);
|
|
38728
|
+
this.sectionsHelper.removeFromParent();
|
|
38729
|
+
this.sectionsHelper.dispose();
|
|
38730
|
+
this.viewer.removeEventListener("initialize", this.syncHelper);
|
|
38731
|
+
this.viewer.removeEventListener("databasechunk", this.syncHelper);
|
|
38732
|
+
this.viewer.removeEventListener("drawviewpoint", this.syncHelper);
|
|
38733
|
+
this.viewer.removeEventListener("changecuttingplanes", this.syncSections);
|
|
38734
|
+
this.viewer.removeEventListener("explode", this.syncSections);
|
|
38735
|
+
this.viewer.removeEventListener("hide", this.syncSections);
|
|
38736
|
+
this.viewer.removeEventListener("isolate", this.syncSections);
|
|
38737
|
+
this.viewer.removeEventListener("show", this.syncSections);
|
|
38738
|
+
this.viewer.removeEventListener("showall", this.syncSections);
|
|
38739
|
+
this.viewer.removeEventListener("resize", this.viewerResize);
|
|
38740
|
+
this.viewer.removeEventListener("optionschange", this.syncOptions);
|
|
38741
|
+
}
|
|
38742
|
+
}
|
|
38743
|
+
|
|
37625
38744
|
class WCSHelper extends Object3D {
|
|
37626
38745
|
constructor(camera) {
|
|
37627
38746
|
super();
|
|
38747
|
+
this.type = "WCSHelper";
|
|
37628
38748
|
this.camera = camera;
|
|
37629
38749
|
this.size = 160;
|
|
37630
38750
|
this.orthoCamera = new OrthographicCamera(-2, 2, 2, -2, 0, 4);
|
|
@@ -37684,11 +38804,13 @@ void main() {
|
|
|
37684
38804
|
canvas.width = 64;
|
|
37685
38805
|
canvas.height = 64;
|
|
37686
38806
|
const context = canvas.getContext("2d");
|
|
37687
|
-
context
|
|
37688
|
-
|
|
37689
|
-
|
|
37690
|
-
|
|
37691
|
-
|
|
38807
|
+
if (context) {
|
|
38808
|
+
context.clearRect(0, 0, 64, 64);
|
|
38809
|
+
context.font = "24px Arial";
|
|
38810
|
+
context.textAlign = "center";
|
|
38811
|
+
context.fillStyle = color.getStyle();
|
|
38812
|
+
context.fillText(text, 32, 41);
|
|
38813
|
+
}
|
|
37692
38814
|
const texture = new CanvasTexture(canvas);
|
|
37693
38815
|
texture.colorSpace = SRGBColorSpace;
|
|
37694
38816
|
return new SpriteMaterial({ map: texture, toneMapped: false });
|
|
@@ -37712,7 +38834,7 @@ void main() {
|
|
|
37712
38834
|
|
|
37713
38835
|
class WCSHelperComponent {
|
|
37714
38836
|
constructor(viewer) {
|
|
37715
|
-
this.
|
|
38837
|
+
this.syncHelper = () => {
|
|
37716
38838
|
this.wcsHelper.dispose();
|
|
37717
38839
|
this.wcsHelper = new WCSHelper(this.viewer.camera);
|
|
37718
38840
|
};
|
|
@@ -37726,14 +38848,14 @@ void main() {
|
|
|
37726
38848
|
};
|
|
37727
38849
|
this.wcsHelper = new WCSHelper(viewer.camera);
|
|
37728
38850
|
this.viewer = viewer;
|
|
37729
|
-
this.viewer.addEventListener("databasechunk", this.
|
|
37730
|
-
this.viewer.addEventListener("drawviewpoint", this.
|
|
38851
|
+
this.viewer.addEventListener("databasechunk", this.syncHelper);
|
|
38852
|
+
this.viewer.addEventListener("drawviewpoint", this.syncHelper);
|
|
37731
38853
|
this.viewer.addEventListener("render", this.viewerRender);
|
|
37732
38854
|
this.viewer.addEventListener("changecameramode", this.updateHelperCamera);
|
|
37733
38855
|
}
|
|
37734
38856
|
dispose() {
|
|
37735
|
-
this.viewer.removeEventListener("databasechunk", this.
|
|
37736
|
-
this.viewer.removeEventListener("drawviewpoint", this.
|
|
38857
|
+
this.viewer.removeEventListener("databasechunk", this.syncHelper);
|
|
38858
|
+
this.viewer.removeEventListener("drawviewpoint", this.syncHelper);
|
|
37737
38859
|
this.viewer.removeEventListener("render", this.viewerRender);
|
|
37738
38860
|
this.viewer.removeEventListener("changecameramode", this.updateHelperCamera);
|
|
37739
38861
|
this.wcsHelper.dispose();
|
|
@@ -37779,11 +38901,14 @@ void main() {
|
|
|
37779
38901
|
components.registerComponent("RenderLoopComponent", (viewer) => new RenderLoopComponent(viewer));
|
|
37780
38902
|
components.registerComponent("HighlighterComponent", (viewer) => new HighlighterComponent(viewer));
|
|
37781
38903
|
components.registerComponent("SelectionComponent", (viewer) => new SelectionComponent(viewer));
|
|
38904
|
+
components.registerComponent("ClippingPlaneComponent", (viewer) => new ClippingPlaneComponent(viewer));
|
|
38905
|
+
components.registerComponent("SectionsComponent", (viewer) => new SectionsComponent(viewer));
|
|
37782
38906
|
components.registerComponent("WCSHelperComponent", (viewer) => new WCSHelperComponent(viewer));
|
|
37783
38907
|
components.registerComponent("ResetComponent", (viewer) => new ResetComponent(viewer));
|
|
37784
38908
|
|
|
37785
38909
|
class ModelImpl {
|
|
37786
38910
|
constructor(scene) {
|
|
38911
|
+
this.id = "";
|
|
37787
38912
|
this.scene = scene;
|
|
37788
38913
|
this.handleToObjects = new Map();
|
|
37789
38914
|
this.originalObjects = new Set();
|
|
@@ -37814,8 +38939,8 @@ void main() {
|
|
|
37814
38939
|
if (object.material)
|
|
37815
38940
|
disposeMaterials(object.material);
|
|
37816
38941
|
}
|
|
37817
|
-
this.handleToObjects
|
|
37818
|
-
this.originalObjects
|
|
38942
|
+
this.handleToObjects.clear();
|
|
38943
|
+
this.originalObjects.clear();
|
|
37819
38944
|
this.scene.traverse(disposeObject);
|
|
37820
38945
|
this.scene.clear();
|
|
37821
38946
|
}
|
|
@@ -37959,7 +39084,25 @@ void main() {
|
|
|
37959
39084
|
return info;
|
|
37960
39085
|
}
|
|
37961
39086
|
getExtents(target) {
|
|
37962
|
-
|
|
39087
|
+
const _box = new Box3();
|
|
39088
|
+
function expandByObject(object, target) {
|
|
39089
|
+
if (!object.geometry)
|
|
39090
|
+
return;
|
|
39091
|
+
object.updateWorldMatrix(false, false);
|
|
39092
|
+
if (object.boundingBox !== undefined) {
|
|
39093
|
+
if (object.boundingBox === null)
|
|
39094
|
+
object.computeBoundingBox();
|
|
39095
|
+
_box.copy(object.boundingBox);
|
|
39096
|
+
}
|
|
39097
|
+
else {
|
|
39098
|
+
if (object.geometry.boundingBox === null)
|
|
39099
|
+
object.geometry.computeBoundingBox();
|
|
39100
|
+
_box.copy(object.geometry.boundingBox);
|
|
39101
|
+
}
|
|
39102
|
+
_box.applyMatrix4(object.matrixWorld);
|
|
39103
|
+
target.union(_box);
|
|
39104
|
+
}
|
|
39105
|
+
this.scene.traverseVisible((object) => expandByObject(object, target));
|
|
37963
39106
|
return target;
|
|
37964
39107
|
}
|
|
37965
39108
|
getObjects() {
|
|
@@ -37967,8 +39110,8 @@ void main() {
|
|
|
37967
39110
|
}
|
|
37968
39111
|
getVisibleObjects() {
|
|
37969
39112
|
const objects = [];
|
|
37970
|
-
this.scene.traverseVisible((object) => objects.push(object));
|
|
37971
|
-
return objects
|
|
39113
|
+
this.scene.traverseVisible((object) => object.userData.handle && objects.push(object));
|
|
39114
|
+
return objects;
|
|
37972
39115
|
}
|
|
37973
39116
|
getObjectsByHandles(handles) {
|
|
37974
39117
|
if (!Array.isArray(handles))
|
|
@@ -38063,44 +39206,54 @@ void main() {
|
|
|
38063
39206
|
centersCache.set(handle, target.clone());
|
|
38064
39207
|
return target;
|
|
38065
39208
|
};
|
|
38066
|
-
|
|
38067
|
-
|
|
38068
|
-
|
|
38069
|
-
|
|
38070
|
-
|
|
38071
|
-
|
|
38072
|
-
|
|
39209
|
+
const calcObjectOffset = (object, target) => {
|
|
39210
|
+
const parent = object.parent;
|
|
39211
|
+
if (!parent || parent.userData.originalCenter === undefined)
|
|
39212
|
+
return target;
|
|
39213
|
+
return target.subVectors(object.userData.originalCenter, parent.userData.originalCenter);
|
|
39214
|
+
};
|
|
39215
|
+
const calcObjectDepth = (object) => {
|
|
39216
|
+
if (object.userData.depth !== undefined)
|
|
39217
|
+
return object.userData.depth;
|
|
39218
|
+
const parent = object.parent;
|
|
39219
|
+
const depth = parent && object !== explodeRoot ? calcObjectDepth(parent) + 1 : 0;
|
|
39220
|
+
object.userData.depth = depth;
|
|
38073
39221
|
object.userData.originalPosition = object.position.clone();
|
|
38074
39222
|
object.userData.originalCenter = calcObjectCenter(object, new Vector3());
|
|
38075
|
-
|
|
38076
|
-
|
|
39223
|
+
object.userData.originalOffset = calcObjectOffset(object, new Vector3());
|
|
39224
|
+
return depth;
|
|
39225
|
+
};
|
|
38077
39226
|
const explodeScale = scale / 100;
|
|
38078
39227
|
const explodeRoot = this.scene;
|
|
38079
|
-
|
|
38080
|
-
|
|
39228
|
+
const explodeObjects = this.getObjects();
|
|
39229
|
+
if (explodeRoot.userData.explodeDepth === undefined) {
|
|
39230
|
+
let maxDepth = 0;
|
|
39231
|
+
explodeObjects.forEach((object) => {
|
|
39232
|
+
const depth = calcObjectDepth(object);
|
|
39233
|
+
if (depth > maxDepth)
|
|
39234
|
+
maxDepth = depth;
|
|
39235
|
+
});
|
|
39236
|
+
explodeRoot.userData.explodeDepth = maxDepth;
|
|
38081
39237
|
}
|
|
38082
39238
|
const maxDepth = explodeRoot.userData.explodeDepth;
|
|
38083
39239
|
const scaledExplodeDepth = explodeScale * maxDepth + 1;
|
|
38084
39240
|
const explodeDepth = 0 | scaledExplodeDepth;
|
|
38085
39241
|
const currentSegmentFraction = scaledExplodeDepth - explodeDepth;
|
|
38086
|
-
|
|
39242
|
+
const explodeObject = (object) => {
|
|
38087
39243
|
if (object.isCamera)
|
|
38088
39244
|
return;
|
|
38089
|
-
if (object.userData.isHighlightWireframe)
|
|
38090
|
-
return;
|
|
38091
39245
|
object.position.copy(object.userData.originalPosition);
|
|
39246
|
+
const depth = object.userData.depth;
|
|
38092
39247
|
if (depth > 0 && depth <= explodeDepth) {
|
|
38093
39248
|
let objectScale = explodeScale * coeff;
|
|
38094
39249
|
if (depth === explodeDepth)
|
|
38095
39250
|
objectScale *= currentSegmentFraction;
|
|
38096
|
-
|
|
38097
|
-
const objectCenter = object.userData.originalCenter;
|
|
38098
|
-
const localOffset = objectCenter.clone().sub(parentCenter).multiplyScalar(objectScale);
|
|
38099
|
-
object.position.add(localOffset);
|
|
39251
|
+
object.position.addScaledVector(object.userData.originalOffset, objectScale);
|
|
38100
39252
|
}
|
|
38101
|
-
|
|
38102
|
-
|
|
38103
|
-
|
|
39253
|
+
};
|
|
39254
|
+
explodeObjects.forEach((object) => {
|
|
39255
|
+
explodeObject(object);
|
|
39256
|
+
});
|
|
38104
39257
|
this.scene.updateMatrixWorld();
|
|
38105
39258
|
return this;
|
|
38106
39259
|
}
|
|
@@ -38203,6 +39356,12 @@ void main() {
|
|
|
38203
39356
|
centersCache.set(handle, target.clone());
|
|
38204
39357
|
return target;
|
|
38205
39358
|
};
|
|
39359
|
+
const calcObjectOffset = (object, target) => {
|
|
39360
|
+
const parent = object.parent;
|
|
39361
|
+
if (!parent || parent.userData.originalCenter === undefined)
|
|
39362
|
+
return target;
|
|
39363
|
+
return target.subVectors(object.userData.originalCenter, parent.userData.originalCenter);
|
|
39364
|
+
};
|
|
38206
39365
|
const calcObjectDepth = (object) => {
|
|
38207
39366
|
if (object.userData.depth !== undefined)
|
|
38208
39367
|
return object.userData.depth;
|
|
@@ -38211,13 +39370,15 @@ void main() {
|
|
|
38211
39370
|
object.userData.depth = depth;
|
|
38212
39371
|
object.userData.originalPosition = object.position.clone();
|
|
38213
39372
|
object.userData.originalCenter = calcObjectCenter(object, new Vector3());
|
|
39373
|
+
object.userData.originalOffset = calcObjectOffset(object, new Vector3());
|
|
38214
39374
|
return depth;
|
|
38215
39375
|
};
|
|
38216
39376
|
const explodeScale = scale / 100;
|
|
38217
39377
|
const explodeRoot = this.scene.children[0];
|
|
38218
|
-
|
|
39378
|
+
const explodeObjects = this.getObjects();
|
|
39379
|
+
if (explodeRoot.userData.explodeDepth === undefined) {
|
|
38219
39380
|
let maxDepth = 0;
|
|
38220
|
-
|
|
39381
|
+
explodeObjects.forEach((object) => {
|
|
38221
39382
|
const depth = calcObjectDepth(object);
|
|
38222
39383
|
if (depth > maxDepth)
|
|
38223
39384
|
maxDepth = depth;
|
|
@@ -38229,29 +39390,26 @@ void main() {
|
|
|
38229
39390
|
const explodeDepth = 0 | scaledExplodeDepth;
|
|
38230
39391
|
const currentSegmentFraction = scaledExplodeDepth - explodeDepth;
|
|
38231
39392
|
const offsetCache = new Map();
|
|
38232
|
-
const
|
|
39393
|
+
const calcExplodeOffset = (object, target) => {
|
|
38233
39394
|
if (offsetCache.has(object))
|
|
38234
39395
|
return target.copy(offsetCache.get(object));
|
|
38235
39396
|
const parent = object.parent;
|
|
38236
39397
|
if (parent && object !== explodeRoot)
|
|
38237
|
-
|
|
39398
|
+
calcExplodeOffset(parent, target);
|
|
38238
39399
|
const depth = object.userData.depth;
|
|
38239
39400
|
if (depth > 0 && depth <= explodeDepth) {
|
|
38240
39401
|
let objectScale = explodeScale * coeff;
|
|
38241
39402
|
if (depth === explodeDepth)
|
|
38242
39403
|
objectScale *= currentSegmentFraction;
|
|
38243
|
-
|
|
38244
|
-
const objectCenter = object.userData.originalCenter;
|
|
38245
|
-
const localOffset = objectCenter.clone().sub(parentCenter).multiplyScalar(objectScale);
|
|
38246
|
-
target.add(localOffset);
|
|
39404
|
+
target.addScaledVector(object.userData.originalOffset, objectScale);
|
|
38247
39405
|
}
|
|
38248
39406
|
offsetCache.set(object, target.clone());
|
|
38249
39407
|
return target;
|
|
38250
39408
|
};
|
|
38251
39409
|
const transformMap = new Map();
|
|
38252
|
-
|
|
38253
|
-
const
|
|
38254
|
-
transformMap.set(object, new Matrix4().makeTranslation(
|
|
39410
|
+
explodeObjects.forEach((object) => {
|
|
39411
|
+
const offset = calcExplodeOffset(object, new Vector3());
|
|
39412
|
+
transformMap.set(object, new Matrix4().makeTranslation(offset));
|
|
38255
39413
|
});
|
|
38256
39414
|
this.gltfLoader.applyObjectTransforms(transformMap);
|
|
38257
39415
|
this.scene.updateMatrixWorld();
|
|
@@ -38322,6 +39480,7 @@ void main() {
|
|
|
38322
39480
|
this._nextObjectId = 1;
|
|
38323
39481
|
this.loadingAborted = false;
|
|
38324
39482
|
this.criticalError = null;
|
|
39483
|
+
this.embeddedBinaryChunk = null;
|
|
38325
39484
|
}
|
|
38326
39485
|
async initialize(loader) {
|
|
38327
39486
|
const json = await this.loadController.loadJson();
|
|
@@ -38330,28 +39489,72 @@ void main() {
|
|
|
38330
39489
|
}
|
|
38331
39490
|
this.json = json;
|
|
38332
39491
|
this.loader = loader;
|
|
38333
|
-
|
|
39492
|
+
const bufferUri = this.json.buffers?.[0]?.uri || "";
|
|
39493
|
+
if (bufferUri.startsWith("data:")) {
|
|
39494
|
+
this.embeddedBinaryChunk = await this._decodeDataUri(bufferUri);
|
|
39495
|
+
this.uri = "";
|
|
39496
|
+
} else {
|
|
39497
|
+
this.uri = bufferUri;
|
|
39498
|
+
}
|
|
39499
|
+
}
|
|
39500
|
+
async _decodeDataUri(dataUri) {
|
|
39501
|
+
try {
|
|
39502
|
+
const response = await fetch(dataUri);
|
|
39503
|
+
return await response.arrayBuffer();
|
|
39504
|
+
} catch (e) {
|
|
39505
|
+
throw new Error(`DynamicLoader: Failed to decode embedded data URI: ${e.message}`);
|
|
39506
|
+
}
|
|
38334
39507
|
}
|
|
38335
39508
|
clear() {
|
|
38336
|
-
this.json = null;
|
|
38337
|
-
this.loadController = null;
|
|
38338
|
-
this.pendingRequests = [];
|
|
38339
39509
|
if (this.batchTimeout) {
|
|
38340
39510
|
clearTimeout(this.batchTimeout);
|
|
38341
39511
|
this.batchTimeout = null;
|
|
38342
39512
|
}
|
|
38343
|
-
this.
|
|
38344
|
-
this.
|
|
38345
|
-
|
|
39513
|
+
this._rejectPendingRequests();
|
|
39514
|
+
if (this.disposeMaterials) {
|
|
39515
|
+
try {
|
|
39516
|
+
this.disposeMaterials();
|
|
39517
|
+
} catch (e) {
|
|
39518
|
+
console.warn("DynamicLoader: error during disposeMaterials in clear():", e);
|
|
39519
|
+
}
|
|
39520
|
+
}
|
|
39521
|
+
if (this.textureCache) this.textureCache.clear();
|
|
39522
|
+
if (this.materials) this.materials.clear();
|
|
39523
|
+
this.embeddedBinaryChunk = null;
|
|
39524
|
+
this.json = null;
|
|
39525
|
+
this.loadController = null;
|
|
39526
|
+
this.uri = "";
|
|
38346
39527
|
this.activeChunkLoads = 0;
|
|
38347
39528
|
this.chunkQueue = [];
|
|
38348
39529
|
this.loadingAborted = false;
|
|
38349
39530
|
this.criticalError = null;
|
|
38350
39531
|
}
|
|
39532
|
+
_rejectPendingRequests() {
|
|
39533
|
+
const pending = this.pendingRequests;
|
|
39534
|
+
this.pendingRequests = [];
|
|
39535
|
+
if (!pending || pending.length === 0) return;
|
|
39536
|
+
const cancelError = new Error("DynamicLoader: Structure cleared while requests pending");
|
|
39537
|
+
for (let i = 0; i < pending.length; i++) {
|
|
39538
|
+
const item = pending[i];
|
|
39539
|
+
if (item && typeof item._reject === "function") {
|
|
39540
|
+
try {
|
|
39541
|
+
item._reject(cancelError);
|
|
39542
|
+
} catch {
|
|
39543
|
+
}
|
|
39544
|
+
}
|
|
39545
|
+
}
|
|
39546
|
+
}
|
|
38351
39547
|
getJson() {
|
|
38352
39548
|
return this.json;
|
|
38353
39549
|
}
|
|
38354
39550
|
scheduleRequest(request) {
|
|
39551
|
+
if (this.embeddedBinaryChunk && !this.uri) {
|
|
39552
|
+
return Promise.resolve({
|
|
39553
|
+
buffer: this.embeddedBinaryChunk,
|
|
39554
|
+
relOffset: request.offset,
|
|
39555
|
+
length: request.length,
|
|
39556
|
+
});
|
|
39557
|
+
}
|
|
38355
39558
|
return new Promise((resolve, reject) => {
|
|
38356
39559
|
if (this.loadingAborted) {
|
|
38357
39560
|
reject(
|
|
@@ -38628,8 +39831,13 @@ void main() {
|
|
|
38628
39831
|
return await this.textureLoader.loadAsync(fullUrl);
|
|
38629
39832
|
} else if (image.bufferView !== undefined) {
|
|
38630
39833
|
const bufferView = this.json.bufferViews[image.bufferView];
|
|
38631
|
-
const
|
|
38632
|
-
|
|
39834
|
+
const { buffer, relOffset } = await this.getBufferView(
|
|
39835
|
+
bufferView.byteOffset || 0,
|
|
39836
|
+
bufferView.byteLength,
|
|
39837
|
+
5121
|
|
39838
|
+
);
|
|
39839
|
+
const imageBytes = new Uint8Array(buffer, relOffset, bufferView.byteLength);
|
|
39840
|
+
const blob = new Blob([imageBytes], { type: image.mimeType });
|
|
38633
39841
|
const url = URL.createObjectURL(blob);
|
|
38634
39842
|
const texture = await this.textureLoader.loadAsync(url);
|
|
38635
39843
|
URL.revokeObjectURL(url);
|
|
@@ -38659,6 +39867,7 @@ void main() {
|
|
|
38659
39867
|
})
|
|
38660
39868
|
);
|
|
38661
39869
|
}
|
|
39870
|
+
await this.flushBufferRequests();
|
|
38662
39871
|
await Promise.all(texturePromises);
|
|
38663
39872
|
}
|
|
38664
39873
|
loadMaterials() {
|
|
@@ -39016,6 +40225,7 @@ void main() {
|
|
|
39016
40225
|
return result;
|
|
39017
40226
|
}
|
|
39018
40227
|
|
|
40228
|
+
const DRACO_EXTENSION_NAME = "KHR_draco_mesh_compression";
|
|
39019
40229
|
const STRUCTURE_ID_SEPARATOR = ":";
|
|
39020
40230
|
class DynamicGltfLoader {
|
|
39021
40231
|
constructor(camera, scene, renderer) {
|
|
@@ -39090,6 +40300,189 @@ void main() {
|
|
|
39090
40300
|
this.transformData = null;
|
|
39091
40301
|
this.identityTransformData = null;
|
|
39092
40302
|
this.visibilityMaterials = new Set();
|
|
40303
|
+
this._dracoLoader = null;
|
|
40304
|
+
}
|
|
40305
|
+
setDracoLoader(loader = null) {
|
|
40306
|
+
this._dracoLoader = loader || null;
|
|
40307
|
+
}
|
|
40308
|
+
async _decodeDracoPrimitive(structure, primitive, dracoBufferData) {
|
|
40309
|
+
const dracoExt = primitive.extensions[DRACO_EXTENSION_NAME];
|
|
40310
|
+
const loader = this._dracoLoader;
|
|
40311
|
+
const attributeIDs = {};
|
|
40312
|
+
const attributeTypes = {};
|
|
40313
|
+
const gltfNameToThreeName = new Map();
|
|
40314
|
+
const threeNameToAccessor = new Map();
|
|
40315
|
+
for (const [gltfAttrName, dracoUniqueId] of Object.entries(dracoExt.attributes)) {
|
|
40316
|
+
const threeName = this._gltfAttributeNameToThreeName(gltfAttrName);
|
|
40317
|
+
attributeIDs[threeName] = dracoUniqueId;
|
|
40318
|
+
gltfNameToThreeName.set(gltfAttrName, threeName);
|
|
40319
|
+
const accessorIdx = primitive.attributes[gltfAttrName];
|
|
40320
|
+
if (accessorIdx !== undefined) {
|
|
40321
|
+
const accessor = structure.json.accessors[accessorIdx];
|
|
40322
|
+
attributeTypes[threeName] = this._gltfComponentTypeToTypedArrayName(accessor.componentType);
|
|
40323
|
+
threeNameToAccessor.set(threeName, accessor);
|
|
40324
|
+
}
|
|
40325
|
+
}
|
|
40326
|
+
const geometry = await loader.decodeGeometry(dracoBufferData, {
|
|
40327
|
+
attributeIDs,
|
|
40328
|
+
attributeTypes,
|
|
40329
|
+
useUniqueIDs: true,
|
|
40330
|
+
});
|
|
40331
|
+
for (const [threeName, accessor] of threeNameToAccessor) {
|
|
40332
|
+
const attribute = geometry.getAttribute(threeName);
|
|
40333
|
+
if (!attribute) continue;
|
|
40334
|
+
if (accessor.normalized === true) {
|
|
40335
|
+
attribute.normalized = true;
|
|
40336
|
+
}
|
|
40337
|
+
if (accessor.min) attribute.min = accessor.min;
|
|
40338
|
+
if (accessor.max) attribute.max = accessor.max;
|
|
40339
|
+
}
|
|
40340
|
+
for (const [threeName, accessor] of threeNameToAccessor) {
|
|
40341
|
+
const attribute = geometry.getAttribute(threeName);
|
|
40342
|
+
if (!attribute || !attribute.normalized) continue;
|
|
40343
|
+
const denom = this._normalizedDenominator(accessor.componentType);
|
|
40344
|
+
if (denom <= 0) continue;
|
|
40345
|
+
const src = attribute.array;
|
|
40346
|
+
const inv = 1 / denom;
|
|
40347
|
+
const isSigned = accessor.componentType === 5120 || accessor.componentType === 5122;
|
|
40348
|
+
const out = new Float32Array(src.length);
|
|
40349
|
+
for (let i = 0; i < src.length; i++) {
|
|
40350
|
+
let v = src[i] * inv;
|
|
40351
|
+
if (isSigned && v < -1) v = -1;
|
|
40352
|
+
out[i] = v;
|
|
40353
|
+
}
|
|
40354
|
+
const newAttr = new BufferAttribute(out, attribute.itemSize, false);
|
|
40355
|
+
if (accessor.min) newAttr.min = accessor.min;
|
|
40356
|
+
if (accessor.max) newAttr.max = accessor.max;
|
|
40357
|
+
geometry.setAttribute(threeName, newAttr);
|
|
40358
|
+
}
|
|
40359
|
+
return geometry;
|
|
40360
|
+
}
|
|
40361
|
+
_gltfComponentTypeToTypedArrayName(componentType) {
|
|
40362
|
+
switch (componentType) {
|
|
40363
|
+
case 5120:
|
|
40364
|
+
return "Int8Array";
|
|
40365
|
+
case 5121:
|
|
40366
|
+
return "Uint8Array";
|
|
40367
|
+
case 5122:
|
|
40368
|
+
return "Int16Array";
|
|
40369
|
+
case 5123:
|
|
40370
|
+
return "Uint16Array";
|
|
40371
|
+
case 5125:
|
|
40372
|
+
return "Uint32Array";
|
|
40373
|
+
case 5126:
|
|
40374
|
+
return "Float32Array";
|
|
40375
|
+
default:
|
|
40376
|
+
return "Float32Array";
|
|
40377
|
+
}
|
|
40378
|
+
}
|
|
40379
|
+
_normalizedDenominator(componentType) {
|
|
40380
|
+
switch (componentType) {
|
|
40381
|
+
case 5120:
|
|
40382
|
+
return 127;
|
|
40383
|
+
case 5121:
|
|
40384
|
+
return 255;
|
|
40385
|
+
case 5122:
|
|
40386
|
+
return 32767;
|
|
40387
|
+
case 5123:
|
|
40388
|
+
return 65535;
|
|
40389
|
+
default:
|
|
40390
|
+
return 0;
|
|
40391
|
+
}
|
|
40392
|
+
}
|
|
40393
|
+
_gltfAttributeNameToThreeName(name) {
|
|
40394
|
+
switch (name) {
|
|
40395
|
+
case "POSITION":
|
|
40396
|
+
return "position";
|
|
40397
|
+
case "NORMAL":
|
|
40398
|
+
return "normal";
|
|
40399
|
+
case "TANGENT":
|
|
40400
|
+
return "tangent";
|
|
40401
|
+
case "TEXCOORD_0":
|
|
40402
|
+
return "uv";
|
|
40403
|
+
case "TEXCOORD_1":
|
|
40404
|
+
return "uv2";
|
|
40405
|
+
case "COLOR_0":
|
|
40406
|
+
return "color";
|
|
40407
|
+
case "JOINTS_0":
|
|
40408
|
+
return "skinIndex";
|
|
40409
|
+
case "WEIGHTS_0":
|
|
40410
|
+
return "skinWeight";
|
|
40411
|
+
default:
|
|
40412
|
+
return name.toLowerCase();
|
|
40413
|
+
}
|
|
40414
|
+
}
|
|
40415
|
+
_buildAccessorRequest(structure, accessorIndex, type, primIdx) {
|
|
40416
|
+
const accessor = structure.json.accessors[accessorIndex];
|
|
40417
|
+
const bufferView = structure.json.bufferViews[accessor.bufferView];
|
|
40418
|
+
const components = structure.getNumComponents(accessor.type);
|
|
40419
|
+
const componentSize = structure.getComponentSize(accessor.componentType);
|
|
40420
|
+
const itemBytes = components * componentSize;
|
|
40421
|
+
const accessorByteOffset = accessor.byteOffset || 0;
|
|
40422
|
+
const bvByteOffset = bufferView.byteOffset || 0;
|
|
40423
|
+
const byteStride = bufferView.byteStride || 0;
|
|
40424
|
+
const interleaved = byteStride !== 0 && byteStride !== itemBytes;
|
|
40425
|
+
const offset = bvByteOffset + accessorByteOffset;
|
|
40426
|
+
let length;
|
|
40427
|
+
if (interleaved) {
|
|
40428
|
+
length = (accessor.count - 1) * byteStride + itemBytes;
|
|
40429
|
+
} else {
|
|
40430
|
+
length = accessor.count * itemBytes;
|
|
40431
|
+
}
|
|
40432
|
+
return {
|
|
40433
|
+
offset,
|
|
40434
|
+
length,
|
|
40435
|
+
componentType: accessor.componentType,
|
|
40436
|
+
accessorIndex,
|
|
40437
|
+
type,
|
|
40438
|
+
primIdx,
|
|
40439
|
+
_accessor: accessor,
|
|
40440
|
+
_components: components,
|
|
40441
|
+
_componentSize: componentSize,
|
|
40442
|
+
_itemBytes: itemBytes,
|
|
40443
|
+
_byteStride: byteStride,
|
|
40444
|
+
_interleaved: interleaved,
|
|
40445
|
+
};
|
|
40446
|
+
}
|
|
40447
|
+
_createGeometryAttribute(req) {
|
|
40448
|
+
const accessor = req._accessor;
|
|
40449
|
+
const components = req._components;
|
|
40450
|
+
const count = accessor.count;
|
|
40451
|
+
const stride = req._interleaved ? req._byteStride / req._componentSize : components;
|
|
40452
|
+
const normalized = accessor.normalized === true;
|
|
40453
|
+
const componentType = req.componentType;
|
|
40454
|
+
const src = req.data;
|
|
40455
|
+
if (!req._interleaved && !normalized) {
|
|
40456
|
+
return new BufferAttribute(src, components, false);
|
|
40457
|
+
}
|
|
40458
|
+
if (normalized) {
|
|
40459
|
+
const denom = this._normalizedDenominator(componentType);
|
|
40460
|
+
if (denom > 0) {
|
|
40461
|
+
const out = new Float32Array(count * components);
|
|
40462
|
+
const inv = 1 / denom;
|
|
40463
|
+
const isSignedNormalized = componentType === 5120 || componentType === 5122;
|
|
40464
|
+
for (let i = 0; i < count; i++) {
|
|
40465
|
+
const srcBase = i * stride;
|
|
40466
|
+
const dstBase = i * components;
|
|
40467
|
+
for (let c = 0; c < components; c++) {
|
|
40468
|
+
let v = src[srcBase + c] * inv;
|
|
40469
|
+
if (isSignedNormalized && v < -1) v = -1;
|
|
40470
|
+
out[dstBase + c] = v;
|
|
40471
|
+
}
|
|
40472
|
+
}
|
|
40473
|
+
return new BufferAttribute(out, components, false);
|
|
40474
|
+
}
|
|
40475
|
+
}
|
|
40476
|
+
const TypedArrayCtor = src.constructor;
|
|
40477
|
+
const out = new TypedArrayCtor(count * components);
|
|
40478
|
+
for (let i = 0; i < count; i++) {
|
|
40479
|
+
const srcBase = i * stride;
|
|
40480
|
+
const dstBase = i * components;
|
|
40481
|
+
for (let c = 0; c < components; c++) {
|
|
40482
|
+
out[dstBase + c] = src[srcBase + c];
|
|
40483
|
+
}
|
|
40484
|
+
}
|
|
40485
|
+
return new BufferAttribute(out, components, false);
|
|
39093
40486
|
}
|
|
39094
40487
|
createDummyTexture() {
|
|
39095
40488
|
const data = new Float32Array(16);
|
|
@@ -39161,7 +40554,7 @@ void main() {
|
|
|
39161
40554
|
if (!this.transformTexture) return;
|
|
39162
40555
|
this.transformTexture.needsUpdate = true;
|
|
39163
40556
|
}
|
|
39164
|
-
setVisibleEdges(visible) {
|
|
40557
|
+
setVisibleEdges(visible = true) {
|
|
39165
40558
|
this.visibleEdges = visible;
|
|
39166
40559
|
}
|
|
39167
40560
|
getAvailableMemory() {
|
|
@@ -39415,78 +40808,51 @@ void main() {
|
|
|
39415
40808
|
node.loading = true;
|
|
39416
40809
|
const meshDef = node.structure.getJson().meshes[node.meshIndex];
|
|
39417
40810
|
try {
|
|
40811
|
+
if (
|
|
40812
|
+
!this._dracoLoader &&
|
|
40813
|
+
meshDef.primitives &&
|
|
40814
|
+
meshDef.primitives.some((p) => p.extensions && p.extensions[DRACO_EXTENSION_NAME])
|
|
40815
|
+
) {
|
|
40816
|
+
throw new Error(
|
|
40817
|
+
"primitive uses KHR_draco_mesh_compression but no DRACOLoader is configured. " +
|
|
40818
|
+
"Inject one via dynamicLoader.setDracoLoader(new DRACOLoader()) before opening the file."
|
|
40819
|
+
);
|
|
40820
|
+
}
|
|
39418
40821
|
const bufferRequests = [];
|
|
39419
40822
|
const primitiveReqMap = new Map();
|
|
40823
|
+
const dracoPrimitives = new Map();
|
|
39420
40824
|
for (let primIdx = 0; primIdx < meshDef.primitives.length; primIdx++) {
|
|
39421
40825
|
const primitive = meshDef.primitives[primIdx];
|
|
39422
40826
|
const reqs = [];
|
|
39423
|
-
|
|
39424
|
-
|
|
39425
|
-
const
|
|
39426
|
-
const
|
|
39427
|
-
const
|
|
39428
|
-
const
|
|
39429
|
-
const count = accessor.count;
|
|
39430
|
-
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
39431
|
-
reqs.push({
|
|
40827
|
+
const dracoExt = primitive.extensions && primitive.extensions[DRACO_EXTENSION_NAME];
|
|
40828
|
+
if (dracoExt) {
|
|
40829
|
+
const bufferView = node.structure.json.bufferViews[dracoExt.bufferView];
|
|
40830
|
+
const byteOffset = bufferView.byteOffset || 0;
|
|
40831
|
+
const byteLength = bufferView.byteLength;
|
|
40832
|
+
const dracoReq = {
|
|
39432
40833
|
offset: byteOffset,
|
|
39433
40834
|
length: byteLength,
|
|
39434
|
-
componentType:
|
|
39435
|
-
|
|
39436
|
-
type: "position",
|
|
40835
|
+
componentType: 5121,
|
|
40836
|
+
type: "draco",
|
|
39437
40837
|
primIdx,
|
|
39438
|
-
}
|
|
40838
|
+
};
|
|
40839
|
+
reqs.push(dracoReq);
|
|
40840
|
+
dracoPrimitives.set(primIdx, { req: dracoReq, primitive });
|
|
40841
|
+
primitiveReqMap.set(primIdx, reqs);
|
|
40842
|
+
bufferRequests.push(...reqs);
|
|
40843
|
+
continue;
|
|
40844
|
+
}
|
|
40845
|
+
if (primitive.attributes.POSITION !== undefined) {
|
|
40846
|
+
reqs.push(this._buildAccessorRequest(node.structure, primitive.attributes.POSITION, "position", primIdx));
|
|
39439
40847
|
}
|
|
39440
40848
|
if (primitive.attributes.NORMAL !== undefined) {
|
|
39441
|
-
|
|
39442
|
-
const accessor = node.structure.json.accessors[accessorIndex];
|
|
39443
|
-
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
39444
|
-
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
39445
|
-
const components = node.structure.getNumComponents(accessor.type);
|
|
39446
|
-
const count = accessor.count;
|
|
39447
|
-
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
39448
|
-
reqs.push({
|
|
39449
|
-
offset: byteOffset,
|
|
39450
|
-
length: byteLength,
|
|
39451
|
-
componentType: accessor.componentType,
|
|
39452
|
-
accessorIndex,
|
|
39453
|
-
type: "normal",
|
|
39454
|
-
primIdx,
|
|
39455
|
-
});
|
|
40849
|
+
reqs.push(this._buildAccessorRequest(node.structure, primitive.attributes.NORMAL, "normal", primIdx));
|
|
39456
40850
|
}
|
|
39457
40851
|
if (primitive.attributes.TEXCOORD_0 !== undefined) {
|
|
39458
|
-
|
|
39459
|
-
const accessor = node.structure.json.accessors[accessorIndex];
|
|
39460
|
-
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
39461
|
-
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
39462
|
-
const components = node.structure.getNumComponents(accessor.type);
|
|
39463
|
-
const count = accessor.count;
|
|
39464
|
-
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
39465
|
-
reqs.push({
|
|
39466
|
-
offset: byteOffset,
|
|
39467
|
-
length: byteLength,
|
|
39468
|
-
componentType: accessor.componentType,
|
|
39469
|
-
accessorIndex,
|
|
39470
|
-
type: "uv",
|
|
39471
|
-
primIdx,
|
|
39472
|
-
});
|
|
40852
|
+
reqs.push(this._buildAccessorRequest(node.structure, primitive.attributes.TEXCOORD_0, "uv", primIdx));
|
|
39473
40853
|
}
|
|
39474
40854
|
if (primitive.indices !== undefined) {
|
|
39475
|
-
|
|
39476
|
-
const accessor = node.structure.json.accessors[accessorIndex];
|
|
39477
|
-
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
39478
|
-
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
39479
|
-
const components = node.structure.getNumComponents(accessor.type);
|
|
39480
|
-
const count = accessor.count;
|
|
39481
|
-
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
39482
|
-
reqs.push({
|
|
39483
|
-
offset: byteOffset,
|
|
39484
|
-
length: byteLength,
|
|
39485
|
-
componentType: accessor.componentType,
|
|
39486
|
-
accessorIndex,
|
|
39487
|
-
type: "index",
|
|
39488
|
-
primIdx,
|
|
39489
|
-
});
|
|
40855
|
+
reqs.push(this._buildAccessorRequest(node.structure, primitive.indices, "index", primIdx));
|
|
39490
40856
|
}
|
|
39491
40857
|
primitiveReqMap.set(primIdx, reqs);
|
|
39492
40858
|
bufferRequests.push(...reqs);
|
|
@@ -39512,29 +40878,31 @@ void main() {
|
|
|
39512
40878
|
}
|
|
39513
40879
|
for (let primIdx = 0; primIdx < meshDef.primitives.length; primIdx++) {
|
|
39514
40880
|
const primitive = meshDef.primitives[primIdx];
|
|
39515
|
-
const geometry = new BufferGeometry();
|
|
39516
40881
|
const reqs = primitiveReqMap.get(primIdx);
|
|
39517
|
-
|
|
39518
|
-
|
|
39519
|
-
const
|
|
39520
|
-
const
|
|
39521
|
-
|
|
39522
|
-
|
|
39523
|
-
|
|
39524
|
-
|
|
39525
|
-
|
|
39526
|
-
|
|
39527
|
-
|
|
39528
|
-
|
|
39529
|
-
|
|
39530
|
-
|
|
39531
|
-
|
|
39532
|
-
|
|
39533
|
-
|
|
39534
|
-
|
|
39535
|
-
|
|
39536
|
-
|
|
39537
|
-
|
|
40882
|
+
let geometry;
|
|
40883
|
+
if (dracoPrimitives.has(primIdx)) {
|
|
40884
|
+
const dracoReq = reqs.find((r) => r.type === "draco");
|
|
40885
|
+
const dracoBytes = new Uint8Array(dracoReq.data.buffer, dracoReq.data.byteOffset, dracoReq.data.byteLength);
|
|
40886
|
+
const dracoBuffer = dracoBytes.slice().buffer;
|
|
40887
|
+
geometry = await this._decodeDracoPrimitive(node.structure, primitive, dracoBuffer);
|
|
40888
|
+
} else {
|
|
40889
|
+
geometry = new BufferGeometry();
|
|
40890
|
+
if (primitive.attributes.POSITION !== undefined) {
|
|
40891
|
+
const req = reqs.find((r) => r.type === "position" && r.accessorIndex === primitive.attributes.POSITION);
|
|
40892
|
+
geometry.setAttribute("position", this._createGeometryAttribute(req));
|
|
40893
|
+
}
|
|
40894
|
+
if (primitive.attributes.NORMAL !== undefined) {
|
|
40895
|
+
const req = reqs.find((r) => r.type === "normal" && r.accessorIndex === primitive.attributes.NORMAL);
|
|
40896
|
+
geometry.setAttribute("normal", this._createGeometryAttribute(req));
|
|
40897
|
+
}
|
|
40898
|
+
if (primitive.attributes.TEXCOORD_0 !== undefined) {
|
|
40899
|
+
const req = reqs.find((r) => r.type === "uv" && r.accessorIndex === primitive.attributes.TEXCOORD_0);
|
|
40900
|
+
geometry.setAttribute("uv", this._createGeometryAttribute(req));
|
|
40901
|
+
}
|
|
40902
|
+
if (primitive.indices !== undefined) {
|
|
40903
|
+
const req = reqs.find((r) => r.type === "index" && r.accessorIndex === primitive.indices);
|
|
40904
|
+
geometry.setIndex(this._createGeometryAttribute(req));
|
|
40905
|
+
}
|
|
39538
40906
|
}
|
|
39539
40907
|
let material;
|
|
39540
40908
|
if (primitive.material !== undefined) {
|
|
@@ -39773,20 +41141,43 @@ void main() {
|
|
|
39773
41141
|
const nodeMatrix = new Matrix4();
|
|
39774
41142
|
const uniqueNodeId = `${structure.id}_${nodeId}`;
|
|
39775
41143
|
const meshDef = structure.json.meshes[nodeDef.mesh];
|
|
41144
|
+
if (!meshDef || !meshDef.primitives || meshDef.primitives.length === 0) {
|
|
41145
|
+
if (nodeDef.children) {
|
|
41146
|
+
for (const childId of nodeDef.children) {
|
|
41147
|
+
await this.processNodeHierarchy(structure, childId, nodeGroup || parentGroup);
|
|
41148
|
+
}
|
|
41149
|
+
}
|
|
41150
|
+
return nodeGroup;
|
|
41151
|
+
}
|
|
39776
41152
|
const geometryExtents = new Box3();
|
|
39777
41153
|
for (const primitive of meshDef.primitives) {
|
|
41154
|
+
if (!primitive.attributes) continue;
|
|
39778
41155
|
const positionAccessor = structure.json.accessors[primitive.attributes.POSITION];
|
|
39779
41156
|
if (positionAccessor && positionAccessor.min && positionAccessor.max) {
|
|
39780
|
-
const
|
|
39781
|
-
|
|
39782
|
-
|
|
39783
|
-
|
|
39784
|
-
|
|
41157
|
+
const minVec = new Vector3().fromArray(positionAccessor.min);
|
|
41158
|
+
const maxVec = new Vector3().fromArray(positionAccessor.max);
|
|
41159
|
+
if (positionAccessor.normalized === true) {
|
|
41160
|
+
const denom = this._normalizedDenominator(positionAccessor.componentType);
|
|
41161
|
+
if (denom > 0) {
|
|
41162
|
+
minVec.divideScalar(denom);
|
|
41163
|
+
maxVec.divideScalar(denom);
|
|
41164
|
+
if (positionAccessor.componentType === 5120 || positionAccessor.componentType === 5122) {
|
|
41165
|
+
minVec.x = Math.max(minVec.x, -1);
|
|
41166
|
+
minVec.y = Math.max(minVec.y, -1);
|
|
41167
|
+
minVec.z = Math.max(minVec.z, -1);
|
|
41168
|
+
maxVec.x = Math.max(maxVec.x, -1);
|
|
41169
|
+
maxVec.y = Math.max(maxVec.y, -1);
|
|
41170
|
+
maxVec.z = Math.max(maxVec.z, -1);
|
|
41171
|
+
}
|
|
41172
|
+
}
|
|
41173
|
+
}
|
|
41174
|
+
geometryExtents.union(new Box3(minVec, maxVec));
|
|
39785
41175
|
}
|
|
39786
41176
|
}
|
|
39787
41177
|
let isEdge = false;
|
|
39788
|
-
|
|
39789
|
-
|
|
41178
|
+
const firstPrimitive = meshDef.primitives[0];
|
|
41179
|
+
if (firstPrimitive && firstPrimitive.material !== undefined) {
|
|
41180
|
+
const material = structure.json.materials[firstPrimitive.material];
|
|
39790
41181
|
if (material?.name === "edges") {
|
|
39791
41182
|
isEdge = true;
|
|
39792
41183
|
}
|
|
@@ -40099,6 +41490,10 @@ void main() {
|
|
|
40099
41490
|
vec3 objectNormal = vec3( normal );
|
|
40100
41491
|
mat3 bm = mat3( batchingMatrix );
|
|
40101
41492
|
objectNormal = bm * objectNormal;
|
|
41493
|
+
#ifdef USE_TANGENT
|
|
41494
|
+
vec3 objectTangent = vec3( tangent.xyz );
|
|
41495
|
+
objectTangent = bm * objectTangent;
|
|
41496
|
+
#endif
|
|
40102
41497
|
`
|
|
40103
41498
|
);
|
|
40104
41499
|
}
|
|
@@ -41271,7 +42666,7 @@ void main() {
|
|
|
41271
42666
|
}
|
|
41272
42667
|
return extent;
|
|
41273
42668
|
}
|
|
41274
|
-
setMaxConcurrentChunks(maxChunks) {
|
|
42669
|
+
setMaxConcurrentChunks(maxChunks = 6) {
|
|
41275
42670
|
if (maxChunks < 1) {
|
|
41276
42671
|
console.warn("Max concurrent chunks must be at least 1");
|
|
41277
42672
|
return;
|
|
@@ -41373,10 +42768,10 @@ void main() {
|
|
|
41373
42768
|
}
|
|
41374
42769
|
offset += chunkLength;
|
|
41375
42770
|
}
|
|
41376
|
-
if (
|
|
42771
|
+
if (this.content === undefined) {
|
|
41377
42772
|
throw new Error("GLTFBinaryParser: JSON content not found.");
|
|
41378
42773
|
}
|
|
41379
|
-
if (
|
|
42774
|
+
if (this.body === undefined) {
|
|
41380
42775
|
throw new Error("GLTFBinaryParser: Binary buffer chunk not found or type not supported.");
|
|
41381
42776
|
}
|
|
41382
42777
|
}
|
|
@@ -42702,16 +44097,18 @@ void main() {
|
|
|
42702
44097
|
if (this.manager)
|
|
42703
44098
|
this.manager.dispose();
|
|
42704
44099
|
}
|
|
42705
|
-
isSupport(file, format) {
|
|
44100
|
+
isSupport(file, format = "") {
|
|
42706
44101
|
return ((typeof file === "string" || file instanceof globalThis.File || file instanceof ArrayBuffer) &&
|
|
42707
44102
|
/(gltf|glb)$/i.test(format));
|
|
42708
44103
|
}
|
|
42709
|
-
async load(file, format, params) {
|
|
44104
|
+
async load(file, format, params = {}) {
|
|
42710
44105
|
this.manager = new GLTFLoadingManager(file, params);
|
|
42711
44106
|
const scene = new Group$1();
|
|
42712
44107
|
this.gltfLoader = new DynamicGltfLoader(this.viewer.camera, scene, this.viewer.renderer);
|
|
42713
|
-
this.gltfLoader.
|
|
42714
|
-
this.gltfLoader.
|
|
44108
|
+
this.gltfLoader.setMemoryLimit(this.viewer.options.memoryLimit);
|
|
44109
|
+
this.gltfLoader.setVisibleEdges(this.viewer.options.edgeModel);
|
|
44110
|
+
this.gltfLoader.setMaxConcurrentChunks(params.maxConcurrentChunks);
|
|
44111
|
+
this.gltfLoader.setDracoLoader(params.dracoLoader);
|
|
42715
44112
|
const modelImpl = new DynamicModelImpl(scene);
|
|
42716
44113
|
modelImpl.id = params.modelId || this.extractFileName(file);
|
|
42717
44114
|
modelImpl.gltfLoader = this.gltfLoader;
|
|
@@ -42798,8 +44195,10 @@ void main() {
|
|
|
42798
44195
|
async load(model, format, params = {}) {
|
|
42799
44196
|
const scene = new Group$1();
|
|
42800
44197
|
this.gltfLoader = new DynamicGltfLoader(this.viewer.camera, scene, this.viewer.renderer);
|
|
42801
|
-
this.gltfLoader.
|
|
44198
|
+
this.gltfLoader.setMemoryLimit(this.viewer.options.memoryLimit);
|
|
42802
44199
|
this.gltfLoader.setVisibleEdges(this.viewer.options.edgeModel);
|
|
44200
|
+
this.gltfLoader.setMaxConcurrentChunks(params.maxConcurrentChunks);
|
|
44201
|
+
this.gltfLoader.setDracoLoader(params.dracoLoader);
|
|
42803
44202
|
const modelImpl = new DynamicModelImpl(scene);
|
|
42804
44203
|
modelImpl.id = model.file.id;
|
|
42805
44204
|
modelImpl.gltfLoader = this.gltfLoader;
|
|
@@ -44015,186 +45414,133 @@ void main() {
|
|
|
44015
45414
|
}
|
|
44016
45415
|
|
|
44017
45416
|
class SSAARenderPass extends Pass {
|
|
44018
|
-
|
|
44019
|
-
|
|
44020
|
-
|
|
44021
|
-
|
|
44022
|
-
|
|
44023
|
-
|
|
44024
|
-
|
|
44025
|
-
|
|
44026
|
-
|
|
44027
|
-
|
|
44028
|
-
|
|
44029
|
-
|
|
44030
|
-
|
|
44031
|
-
|
|
44032
|
-
|
|
44033
|
-
|
|
44034
|
-
|
|
44035
|
-
|
|
44036
|
-
|
|
44037
|
-
|
|
44038
|
-
|
|
44039
|
-
|
|
44040
|
-
|
|
44041
|
-
|
|
44042
|
-
|
|
44043
|
-
|
|
44044
|
-
|
|
44045
|
-
|
|
44046
|
-
|
|
44047
|
-
|
|
44048
|
-
|
|
44049
|
-
|
|
44050
|
-
|
|
44051
|
-
|
|
44052
|
-
|
|
44053
|
-
|
|
44054
|
-
|
|
44055
|
-
|
|
44056
|
-
|
|
44057
|
-
|
|
44058
|
-
|
|
44059
|
-
|
|
44060
|
-
|
|
44061
|
-
|
|
44062
|
-
|
|
44063
|
-
|
|
44064
|
-
|
|
44065
|
-
|
|
44066
|
-
|
|
44067
|
-
|
|
44068
|
-
|
|
44069
|
-
|
|
44070
|
-
|
|
44071
|
-
|
|
44072
|
-
|
|
44073
|
-
|
|
44074
|
-
|
|
44075
|
-
|
|
44076
|
-
|
|
44077
|
-
|
|
44078
|
-
|
|
44079
|
-
|
|
44080
|
-
|
|
44081
|
-
|
|
44082
|
-
|
|
44083
|
-
|
|
44084
|
-
|
|
44085
|
-
|
|
44086
|
-
|
|
44087
|
-
|
|
44088
|
-
|
|
44089
|
-
|
|
44090
|
-
|
|
44091
|
-
|
|
44092
|
-
|
|
44093
|
-
|
|
44094
|
-
|
|
44095
|
-
|
|
44096
|
-
|
|
44097
|
-
|
|
44098
|
-
|
|
44099
|
-
|
|
44100
|
-
|
|
44101
|
-
|
|
44102
|
-
|
|
44103
|
-
|
|
44104
|
-
|
|
44105
|
-
|
|
44106
|
-
|
|
44107
|
-
|
|
44108
|
-
|
|
44109
|
-
|
|
44110
|
-
|
|
44111
|
-
|
|
44112
|
-
|
|
44113
|
-
|
|
44114
|
-
originalViewOffset.width,
|
|
44115
|
-
originalViewOffset.height
|
|
44116
|
-
);
|
|
44117
|
-
} else if (this.camera.clearViewOffset) {
|
|
44118
|
-
this.camera.clearViewOffset();
|
|
44119
|
-
}
|
|
44120
|
-
renderer.autoClear = autoClear;
|
|
44121
|
-
renderer.setClearColor(this._oldClearColor, oldClearAlpha);
|
|
44122
|
-
}
|
|
45417
|
+
constructor( scene, camera, clearColor = 0x000000, clearAlpha = 0 ) {
|
|
45418
|
+
super();
|
|
45419
|
+
this.scene = scene;
|
|
45420
|
+
this.camera = camera;
|
|
45421
|
+
this.sampleLevel = 4;
|
|
45422
|
+
this.unbiased = true;
|
|
45423
|
+
this.stencilBuffer = false;
|
|
45424
|
+
this.clearColor = clearColor;
|
|
45425
|
+
this.clearAlpha = clearAlpha;
|
|
45426
|
+
this._sampleRenderTarget = null;
|
|
45427
|
+
this._oldClearColor = new Color();
|
|
45428
|
+
this._copyUniforms = UniformsUtils.clone( CopyShader.uniforms );
|
|
45429
|
+
this._copyMaterial = new ShaderMaterial( {
|
|
45430
|
+
uniforms: this._copyUniforms,
|
|
45431
|
+
vertexShader: CopyShader.vertexShader,
|
|
45432
|
+
fragmentShader: CopyShader.fragmentShader,
|
|
45433
|
+
transparent: true,
|
|
45434
|
+
depthTest: false,
|
|
45435
|
+
depthWrite: false,
|
|
45436
|
+
premultipliedAlpha: true,
|
|
45437
|
+
blending: AdditiveBlending
|
|
45438
|
+
} );
|
|
45439
|
+
this._fsQuad = new FullScreenQuad( this._copyMaterial );
|
|
45440
|
+
}
|
|
45441
|
+
dispose() {
|
|
45442
|
+
if ( this._sampleRenderTarget ) {
|
|
45443
|
+
this._sampleRenderTarget.dispose();
|
|
45444
|
+
this._sampleRenderTarget = null;
|
|
45445
|
+
}
|
|
45446
|
+
this._copyMaterial.dispose();
|
|
45447
|
+
this._fsQuad.dispose();
|
|
45448
|
+
}
|
|
45449
|
+
setSize( width, height ) {
|
|
45450
|
+
if ( this._sampleRenderTarget ) this._sampleRenderTarget.setSize( width, height );
|
|
45451
|
+
}
|
|
45452
|
+
render( renderer, writeBuffer, readBuffer ) {
|
|
45453
|
+
if ( ! this._sampleRenderTarget ) {
|
|
45454
|
+
this._sampleRenderTarget = new WebGLRenderTarget( readBuffer.width, readBuffer.height, { type: HalfFloatType, stencilBuffer: this.stencilBuffer } );
|
|
45455
|
+
this._sampleRenderTarget.texture.name = 'SSAARenderPass.sample';
|
|
45456
|
+
}
|
|
45457
|
+
const jitterOffsets = _JitterVectors[ Math.max( 0, Math.min( this.sampleLevel, 5 ) ) ];
|
|
45458
|
+
const autoClear = renderer.autoClear;
|
|
45459
|
+
renderer.autoClear = false;
|
|
45460
|
+
renderer.getClearColor( this._oldClearColor );
|
|
45461
|
+
const oldClearAlpha = renderer.getClearAlpha();
|
|
45462
|
+
const baseSampleWeight = 1.0 / jitterOffsets.length;
|
|
45463
|
+
const roundingRange = 1 / 32;
|
|
45464
|
+
this._copyUniforms[ 'tDiffuse' ].value = this._sampleRenderTarget.texture;
|
|
45465
|
+
const viewOffset = {
|
|
45466
|
+
fullWidth: readBuffer.width,
|
|
45467
|
+
fullHeight: readBuffer.height,
|
|
45468
|
+
offsetX: 0,
|
|
45469
|
+
offsetY: 0,
|
|
45470
|
+
width: readBuffer.width,
|
|
45471
|
+
height: readBuffer.height
|
|
45472
|
+
};
|
|
45473
|
+
const originalViewOffset = Object.assign( {}, this.camera.view );
|
|
45474
|
+
if ( originalViewOffset.enabled ) Object.assign( viewOffset, originalViewOffset );
|
|
45475
|
+
for ( let i = 0; i < jitterOffsets.length; i ++ ) {
|
|
45476
|
+
const jitterOffset = jitterOffsets[ i ];
|
|
45477
|
+
if ( this.camera.setViewOffset ) {
|
|
45478
|
+
this.camera.setViewOffset(
|
|
45479
|
+
viewOffset.fullWidth, viewOffset.fullHeight,
|
|
45480
|
+
viewOffset.offsetX + jitterOffset[ 0 ] * 0.0625, viewOffset.offsetY + jitterOffset[ 1 ] * 0.0625,
|
|
45481
|
+
viewOffset.width, viewOffset.height
|
|
45482
|
+
);
|
|
45483
|
+
}
|
|
45484
|
+
let sampleWeight = baseSampleWeight;
|
|
45485
|
+
if ( this.unbiased ) {
|
|
45486
|
+
const uniformCenteredDistribution = ( -0.5 + ( i + 0.5 ) / jitterOffsets.length );
|
|
45487
|
+
sampleWeight += roundingRange * uniformCenteredDistribution;
|
|
45488
|
+
}
|
|
45489
|
+
this._copyUniforms[ 'opacity' ].value = sampleWeight;
|
|
45490
|
+
renderer.setClearColor( this.clearColor, this.clearAlpha );
|
|
45491
|
+
renderer.setRenderTarget( this._sampleRenderTarget );
|
|
45492
|
+
renderer.clear();
|
|
45493
|
+
renderer.render( this.scene, this.camera );
|
|
45494
|
+
renderer.setRenderTarget( this.renderToScreen ? null : writeBuffer );
|
|
45495
|
+
if ( i === 0 ) {
|
|
45496
|
+
renderer.setClearColor( 0x000000, 0.0 );
|
|
45497
|
+
renderer.clear();
|
|
45498
|
+
}
|
|
45499
|
+
this._fsQuad.render( renderer );
|
|
45500
|
+
}
|
|
45501
|
+
if ( this.camera.setViewOffset && originalViewOffset.enabled ) {
|
|
45502
|
+
this.camera.setViewOffset(
|
|
45503
|
+
originalViewOffset.fullWidth, originalViewOffset.fullHeight,
|
|
45504
|
+
originalViewOffset.offsetX, originalViewOffset.offsetY,
|
|
45505
|
+
originalViewOffset.width, originalViewOffset.height
|
|
45506
|
+
);
|
|
45507
|
+
} else if ( this.camera.clearViewOffset ) {
|
|
45508
|
+
this.camera.clearViewOffset();
|
|
45509
|
+
}
|
|
45510
|
+
renderer.autoClear = autoClear;
|
|
45511
|
+
renderer.setClearColor( this._oldClearColor, oldClearAlpha );
|
|
45512
|
+
}
|
|
44123
45513
|
}
|
|
44124
45514
|
const _JitterVectors = [
|
|
44125
|
-
|
|
44126
|
-
|
|
44127
|
-
|
|
44128
|
-
|
|
44129
|
-
|
|
44130
|
-
|
|
44131
|
-
|
|
44132
|
-
|
|
44133
|
-
|
|
44134
|
-
|
|
44135
|
-
|
|
44136
|
-
|
|
44137
|
-
|
|
44138
|
-
|
|
44139
|
-
|
|
44140
|
-
|
|
44141
|
-
|
|
44142
|
-
|
|
44143
|
-
|
|
44144
|
-
|
|
44145
|
-
|
|
44146
|
-
|
|
44147
|
-
|
|
44148
|
-
|
|
44149
|
-
|
|
44150
|
-
|
|
44151
|
-
|
|
44152
|
-
|
|
44153
|
-
|
|
44154
|
-
[3, -5],
|
|
44155
|
-
[-2, 6],
|
|
44156
|
-
[0, -7],
|
|
44157
|
-
[-4, -6],
|
|
44158
|
-
[-6, 4],
|
|
44159
|
-
[-8, 0],
|
|
44160
|
-
[7, -4],
|
|
44161
|
-
[6, 7],
|
|
44162
|
-
[-7, -8],
|
|
44163
|
-
],
|
|
44164
|
-
[
|
|
44165
|
-
[-4, -7],
|
|
44166
|
-
[-7, -5],
|
|
44167
|
-
[-3, -5],
|
|
44168
|
-
[-5, -4],
|
|
44169
|
-
[-1, -4],
|
|
44170
|
-
[-2, -2],
|
|
44171
|
-
[-6, -1],
|
|
44172
|
-
[-4, 0],
|
|
44173
|
-
[-7, 1],
|
|
44174
|
-
[-1, 2],
|
|
44175
|
-
[-6, 3],
|
|
44176
|
-
[-3, 3],
|
|
44177
|
-
[-7, 6],
|
|
44178
|
-
[-3, 6],
|
|
44179
|
-
[-5, 7],
|
|
44180
|
-
[-1, 7],
|
|
44181
|
-
[5, -7],
|
|
44182
|
-
[1, -6],
|
|
44183
|
-
[6, -5],
|
|
44184
|
-
[4, -4],
|
|
44185
|
-
[2, -3],
|
|
44186
|
-
[7, -2],
|
|
44187
|
-
[1, -1],
|
|
44188
|
-
[4, -1],
|
|
44189
|
-
[2, 1],
|
|
44190
|
-
[6, 2],
|
|
44191
|
-
[0, 4],
|
|
44192
|
-
[4, 4],
|
|
44193
|
-
[2, 5],
|
|
44194
|
-
[7, 5],
|
|
44195
|
-
[5, 6],
|
|
44196
|
-
[3, 7],
|
|
44197
|
-
],
|
|
45515
|
+
[
|
|
45516
|
+
[ 0, 0 ]
|
|
45517
|
+
],
|
|
45518
|
+
[
|
|
45519
|
+
[ 4, 4 ], [ -4, -4 ]
|
|
45520
|
+
],
|
|
45521
|
+
[
|
|
45522
|
+
[ -2, -6 ], [ 6, -2 ], [ -6, 2 ], [ 2, 6 ]
|
|
45523
|
+
],
|
|
45524
|
+
[
|
|
45525
|
+
[ 1, -3 ], [ -1, 3 ], [ 5, 1 ], [ -3, -5 ],
|
|
45526
|
+
[ -5, 5 ], [ -7, -1 ], [ 3, 7 ], [ 7, -7 ]
|
|
45527
|
+
],
|
|
45528
|
+
[
|
|
45529
|
+
[ 1, 1 ], [ -1, -3 ], [ -3, 2 ], [ 4, -1 ],
|
|
45530
|
+
[ -5, -2 ], [ 2, 5 ], [ 5, 3 ], [ 3, -5 ],
|
|
45531
|
+
[ -2, 6 ], [ 0, -7 ], [ -4, -6 ], [ -6, 4 ],
|
|
45532
|
+
[ -8, 0 ], [ 7, -4 ], [ 6, 7 ], [ -7, -8 ]
|
|
45533
|
+
],
|
|
45534
|
+
[
|
|
45535
|
+
[ -4, -7 ], [ -7, -5 ], [ -3, -5 ], [ -5, -4 ],
|
|
45536
|
+
[ -1, -4 ], [ -2, -2 ], [ -6, -1 ], [ -4, 0 ],
|
|
45537
|
+
[ -7, 1 ], [ -1, 2 ], [ -6, 3 ], [ -3, 3 ],
|
|
45538
|
+
[ -7, 6 ], [ -3, 6 ], [ -5, 7 ], [ -1, 7 ],
|
|
45539
|
+
[ 5, -7 ], [ 1, -6 ], [ 6, -5 ], [ 4, -4 ],
|
|
45540
|
+
[ 2, -3 ], [ 7, -2 ], [ 1, -1 ], [ 4, -1 ],
|
|
45541
|
+
[ 2, 1 ], [ 6, 2 ], [ 0, 4 ], [ 4, 4 ],
|
|
45542
|
+
[ 2, 5 ], [ 7, 5 ], [ 5, 6 ], [ 3, 7 ]
|
|
45543
|
+
]
|
|
44198
45544
|
];
|
|
44199
45545
|
|
|
44200
45546
|
const OutputShader = {
|
|
@@ -57135,8 +58481,8 @@ js: import "konva/skia-backend";
|
|
|
57135
58481
|
this.lineWidth = 4;
|
|
57136
58482
|
this.lineType = "solid";
|
|
57137
58483
|
this.fontSize = 34;
|
|
57138
|
-
this.changeActiveDragger = (
|
|
57139
|
-
const draggerName =
|
|
58484
|
+
this.changeActiveDragger = ({ data }) => {
|
|
58485
|
+
const draggerName = data || "";
|
|
57140
58486
|
this._markupContainer.className = this._container.className
|
|
57141
58487
|
.split(" ")
|
|
57142
58488
|
.filter((x) => !x.startsWith("oda-cursor-"))
|
|
@@ -57197,19 +58543,19 @@ js: import "konva/skia-backend";
|
|
|
57197
58543
|
this._resizeObserver = new ResizeObserver(this.resizeContainer);
|
|
57198
58544
|
this._resizeObserver.observe(container);
|
|
57199
58545
|
if (this._viewer) {
|
|
57200
|
-
this._viewer.
|
|
57201
|
-
this._viewer.
|
|
57202
|
-
this._viewer.
|
|
57203
|
-
this._viewer.
|
|
58546
|
+
this._viewer.on("changeactivedragger", this.changeActiveDragger);
|
|
58547
|
+
this._viewer.on("pan", this.pan);
|
|
58548
|
+
this._viewer.on("zoomat", this.zoomAt);
|
|
58549
|
+
this._viewer.on("changecameramode", this.changeCameraMode);
|
|
57204
58550
|
}
|
|
57205
58551
|
}
|
|
57206
58552
|
dispose() {
|
|
57207
58553
|
var _a, _b;
|
|
57208
58554
|
if (this._viewer) {
|
|
57209
|
-
this._viewer.
|
|
57210
|
-
this._viewer.
|
|
57211
|
-
this._viewer.
|
|
57212
|
-
this._viewer.
|
|
58555
|
+
this._viewer.off("changecameramode", this.changeCameraMode);
|
|
58556
|
+
this._viewer.off("zoomat", this.zoomAt);
|
|
58557
|
+
this._viewer.off("pan", this.pan);
|
|
58558
|
+
this._viewer.off("changeactivedragger", this.changeActiveDragger);
|
|
57213
58559
|
}
|
|
57214
58560
|
(_a = this._resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
57215
58561
|
this._resizeObserver = undefined;
|
|
@@ -57968,24 +59314,6 @@ js: import "konva/skia-backend";
|
|
|
57968
59314
|
}
|
|
57969
59315
|
}
|
|
57970
59316
|
|
|
57971
|
-
class Helpers extends Scene {
|
|
57972
|
-
constructor() {
|
|
57973
|
-
super(...arguments);
|
|
57974
|
-
this.oldAutoClear = false;
|
|
57975
|
-
this.oldClippingPlanes = [];
|
|
57976
|
-
}
|
|
57977
|
-
onBeforeRender(renderer) {
|
|
57978
|
-
this.oldAutoClear = renderer.autoClear;
|
|
57979
|
-
this.oldClippingPlanes = renderer.clippingPlanes;
|
|
57980
|
-
renderer.autoClear = false;
|
|
57981
|
-
renderer.clippingPlanes = [];
|
|
57982
|
-
}
|
|
57983
|
-
onAfterRender(renderer) {
|
|
57984
|
-
renderer.clippingPlanes = this.oldClippingPlanes;
|
|
57985
|
-
renderer.autoClear = this.oldAutoClear;
|
|
57986
|
-
}
|
|
57987
|
-
}
|
|
57988
|
-
|
|
57989
59317
|
class Viewer extends EventEmitter2 {
|
|
57990
59318
|
constructor(client) {
|
|
57991
59319
|
super();
|
|
@@ -57999,9 +59327,9 @@ js: import "konva/skia-backend";
|
|
|
57999
59327
|
this.selected = [];
|
|
58000
59328
|
this.extents = new Box3();
|
|
58001
59329
|
this.target = new Vector3(0, 0, 0);
|
|
59330
|
+
this.clippingPlanes = [];
|
|
58002
59331
|
this._activeDragger = null;
|
|
58003
59332
|
this._components = [];
|
|
58004
|
-
this._updateDelay = 1000;
|
|
58005
59333
|
this._renderNeeded = false;
|
|
58006
59334
|
this._renderTime = 0;
|
|
58007
59335
|
this.render = this.render.bind(this);
|
|
@@ -58020,7 +59348,9 @@ js: import "konva/skia-backend";
|
|
|
58020
59348
|
initialize(canvas, onProgress) {
|
|
58021
59349
|
this.addEventListener("optionschange", (event) => this.syncOptions(event.data));
|
|
58022
59350
|
this.scene = new Scene();
|
|
58023
|
-
this.helpers = new
|
|
59351
|
+
this.helpers = new Group$1();
|
|
59352
|
+
this.helpers.name = "Helpers";
|
|
59353
|
+
this.scene.add(this.helpers);
|
|
58024
59354
|
const pixelRatio = window.devicePixelRatio;
|
|
58025
59355
|
const rect = canvas.parentElement.getBoundingClientRect();
|
|
58026
59356
|
const width = rect.width || 1;
|
|
@@ -58042,17 +59372,17 @@ js: import "konva/skia-backend";
|
|
|
58042
59372
|
this.renderer.setPixelRatio(pixelRatio);
|
|
58043
59373
|
this.renderer.setSize(width, height);
|
|
58044
59374
|
this.renderer.outputColorSpace = LinearSRGBColorSpace;
|
|
59375
|
+
this.renderer.localClippingEnabled = true;
|
|
58045
59376
|
this.renderPass = new RenderPass(this.scene, this.camera);
|
|
58046
|
-
this.helpersPass = new RenderPass(this.helpers, this.camera);
|
|
58047
|
-
this.helpersPass.clear = false;
|
|
58048
59377
|
this.fxaaPass = new FXAAPass();
|
|
58049
59378
|
this.smaaPass = new SMAAPass();
|
|
58050
|
-
this.ssaaRenderPass = new SSAARenderPass(
|
|
59379
|
+
this.ssaaRenderPass = new SSAARenderPass(this.scene, this.camera);
|
|
58051
59380
|
this.ssaaRenderPass.unbiased = true;
|
|
58052
59381
|
this.outputPass = new OutputPass();
|
|
58053
|
-
|
|
59382
|
+
const renderTarget = new WebGLRenderTarget(1, 1, { samples: 4 });
|
|
59383
|
+
renderTarget.texture.name = "EffectComposer.rt1";
|
|
59384
|
+
this.composer = new EffectComposer(this.renderer, renderTarget);
|
|
58054
59385
|
this.composer.addPass(this.renderPass);
|
|
58055
|
-
this.composer.addPass(this.helpersPass);
|
|
58056
59386
|
this.composer.addPass(this.smaaPass);
|
|
58057
59387
|
this.composer.addPass(this.fxaaPass);
|
|
58058
59388
|
this.composer.addPass(this.ssaaRenderPass);
|
|
@@ -58062,7 +59392,9 @@ js: import "konva/skia-backend";
|
|
|
58062
59392
|
this.canvasEvents.forEach((x) => canvas.addEventListener(x, this.canvaseventlistener));
|
|
58063
59393
|
this._markup.initialize(this.canvas, this.canvasEvents, this, this);
|
|
58064
59394
|
for (const name of components.getComponents().keys()) {
|
|
58065
|
-
|
|
59395
|
+
const component = components.createComponent(name, this);
|
|
59396
|
+
if (component)
|
|
59397
|
+
this._components.push(component);
|
|
58066
59398
|
}
|
|
58067
59399
|
this.syncOptions();
|
|
58068
59400
|
this.syncOverlay();
|
|
@@ -58083,7 +59415,7 @@ js: import "konva/skia-backend";
|
|
|
58083
59415
|
this.removeAllListeners();
|
|
58084
59416
|
this.setActiveDragger();
|
|
58085
59417
|
this._components.forEach((component) => component.dispose());
|
|
58086
|
-
this._components =
|
|
59418
|
+
this._components.length = 0;
|
|
58087
59419
|
this._markup.dispose();
|
|
58088
59420
|
if (this.canvas) {
|
|
58089
59421
|
this.canvasEvents.forEach((x) => this.canvas.removeEventListener(x, this.canvaseventlistener));
|
|
@@ -58093,8 +59425,6 @@ js: import "konva/skia-backend";
|
|
|
58093
59425
|
this.composer.dispose();
|
|
58094
59426
|
if (this.renderPass)
|
|
58095
59427
|
this.renderPass.dispose();
|
|
58096
|
-
if (this.helpersPass)
|
|
58097
|
-
this.helpersPass.dispose();
|
|
58098
59428
|
if (this.fxaaPass)
|
|
58099
59429
|
this.fxaaPass.dispose();
|
|
58100
59430
|
if (this.smaaPass)
|
|
@@ -58110,7 +59440,6 @@ js: import "konva/skia-backend";
|
|
|
58110
59440
|
this.camera = undefined;
|
|
58111
59441
|
this.renderer = undefined;
|
|
58112
59442
|
this.renderPass = undefined;
|
|
58113
|
-
this.helpersPass = undefined;
|
|
58114
59443
|
this.fxaaPass = undefined;
|
|
58115
59444
|
this.smaaPass = undefined;
|
|
58116
59445
|
this.ssaaRenderPass = undefined;
|
|
@@ -58142,11 +59471,12 @@ js: import "konva/skia-backend";
|
|
|
58142
59471
|
}
|
|
58143
59472
|
update(force = false) {
|
|
58144
59473
|
const time = performance.now();
|
|
58145
|
-
|
|
59474
|
+
if (typeof force === "number" && time - this._renderTime >= force)
|
|
59475
|
+
force = true;
|
|
58146
59476
|
this._renderNeeded = true;
|
|
58147
59477
|
if (force)
|
|
58148
59478
|
this.render(time);
|
|
58149
|
-
this.emitEvent({ type: "update", force });
|
|
59479
|
+
this.emitEvent({ type: "update", force: !!force });
|
|
58150
59480
|
}
|
|
58151
59481
|
render(time, force = false) {
|
|
58152
59482
|
if (!this.renderer)
|
|
@@ -58160,13 +59490,7 @@ js: import "konva/skia-backend";
|
|
|
58160
59490
|
this._renderNeeded = false;
|
|
58161
59491
|
this.renderer.info.autoReset = false;
|
|
58162
59492
|
this.renderer.info.reset();
|
|
58163
|
-
|
|
58164
|
-
this.renderer.render(this.scene, this.camera);
|
|
58165
|
-
this.renderer.render(this.helpers, this.camera);
|
|
58166
|
-
}
|
|
58167
|
-
else {
|
|
58168
|
-
this.composer.render(deltaTime);
|
|
58169
|
-
}
|
|
59493
|
+
this.composer.render(deltaTime);
|
|
58170
59494
|
this.emitEvent({ type: "render", time, deltaTime });
|
|
58171
59495
|
}
|
|
58172
59496
|
loadReferences(model) {
|
|
@@ -58226,11 +59550,12 @@ js: import "konva/skia-backend";
|
|
|
58226
59550
|
this.clearOverlay();
|
|
58227
59551
|
this.clearSelected();
|
|
58228
59552
|
this.loaders.forEach((loader) => loader.dispose());
|
|
58229
|
-
this.loaders =
|
|
59553
|
+
this.loaders.length = 0;
|
|
58230
59554
|
this.models.forEach((model) => model.dispose());
|
|
58231
|
-
this.models =
|
|
58232
|
-
this.scene.clear();
|
|
59555
|
+
this.models.length = 0;
|
|
58233
59556
|
this.helpers.clear();
|
|
59557
|
+
this.scene.clear();
|
|
59558
|
+
this.scene.add(this.helpers);
|
|
58234
59559
|
this.extents.makeEmpty();
|
|
58235
59560
|
this.syncOptions();
|
|
58236
59561
|
this.syncOverlay();
|
|
@@ -58247,8 +59572,15 @@ js: import "konva/skia-backend";
|
|
|
58247
59572
|
this.fxaaPass.enabled = options.antialiasing === "fxaa";
|
|
58248
59573
|
this.smaaPass.enabled = options.antialiasing === "smaa";
|
|
58249
59574
|
this.ssaaRenderPass.enabled = options.antialiasing === "ssaa";
|
|
58250
|
-
this.renderPass.enabled =
|
|
58251
|
-
|
|
59575
|
+
this.renderPass.enabled = options.antialiasing !== "ssaa";
|
|
59576
|
+
const samples = options.antialiasing === true || options.antialiasing === "msaa" ? 4 : 0;
|
|
59577
|
+
if (this.composer.renderTarget1.samples !== samples) {
|
|
59578
|
+
const size = this.renderer.getSize(new Vector2());
|
|
59579
|
+
const newRenderTarget = new WebGLRenderTarget(1, 1, { samples });
|
|
59580
|
+
newRenderTarget.texture.name = "EffectComposer.rt1";
|
|
59581
|
+
this.composer.reset(newRenderTarget);
|
|
59582
|
+
this.composer.setSize(size.x, size.y);
|
|
59583
|
+
}
|
|
58252
59584
|
this.update();
|
|
58253
59585
|
}
|
|
58254
59586
|
syncOverlay() {
|
|
@@ -58267,7 +59599,8 @@ js: import "konva/skia-backend";
|
|
|
58267
59599
|
clearSlices() {
|
|
58268
59600
|
if (!this.renderer)
|
|
58269
59601
|
return;
|
|
58270
|
-
this.
|
|
59602
|
+
this.clippingPlanes.length = 0;
|
|
59603
|
+
this.emitEvent({ type: "changecuttingplanes" });
|
|
58271
59604
|
this.emitEvent({ type: "clearslices" });
|
|
58272
59605
|
this.update();
|
|
58273
59606
|
}
|
|
@@ -58336,7 +59669,7 @@ js: import "konva/skia-backend";
|
|
|
58336
59669
|
}
|
|
58337
59670
|
}
|
|
58338
59671
|
getComponent(name) {
|
|
58339
|
-
return this._components.find((component) => component.name === name);
|
|
59672
|
+
return this._components.find((component) => component.name === name) || null;
|
|
58340
59673
|
}
|
|
58341
59674
|
drawViewpoint(viewpoint) {
|
|
58342
59675
|
var _a, _b, _c, _d;
|
|
@@ -58363,7 +59696,6 @@ js: import "konva/skia-backend";
|
|
|
58363
59696
|
camera.updateMatrixWorld();
|
|
58364
59697
|
this.camera = camera;
|
|
58365
59698
|
this.renderPass.camera = camera;
|
|
58366
|
-
this.helpersPass.camera = camera;
|
|
58367
59699
|
this.ssaaRenderPass.camera = camera;
|
|
58368
59700
|
this.options.cameraMode = "orthographic";
|
|
58369
59701
|
this.emitEvent({ type: "changecameramode", mode: "orthographic" });
|
|
@@ -58386,7 +59718,6 @@ js: import "konva/skia-backend";
|
|
|
58386
59718
|
camera.updateMatrixWorld();
|
|
58387
59719
|
this.camera = camera;
|
|
58388
59720
|
this.renderPass.camera = camera;
|
|
58389
|
-
this.helpersPass.camera = camera;
|
|
58390
59721
|
this.ssaaRenderPass.camera = camera;
|
|
58391
59722
|
this.options.cameraMode = "perspective";
|
|
58392
59723
|
this.emitEvent({ type: "changecameramode", mode: "perspective" });
|
|
@@ -58397,8 +59728,9 @@ js: import "konva/skia-backend";
|
|
|
58397
59728
|
clipping_planes.forEach((clipping_plane) => {
|
|
58398
59729
|
const plane = new Plane();
|
|
58399
59730
|
plane.setFromNormalAndCoplanarPoint(getVector3FromPoint3d(clipping_plane.direction), getVector3FromPoint3d(clipping_plane.location));
|
|
58400
|
-
this.
|
|
59731
|
+
this.clippingPlanes.push(plane);
|
|
58401
59732
|
});
|
|
59733
|
+
this.emitEvent({ type: "changecuttingplanes" });
|
|
58402
59734
|
}
|
|
58403
59735
|
};
|
|
58404
59736
|
const setSelection = (selection) => {
|
|
@@ -58453,7 +59785,7 @@ js: import "konva/skia-backend";
|
|
|
58453
59785
|
};
|
|
58454
59786
|
const getClippingPlanes = () => {
|
|
58455
59787
|
const clipping_planes = [];
|
|
58456
|
-
this.
|
|
59788
|
+
this.clippingPlanes.forEach((plane) => {
|
|
58457
59789
|
const clipping_plane = {
|
|
58458
59790
|
location: getPoint3dFromVector3(plane.coplanarPoint(new Vector3())),
|
|
58459
59791
|
direction: getPoint3dFromVector3(plane.normal),
|