@inweb/viewer-three 27.4.7 → 27.5.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 +1 -0
- 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 +1 -0
- package/dist/extensions/components/LightHelperComponent.module.js.map +1 -1
- package/dist/viewer-three.js +1766 -438
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +4 -4
- package/dist/viewer-three.module.js +1303 -403
- 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 +1 -0
- package/lib/Viewer/Viewer.d.ts +5 -7
- 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 +3 -3
- package/package.json +5 -5
- package/src/Viewer/Viewer.ts +50 -37
- package/src/Viewer/commands/index.ts +1 -1
- package/src/Viewer/components/BackgroundComponent.ts +1 -0
- package/src/Viewer/components/CameraComponent.ts +5 -6
- package/src/Viewer/{scenes/Helpers.ts → components/ClippingPlaneComponent.ts} +22 -12
- package/src/Viewer/components/HighlighterComponent.ts +9 -5
- package/src/Viewer/components/InfoComponent.ts +4 -4
- package/src/Viewer/components/SectionsComponent.ts +119 -0
- package/src/Viewer/components/SelectionComponent.ts +1 -1
- 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 +1065 -0
- package/src/Viewer/helpers/WCSHelper.ts +24 -0
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +417 -92
- package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +76 -9
- package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +3 -2
- package/src/Viewer/loaders/GLTFFileDynamicLoader.ts +4 -2
- package/src/Viewer/measurement/Snapper.ts +4 -5
- package/src/Viewer/models/ModelImpl.ts +27 -3
- package/lib/Viewer/scenes/Helpers.d.ts +0 -7
- package/src/Viewer/postprocessing/SSAARenderPass.js +0 -245
package/dist/viewer-three.js
CHANGED
|
@@ -235,6 +235,15 @@
|
|
|
235
235
|
enablePartialMode: false,
|
|
236
236
|
memoryLimit: 3294967296,
|
|
237
237
|
cuttingPlaneFillColor: { red: 0xff, green: 0x98, blue: 0x00 },
|
|
238
|
+
enableSectionFill: true,
|
|
239
|
+
sectionFillColor: { r: 0xff, g: 0x98, b: 0x00 },
|
|
240
|
+
sectionUseObjectColor: false,
|
|
241
|
+
enableSectionHatch: true,
|
|
242
|
+
sectionHatchColor: { r: 0, g: 0, b: 0 },
|
|
243
|
+
sectionHatchScale: 8,
|
|
244
|
+
enableSectionOutline: true,
|
|
245
|
+
sectionOutlineColor: { r: 0, g: 0, b: 0 },
|
|
246
|
+
sectionOutlineWidth: 2,
|
|
238
247
|
edgesColor: { r: 0xff, g: 0x98, b: 0x00 },
|
|
239
248
|
facesColor: { r: 0xff, g: 0x98, b: 0x00 },
|
|
240
249
|
edgesVisibility: true,
|
|
@@ -309,9 +318,17 @@
|
|
|
309
318
|
return this._data;
|
|
310
319
|
}
|
|
311
320
|
set data(value) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
321
|
+
this._data = { ...Options.defaults(), ...this._data, ...value };
|
|
322
|
+
if (this._data.enablePartialMode) {
|
|
323
|
+
this._data.enableStreamingMode = true;
|
|
324
|
+
this._data.sceneGraph = false;
|
|
325
|
+
}
|
|
326
|
+
if (!value.sectionFillColor && value.cuttingPlaneFillColor)
|
|
327
|
+
this._data.sectionFillColor = {
|
|
328
|
+
r: value.cuttingPlaneFillColor.red,
|
|
329
|
+
g: value.cuttingPlaneFillColor.green,
|
|
330
|
+
b: value.cuttingPlaneFillColor.blue,
|
|
331
|
+
};
|
|
315
332
|
this.change();
|
|
316
333
|
}
|
|
317
334
|
get showWCS() {
|
|
@@ -398,10 +415,83 @@
|
|
|
398
415
|
this.change();
|
|
399
416
|
}
|
|
400
417
|
get cuttingPlaneFillColor() {
|
|
401
|
-
|
|
418
|
+
console.warn("Options.cuttingPlaneFillColor has been deprecated since 27.5 and will be removed in a future release, use sectionFillColor instead");
|
|
419
|
+
return {
|
|
420
|
+
red: this._data.sectionFillColor.r,
|
|
421
|
+
green: this._data.sectionFillColor.g,
|
|
422
|
+
blue: this._data.sectionFillColor.b,
|
|
423
|
+
};
|
|
402
424
|
}
|
|
403
425
|
set cuttingPlaneFillColor(value) {
|
|
404
|
-
|
|
426
|
+
console.warn("Options.cuttingPlaneFillColor has been deprecated since 27.5 and will be removed in a future release, use sectionFillColor instead");
|
|
427
|
+
this._data.sectionFillColor = {
|
|
428
|
+
r: value.red,
|
|
429
|
+
g: value.green,
|
|
430
|
+
b: value.blue,
|
|
431
|
+
};
|
|
432
|
+
this.change();
|
|
433
|
+
}
|
|
434
|
+
get enableSectionFill() {
|
|
435
|
+
return this._data.enableSectionFill;
|
|
436
|
+
}
|
|
437
|
+
set enableSectionFill(value) {
|
|
438
|
+
this._data.enableSectionFill = value;
|
|
439
|
+
this.change();
|
|
440
|
+
}
|
|
441
|
+
get sectionFillColor() {
|
|
442
|
+
return this._data.sectionFillColor;
|
|
443
|
+
}
|
|
444
|
+
set sectionFillColor(value) {
|
|
445
|
+
this._data.sectionFillColor = value;
|
|
446
|
+
this.change();
|
|
447
|
+
}
|
|
448
|
+
get sectionUseObjectColor() {
|
|
449
|
+
return this._data.sectionUseObjectColor;
|
|
450
|
+
}
|
|
451
|
+
set sectionUseObjectColor(value) {
|
|
452
|
+
this._data.sectionUseObjectColor = value;
|
|
453
|
+
this.change();
|
|
454
|
+
}
|
|
455
|
+
get enableSectionHatch() {
|
|
456
|
+
return this._data.enableSectionHatch;
|
|
457
|
+
}
|
|
458
|
+
set enableSectionHatch(value) {
|
|
459
|
+
this._data.enableSectionHatch = value;
|
|
460
|
+
this.change();
|
|
461
|
+
}
|
|
462
|
+
get sectionHatchColor() {
|
|
463
|
+
return this._data.sectionHatchColor;
|
|
464
|
+
}
|
|
465
|
+
set sectionHatchColor(value) {
|
|
466
|
+
this._data.sectionHatchColor = value;
|
|
467
|
+
this.change();
|
|
468
|
+
}
|
|
469
|
+
get sectionHatchScale() {
|
|
470
|
+
return this._data.sectionHatchScale;
|
|
471
|
+
}
|
|
472
|
+
set sectionHatchScale(value) {
|
|
473
|
+
this._data.sectionHatchScale = value;
|
|
474
|
+
this.change();
|
|
475
|
+
}
|
|
476
|
+
get enableSectionOutline() {
|
|
477
|
+
return this._data.enableSectionOutline;
|
|
478
|
+
}
|
|
479
|
+
set enableSectionOutline(value) {
|
|
480
|
+
this._data.enableSectionOutline = value;
|
|
481
|
+
this.change();
|
|
482
|
+
}
|
|
483
|
+
get sectionOutlineColor() {
|
|
484
|
+
return this._data.sectionOutlineColor;
|
|
485
|
+
}
|
|
486
|
+
set sectionOutlineColor(value) {
|
|
487
|
+
this._data.sectionOutlineColor = value;
|
|
488
|
+
this.change();
|
|
489
|
+
}
|
|
490
|
+
get sectionOutlineWidth() {
|
|
491
|
+
return this._data.sectionOutlineWidth;
|
|
492
|
+
}
|
|
493
|
+
set sectionOutlineWidth(value) {
|
|
494
|
+
this._data.sectionOutlineWidth = value;
|
|
405
495
|
this.change();
|
|
406
496
|
}
|
|
407
497
|
get edgesColor() {
|
|
@@ -9820,7 +9910,7 @@
|
|
|
9820
9910
|
const _whiteColor = new Color( 1, 1, 1 );
|
|
9821
9911
|
const _frustum = new Frustum();
|
|
9822
9912
|
const _frustumArray = new FrustumArray();
|
|
9823
|
-
const _box$1 = new Box3();
|
|
9913
|
+
const _box$1$1 = new Box3();
|
|
9824
9914
|
const _sphere$2 = new Sphere();
|
|
9825
9915
|
const _vector$5 = new Vector3();
|
|
9826
9916
|
const _forward$1 = new Vector3();
|
|
@@ -9983,8 +10073,8 @@
|
|
|
9983
10073
|
if ( instanceInfo[ i ].active === false ) continue;
|
|
9984
10074
|
const geometryId = instanceInfo[ i ].geometryIndex;
|
|
9985
10075
|
this.getMatrixAt( i, _matrix$1 );
|
|
9986
|
-
this.getBoundingBoxAt( geometryId, _box$1 ).applyMatrix4( _matrix$1 );
|
|
9987
|
-
boundingBox.union( _box$1 );
|
|
10076
|
+
this.getBoundingBoxAt( geometryId, _box$1$1 ).applyMatrix4( _matrix$1 );
|
|
10077
|
+
boundingBox.union( _box$1$1 );
|
|
9988
10078
|
}
|
|
9989
10079
|
}
|
|
9990
10080
|
computeBoundingSphere() {
|
|
@@ -10244,8 +10334,8 @@
|
|
|
10244
10334
|
const geometryInfo = this._geometryInfo[ geometryId ];
|
|
10245
10335
|
if ( geometryInfo.boundingSphere === null ) {
|
|
10246
10336
|
const sphere = new Sphere();
|
|
10247
|
-
this.getBoundingBoxAt( geometryId, _box$1 );
|
|
10248
|
-
_box$1.getCenter( sphere.center );
|
|
10337
|
+
this.getBoundingBoxAt( geometryId, _box$1$1 );
|
|
10338
|
+
_box$1$1.getCenter( sphere.center );
|
|
10249
10339
|
const index = geometry.index;
|
|
10250
10340
|
const position = geometry.attributes.position;
|
|
10251
10341
|
let maxRadiusSq = 0;
|
|
@@ -10713,8 +10803,8 @@
|
|
|
10713
10803
|
object: object
|
|
10714
10804
|
};
|
|
10715
10805
|
}
|
|
10716
|
-
const _start$
|
|
10717
|
-
const _end$
|
|
10806
|
+
const _start$3 = new Vector3();
|
|
10807
|
+
const _end$3 = new Vector3();
|
|
10718
10808
|
class LineSegments extends Line$1 {
|
|
10719
10809
|
constructor( geometry, material ) {
|
|
10720
10810
|
super( geometry, material );
|
|
@@ -10727,10 +10817,10 @@
|
|
|
10727
10817
|
const positionAttribute = geometry.attributes.position;
|
|
10728
10818
|
const lineDistances = [];
|
|
10729
10819
|
for ( let i = 0, l = positionAttribute.count; i < l; i += 2 ) {
|
|
10730
|
-
_start$
|
|
10731
|
-
_end$
|
|
10820
|
+
_start$3.fromBufferAttribute( positionAttribute, i );
|
|
10821
|
+
_end$3.fromBufferAttribute( positionAttribute, i + 1 );
|
|
10732
10822
|
lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ];
|
|
10733
|
-
lineDistances[ i + 1 ] = lineDistances[ i ] + _start$
|
|
10823
|
+
lineDistances[ i + 1 ] = lineDistances[ i ] + _start$3.distanceTo( _end$3 );
|
|
10734
10824
|
}
|
|
10735
10825
|
geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) );
|
|
10736
10826
|
} else {
|
|
@@ -10771,8 +10861,8 @@
|
|
|
10771
10861
|
}
|
|
10772
10862
|
}
|
|
10773
10863
|
const _inverseMatrix = new Matrix4();
|
|
10774
|
-
const _ray = new Ray();
|
|
10775
|
-
const _sphere = new Sphere();
|
|
10864
|
+
const _ray$4 = new Ray();
|
|
10865
|
+
const _sphere$7 = new Sphere();
|
|
10776
10866
|
const _position$2 = new Vector3();
|
|
10777
10867
|
class Points extends Object3D {
|
|
10778
10868
|
constructor( geometry = new BufferGeometry(), material = new PointsMaterial() ) {
|
|
@@ -10797,12 +10887,12 @@
|
|
|
10797
10887
|
const threshold = raycaster.params.Points.threshold;
|
|
10798
10888
|
const drawRange = geometry.drawRange;
|
|
10799
10889
|
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;
|
|
10890
|
+
_sphere$7.copy( geometry.boundingSphere );
|
|
10891
|
+
_sphere$7.applyMatrix4( matrixWorld );
|
|
10892
|
+
_sphere$7.radius += threshold;
|
|
10893
|
+
if ( raycaster.ray.intersectsSphere( _sphere$7 ) === false ) return;
|
|
10804
10894
|
_inverseMatrix.copy( matrixWorld ).invert();
|
|
10805
|
-
_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
|
|
10895
|
+
_ray$4.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
|
|
10806
10896
|
const localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
|
|
10807
10897
|
const localThresholdSq = localThreshold * localThreshold;
|
|
10808
10898
|
const index = geometry.index;
|
|
@@ -10844,10 +10934,10 @@
|
|
|
10844
10934
|
}
|
|
10845
10935
|
}
|
|
10846
10936
|
function testPoint( point, index, localThresholdSq, matrixWorld, raycaster, intersects, object ) {
|
|
10847
|
-
const rayPointDistanceSq = _ray.distanceSqToPoint( point );
|
|
10937
|
+
const rayPointDistanceSq = _ray$4.distanceSqToPoint( point );
|
|
10848
10938
|
if ( rayPointDistanceSq < localThresholdSq ) {
|
|
10849
10939
|
const intersectPoint = new Vector3();
|
|
10850
|
-
_ray.closestPointToPoint( point, intersectPoint );
|
|
10940
|
+
_ray$4.closestPointToPoint( point, intersectPoint );
|
|
10851
10941
|
intersectPoint.applyMatrix4( matrixWorld );
|
|
10852
10942
|
const distance = raycaster.ray.origin.distanceTo( intersectPoint );
|
|
10853
10943
|
if ( distance < raycaster.near || distance > raycaster.far ) return;
|
|
@@ -34348,15 +34438,15 @@ void main() {
|
|
|
34348
34438
|
const DESKTOP_SNAP_DISTANCE = 10;
|
|
34349
34439
|
const MOBILE_SNAP_DISTANCE = 50;
|
|
34350
34440
|
const _vertex = new Vector3();
|
|
34351
|
-
const _start$
|
|
34352
|
-
const _end$
|
|
34353
|
-
const _line = new Line3();
|
|
34441
|
+
const _start$2 = new Vector3();
|
|
34442
|
+
const _end$2 = new Vector3();
|
|
34443
|
+
const _line$1 = new Line3();
|
|
34354
34444
|
const _center = new Vector3();
|
|
34355
34445
|
const _projection = new Vector3();
|
|
34356
34446
|
class Snapper {
|
|
34357
|
-
constructor(camera,
|
|
34447
|
+
constructor(camera, clippingPlanes, canvas) {
|
|
34358
34448
|
this.camera = camera;
|
|
34359
|
-
this.
|
|
34449
|
+
this.clippingPlanes = clippingPlanes;
|
|
34360
34450
|
this.canvas = canvas;
|
|
34361
34451
|
this.threshold = 0.0001;
|
|
34362
34452
|
this.raycaster = new Raycaster();
|
|
@@ -34387,7 +34477,7 @@ void main() {
|
|
|
34387
34477
|
};
|
|
34388
34478
|
let intersects = this.raycaster.intersectObjects(objects, recursive);
|
|
34389
34479
|
if (clip) {
|
|
34390
|
-
const clippingPlanes = this.
|
|
34480
|
+
const clippingPlanes = this.clippingPlanes;
|
|
34391
34481
|
clippingPlanes.forEach((plane) => {
|
|
34392
34482
|
intersects = intersects.filter((intersect) => plane.distanceToPoint(intersect.point) >= 0);
|
|
34393
34483
|
});
|
|
@@ -34439,17 +34529,17 @@ void main() {
|
|
|
34439
34529
|
}
|
|
34440
34530
|
const edgePositions = edges.attributes.position.array;
|
|
34441
34531
|
for (let i = 0; i < edgePositions.length; i += 6) {
|
|
34442
|
-
_start$
|
|
34443
|
-
_end$
|
|
34444
|
-
_line.set(_start$
|
|
34445
|
-
_line.getCenter(_center);
|
|
34532
|
+
_start$2.set(edgePositions[i], edgePositions[i + 1], edgePositions[i + 2]);
|
|
34533
|
+
_end$2.set(edgePositions[i + 3], edgePositions[i + 4], edgePositions[i + 5]);
|
|
34534
|
+
_line$1.set(_start$2, _end$2);
|
|
34535
|
+
_line$1.getCenter(_center);
|
|
34446
34536
|
const centerDistance = _center.distanceTo(localPoint);
|
|
34447
34537
|
if (centerDistance < snapDistance) {
|
|
34448
34538
|
snapDistance = centerDistance;
|
|
34449
34539
|
snapPoint = _center.clone();
|
|
34450
34540
|
continue;
|
|
34451
34541
|
}
|
|
34452
|
-
_line.closestPointToPoint(localPoint, true, _projection);
|
|
34542
|
+
_line$1.closestPointToPoint(localPoint, true, _projection);
|
|
34453
34543
|
const lineDistance = _projection.distanceTo(localPoint);
|
|
34454
34544
|
if (lineDistance < snapDistance) {
|
|
34455
34545
|
snapDistance = lineDistance;
|
|
@@ -34474,7 +34564,7 @@ void main() {
|
|
|
34474
34564
|
this.orbit.object = this.viewer.camera;
|
|
34475
34565
|
this.orbit.update();
|
|
34476
34566
|
};
|
|
34477
|
-
this.
|
|
34567
|
+
this.updateZoomSpeed = ({ data: options }) => {
|
|
34478
34568
|
this.orbit.zoomSpeed = Math.abs(this.orbit.zoomSpeed) * (options.reverseZoomWheel ? -1 : 1);
|
|
34479
34569
|
};
|
|
34480
34570
|
this.controlsStart = () => {
|
|
@@ -34533,7 +34623,7 @@ void main() {
|
|
|
34533
34623
|
this.viewer.addEventListener("zoom", this.updateControls);
|
|
34534
34624
|
this.viewer.addEventListener("drawviewpoint", this.updateControls);
|
|
34535
34625
|
this.viewer.addEventListener("changecameramode", this.updateControlsCamera);
|
|
34536
|
-
this.viewer.addEventListener("optionschange", this.
|
|
34626
|
+
this.viewer.addEventListener("optionschange", this.updateZoomSpeed);
|
|
34537
34627
|
this.viewer.addEventListener("contextmenu", this.stopContextMenu);
|
|
34538
34628
|
this.updateControls();
|
|
34539
34629
|
this.updateControlsCamera();
|
|
@@ -34545,7 +34635,7 @@ void main() {
|
|
|
34545
34635
|
this.viewer.removeEventListener("zoom", this.updateControls);
|
|
34546
34636
|
this.viewer.removeEventListener("drawviewpoint", this.updateControls);
|
|
34547
34637
|
this.viewer.removeEventListener("changecameramode", this.updateControlsCamera);
|
|
34548
|
-
this.viewer.removeEventListener("optionschange", this.
|
|
34638
|
+
this.viewer.removeEventListener("optionschange", this.updateZoomSpeed);
|
|
34549
34639
|
this.viewer.removeEventListener("contextmenu", this.stopContextMenu);
|
|
34550
34640
|
this.orbit.removeEventListener("start", this.controlsStart);
|
|
34551
34641
|
this.orbit.removeEventListener("change", this.controlsChange);
|
|
@@ -34557,13 +34647,17 @@ void main() {
|
|
|
34557
34647
|
constructor(viewer) {
|
|
34558
34648
|
super(viewer);
|
|
34559
34649
|
this.helpers = [];
|
|
34560
|
-
this.activeHelper =
|
|
34650
|
+
this.activeHelper = undefined;
|
|
34651
|
+
this.transformUpdate = () => {
|
|
34652
|
+
this.viewer.update();
|
|
34653
|
+
};
|
|
34561
34654
|
this.transformChange = () => {
|
|
34562
34655
|
if (!this.activeHelper)
|
|
34563
34656
|
return;
|
|
34564
34657
|
const plane = this.activeHelper.plane;
|
|
34565
34658
|
plane.normal.copy(new Vector3(0, 0, -1)).applyQuaternion(this.activeHelper.quaternion);
|
|
34566
34659
|
plane.constant = -this.activeHelper.position.dot(plane.normal);
|
|
34660
|
+
this.viewer.emitEvent({ type: "changecuttingplanes" });
|
|
34567
34661
|
this.viewer.update();
|
|
34568
34662
|
this.changed = true;
|
|
34569
34663
|
};
|
|
@@ -34575,25 +34669,29 @@ void main() {
|
|
|
34575
34669
|
this.orbit.enabled = !event.value;
|
|
34576
34670
|
this.translate.enabled = !event.value;
|
|
34577
34671
|
};
|
|
34578
|
-
this.
|
|
34672
|
+
this.syncHelpers = () => {
|
|
34579
34673
|
const extentsSize = this.viewer.extents.getSize(new Vector3()).length() || 1;
|
|
34580
|
-
this.
|
|
34674
|
+
const extentsCenter = this.viewer.extents.getCenter(new Vector3());
|
|
34675
|
+
this.helpers.forEach((planeHelper) => {
|
|
34676
|
+
planeHelper.size = extentsSize;
|
|
34677
|
+
planeHelper.position.copy(planeHelper.plane.projectPoint(extentsCenter, new Vector3()));
|
|
34678
|
+
});
|
|
34581
34679
|
this.viewer.update();
|
|
34582
34680
|
};
|
|
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
34681
|
this.clearHelpers = () => {
|
|
34589
34682
|
this.setActiveHelper();
|
|
34590
34683
|
this.helpers.forEach((helper) => {
|
|
34591
34684
|
helper.removeFromParent();
|
|
34592
34685
|
helper.dispose();
|
|
34593
34686
|
});
|
|
34594
|
-
this.helpers =
|
|
34687
|
+
this.helpers.length = 0;
|
|
34595
34688
|
this.viewer.update();
|
|
34596
34689
|
};
|
|
34690
|
+
this.updateTransformCamera = () => {
|
|
34691
|
+
this.translate.camera = this.viewer.camera;
|
|
34692
|
+
this.rotate.camera = this.viewer.camera;
|
|
34693
|
+
this.snapper.camera = this.viewer.camera;
|
|
34694
|
+
};
|
|
34597
34695
|
this.onKeyDown = (event) => {
|
|
34598
34696
|
if (event.key === "Shift")
|
|
34599
34697
|
this.rotate.setRotationSnap(Math.PI / 4);
|
|
@@ -34637,12 +34735,9 @@ void main() {
|
|
|
34637
34735
|
this.transformChange();
|
|
34638
34736
|
event.stopPropagation();
|
|
34639
34737
|
};
|
|
34640
|
-
|
|
34641
|
-
viewer.renderer.clippingPlanes = [];
|
|
34642
|
-
this.clippingPlanes = viewer.renderer.clippingPlanes;
|
|
34643
|
-
this.clippingPlanes.forEach((plane) => this.addHelper(plane));
|
|
34738
|
+
viewer.clippingPlanes.forEach((plane) => this.addHelper(plane));
|
|
34644
34739
|
const extentsSize = viewer.extents.getSize(new Vector3()).length() || 1;
|
|
34645
|
-
this.snapper = new Snapper(viewer.camera, viewer.
|
|
34740
|
+
this.snapper = new Snapper(viewer.camera, viewer.clippingPlanes, viewer.canvas);
|
|
34646
34741
|
this.snapper.threshold = extentsSize / 10000;
|
|
34647
34742
|
this.downPosition = new Vector2();
|
|
34648
34743
|
this.position0 = new Vector3();
|
|
@@ -34653,7 +34748,8 @@ void main() {
|
|
|
34653
34748
|
this.translate.showX = false;
|
|
34654
34749
|
this.translate.showY = false;
|
|
34655
34750
|
this.translate.showZ = true;
|
|
34656
|
-
this.translate.addEventListener("change", this.
|
|
34751
|
+
this.translate.addEventListener("change", this.transformUpdate);
|
|
34752
|
+
this.translate.addEventListener("objectChange", this.transformChange);
|
|
34657
34753
|
this.translate.addEventListener("dragging-changed", this.translateDrag);
|
|
34658
34754
|
this.viewer.helpers.add(this.translate.getHelper());
|
|
34659
34755
|
this.rotate = new TransformControls(viewer.camera, viewer.canvas);
|
|
@@ -34662,15 +34758,18 @@ void main() {
|
|
|
34662
34758
|
this.rotate.showX = true;
|
|
34663
34759
|
this.rotate.showY = true;
|
|
34664
34760
|
this.rotate.showZ = false;
|
|
34665
|
-
this.rotate.addEventListener("change", this.
|
|
34761
|
+
this.rotate.addEventListener("change", this.transformUpdate);
|
|
34762
|
+
this.rotate.addEventListener("objectChange", this.transformChange);
|
|
34666
34763
|
this.rotate.addEventListener("dragging-changed", this.rotateDrag);
|
|
34667
34764
|
this.viewer.helpers.add(this.rotate.getHelper());
|
|
34668
34765
|
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("
|
|
34766
|
+
this.viewer.addEventListener("explode", this.syncHelpers);
|
|
34767
|
+
this.viewer.addEventListener("hide", this.syncHelpers);
|
|
34768
|
+
this.viewer.addEventListener("isolate", this.syncHelpers);
|
|
34769
|
+
this.viewer.addEventListener("show", this.syncHelpers);
|
|
34770
|
+
this.viewer.addEventListener("showall", this.syncHelpers);
|
|
34673
34771
|
this.viewer.addEventListener("clearslices", this.clearHelpers);
|
|
34772
|
+
this.viewer.addEventListener("changecameramode", this.updateTransformCamera);
|
|
34674
34773
|
this.viewer.canvas.addEventListener("pointerdown", this.onPointerDown, true);
|
|
34675
34774
|
this.viewer.canvas.addEventListener("pointerup", this.onPointerUp, true);
|
|
34676
34775
|
this.viewer.canvas.addEventListener("pointercancel", this.onPointerCancel, true);
|
|
@@ -34680,23 +34779,27 @@ void main() {
|
|
|
34680
34779
|
this.viewer.update();
|
|
34681
34780
|
}
|
|
34682
34781
|
dispose() {
|
|
34683
|
-
this.viewer.removeEventListener("explode", this.
|
|
34684
|
-
this.viewer.removeEventListener("
|
|
34685
|
-
this.viewer.removeEventListener("
|
|
34686
|
-
this.viewer.removeEventListener("
|
|
34782
|
+
this.viewer.removeEventListener("explode", this.syncHelpers);
|
|
34783
|
+
this.viewer.removeEventListener("hide", this.syncHelpers);
|
|
34784
|
+
this.viewer.removeEventListener("isolate", this.syncHelpers);
|
|
34785
|
+
this.viewer.removeEventListener("show", this.syncHelpers);
|
|
34786
|
+
this.viewer.removeEventListener("showall", this.syncHelpers);
|
|
34687
34787
|
this.viewer.removeEventListener("clearslices", this.clearHelpers);
|
|
34788
|
+
this.viewer.removeEventListener("changecameramode", this.updateTransformCamera);
|
|
34688
34789
|
this.viewer.canvas.removeEventListener("pointerdown", this.onPointerDown, true);
|
|
34689
34790
|
this.viewer.canvas.removeEventListener("pointerup", this.onPointerUp, true);
|
|
34690
34791
|
this.viewer.canvas.removeEventListener("pointercancel", this.onPointerCancel, true);
|
|
34691
34792
|
this.viewer.canvas.removeEventListener("dblclick", this.onDoubleClick, true);
|
|
34692
34793
|
window.removeEventListener("keydown", this.onKeyDown);
|
|
34693
34794
|
window.removeEventListener("keyup", this.onKeyUp);
|
|
34694
|
-
this.translate.removeEventListener("change", this.
|
|
34795
|
+
this.translate.removeEventListener("change", this.transformUpdate);
|
|
34796
|
+
this.translate.removeEventListener("objectChange", this.transformChange);
|
|
34695
34797
|
this.translate.removeEventListener("dragging-changed", this.translateDrag);
|
|
34696
34798
|
this.translate.getHelper().removeFromParent();
|
|
34697
34799
|
this.translate.detach();
|
|
34698
34800
|
this.translate.dispose();
|
|
34699
|
-
this.rotate.removeEventListener("change", this.
|
|
34801
|
+
this.rotate.removeEventListener("change", this.transformUpdate);
|
|
34802
|
+
this.rotate.removeEventListener("objectChange", this.transformChange);
|
|
34700
34803
|
this.rotate.removeEventListener("dragging-changed", this.rotateDrag);
|
|
34701
34804
|
this.rotate.getHelper().removeFromParent();
|
|
34702
34805
|
this.rotate.detach();
|
|
@@ -34705,8 +34808,8 @@ void main() {
|
|
|
34705
34808
|
helper.removeFromParent();
|
|
34706
34809
|
helper.dispose();
|
|
34707
34810
|
});
|
|
34708
|
-
this.helpers =
|
|
34709
|
-
this.activeHelper =
|
|
34811
|
+
this.helpers.length = 0;
|
|
34812
|
+
this.activeHelper = undefined;
|
|
34710
34813
|
super.dispose();
|
|
34711
34814
|
}
|
|
34712
34815
|
addHelper(plane) {
|
|
@@ -34758,9 +34861,10 @@ void main() {
|
|
|
34758
34861
|
const extentsCenter = this.viewer.extents.getCenter(new Vector3());
|
|
34759
34862
|
const constant = -extentsCenter.dot(normal);
|
|
34760
34863
|
const plane = new Plane(normal, constant);
|
|
34761
|
-
this.clippingPlanes.push(plane);
|
|
34864
|
+
this.viewer.clippingPlanes.push(plane);
|
|
34762
34865
|
const helper = this.addHelper(plane);
|
|
34763
34866
|
this.setActiveHelper(helper);
|
|
34867
|
+
this.viewer.emitEvent({ type: "changecuttingplanes" });
|
|
34764
34868
|
}
|
|
34765
34869
|
addPlaneX() {
|
|
34766
34870
|
this.addPlane(new Vector3(-1, 0, 0));
|
|
@@ -34775,13 +34879,14 @@ void main() {
|
|
|
34775
34879
|
if (!this.activeHelper)
|
|
34776
34880
|
return;
|
|
34777
34881
|
const helper = this.activeHelper;
|
|
34778
|
-
const index = this.clippingPlanes.indexOf(helper.plane);
|
|
34882
|
+
const index = this.viewer.clippingPlanes.indexOf(helper.plane);
|
|
34779
34883
|
if (index !== -1)
|
|
34780
|
-
this.clippingPlanes.splice(index, 1);
|
|
34884
|
+
this.viewer.clippingPlanes.splice(index, 1);
|
|
34781
34885
|
this.helpers = this.helpers.filter((x) => x !== helper);
|
|
34782
34886
|
helper.removeFromParent();
|
|
34783
34887
|
helper.dispose();
|
|
34784
34888
|
this.setActiveHelper(this.helpers[this.helpers.length - 1]);
|
|
34889
|
+
this.viewer.emitEvent({ type: "changecuttingplanes" });
|
|
34785
34890
|
}
|
|
34786
34891
|
}
|
|
34787
34892
|
|
|
@@ -34975,7 +35080,7 @@ void main() {
|
|
|
34975
35080
|
this.line = new MeasureLine(this.overlay, this.scale, this.units, this.precision);
|
|
34976
35081
|
this.overlay.addLine(this.line);
|
|
34977
35082
|
const extentsSize = this.viewer.extents.getSize(new Vector3()).length() || 1;
|
|
34978
|
-
this.snapper = new Snapper(viewer.camera, viewer.
|
|
35083
|
+
this.snapper = new Snapper(viewer.camera, viewer.clippingPlanes, viewer.canvas);
|
|
34979
35084
|
this.snapper.threshold = extentsSize / 10000;
|
|
34980
35085
|
this.objects = [];
|
|
34981
35086
|
this.updateObjects();
|
|
@@ -36254,8 +36359,8 @@ void main() {
|
|
|
36254
36359
|
commands.registerCommand("right", (viewer) => setDefaultViewPosition(viewer, "right"));
|
|
36255
36360
|
commands.registerCommand("front", (viewer) => setDefaultViewPosition(viewer, "front"));
|
|
36256
36361
|
commands.registerCommand("back", (viewer) => setDefaultViewPosition(viewer, "back"));
|
|
36257
|
-
commands.registerCommand("sw", (viewer) => setDefaultViewPosition(viewer, "sw"));
|
|
36258
36362
|
commands.registerCommand("se", (viewer) => setDefaultViewPosition(viewer, "se"));
|
|
36363
|
+
commands.registerCommand("sw", (viewer) => setDefaultViewPosition(viewer, "sw"));
|
|
36259
36364
|
commands.registerCommand("ne", (viewer) => setDefaultViewPosition(viewer, "ne"));
|
|
36260
36365
|
commands.registerCommand("nw", (viewer) => setDefaultViewPosition(viewer, "nw"));
|
|
36261
36366
|
commands.registerCommandAlias("clearMarkup", "clearOverlay");
|
|
@@ -36278,6 +36383,7 @@ void main() {
|
|
|
36278
36383
|
this.syncOptions = () => {
|
|
36279
36384
|
this.backgroundColor.setHex(0xffffff);
|
|
36280
36385
|
this.viewer.renderer.setClearColor(this.backgroundColor);
|
|
36386
|
+
this.viewer.update();
|
|
36281
36387
|
};
|
|
36282
36388
|
this.viewer = viewer;
|
|
36283
36389
|
this.backgroundColor = new Color(0xffffff);
|
|
@@ -36293,7 +36399,7 @@ void main() {
|
|
|
36293
36399
|
|
|
36294
36400
|
class CameraComponent {
|
|
36295
36401
|
constructor(viewer) {
|
|
36296
|
-
this.
|
|
36402
|
+
this.syncOptions = () => {
|
|
36297
36403
|
this.switchCameraMode(this.viewer.options.cameraMode);
|
|
36298
36404
|
};
|
|
36299
36405
|
this.geometryEnd = () => {
|
|
@@ -36324,13 +36430,13 @@ void main() {
|
|
|
36324
36430
|
};
|
|
36325
36431
|
this.viewer = viewer;
|
|
36326
36432
|
this.viewer.addEventListener("databasechunk", this.geometryEnd);
|
|
36327
|
-
this.viewer.addEventListener("optionschange", this.
|
|
36328
|
-
this.viewer.addEventListener("initialize", this.
|
|
36433
|
+
this.viewer.addEventListener("optionschange", this.syncOptions);
|
|
36434
|
+
this.viewer.addEventListener("initialize", this.syncOptions);
|
|
36329
36435
|
}
|
|
36330
36436
|
dispose() {
|
|
36331
36437
|
this.viewer.removeEventListener("databasechunk", this.geometryEnd);
|
|
36332
|
-
this.viewer.removeEventListener("optionschange", this.
|
|
36333
|
-
this.viewer.removeEventListener("initialize", this.
|
|
36438
|
+
this.viewer.removeEventListener("optionschange", this.syncOptions);
|
|
36439
|
+
this.viewer.removeEventListener("initialize", this.syncOptions);
|
|
36334
36440
|
}
|
|
36335
36441
|
getCameraMode(camera) {
|
|
36336
36442
|
return camera.isOrthographicCamera ? "orthographic" : "perspective";
|
|
@@ -36353,7 +36459,6 @@ void main() {
|
|
|
36353
36459
|
camera.updateProjectionMatrix();
|
|
36354
36460
|
this.viewer.camera = camera;
|
|
36355
36461
|
this.viewer.renderPass.camera = camera;
|
|
36356
|
-
this.viewer.helpersPass.camera = camera;
|
|
36357
36462
|
this.viewer.ssaaRenderPass.camera = camera;
|
|
36358
36463
|
this.viewer.update();
|
|
36359
36464
|
}
|
|
@@ -36497,7 +36602,7 @@ void main() {
|
|
|
36497
36602
|
console.log("WebGL Renderer:", this.viewer.info.system.webglRenderer);
|
|
36498
36603
|
console.log("WebGL Vendor:", this.viewer.info.system.webglVendor);
|
|
36499
36604
|
this.resize();
|
|
36500
|
-
this.
|
|
36605
|
+
this.syncOptions({ data: this.viewer.options });
|
|
36501
36606
|
};
|
|
36502
36607
|
this.clear = () => {
|
|
36503
36608
|
this.viewer.info.performance.timeToFirstRender = 0;
|
|
@@ -36521,7 +36626,7 @@ void main() {
|
|
|
36521
36626
|
this.viewer.info.memory.totalEstimatedGpuBytes = 0;
|
|
36522
36627
|
this.viewer.info.memory.usedJSHeapSize = 0;
|
|
36523
36628
|
};
|
|
36524
|
-
this.
|
|
36629
|
+
this.syncOptions = ({ data: options }) => {
|
|
36525
36630
|
if (options.antialiasing === false)
|
|
36526
36631
|
this.viewer.info.render.antialiasing = "";
|
|
36527
36632
|
else if (options.antialiasing === true)
|
|
@@ -36596,7 +36701,7 @@ void main() {
|
|
|
36596
36701
|
this.frames = 0;
|
|
36597
36702
|
this.viewer.addEventListener("initialize", this.initialize);
|
|
36598
36703
|
this.viewer.addEventListener("clear", this.clear);
|
|
36599
|
-
this.viewer.addEventListener("optionschange", this.
|
|
36704
|
+
this.viewer.addEventListener("optionschange", this.syncOptions);
|
|
36600
36705
|
this.viewer.addEventListener("geometrystart", this.geometryStart);
|
|
36601
36706
|
this.viewer.addEventListener("databasechunk", this.databaseChunk);
|
|
36602
36707
|
this.viewer.addEventListener("geometryend", this.geometryEnd);
|
|
@@ -36607,7 +36712,7 @@ void main() {
|
|
|
36607
36712
|
dispose() {
|
|
36608
36713
|
this.viewer.removeEventListener("initialize", this.initialize);
|
|
36609
36714
|
this.viewer.removeEventListener("clear", this.clear);
|
|
36610
|
-
this.viewer.removeEventListener("optionschange", this.
|
|
36715
|
+
this.viewer.removeEventListener("optionschange", this.syncOptions);
|
|
36611
36716
|
this.viewer.removeEventListener("geometrystart", this.geometryStart);
|
|
36612
36717
|
this.viewer.removeEventListener("databasechunk", this.databaseChunk);
|
|
36613
36718
|
this.viewer.removeEventListener("geometryend", this.geometryEnd);
|
|
@@ -36674,7 +36779,7 @@ void main() {
|
|
|
36674
36779
|
}
|
|
36675
36780
|
}
|
|
36676
36781
|
|
|
36677
|
-
const _box = new Box3();
|
|
36782
|
+
const _box$1 = new Box3();
|
|
36678
36783
|
const _vector = new Vector3();
|
|
36679
36784
|
class LineSegmentsGeometry extends InstancedBufferGeometry {
|
|
36680
36785
|
constructor() {
|
|
@@ -36756,8 +36861,8 @@ void main() {
|
|
|
36756
36861
|
const end = this.attributes.instanceEnd;
|
|
36757
36862
|
if ( start !== undefined && end !== undefined ) {
|
|
36758
36863
|
this.boundingBox.setFromBufferAttribute( start );
|
|
36759
|
-
_box.setFromBufferAttribute( end );
|
|
36760
|
-
this.boundingBox.union( _box );
|
|
36864
|
+
_box$1.setFromBufferAttribute( end );
|
|
36865
|
+
this.boundingBox.union( _box$1 );
|
|
36761
36866
|
}
|
|
36762
36867
|
}
|
|
36763
36868
|
computeBoundingSphere() {
|
|
@@ -37279,9 +37384,9 @@ void main() {
|
|
|
37279
37384
|
}
|
|
37280
37385
|
}
|
|
37281
37386
|
|
|
37282
|
-
const _start = new Vector3();
|
|
37283
|
-
const _end = new Vector3();
|
|
37284
|
-
const _viewport = new Vector4();
|
|
37387
|
+
const _start$1 = new Vector3();
|
|
37388
|
+
const _end$1 = new Vector3();
|
|
37389
|
+
const _viewport$1 = new Vector4();
|
|
37285
37390
|
class Wireframe extends Mesh {
|
|
37286
37391
|
constructor( geometry = new LineSegmentsGeometry(), material = new LineMaterial( { color: Math.random() * 0xffffff } ) ) {
|
|
37287
37392
|
super( geometry, material );
|
|
@@ -37294,10 +37399,10 @@ void main() {
|
|
|
37294
37399
|
const instanceEnd = geometry.attributes.instanceEnd;
|
|
37295
37400
|
const lineDistances = new Float32Array( 2 * instanceStart.count );
|
|
37296
37401
|
for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
|
|
37297
|
-
_start.fromBufferAttribute( instanceStart, i );
|
|
37298
|
-
_end.fromBufferAttribute( instanceEnd, i );
|
|
37402
|
+
_start$1.fromBufferAttribute( instanceStart, i );
|
|
37403
|
+
_end$1.fromBufferAttribute( instanceEnd, i );
|
|
37299
37404
|
lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
|
|
37300
|
-
lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
|
|
37405
|
+
lineDistances[ j + 1 ] = lineDistances[ j ] + _start$1.distanceTo( _end$1 );
|
|
37301
37406
|
}
|
|
37302
37407
|
const instanceDistanceBuffer = new InstancedInterleavedBuffer( lineDistances, 2, 1 );
|
|
37303
37408
|
geometry.setAttribute( 'instanceDistanceStart', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) );
|
|
@@ -37307,8 +37412,8 @@ void main() {
|
|
|
37307
37412
|
onBeforeRender( renderer ) {
|
|
37308
37413
|
const uniforms = this.material.uniforms;
|
|
37309
37414
|
if ( uniforms && uniforms.resolution ) {
|
|
37310
|
-
renderer.getViewport( _viewport );
|
|
37311
|
-
this.material.uniforms.resolution.value.set( _viewport.z, _viewport.w );
|
|
37415
|
+
renderer.getViewport( _viewport$1 );
|
|
37416
|
+
this.material.uniforms.resolution.value.set( _viewport$1.z, _viewport$1.w );
|
|
37312
37417
|
}
|
|
37313
37418
|
}
|
|
37314
37419
|
}
|
|
@@ -37384,28 +37489,38 @@ void main() {
|
|
|
37384
37489
|
polygonOffset: true,
|
|
37385
37490
|
polygonOffsetFactor: 1,
|
|
37386
37491
|
polygonOffsetUnits: 1,
|
|
37492
|
+
clippingPlanes: this.viewer.clippingPlanes,
|
|
37387
37493
|
});
|
|
37388
37494
|
this.edgesMaterial = new LineMaterial({
|
|
37389
37495
|
linewidth: 1.5,
|
|
37390
37496
|
resolution: new Vector2(window.innerWidth, window.innerHeight),
|
|
37497
|
+
clippingPlanes: this.viewer.clippingPlanes,
|
|
37391
37498
|
});
|
|
37392
37499
|
this.lineMaterial = new LineBasicMaterial({
|
|
37393
37500
|
transparent: true,
|
|
37394
37501
|
depthTest: true,
|
|
37395
37502
|
depthWrite: true,
|
|
37503
|
+
clippingPlanes: this.viewer.clippingPlanes,
|
|
37396
37504
|
});
|
|
37397
37505
|
this.lineGlowMaterial = new LineMaterial({
|
|
37398
37506
|
linewidth: 1.5,
|
|
37399
37507
|
transparent: true,
|
|
37400
37508
|
opacity: 0.8,
|
|
37401
37509
|
resolution: new Vector2(window.innerWidth, window.innerHeight),
|
|
37510
|
+
clippingPlanes: this.viewer.clippingPlanes,
|
|
37402
37511
|
});
|
|
37403
37512
|
this.syncHighlightColors();
|
|
37404
37513
|
};
|
|
37405
|
-
this.
|
|
37514
|
+
this.syncOptions = () => {
|
|
37406
37515
|
this.syncHighlightColors();
|
|
37407
37516
|
this.viewer.update();
|
|
37408
37517
|
};
|
|
37518
|
+
this.viewerResize = (event) => {
|
|
37519
|
+
var _a, _b, _c;
|
|
37520
|
+
(_a = this.renderTarget) === null || _a === void 0 ? void 0 : _a.setSize(event.width, event.height);
|
|
37521
|
+
(_b = this.edgesMaterial) === null || _b === void 0 ? void 0 : _b.resolution.set(event.width, event.height);
|
|
37522
|
+
(_c = this.lineGlowMaterial) === null || _c === void 0 ? void 0 : _c.resolution.set(event.width, event.height);
|
|
37523
|
+
};
|
|
37409
37524
|
this.viewer = viewer;
|
|
37410
37525
|
const gl2 = viewer.canvas.getContext("webgl2");
|
|
37411
37526
|
if (gl2) {
|
|
@@ -37418,13 +37533,13 @@ void main() {
|
|
|
37418
37533
|
});
|
|
37419
37534
|
}
|
|
37420
37535
|
this.viewer.addEventListener("databasechunk", this.geometryEnd);
|
|
37421
|
-
this.viewer.addEventListener("optionschange", this.
|
|
37536
|
+
this.viewer.addEventListener("optionschange", this.syncOptions);
|
|
37422
37537
|
this.viewer.addEventListener("resize", this.viewerResize);
|
|
37423
37538
|
this.geometryEnd();
|
|
37424
37539
|
}
|
|
37425
37540
|
dispose() {
|
|
37426
37541
|
this.viewer.removeEventListener("databasechunk", this.geometryEnd);
|
|
37427
|
-
this.viewer.removeEventListener("optionschange", this.
|
|
37542
|
+
this.viewer.removeEventListener("optionschange", this.syncOptions);
|
|
37428
37543
|
this.viewer.removeEventListener("resize", this.viewerResize);
|
|
37429
37544
|
}
|
|
37430
37545
|
highlight(objects) {
|
|
@@ -37503,12 +37618,6 @@ void main() {
|
|
|
37503
37618
|
wireframe.visible = edgesVisibility;
|
|
37504
37619
|
});
|
|
37505
37620
|
}
|
|
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
37621
|
}
|
|
37513
37622
|
|
|
37514
37623
|
class SelectionComponent {
|
|
@@ -37525,7 +37634,7 @@ void main() {
|
|
|
37525
37634
|
if (upPosition.distanceTo(this.downPosition) !== 0)
|
|
37526
37635
|
return;
|
|
37527
37636
|
const extentsSize = this.viewer.extents.getSize(new Vector3()).length() || 1;
|
|
37528
|
-
const snapper = new Snapper(this.viewer.camera, this.viewer.
|
|
37637
|
+
const snapper = new Snapper(this.viewer.camera, this.viewer.clippingPlanes, this.viewer.canvas);
|
|
37529
37638
|
snapper.threshold = extentsSize / 10000;
|
|
37530
37639
|
let intersections = [];
|
|
37531
37640
|
this.viewer.models.forEach((model) => {
|
|
@@ -37622,9 +37731,1032 @@ void main() {
|
|
|
37622
37731
|
}
|
|
37623
37732
|
}
|
|
37624
37733
|
|
|
37734
|
+
class ClippingPlaneComponent {
|
|
37735
|
+
constructor(viewer) {
|
|
37736
|
+
this.applyClippingPlanes = () => {
|
|
37737
|
+
this.viewer.models.forEach((model) => {
|
|
37738
|
+
model.scene.traverse((object) => {
|
|
37739
|
+
if (object.material) {
|
|
37740
|
+
const materials = Array.isArray(object.material) ? object.material : [object.material];
|
|
37741
|
+
materials.forEach((material) => (material.clippingPlanes = this.viewer.clippingPlanes));
|
|
37742
|
+
}
|
|
37743
|
+
});
|
|
37744
|
+
});
|
|
37745
|
+
};
|
|
37746
|
+
this.viewer = viewer;
|
|
37747
|
+
this.viewer.addEventListener("geometryend", this.applyClippingPlanes);
|
|
37748
|
+
this.viewer.addEventListener("changecuttingplanes", this.applyClippingPlanes);
|
|
37749
|
+
}
|
|
37750
|
+
dispose() {
|
|
37751
|
+
this.viewer.removeEventListener("geometryend", this.applyClippingPlanes);
|
|
37752
|
+
this.viewer.removeEventListener("changecuttingplanes", this.applyClippingPlanes);
|
|
37753
|
+
}
|
|
37754
|
+
}
|
|
37755
|
+
|
|
37756
|
+
const _viewport = new Vector4();
|
|
37757
|
+
const _start = new Vector3();
|
|
37758
|
+
const _end = new Vector3();
|
|
37759
|
+
const _start4 = new Vector4();
|
|
37760
|
+
const _end4 = new Vector4();
|
|
37761
|
+
const _ssOrigin = new Vector4();
|
|
37762
|
+
const _ssOrigin3 = new Vector3();
|
|
37763
|
+
const _mvMatrix = new Matrix4();
|
|
37764
|
+
const _line = new Line3();
|
|
37765
|
+
const _closestPoint = new Vector3();
|
|
37766
|
+
const _box = new Box3();
|
|
37767
|
+
const _sphere = new Sphere();
|
|
37768
|
+
const _clipToWorldVector = new Vector4();
|
|
37769
|
+
let _ray, _lineWidth;
|
|
37770
|
+
function getWorldSpaceHalfWidth( camera, distance, resolution ) {
|
|
37771
|
+
_clipToWorldVector.set( 0, 0, - distance, 1.0 ).applyMatrix4( camera.projectionMatrix );
|
|
37772
|
+
_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
|
|
37773
|
+
_clipToWorldVector.x = _lineWidth / resolution.width;
|
|
37774
|
+
_clipToWorldVector.y = _lineWidth / resolution.height;
|
|
37775
|
+
_clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse );
|
|
37776
|
+
_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
|
|
37777
|
+
return Math.abs( Math.max( _clipToWorldVector.x, _clipToWorldVector.y ) );
|
|
37778
|
+
}
|
|
37779
|
+
function raycastWorldUnits( lineSegments, intersects ) {
|
|
37780
|
+
const matrixWorld = lineSegments.matrixWorld;
|
|
37781
|
+
const geometry = lineSegments.geometry;
|
|
37782
|
+
const instanceStart = geometry.attributes.instanceStart;
|
|
37783
|
+
const instanceEnd = geometry.attributes.instanceEnd;
|
|
37784
|
+
const segmentCount = Math.min( geometry.instanceCount, instanceStart.count );
|
|
37785
|
+
for ( let i = 0, l = segmentCount; i < l; i ++ ) {
|
|
37786
|
+
_line.start.fromBufferAttribute( instanceStart, i );
|
|
37787
|
+
_line.end.fromBufferAttribute( instanceEnd, i );
|
|
37788
|
+
_line.applyMatrix4( matrixWorld );
|
|
37789
|
+
const pointOnLine = new Vector3();
|
|
37790
|
+
const point = new Vector3();
|
|
37791
|
+
_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
|
|
37792
|
+
const isInside = point.distanceTo( pointOnLine ) < _lineWidth * 0.5;
|
|
37793
|
+
if ( isInside ) {
|
|
37794
|
+
intersects.push( {
|
|
37795
|
+
point,
|
|
37796
|
+
pointOnLine,
|
|
37797
|
+
distance: _ray.origin.distanceTo( point ),
|
|
37798
|
+
object: lineSegments,
|
|
37799
|
+
face: null,
|
|
37800
|
+
faceIndex: i,
|
|
37801
|
+
uv: null,
|
|
37802
|
+
uv1: null,
|
|
37803
|
+
} );
|
|
37804
|
+
}
|
|
37805
|
+
}
|
|
37806
|
+
}
|
|
37807
|
+
function raycastScreenSpace( lineSegments, camera, intersects ) {
|
|
37808
|
+
const projectionMatrix = camera.projectionMatrix;
|
|
37809
|
+
const material = lineSegments.material;
|
|
37810
|
+
const resolution = material.resolution;
|
|
37811
|
+
const matrixWorld = lineSegments.matrixWorld;
|
|
37812
|
+
const geometry = lineSegments.geometry;
|
|
37813
|
+
const instanceStart = geometry.attributes.instanceStart;
|
|
37814
|
+
const instanceEnd = geometry.attributes.instanceEnd;
|
|
37815
|
+
const segmentCount = Math.min( geometry.instanceCount, instanceStart.count );
|
|
37816
|
+
const near = - camera.near;
|
|
37817
|
+
_ray.at( 1, _ssOrigin );
|
|
37818
|
+
_ssOrigin.w = 1;
|
|
37819
|
+
_ssOrigin.applyMatrix4( camera.matrixWorldInverse );
|
|
37820
|
+
_ssOrigin.applyMatrix4( projectionMatrix );
|
|
37821
|
+
_ssOrigin.multiplyScalar( 1 / _ssOrigin.w );
|
|
37822
|
+
_ssOrigin.x *= resolution.x / 2;
|
|
37823
|
+
_ssOrigin.y *= resolution.y / 2;
|
|
37824
|
+
_ssOrigin.z = 0;
|
|
37825
|
+
_ssOrigin3.copy( _ssOrigin );
|
|
37826
|
+
_mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
|
|
37827
|
+
for ( let i = 0, l = segmentCount; i < l; i ++ ) {
|
|
37828
|
+
_start4.fromBufferAttribute( instanceStart, i );
|
|
37829
|
+
_end4.fromBufferAttribute( instanceEnd, i );
|
|
37830
|
+
_start4.w = 1;
|
|
37831
|
+
_end4.w = 1;
|
|
37832
|
+
_start4.applyMatrix4( _mvMatrix );
|
|
37833
|
+
_end4.applyMatrix4( _mvMatrix );
|
|
37834
|
+
const isBehindCameraNear = _start4.z > near && _end4.z > near;
|
|
37835
|
+
if ( isBehindCameraNear ) {
|
|
37836
|
+
continue;
|
|
37837
|
+
}
|
|
37838
|
+
if ( _start4.z > near ) {
|
|
37839
|
+
const deltaDist = _start4.z - _end4.z;
|
|
37840
|
+
const t = ( _start4.z - near ) / deltaDist;
|
|
37841
|
+
_start4.lerp( _end4, t );
|
|
37842
|
+
} else if ( _end4.z > near ) {
|
|
37843
|
+
const deltaDist = _end4.z - _start4.z;
|
|
37844
|
+
const t = ( _end4.z - near ) / deltaDist;
|
|
37845
|
+
_end4.lerp( _start4, t );
|
|
37846
|
+
}
|
|
37847
|
+
_start4.applyMatrix4( projectionMatrix );
|
|
37848
|
+
_end4.applyMatrix4( projectionMatrix );
|
|
37849
|
+
_start4.multiplyScalar( 1 / _start4.w );
|
|
37850
|
+
_end4.multiplyScalar( 1 / _end4.w );
|
|
37851
|
+
_start4.x *= resolution.x / 2;
|
|
37852
|
+
_start4.y *= resolution.y / 2;
|
|
37853
|
+
_end4.x *= resolution.x / 2;
|
|
37854
|
+
_end4.y *= resolution.y / 2;
|
|
37855
|
+
_line.start.copy( _start4 );
|
|
37856
|
+
_line.start.z = 0;
|
|
37857
|
+
_line.end.copy( _end4 );
|
|
37858
|
+
_line.end.z = 0;
|
|
37859
|
+
const param = _line.closestPointToPointParameter( _ssOrigin3, true );
|
|
37860
|
+
_line.at( param, _closestPoint );
|
|
37861
|
+
const zPos = MathUtils.lerp( _start4.z, _end4.z, param );
|
|
37862
|
+
const isInClipSpace = zPos >= -1 && zPos <= 1;
|
|
37863
|
+
const isInside = _ssOrigin3.distanceTo( _closestPoint ) < _lineWidth * 0.5;
|
|
37864
|
+
if ( isInClipSpace && isInside ) {
|
|
37865
|
+
_line.start.fromBufferAttribute( instanceStart, i );
|
|
37866
|
+
_line.end.fromBufferAttribute( instanceEnd, i );
|
|
37867
|
+
_line.start.applyMatrix4( matrixWorld );
|
|
37868
|
+
_line.end.applyMatrix4( matrixWorld );
|
|
37869
|
+
const pointOnLine = new Vector3();
|
|
37870
|
+
const point = new Vector3();
|
|
37871
|
+
_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
|
|
37872
|
+
intersects.push( {
|
|
37873
|
+
point: point,
|
|
37874
|
+
pointOnLine: pointOnLine,
|
|
37875
|
+
distance: _ray.origin.distanceTo( point ),
|
|
37876
|
+
object: lineSegments,
|
|
37877
|
+
face: null,
|
|
37878
|
+
faceIndex: i,
|
|
37879
|
+
uv: null,
|
|
37880
|
+
uv1: null,
|
|
37881
|
+
} );
|
|
37882
|
+
}
|
|
37883
|
+
}
|
|
37884
|
+
}
|
|
37885
|
+
class LineSegments2 extends Mesh {
|
|
37886
|
+
constructor( geometry = new LineSegmentsGeometry(), material = new LineMaterial( { color: Math.random() * 0xffffff } ) ) {
|
|
37887
|
+
super( geometry, material );
|
|
37888
|
+
this.isLineSegments2 = true;
|
|
37889
|
+
this.type = 'LineSegments2';
|
|
37890
|
+
}
|
|
37891
|
+
computeLineDistances() {
|
|
37892
|
+
const geometry = this.geometry;
|
|
37893
|
+
const instanceStart = geometry.attributes.instanceStart;
|
|
37894
|
+
const instanceEnd = geometry.attributes.instanceEnd;
|
|
37895
|
+
const lineDistances = new Float32Array( 2 * instanceStart.count );
|
|
37896
|
+
for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
|
|
37897
|
+
_start.fromBufferAttribute( instanceStart, i );
|
|
37898
|
+
_end.fromBufferAttribute( instanceEnd, i );
|
|
37899
|
+
lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
|
|
37900
|
+
lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
|
|
37901
|
+
}
|
|
37902
|
+
const instanceDistanceBuffer = new InstancedInterleavedBuffer( lineDistances, 2, 1 );
|
|
37903
|
+
geometry.setAttribute( 'instanceDistanceStart', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) );
|
|
37904
|
+
geometry.setAttribute( 'instanceDistanceEnd', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) );
|
|
37905
|
+
return this;
|
|
37906
|
+
}
|
|
37907
|
+
raycast( raycaster, intersects ) {
|
|
37908
|
+
const worldUnits = this.material.worldUnits;
|
|
37909
|
+
const camera = raycaster.camera;
|
|
37910
|
+
if ( camera === null && ! worldUnits ) {
|
|
37911
|
+
console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2 while worldUnits is set to false.' );
|
|
37912
|
+
}
|
|
37913
|
+
const threshold = ( raycaster.params.Line2 !== undefined ) ? raycaster.params.Line2.threshold || 0 : 0;
|
|
37914
|
+
_ray = raycaster.ray;
|
|
37915
|
+
const matrixWorld = this.matrixWorld;
|
|
37916
|
+
const geometry = this.geometry;
|
|
37917
|
+
const material = this.material;
|
|
37918
|
+
_lineWidth = material.linewidth + threshold;
|
|
37919
|
+
if ( geometry.boundingSphere === null ) {
|
|
37920
|
+
geometry.computeBoundingSphere();
|
|
37921
|
+
}
|
|
37922
|
+
_sphere.copy( geometry.boundingSphere ).applyMatrix4( matrixWorld );
|
|
37923
|
+
let sphereMargin;
|
|
37924
|
+
if ( worldUnits ) {
|
|
37925
|
+
sphereMargin = _lineWidth * 0.5;
|
|
37926
|
+
} else {
|
|
37927
|
+
const distanceToSphere = Math.max( camera.near, _sphere.distanceToPoint( _ray.origin ) );
|
|
37928
|
+
sphereMargin = getWorldSpaceHalfWidth( camera, distanceToSphere, material.resolution );
|
|
37929
|
+
}
|
|
37930
|
+
_sphere.radius += sphereMargin;
|
|
37931
|
+
if ( _ray.intersectsSphere( _sphere ) === false ) {
|
|
37932
|
+
return;
|
|
37933
|
+
}
|
|
37934
|
+
if ( geometry.boundingBox === null ) {
|
|
37935
|
+
geometry.computeBoundingBox();
|
|
37936
|
+
}
|
|
37937
|
+
_box.copy( geometry.boundingBox ).applyMatrix4( matrixWorld );
|
|
37938
|
+
let boxMargin;
|
|
37939
|
+
if ( worldUnits ) {
|
|
37940
|
+
boxMargin = _lineWidth * 0.5;
|
|
37941
|
+
} else {
|
|
37942
|
+
const distanceToBox = Math.max( camera.near, _box.distanceToPoint( _ray.origin ) );
|
|
37943
|
+
boxMargin = getWorldSpaceHalfWidth( camera, distanceToBox, material.resolution );
|
|
37944
|
+
}
|
|
37945
|
+
_box.expandByScalar( boxMargin );
|
|
37946
|
+
if ( _ray.intersectsBox( _box ) === false ) {
|
|
37947
|
+
return;
|
|
37948
|
+
}
|
|
37949
|
+
if ( worldUnits ) {
|
|
37950
|
+
raycastWorldUnits( this, intersects );
|
|
37951
|
+
} else {
|
|
37952
|
+
raycastScreenSpace( this, camera, intersects );
|
|
37953
|
+
}
|
|
37954
|
+
}
|
|
37955
|
+
onBeforeRender( renderer ) {
|
|
37956
|
+
const uniforms = this.material.uniforms;
|
|
37957
|
+
if ( uniforms && uniforms.resolution ) {
|
|
37958
|
+
renderer.getViewport( _viewport );
|
|
37959
|
+
this.material.uniforms.resolution.value.set( _viewport.z, _viewport.w );
|
|
37960
|
+
}
|
|
37961
|
+
}
|
|
37962
|
+
}
|
|
37963
|
+
|
|
37964
|
+
class PointHashGrid {
|
|
37965
|
+
constructor(tolerance = 1e-5) {
|
|
37966
|
+
this.tolerance = tolerance;
|
|
37967
|
+
this.points = [];
|
|
37968
|
+
this.grid = new Map();
|
|
37969
|
+
}
|
|
37970
|
+
_hash(hx, hy, hz) {
|
|
37971
|
+
return `${hx},${hy},${hz}`;
|
|
37972
|
+
}
|
|
37973
|
+
add(v) {
|
|
37974
|
+
const hx = Math.round(v.x / this.tolerance);
|
|
37975
|
+
const hy = Math.round(v.y / this.tolerance);
|
|
37976
|
+
const hz = Math.round(v.z / this.tolerance);
|
|
37977
|
+
for (let i = -1; i <= 1; i++) {
|
|
37978
|
+
for (let j = -1; j <= 1; j++) {
|
|
37979
|
+
for (let k = -1; k <= 1; k++) {
|
|
37980
|
+
const hash = this._hash(hx + i, hy + j, hz + k);
|
|
37981
|
+
const cell = this.grid.get(hash);
|
|
37982
|
+
if (cell) {
|
|
37983
|
+
for (const id of cell) {
|
|
37984
|
+
if (this.points[id].distanceTo(v) <= this.tolerance) return id;
|
|
37985
|
+
}
|
|
37986
|
+
}
|
|
37987
|
+
}
|
|
37988
|
+
}
|
|
37989
|
+
}
|
|
37990
|
+
const id = this.points.length;
|
|
37991
|
+
this.points.push(v.clone());
|
|
37992
|
+
const centerHash = this._hash(hx, hy, hz);
|
|
37993
|
+
if (!this.grid.has(centerHash)) this.grid.set(centerHash, []);
|
|
37994
|
+
this.grid.get(centerHash).push(id);
|
|
37995
|
+
return id;
|
|
37996
|
+
}
|
|
37997
|
+
}
|
|
37998
|
+
class SectionsHelper extends Object3D {
|
|
37999
|
+
constructor() {
|
|
38000
|
+
super();
|
|
38001
|
+
this.type = "SectionsHelper";
|
|
38002
|
+
this.flags = {
|
|
38003
|
+
fillEnabled: true,
|
|
38004
|
+
fillColor: "#fffde7",
|
|
38005
|
+
hatchEnabled: true,
|
|
38006
|
+
hatchColor: "#000000",
|
|
38007
|
+
hatchScale: 8.0,
|
|
38008
|
+
outlineEnabled: true,
|
|
38009
|
+
outlineColor: "#000000",
|
|
38010
|
+
outlineWidth: 2,
|
|
38011
|
+
boundaryOnly: true,
|
|
38012
|
+
showDebugSeams: false,
|
|
38013
|
+
showDebugPoints: false,
|
|
38014
|
+
showDebugSegments: false,
|
|
38015
|
+
showDebugGaps: false,
|
|
38016
|
+
showDebugInfo: false,
|
|
38017
|
+
useObjFillColor: false,
|
|
38018
|
+
useObjOutlineColor: false,
|
|
38019
|
+
};
|
|
38020
|
+
this._caps = [];
|
|
38021
|
+
this._outlines = [];
|
|
38022
|
+
this._debugPoints = [];
|
|
38023
|
+
this._debugSegments = [];
|
|
38024
|
+
this._debugGaps = [];
|
|
38025
|
+
this._vA = new Vector3();
|
|
38026
|
+
this._vB = new Vector3();
|
|
38027
|
+
this._vC = new Vector3();
|
|
38028
|
+
this._worldBox = new Box3();
|
|
38029
|
+
}
|
|
38030
|
+
dispose() {
|
|
38031
|
+
const disposeMesh = (item) => {
|
|
38032
|
+
if (item.geometry) item.geometry.dispose();
|
|
38033
|
+
if (item.material) item.material.dispose();
|
|
38034
|
+
this.remove(item);
|
|
38035
|
+
};
|
|
38036
|
+
this._caps.forEach(disposeMesh);
|
|
38037
|
+
this._outlines.forEach(disposeMesh);
|
|
38038
|
+
this._debugPoints.forEach(disposeMesh);
|
|
38039
|
+
this._debugSegments.forEach(disposeMesh);
|
|
38040
|
+
this._debugGaps.forEach(disposeMesh);
|
|
38041
|
+
this._caps.length = 0;
|
|
38042
|
+
this._outlines.length = 0;
|
|
38043
|
+
this._debugPoints.length = 0;
|
|
38044
|
+
this._debugSegments.length = 0;
|
|
38045
|
+
this._debugGaps.length = 0;
|
|
38046
|
+
}
|
|
38047
|
+
setSize(width, height) {
|
|
38048
|
+
this._outlines.forEach((o) => {
|
|
38049
|
+
if (o.material.resolution) o.material.resolution.set(width, height);
|
|
38050
|
+
});
|
|
38051
|
+
this._debugSegments.forEach((s) => {
|
|
38052
|
+
if (s.material.resolution) s.material.resolution.set(width, height);
|
|
38053
|
+
});
|
|
38054
|
+
}
|
|
38055
|
+
_ensureHelpersCount(count) {
|
|
38056
|
+
const hatchVertexShader = `
|
|
38057
|
+
#include <common>
|
|
38058
|
+
#include <logdepthbuf_pars_vertex>
|
|
38059
|
+
#include <clipping_planes_pars_vertex>
|
|
38060
|
+
|
|
38061
|
+
attribute float aHatchDir;
|
|
38062
|
+
attribute vec3 aFillColor;
|
|
38063
|
+
|
|
38064
|
+
varying vec3 vWP;
|
|
38065
|
+
varying float vHatchDir;
|
|
38066
|
+
varying vec3 vFillColor;
|
|
38067
|
+
|
|
38068
|
+
void main() {
|
|
38069
|
+
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
|
|
38070
|
+
#include <clipping_planes_vertex>
|
|
38071
|
+
|
|
38072
|
+
vWP = (modelMatrix * vec4(position, 1.0)).xyz;
|
|
38073
|
+
vHatchDir = aHatchDir;
|
|
38074
|
+
vFillColor = aFillColor;
|
|
38075
|
+
|
|
38076
|
+
gl_Position = projectionMatrix * mvPosition;
|
|
38077
|
+
#include <logdepthbuf_vertex>
|
|
38078
|
+
}
|
|
38079
|
+
`;
|
|
38080
|
+
const hatchFragmentShader = `
|
|
38081
|
+
#include <common>
|
|
38082
|
+
#include <logdepthbuf_pars_fragment>
|
|
38083
|
+
#include <clipping_planes_pars_fragment>
|
|
38084
|
+
|
|
38085
|
+
uniform vec3 lineColor;
|
|
38086
|
+
uniform float uHatchScale;
|
|
38087
|
+
uniform float uHatchEnabled;
|
|
38088
|
+
|
|
38089
|
+
varying vec3 vWP;
|
|
38090
|
+
varying float vHatchDir;
|
|
38091
|
+
varying vec3 vFillColor;
|
|
38092
|
+
|
|
38093
|
+
void main() {
|
|
38094
|
+
#include <clipping_planes_fragment>
|
|
38095
|
+
#include <logdepthbuf_fragment>
|
|
38096
|
+
|
|
38097
|
+
float v1 = mod(gl_FragCoord.x + gl_FragCoord.y, uHatchScale);
|
|
38098
|
+
float v2 = mod(gl_FragCoord.x - gl_FragCoord.y, uHatchScale);
|
|
38099
|
+
float v = mix(v1, v2, vHatchDir);
|
|
38100
|
+
|
|
38101
|
+
float hatchMask = step(v, 1.5) * uHatchEnabled;
|
|
38102
|
+
gl_FragColor = vec4(mix(vFillColor, lineColor, hatchMask), 1.0);
|
|
38103
|
+
}
|
|
38104
|
+
`;
|
|
38105
|
+
while (this._caps.length < count) {
|
|
38106
|
+
const capMat = new ShaderMaterial({
|
|
38107
|
+
uniforms: {
|
|
38108
|
+
lineColor: { value: new Color() },
|
|
38109
|
+
uHatchScale: { value: 10.0 },
|
|
38110
|
+
uHatchEnabled: { value: 1.0 },
|
|
38111
|
+
},
|
|
38112
|
+
vertexShader: hatchVertexShader,
|
|
38113
|
+
fragmentShader: hatchFragmentShader,
|
|
38114
|
+
side: DoubleSide,
|
|
38115
|
+
clipping: true,
|
|
38116
|
+
depthTest: true,
|
|
38117
|
+
depthWrite: false,
|
|
38118
|
+
});
|
|
38119
|
+
const capMesh = new Mesh(new BufferGeometry(), capMat);
|
|
38120
|
+
capMesh.renderOrder = 5;
|
|
38121
|
+
this.add(capMesh);
|
|
38122
|
+
this._caps.push(capMesh);
|
|
38123
|
+
const lineMat = new LineMaterial({
|
|
38124
|
+
color: 0xffffff,
|
|
38125
|
+
linewidth: 2,
|
|
38126
|
+
resolution: new Vector2(window.innerWidth, window.innerHeight),
|
|
38127
|
+
depthTest: true,
|
|
38128
|
+
clipping: true,
|
|
38129
|
+
vertexColors: true,
|
|
38130
|
+
});
|
|
38131
|
+
const lineObj = new LineSegments2(new LineSegmentsGeometry(), lineMat);
|
|
38132
|
+
lineObj.renderOrder = 100;
|
|
38133
|
+
this.add(lineObj);
|
|
38134
|
+
this._outlines.push(lineObj);
|
|
38135
|
+
const ptsMat = new PointsMaterial({
|
|
38136
|
+
color: 0x00aaff,
|
|
38137
|
+
size: 6,
|
|
38138
|
+
sizeAttenuation: false,
|
|
38139
|
+
depthTest: false,
|
|
38140
|
+
transparent: true,
|
|
38141
|
+
depthWrite: false,
|
|
38142
|
+
});
|
|
38143
|
+
const pointsObj = new Points(new BufferGeometry(), ptsMat);
|
|
38144
|
+
pointsObj.renderOrder = 200;
|
|
38145
|
+
this.add(pointsObj);
|
|
38146
|
+
this._debugPoints.push(pointsObj);
|
|
38147
|
+
const debugSegMat = new LineMaterial({
|
|
38148
|
+
color: 0x00ff00,
|
|
38149
|
+
linewidth: 4,
|
|
38150
|
+
resolution: new Vector2(window.innerWidth, window.innerHeight),
|
|
38151
|
+
depthTest: false,
|
|
38152
|
+
transparent: true,
|
|
38153
|
+
depthWrite: false,
|
|
38154
|
+
clipping: true,
|
|
38155
|
+
});
|
|
38156
|
+
const debugSegObj = new LineSegments2(new LineSegmentsGeometry(), debugSegMat);
|
|
38157
|
+
debugSegObj.renderOrder = 150;
|
|
38158
|
+
this.add(debugSegObj);
|
|
38159
|
+
this._debugSegments.push(debugSegObj);
|
|
38160
|
+
const gapPtsMat = new PointsMaterial({
|
|
38161
|
+
size: 6,
|
|
38162
|
+
sizeAttenuation: false,
|
|
38163
|
+
depthTest: false,
|
|
38164
|
+
transparent: true,
|
|
38165
|
+
depthWrite: false,
|
|
38166
|
+
vertexColors: true,
|
|
38167
|
+
});
|
|
38168
|
+
const gapsObj = new Points(new BufferGeometry(), gapPtsMat);
|
|
38169
|
+
gapsObj.renderOrder = 250;
|
|
38170
|
+
this.add(gapsObj);
|
|
38171
|
+
this._debugGaps.push(gapsObj);
|
|
38172
|
+
}
|
|
38173
|
+
for (let i = count; i < this._caps.length; i++) {
|
|
38174
|
+
this._caps[i].visible = false;
|
|
38175
|
+
this._outlines[i].visible = false;
|
|
38176
|
+
this._debugPoints[i].visible = false;
|
|
38177
|
+
this._debugSegments[i].visible = false;
|
|
38178
|
+
this._debugGaps[i].visible = false;
|
|
38179
|
+
}
|
|
38180
|
+
}
|
|
38181
|
+
update(objects, extents, planes) {
|
|
38182
|
+
const t0 = performance.now();
|
|
38183
|
+
this._ensureHelpersCount(planes.length);
|
|
38184
|
+
if (planes.length === 0) return;
|
|
38185
|
+
const sphere = extents.getBoundingSphere(new Sphere());
|
|
38186
|
+
const globalRadius = Math.max(sphere.radius, 1e-3);
|
|
38187
|
+
const clippingBias = globalRadius * 1e-4;
|
|
38188
|
+
const biasedPlanes = planes.map((p) => {
|
|
38189
|
+
const bp = p.clone();
|
|
38190
|
+
bp.constant += clippingBias;
|
|
38191
|
+
return bp;
|
|
38192
|
+
});
|
|
38193
|
+
const targetMeshes = [];
|
|
38194
|
+
objects.forEach((obj) => {
|
|
38195
|
+
if (obj.isMesh && obj.material) {
|
|
38196
|
+
const mats = Array.isArray(obj.material) ? obj.material : [obj.material];
|
|
38197
|
+
if (mats.some((m) => m.clippingPlanes)) targetMeshes.push(obj);
|
|
38198
|
+
}
|
|
38199
|
+
});
|
|
38200
|
+
planes.forEach((plane, pIdx) => {
|
|
38201
|
+
const capMesh = this._caps[pIdx];
|
|
38202
|
+
const outlineMesh = this._outlines[pIdx];
|
|
38203
|
+
const debugPtsMesh = this._debugPoints[pIdx];
|
|
38204
|
+
const debugSegsMesh = this._debugSegments[pIdx];
|
|
38205
|
+
const debugGapsMesh = this._debugGaps[pIdx];
|
|
38206
|
+
const hatchColor = new Color(this.flags.hatchColor);
|
|
38207
|
+
hatchColor.convertLinearToSRGB();
|
|
38208
|
+
capMesh.material.uniforms.lineColor.value.set(hatchColor);
|
|
38209
|
+
capMesh.material.uniforms.uHatchScale.value = this.flags.hatchScale;
|
|
38210
|
+
capMesh.material.uniforms.uHatchEnabled.value = this.flags.hatchEnabled ? 1.0 : 0.0;
|
|
38211
|
+
outlineMesh.material.linewidth = this.flags.outlineWidth;
|
|
38212
|
+
const otherBiasedPlanes = biasedPlanes.filter((_, i) => i !== pIdx);
|
|
38213
|
+
capMesh.material.clippingPlanes = otherBiasedPlanes;
|
|
38214
|
+
outlineMesh.material.clippingPlanes = otherBiasedPlanes;
|
|
38215
|
+
debugSegsMesh.material.clippingPlanes = otherBiasedPlanes;
|
|
38216
|
+
const n = plane.normal;
|
|
38217
|
+
const planeOrigin = n.clone().multiplyScalar(-plane.constant);
|
|
38218
|
+
const up = new Vector3(0, 1, 0);
|
|
38219
|
+
if (Math.abs(n.dot(up)) > 0.999) up.set(1, 0, 0);
|
|
38220
|
+
const uAxis = new Vector3().crossVectors(up, n).normalize();
|
|
38221
|
+
const vAxis = new Vector3().crossVectors(n, uAxis).normalize();
|
|
38222
|
+
const positions = [];
|
|
38223
|
+
const indices = [];
|
|
38224
|
+
const hatchDirs = [];
|
|
38225
|
+
const fillColors = [];
|
|
38226
|
+
const combinedOutlinePoints = [];
|
|
38227
|
+
const combinedOutlineColors = [];
|
|
38228
|
+
const rawPts = [];
|
|
38229
|
+
const rawSegs = [];
|
|
38230
|
+
const rawGaps = [];
|
|
38231
|
+
const rawGapColors = [];
|
|
38232
|
+
targetMeshes.forEach((mesh, meshIndex) => {
|
|
38233
|
+
if (!mesh.geometry.boundingBox) mesh.geometry.computeBoundingBox();
|
|
38234
|
+
if (!mesh.geometry.boundingSphere) mesh.geometry.computeBoundingSphere();
|
|
38235
|
+
this._worldBox.copy(mesh.geometry.boundingBox).applyMatrix4(mesh.matrixWorld);
|
|
38236
|
+
if (!plane.intersectsBox(this._worldBox)) return;
|
|
38237
|
+
const localScale = new Vector3().setFromMatrixScale(mesh.matrixWorld);
|
|
38238
|
+
const maxScale = Math.max(localScale.x, localScale.y, localScale.z);
|
|
38239
|
+
const localRadius = Math.max(mesh.geometry.boundingSphere.radius * maxScale, 1e-3);
|
|
38240
|
+
const localHashTolerance = Math.max(localRadius * 1e-4, 1e-6);
|
|
38241
|
+
const localEps = Math.max(localRadius * 1e-5, 1e-7);
|
|
38242
|
+
const baseColor = new Color(0xffffff);
|
|
38243
|
+
const om = mesh.userData.originalMaterial;
|
|
38244
|
+
const mm = om ?? (Array.isArray(mesh.material) ? mesh.material[0] : mesh.material);
|
|
38245
|
+
if (mm.color) baseColor.copy(mm.color);
|
|
38246
|
+
const objFillColor = baseColor.clone().lerp(new Color(0x000000), 0.2);
|
|
38247
|
+
const objOutlineColor = baseColor.clone().lerp(new Color(0x000000), 0.85);
|
|
38248
|
+
const hue = ((meshIndex * 137.5) % 360) / 360;
|
|
38249
|
+
const meshGapColor = new Color().setHSL(hue, 1.0, 0.5);
|
|
38250
|
+
const currentHatchDir = meshIndex % 2 === 0 ? 0.0 : 1.0;
|
|
38251
|
+
const fillColor = this.flags.useObjFillColor ? objFillColor : new Color(this.flags.fillColor);
|
|
38252
|
+
const outlineColor = this.flags.useObjOutlineColor ? objOutlineColor : new Color(this.flags.outlineColor);
|
|
38253
|
+
meshGapColor.convertLinearToSRGB();
|
|
38254
|
+
fillColor.convertLinearToSRGB();
|
|
38255
|
+
outlineColor.convertLinearToSRGB();
|
|
38256
|
+
const localEdgeStats = new Map();
|
|
38257
|
+
const localPointGrid = new PointHashGrid(localHashTolerance);
|
|
38258
|
+
this._calculateMeshSegmentsUndirected(mesh, plane, localEdgeStats, localPointGrid, localEps);
|
|
38259
|
+
if (localEdgeStats.size > 0) {
|
|
38260
|
+
const boundaryEdges = [];
|
|
38261
|
+
for (const [key, stat] of localEdgeStats.entries()) {
|
|
38262
|
+
const isBoundary = stat.count % 2 !== 0;
|
|
38263
|
+
const ids = key.split("-");
|
|
38264
|
+
const id0 = Number(ids[0]);
|
|
38265
|
+
const id1 = Number(ids[1]);
|
|
38266
|
+
const p1 = localPointGrid.points[id0];
|
|
38267
|
+
const p2 = localPointGrid.points[id1];
|
|
38268
|
+
if (this.flags.showDebugSeams || (this.flags.boundaryOnly ? isBoundary : true)) {
|
|
38269
|
+
combinedOutlinePoints.push(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);
|
|
38270
|
+
combinedOutlineColors.push(outlineColor.r, outlineColor.g, outlineColor.b);
|
|
38271
|
+
combinedOutlineColors.push(outlineColor.r, outlineColor.g, outlineColor.b);
|
|
38272
|
+
}
|
|
38273
|
+
if (isBoundary) boundaryEdges.push([id0, id1]);
|
|
38274
|
+
if (this.flags.showDebugSegments) rawSegs.push(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);
|
|
38275
|
+
}
|
|
38276
|
+
if (this.flags.showDebugPoints) {
|
|
38277
|
+
for (const p of localPointGrid.points) rawPts.push(p.x, p.y, p.z);
|
|
38278
|
+
}
|
|
38279
|
+
if (this.flags.fillEnabled && boundaryEdges.length >= 3) {
|
|
38280
|
+
const currentAdj = new Map();
|
|
38281
|
+
for (const edge of boundaryEdges) {
|
|
38282
|
+
const a = edge[0];
|
|
38283
|
+
const b = edge[1];
|
|
38284
|
+
if (!currentAdj.has(a)) currentAdj.set(a, []);
|
|
38285
|
+
if (!currentAdj.has(b)) currentAdj.set(b, []);
|
|
38286
|
+
currentAdj.get(a).push(b);
|
|
38287
|
+
currentAdj.get(b).push(a);
|
|
38288
|
+
}
|
|
38289
|
+
const degree1 = [];
|
|
38290
|
+
for (const [node, neighbors] of currentAdj.entries()) {
|
|
38291
|
+
if (neighbors.length === 1) degree1.push(node);
|
|
38292
|
+
}
|
|
38293
|
+
const stitchTol = Math.max(localRadius * 0.05, 1e-4);
|
|
38294
|
+
for (let i = 0; i < degree1.length; i++) {
|
|
38295
|
+
const n1 = degree1[i];
|
|
38296
|
+
if (currentAdj.get(n1).length !== 1) continue;
|
|
38297
|
+
const p1 = localPointGrid.points[n1];
|
|
38298
|
+
let bestEdgeIdx = -1;
|
|
38299
|
+
let bestProj = null;
|
|
38300
|
+
let bestT = 0;
|
|
38301
|
+
let minDist = stitchTol;
|
|
38302
|
+
const edgeCount = boundaryEdges.length;
|
|
38303
|
+
for (let eIdx = 0; eIdx < edgeCount; eIdx++) {
|
|
38304
|
+
const edge = boundaryEdges[eIdx];
|
|
38305
|
+
const eA = edge[0];
|
|
38306
|
+
const eB = edge[1];
|
|
38307
|
+
if (eA === n1 || eB === n1) continue;
|
|
38308
|
+
const pA = localPointGrid.points[eA];
|
|
38309
|
+
const pB = localPointGrid.points[eB];
|
|
38310
|
+
const lineVec = new Vector3().subVectors(pB, pA);
|
|
38311
|
+
const lineLenSq = lineVec.lengthSq();
|
|
38312
|
+
let proj;
|
|
38313
|
+
let t;
|
|
38314
|
+
if (lineLenSq < 1e-12) {
|
|
38315
|
+
proj = pA.clone();
|
|
38316
|
+
t = 0;
|
|
38317
|
+
} else {
|
|
38318
|
+
const ptVec = new Vector3().subVectors(p1, pA);
|
|
38319
|
+
t = ptVec.dot(lineVec) / lineLenSq;
|
|
38320
|
+
t = Math.max(0, Math.min(1, t));
|
|
38321
|
+
proj = new Vector3().copy(pA).addScaledVector(lineVec, t);
|
|
38322
|
+
}
|
|
38323
|
+
const dist = p1.distanceTo(proj);
|
|
38324
|
+
if (dist < minDist) {
|
|
38325
|
+
minDist = dist;
|
|
38326
|
+
bestEdgeIdx = eIdx;
|
|
38327
|
+
bestProj = proj;
|
|
38328
|
+
bestT = t;
|
|
38329
|
+
}
|
|
38330
|
+
}
|
|
38331
|
+
if (bestEdgeIdx !== -1) {
|
|
38332
|
+
const edge = boundaryEdges[bestEdgeIdx];
|
|
38333
|
+
const eA = edge[0];
|
|
38334
|
+
const eB = edge[1];
|
|
38335
|
+
if (bestT < 0.001) {
|
|
38336
|
+
boundaryEdges.push([n1, eA]);
|
|
38337
|
+
currentAdj.get(n1).push(eA);
|
|
38338
|
+
currentAdj.get(eA).push(n1);
|
|
38339
|
+
p1.copy(localPointGrid.points[eA]);
|
|
38340
|
+
} else if (bestT > 0.999) {
|
|
38341
|
+
boundaryEdges.push([n1, eB]);
|
|
38342
|
+
currentAdj.get(n1).push(eB);
|
|
38343
|
+
currentAdj.get(eB).push(n1);
|
|
38344
|
+
p1.copy(localPointGrid.points[eB]);
|
|
38345
|
+
} else {
|
|
38346
|
+
const newNodeId = localPointGrid.add(bestProj);
|
|
38347
|
+
edge[1] = newNodeId;
|
|
38348
|
+
boundaryEdges.push([newNodeId, eB]);
|
|
38349
|
+
boundaryEdges.push([n1, newNodeId]);
|
|
38350
|
+
const neighborsA = currentAdj.get(eA);
|
|
38351
|
+
neighborsA[neighborsA.indexOf(eB)] = newNodeId;
|
|
38352
|
+
const neighborsB = currentAdj.get(eB);
|
|
38353
|
+
neighborsB[neighborsB.indexOf(eA)] = newNodeId;
|
|
38354
|
+
if (!currentAdj.has(newNodeId)) currentAdj.set(newNodeId, []);
|
|
38355
|
+
currentAdj.get(newNodeId).push(eA, eB, n1);
|
|
38356
|
+
currentAdj.get(n1).push(newNodeId);
|
|
38357
|
+
p1.copy(bestProj);
|
|
38358
|
+
}
|
|
38359
|
+
}
|
|
38360
|
+
}
|
|
38361
|
+
if (this.flags.showDebugGaps) {
|
|
38362
|
+
for (const [node, neighbors] of currentAdj.entries()) {
|
|
38363
|
+
if (neighbors.length !== 2) {
|
|
38364
|
+
const p = localPointGrid.points[node];
|
|
38365
|
+
rawGaps.push(p.x, p.y, p.z);
|
|
38366
|
+
rawGapColors.push(meshGapColor.r, meshGapColor.g, meshGapColor.b);
|
|
38367
|
+
}
|
|
38368
|
+
}
|
|
38369
|
+
}
|
|
38370
|
+
const loops = this._assembleLoopsUndirected(boundaryEdges, localPointGrid, uAxis, vAxis);
|
|
38371
|
+
if (loops.length > 0) {
|
|
38372
|
+
this._triangulateTreeOptimized(
|
|
38373
|
+
loops,
|
|
38374
|
+
planeOrigin,
|
|
38375
|
+
uAxis,
|
|
38376
|
+
vAxis,
|
|
38377
|
+
positions,
|
|
38378
|
+
indices,
|
|
38379
|
+
localRadius,
|
|
38380
|
+
fillColor,
|
|
38381
|
+
currentHatchDir,
|
|
38382
|
+
hatchDirs,
|
|
38383
|
+
fillColors
|
|
38384
|
+
);
|
|
38385
|
+
}
|
|
38386
|
+
}
|
|
38387
|
+
}
|
|
38388
|
+
});
|
|
38389
|
+
if (indices.length > 0) {
|
|
38390
|
+
capMesh.geometry.dispose();
|
|
38391
|
+
capMesh.geometry = new BufferGeometry();
|
|
38392
|
+
capMesh.geometry.setAttribute("position", new Float32BufferAttribute(positions, 3));
|
|
38393
|
+
capMesh.geometry.setAttribute("aHatchDir", new Float32BufferAttribute(hatchDirs, 1));
|
|
38394
|
+
capMesh.geometry.setAttribute("aFillColor", new Float32BufferAttribute(fillColors, 3));
|
|
38395
|
+
capMesh.geometry.setIndex(indices);
|
|
38396
|
+
capMesh.geometry.computeVertexNormals();
|
|
38397
|
+
capMesh.visible = this.flags.fillEnabled;
|
|
38398
|
+
} else {
|
|
38399
|
+
capMesh.visible = false;
|
|
38400
|
+
}
|
|
38401
|
+
if (outlineMesh.geometry) outlineMesh.geometry.dispose();
|
|
38402
|
+
outlineMesh.geometry = new LineSegmentsGeometry();
|
|
38403
|
+
if (this.flags.outlineEnabled && combinedOutlinePoints.length >= 6) {
|
|
38404
|
+
outlineMesh.geometry.setPositions(new Float32Array(combinedOutlinePoints));
|
|
38405
|
+
outlineMesh.geometry.setColors(new Float32Array(combinedOutlineColors));
|
|
38406
|
+
outlineMesh.visible = true;
|
|
38407
|
+
} else {
|
|
38408
|
+
outlineMesh.visible = false;
|
|
38409
|
+
}
|
|
38410
|
+
if (this.flags.showDebugPoints && rawPts.length > 0) {
|
|
38411
|
+
debugPtsMesh.geometry.setAttribute("position", new Float32BufferAttribute(rawPts, 3));
|
|
38412
|
+
debugPtsMesh.visible = true;
|
|
38413
|
+
} else {
|
|
38414
|
+
debugPtsMesh.visible = false;
|
|
38415
|
+
}
|
|
38416
|
+
if (debugSegsMesh.geometry) debugSegsMesh.geometry.dispose();
|
|
38417
|
+
debugSegsMesh.geometry = new LineSegmentsGeometry();
|
|
38418
|
+
if (this.flags.showDebugSegments && rawSegs.length >= 6) {
|
|
38419
|
+
debugSegsMesh.geometry.setPositions(new Float32Array(rawSegs));
|
|
38420
|
+
debugSegsMesh.visible = true;
|
|
38421
|
+
} else {
|
|
38422
|
+
debugSegsMesh.visible = false;
|
|
38423
|
+
}
|
|
38424
|
+
if (debugGapsMesh.geometry) debugGapsMesh.geometry.dispose();
|
|
38425
|
+
debugGapsMesh.geometry = new BufferGeometry();
|
|
38426
|
+
if (this.flags.showDebugGaps && rawGaps.length > 0) {
|
|
38427
|
+
debugGapsMesh.geometry.setAttribute("position", new Float32BufferAttribute(rawGaps, 3));
|
|
38428
|
+
debugGapsMesh.geometry.setAttribute("color", new Float32BufferAttribute(rawGapColors, 3));
|
|
38429
|
+
debugGapsMesh.visible = true;
|
|
38430
|
+
} else {
|
|
38431
|
+
debugGapsMesh.visible = false;
|
|
38432
|
+
}
|
|
38433
|
+
});
|
|
38434
|
+
if (this.flags.showDebugInfo) {
|
|
38435
|
+
console.log(`[SectionsHelper] v7.00 Updated in ${(performance.now() - t0).toFixed(2)} ms`);
|
|
38436
|
+
}
|
|
38437
|
+
}
|
|
38438
|
+
_assembleLoopsUndirected(edges, pointGrid, uAxis, vAxis) {
|
|
38439
|
+
const adj = new Map();
|
|
38440
|
+
for (const edge of edges) {
|
|
38441
|
+
const a = edge[0];
|
|
38442
|
+
const b = edge[1];
|
|
38443
|
+
if (!adj.has(a)) adj.set(a, []);
|
|
38444
|
+
if (!adj.has(b)) adj.set(b, []);
|
|
38445
|
+
adj.get(a).push(b);
|
|
38446
|
+
adj.get(b).push(a);
|
|
38447
|
+
}
|
|
38448
|
+
const loops = [];
|
|
38449
|
+
while (adj.size > 0) {
|
|
38450
|
+
let startNode = -1;
|
|
38451
|
+
for (const key of adj.keys()) {
|
|
38452
|
+
if (adj.get(key).length > 0) {
|
|
38453
|
+
startNode = key;
|
|
38454
|
+
break;
|
|
38455
|
+
}
|
|
38456
|
+
}
|
|
38457
|
+
if (startNode === -1) break;
|
|
38458
|
+
let current = startNode;
|
|
38459
|
+
let prev = -1;
|
|
38460
|
+
const path = [];
|
|
38461
|
+
const pathIndices = new Map();
|
|
38462
|
+
while (true) {
|
|
38463
|
+
path.push(current);
|
|
38464
|
+
pathIndices.set(current, path.length - 1);
|
|
38465
|
+
const neighbors = adj.get(current);
|
|
38466
|
+
if (!neighbors || neighbors.length === 0) break;
|
|
38467
|
+
let nextIdx = 0;
|
|
38468
|
+
if (neighbors.length > 1 && prev !== -1) {
|
|
38469
|
+
const pPrev = pointGrid.points[prev];
|
|
38470
|
+
const pCurr = pointGrid.points[current];
|
|
38471
|
+
const vIn = new Vector3().subVectors(pCurr, pPrev);
|
|
38472
|
+
const in2d = new Vector2(vIn.dot(uAxis), vIn.dot(vAxis));
|
|
38473
|
+
if (in2d.lengthSq() > 1e-10) {
|
|
38474
|
+
in2d.normalize();
|
|
38475
|
+
let minAngle = Infinity;
|
|
38476
|
+
for (let i = 0; i < neighbors.length; i++) {
|
|
38477
|
+
const pNext = pointGrid.points[neighbors[i]];
|
|
38478
|
+
const vOut = new Vector3().subVectors(pNext, pCurr);
|
|
38479
|
+
const out2d = new Vector2(vOut.dot(uAxis), vOut.dot(vAxis));
|
|
38480
|
+
if (out2d.lengthSq() > 1e-10) {
|
|
38481
|
+
out2d.normalize();
|
|
38482
|
+
const angle = Math.atan2(in2d.cross(out2d), in2d.dot(out2d));
|
|
38483
|
+
if (angle < minAngle) {
|
|
38484
|
+
minAngle = angle;
|
|
38485
|
+
nextIdx = i;
|
|
38486
|
+
}
|
|
38487
|
+
}
|
|
38488
|
+
}
|
|
38489
|
+
}
|
|
38490
|
+
}
|
|
38491
|
+
const next = neighbors[nextIdx];
|
|
38492
|
+
neighbors.splice(nextIdx, 1);
|
|
38493
|
+
const nextNeighbors = adj.get(next);
|
|
38494
|
+
if (nextNeighbors) {
|
|
38495
|
+
const revIdx = nextNeighbors.indexOf(current);
|
|
38496
|
+
if (revIdx !== -1) nextNeighbors.splice(revIdx, 1);
|
|
38497
|
+
}
|
|
38498
|
+
prev = current;
|
|
38499
|
+
current = next;
|
|
38500
|
+
if (pathIndices.has(current)) {
|
|
38501
|
+
const loopStartIdx = pathIndices.get(current);
|
|
38502
|
+
const loopNodes = path.slice(loopStartIdx);
|
|
38503
|
+
if (loopNodes.length >= 3) loops.push(loopNodes.map((id) => pointGrid.points[id]));
|
|
38504
|
+
for (let i = loopStartIdx; i < path.length; i++) pathIndices.delete(path[i]);
|
|
38505
|
+
path.length = loopStartIdx;
|
|
38506
|
+
prev = path.length > 1 ? path[path.length - 2] : -1;
|
|
38507
|
+
}
|
|
38508
|
+
}
|
|
38509
|
+
for (const key of adj.keys()) {
|
|
38510
|
+
if (adj.get(key).length === 0) adj.delete(key);
|
|
38511
|
+
}
|
|
38512
|
+
}
|
|
38513
|
+
return loops;
|
|
38514
|
+
}
|
|
38515
|
+
_triangulateTreeOptimized(
|
|
38516
|
+
loops,
|
|
38517
|
+
planeOrigin,
|
|
38518
|
+
uAxis,
|
|
38519
|
+
vAxis,
|
|
38520
|
+
positionsBuffer,
|
|
38521
|
+
indicesBuffer,
|
|
38522
|
+
localRadius,
|
|
38523
|
+
fillColor,
|
|
38524
|
+
hatchDir,
|
|
38525
|
+
hatchDirsBuffer,
|
|
38526
|
+
fillColorsBuffer
|
|
38527
|
+
) {
|
|
38528
|
+
const shapesData = [];
|
|
38529
|
+
const minArea = localRadius * 1e-5 * (localRadius * 1e-5);
|
|
38530
|
+
loops.forEach((loop) => {
|
|
38531
|
+
const pts2d = loop.map((p) => {
|
|
38532
|
+
const pv = p.clone().sub(planeOrigin);
|
|
38533
|
+
return new Vector2(pv.dot(uAxis), pv.dot(vAxis));
|
|
38534
|
+
});
|
|
38535
|
+
const cleaned = [];
|
|
38536
|
+
for (let k = 0; k < pts2d.length; k++) {
|
|
38537
|
+
const prev = k === 0 ? pts2d[pts2d.length - 1] : pts2d[k - 1];
|
|
38538
|
+
if (pts2d[k].distanceTo(prev) > 1e-5) cleaned.push(pts2d[k]);
|
|
38539
|
+
}
|
|
38540
|
+
if (cleaned.length < 3) return;
|
|
38541
|
+
const area = ShapeUtils.area(cleaned);
|
|
38542
|
+
if (Math.abs(area) > minArea) {
|
|
38543
|
+
shapesData.push({ pts2d: cleaned, absArea: Math.abs(area), depth: 0, parent: -1, holes: [] });
|
|
38544
|
+
}
|
|
38545
|
+
});
|
|
38546
|
+
shapesData.sort((a, b) => b.absArea - a.absArea);
|
|
38547
|
+
for (let i = 0; i < shapesData.length; i++) {
|
|
38548
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
38549
|
+
if (shapesData[i].absArea > shapesData[j].absArea * 0.98) continue;
|
|
38550
|
+
if (this._isLoopInside(shapesData[i].pts2d, shapesData[j].pts2d, localRadius)) {
|
|
38551
|
+
shapesData[i].parent = j;
|
|
38552
|
+
shapesData[i].depth = shapesData[j].depth + 1;
|
|
38553
|
+
break;
|
|
38554
|
+
}
|
|
38555
|
+
}
|
|
38556
|
+
}
|
|
38557
|
+
for (let i = 0; i < shapesData.length; i++) {
|
|
38558
|
+
const shape = shapesData[i];
|
|
38559
|
+
if (shape.depth % 2 === 1 && shape.parent !== -1) {
|
|
38560
|
+
shapesData[shape.parent].holes.push(shape.pts2d);
|
|
38561
|
+
}
|
|
38562
|
+
}
|
|
38563
|
+
for (let i = 0; i < shapesData.length; i++) {
|
|
38564
|
+
const shapeData = shapesData[i];
|
|
38565
|
+
if (shapeData.depth % 2 !== 0) continue;
|
|
38566
|
+
if (ShapeUtils.area(shapeData.pts2d) < 0) {
|
|
38567
|
+
shapeData.pts2d.reverse();
|
|
38568
|
+
}
|
|
38569
|
+
shapeData.holes.forEach((h) => {
|
|
38570
|
+
if (ShapeUtils.area(h) > 0) h.reverse();
|
|
38571
|
+
});
|
|
38572
|
+
const allPoints = [...shapeData.pts2d];
|
|
38573
|
+
shapeData.holes.forEach((h) => allPoints.push(...h));
|
|
38574
|
+
const faces = ShapeUtils.triangulateShape(shapeData.pts2d, shapeData.holes);
|
|
38575
|
+
const vertexOffset = positionsBuffer.length / 3;
|
|
38576
|
+
for (const pt of allPoints) {
|
|
38577
|
+
const p3d = planeOrigin.clone().addScaledVector(uAxis, pt.x).addScaledVector(vAxis, pt.y);
|
|
38578
|
+
positionsBuffer.push(p3d.x, p3d.y, p3d.z);
|
|
38579
|
+
hatchDirsBuffer.push(hatchDir);
|
|
38580
|
+
fillColorsBuffer.push(fillColor.r, fillColor.g, fillColor.b);
|
|
38581
|
+
}
|
|
38582
|
+
for (let f = 0; f < faces.length; f++) {
|
|
38583
|
+
indicesBuffer.push(vertexOffset + faces[f][0], vertexOffset + faces[f][1], vertexOffset + faces[f][2]);
|
|
38584
|
+
}
|
|
38585
|
+
}
|
|
38586
|
+
}
|
|
38587
|
+
_isPointInPoly(pt, poly) {
|
|
38588
|
+
let inside = false;
|
|
38589
|
+
const py = pt.y + 1.119e-7;
|
|
38590
|
+
const px = pt.x;
|
|
38591
|
+
for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {
|
|
38592
|
+
if (
|
|
38593
|
+
poly[i].y > py !== poly[j].y > py &&
|
|
38594
|
+
px < ((poly[j].x - poly[i].x) * (py - poly[i].y)) / (poly[j].y - poly[i].y) + poly[i].x
|
|
38595
|
+
) {
|
|
38596
|
+
inside = !inside;
|
|
38597
|
+
}
|
|
38598
|
+
}
|
|
38599
|
+
return inside;
|
|
38600
|
+
}
|
|
38601
|
+
_isLoopInside(child, parent, localRadius) {
|
|
38602
|
+
let minX1 = Infinity;
|
|
38603
|
+
let maxX1 = -Infinity;
|
|
38604
|
+
let minY1 = Infinity;
|
|
38605
|
+
let maxY1 = -Infinity;
|
|
38606
|
+
for (const p of child) {
|
|
38607
|
+
if (p.x < minX1) minX1 = p.x;
|
|
38608
|
+
if (p.x > maxX1) maxX1 = p.x;
|
|
38609
|
+
if (p.y < minY1) minY1 = p.y;
|
|
38610
|
+
if (p.y > maxY1) maxY1 = p.y;
|
|
38611
|
+
}
|
|
38612
|
+
let minX2 = Infinity;
|
|
38613
|
+
let maxX2 = -Infinity;
|
|
38614
|
+
let minY2 = Infinity;
|
|
38615
|
+
let maxY2 = -Infinity;
|
|
38616
|
+
for (const p of parent) {
|
|
38617
|
+
if (p.x < minX2) minX2 = p.x;
|
|
38618
|
+
if (p.x > maxX2) maxX2 = p.x;
|
|
38619
|
+
if (p.y < minY2) minY2 = p.y;
|
|
38620
|
+
if (p.y > maxY2) maxY2 = p.y;
|
|
38621
|
+
}
|
|
38622
|
+
const margin = Math.max(localRadius * 1e-4, 1e-5);
|
|
38623
|
+
if (minX1 < minX2 - margin || maxX1 > maxX2 + margin || minY1 < minY2 - margin || maxY1 > maxY2 + margin) {
|
|
38624
|
+
return false;
|
|
38625
|
+
}
|
|
38626
|
+
let insideCount = 0;
|
|
38627
|
+
for (let i = 0; i < child.length; i++) {
|
|
38628
|
+
if (this._isPointInPoly(child[i], parent)) {
|
|
38629
|
+
insideCount++;
|
|
38630
|
+
}
|
|
38631
|
+
}
|
|
38632
|
+
return insideCount >= child.length * 0.85;
|
|
38633
|
+
}
|
|
38634
|
+
_calculateMeshSegmentsUndirected(mesh, plane, edgeStats, grid, eps) {
|
|
38635
|
+
const geom = mesh.geometry;
|
|
38636
|
+
const pos = geom.attributes.position;
|
|
38637
|
+
const index = geom.index;
|
|
38638
|
+
const world = mesh.matrixWorld;
|
|
38639
|
+
const count = index ? index.count : pos.count;
|
|
38640
|
+
for (let i = 0; i < count; i += 3) {
|
|
38641
|
+
const i1 = index ? index.getX(i) : i;
|
|
38642
|
+
const i2 = index ? index.getX(i + 1) : i + 1;
|
|
38643
|
+
const i3 = index ? index.getX(i + 2) : i + 2;
|
|
38644
|
+
const v1 = this._vA.fromBufferAttribute(pos, i1).applyMatrix4(world);
|
|
38645
|
+
const v2 = this._vB.fromBufferAttribute(pos, i2).applyMatrix4(world);
|
|
38646
|
+
const v3 = this._vC.fromBufferAttribute(pos, i3).applyMatrix4(world);
|
|
38647
|
+
let d1 = plane.distanceToPoint(v1);
|
|
38648
|
+
let d2 = plane.distanceToPoint(v2);
|
|
38649
|
+
let d3 = plane.distanceToPoint(v3);
|
|
38650
|
+
if (Math.abs(d1) <= eps) d1 = eps;
|
|
38651
|
+
if (Math.abs(d2) <= eps) d2 = eps;
|
|
38652
|
+
if (Math.abs(d3) <= eps) d3 = eps;
|
|
38653
|
+
const s1 = d1 > 0 ? 1 : -1;
|
|
38654
|
+
const s2 = d2 > 0 ? 1 : -1;
|
|
38655
|
+
const s3 = d3 > 0 ? 1 : -1;
|
|
38656
|
+
if (s1 === s2 && s2 === s3) continue;
|
|
38657
|
+
const intersections = [];
|
|
38658
|
+
if (s1 !== s2) {
|
|
38659
|
+
intersections.push(new Vector3().lerpVectors(v1, v2, Math.abs(d1) / (Math.abs(d1) + Math.abs(d2))));
|
|
38660
|
+
}
|
|
38661
|
+
if (s2 !== s3) {
|
|
38662
|
+
intersections.push(new Vector3().lerpVectors(v2, v3, Math.abs(d2) / (Math.abs(d2) + Math.abs(d3))));
|
|
38663
|
+
}
|
|
38664
|
+
if (s3 !== s1) {
|
|
38665
|
+
intersections.push(new Vector3().lerpVectors(v3, v1, Math.abs(d3) / (Math.abs(d3) + Math.abs(d1))));
|
|
38666
|
+
}
|
|
38667
|
+
if (intersections.length >= 2) {
|
|
38668
|
+
const id1 = grid.add(intersections[0]);
|
|
38669
|
+
const id2 = grid.add(intersections[1]);
|
|
38670
|
+
if (id1 !== id2) {
|
|
38671
|
+
const key = id1 < id2 ? `${id1}-${id2}` : `${id2}-${id1}`;
|
|
38672
|
+
const stat = edgeStats.get(key) || { count: 0 };
|
|
38673
|
+
stat.count++;
|
|
38674
|
+
edgeStats.set(key, stat);
|
|
38675
|
+
}
|
|
38676
|
+
}
|
|
38677
|
+
}
|
|
38678
|
+
}
|
|
38679
|
+
}
|
|
38680
|
+
|
|
38681
|
+
class SectionsComponent {
|
|
38682
|
+
constructor(viewer) {
|
|
38683
|
+
this.updateTimerId = 0;
|
|
38684
|
+
this.updateDelay = 250;
|
|
38685
|
+
this.syncOptions = () => {
|
|
38686
|
+
function rgbToHex(c) {
|
|
38687
|
+
const hex = (v = 0) => v.toString(16).padStart(2, "0");
|
|
38688
|
+
return "#" + hex(c.r) + hex(c.g) + hex(c.b);
|
|
38689
|
+
}
|
|
38690
|
+
const options = this.viewer.options;
|
|
38691
|
+
const flags = this.sectionsHelper.flags;
|
|
38692
|
+
flags.fillEnabled = options.enableSectionFill;
|
|
38693
|
+
flags.fillColor = rgbToHex(options.sectionFillColor);
|
|
38694
|
+
flags.useObjFillColor = options.sectionUseObjectColor;
|
|
38695
|
+
flags.hatchEnabled = options.enableSectionHatch;
|
|
38696
|
+
flags.hatchColor = rgbToHex(options.sectionHatchColor);
|
|
38697
|
+
flags.hatchScale = options.sectionHatchScale;
|
|
38698
|
+
flags.outlineEnabled = options.enableSectionOutline;
|
|
38699
|
+
flags.outlineColor = rgbToHex(options.sectionOutlineColor);
|
|
38700
|
+
flags.outlineWidth = options.sectionOutlineWidth;
|
|
38701
|
+
this.syncSections();
|
|
38702
|
+
};
|
|
38703
|
+
this.syncHelper = () => {
|
|
38704
|
+
this.sectionsHelper.removeFromParent();
|
|
38705
|
+
this.viewer.helpers.add(this.sectionsHelper);
|
|
38706
|
+
};
|
|
38707
|
+
this.syncSections = () => {
|
|
38708
|
+
this.sectionsHelper.visible = false;
|
|
38709
|
+
clearTimeout(this.updateTimerId);
|
|
38710
|
+
this.updateTimerId = window.setTimeout(this.updateSections, this.updateDelay);
|
|
38711
|
+
};
|
|
38712
|
+
this.viewerResize = (event) => {
|
|
38713
|
+
this.sectionsHelper.setSize(event.width, event.height);
|
|
38714
|
+
};
|
|
38715
|
+
this.updateSections = () => {
|
|
38716
|
+
const objects = [];
|
|
38717
|
+
this.viewer.models.forEach((model) => objects.push(model.getVisibleObjects()));
|
|
38718
|
+
const objects2 = objects.flat();
|
|
38719
|
+
this.sectionsHelper.update(objects2, this.viewer.extents, this.viewer.clippingPlanes);
|
|
38720
|
+
this.sectionsHelper.visible = true;
|
|
38721
|
+
this.viewer.update();
|
|
38722
|
+
};
|
|
38723
|
+
this.sectionsHelper = new SectionsHelper();
|
|
38724
|
+
this.viewer = viewer;
|
|
38725
|
+
this.viewer.addEventListener("initialize", this.syncHelper);
|
|
38726
|
+
this.viewer.addEventListener("databasechunk", this.syncHelper);
|
|
38727
|
+
this.viewer.addEventListener("drawviewpoint", this.syncHelper);
|
|
38728
|
+
this.viewer.addEventListener("changecuttingplanes", this.syncSections);
|
|
38729
|
+
this.viewer.addEventListener("explode", this.syncSections);
|
|
38730
|
+
this.viewer.addEventListener("hide", this.syncSections);
|
|
38731
|
+
this.viewer.addEventListener("isolate", this.syncSections);
|
|
38732
|
+
this.viewer.addEventListener("show", this.syncSections);
|
|
38733
|
+
this.viewer.addEventListener("showall", this.syncSections);
|
|
38734
|
+
this.viewer.addEventListener("resize", this.viewerResize);
|
|
38735
|
+
this.viewer.addEventListener("optionschange", this.syncOptions);
|
|
38736
|
+
this.syncOptions();
|
|
38737
|
+
}
|
|
38738
|
+
dispose() {
|
|
38739
|
+
clearTimeout(this.updateTimerId);
|
|
38740
|
+
this.sectionsHelper.removeFromParent();
|
|
38741
|
+
this.sectionsHelper.dispose();
|
|
38742
|
+
this.viewer.removeEventListener("initialize", this.syncHelper);
|
|
38743
|
+
this.viewer.removeEventListener("databasechunk", this.syncHelper);
|
|
38744
|
+
this.viewer.removeEventListener("drawviewpoint", this.syncHelper);
|
|
38745
|
+
this.viewer.removeEventListener("changecuttingplanes", this.syncSections);
|
|
38746
|
+
this.viewer.removeEventListener("explode", this.syncSections);
|
|
38747
|
+
this.viewer.removeEventListener("hide", this.syncSections);
|
|
38748
|
+
this.viewer.removeEventListener("isolate", this.syncSections);
|
|
38749
|
+
this.viewer.removeEventListener("show", this.syncSections);
|
|
38750
|
+
this.viewer.removeEventListener("showall", this.syncSections);
|
|
38751
|
+
this.viewer.removeEventListener("resize", this.viewerResize);
|
|
38752
|
+
this.viewer.removeEventListener("optionschange", this.syncOptions);
|
|
38753
|
+
}
|
|
38754
|
+
}
|
|
38755
|
+
|
|
37625
38756
|
class WCSHelper extends Object3D {
|
|
37626
38757
|
constructor(camera) {
|
|
37627
38758
|
super();
|
|
38759
|
+
this.type = "WCSHelper";
|
|
37628
38760
|
this.camera = camera;
|
|
37629
38761
|
this.size = 160;
|
|
37630
38762
|
this.orthoCamera = new OrthographicCamera(-2, 2, 2, -2, 0, 4);
|
|
@@ -37712,7 +38844,7 @@ void main() {
|
|
|
37712
38844
|
|
|
37713
38845
|
class WCSHelperComponent {
|
|
37714
38846
|
constructor(viewer) {
|
|
37715
|
-
this.
|
|
38847
|
+
this.syncHelper = () => {
|
|
37716
38848
|
this.wcsHelper.dispose();
|
|
37717
38849
|
this.wcsHelper = new WCSHelper(this.viewer.camera);
|
|
37718
38850
|
};
|
|
@@ -37726,14 +38858,14 @@ void main() {
|
|
|
37726
38858
|
};
|
|
37727
38859
|
this.wcsHelper = new WCSHelper(viewer.camera);
|
|
37728
38860
|
this.viewer = viewer;
|
|
37729
|
-
this.viewer.addEventListener("databasechunk", this.
|
|
37730
|
-
this.viewer.addEventListener("drawviewpoint", this.
|
|
38861
|
+
this.viewer.addEventListener("databasechunk", this.syncHelper);
|
|
38862
|
+
this.viewer.addEventListener("drawviewpoint", this.syncHelper);
|
|
37731
38863
|
this.viewer.addEventListener("render", this.viewerRender);
|
|
37732
38864
|
this.viewer.addEventListener("changecameramode", this.updateHelperCamera);
|
|
37733
38865
|
}
|
|
37734
38866
|
dispose() {
|
|
37735
|
-
this.viewer.removeEventListener("databasechunk", this.
|
|
37736
|
-
this.viewer.removeEventListener("drawviewpoint", this.
|
|
38867
|
+
this.viewer.removeEventListener("databasechunk", this.syncHelper);
|
|
38868
|
+
this.viewer.removeEventListener("drawviewpoint", this.syncHelper);
|
|
37737
38869
|
this.viewer.removeEventListener("render", this.viewerRender);
|
|
37738
38870
|
this.viewer.removeEventListener("changecameramode", this.updateHelperCamera);
|
|
37739
38871
|
this.wcsHelper.dispose();
|
|
@@ -37779,11 +38911,14 @@ void main() {
|
|
|
37779
38911
|
components.registerComponent("RenderLoopComponent", (viewer) => new RenderLoopComponent(viewer));
|
|
37780
38912
|
components.registerComponent("HighlighterComponent", (viewer) => new HighlighterComponent(viewer));
|
|
37781
38913
|
components.registerComponent("SelectionComponent", (viewer) => new SelectionComponent(viewer));
|
|
38914
|
+
components.registerComponent("ClippingPlaneComponent", (viewer) => new ClippingPlaneComponent(viewer));
|
|
38915
|
+
components.registerComponent("SectionsComponent", (viewer) => new SectionsComponent(viewer));
|
|
37782
38916
|
components.registerComponent("WCSHelperComponent", (viewer) => new WCSHelperComponent(viewer));
|
|
37783
38917
|
components.registerComponent("ResetComponent", (viewer) => new ResetComponent(viewer));
|
|
37784
38918
|
|
|
37785
38919
|
class ModelImpl {
|
|
37786
38920
|
constructor(scene) {
|
|
38921
|
+
this.id = "";
|
|
37787
38922
|
this.scene = scene;
|
|
37788
38923
|
this.handleToObjects = new Map();
|
|
37789
38924
|
this.originalObjects = new Set();
|
|
@@ -37959,7 +39094,25 @@ void main() {
|
|
|
37959
39094
|
return info;
|
|
37960
39095
|
}
|
|
37961
39096
|
getExtents(target) {
|
|
37962
|
-
|
|
39097
|
+
const _box = new Box3();
|
|
39098
|
+
function expandByObject(object, target) {
|
|
39099
|
+
if (!object.geometry)
|
|
39100
|
+
return;
|
|
39101
|
+
object.updateWorldMatrix(false, false);
|
|
39102
|
+
if (object.boundingBox !== undefined) {
|
|
39103
|
+
if (object.boundingBox === null)
|
|
39104
|
+
object.computeBoundingBox();
|
|
39105
|
+
_box.copy(object.boundingBox);
|
|
39106
|
+
}
|
|
39107
|
+
else {
|
|
39108
|
+
if (object.geometry.boundingBox === null)
|
|
39109
|
+
object.geometry.computeBoundingBox();
|
|
39110
|
+
_box.copy(object.geometry.boundingBox);
|
|
39111
|
+
}
|
|
39112
|
+
_box.applyMatrix4(object.matrixWorld);
|
|
39113
|
+
target.union(_box);
|
|
39114
|
+
}
|
|
39115
|
+
this.scene.traverseVisible((object) => expandByObject(object, target));
|
|
37963
39116
|
return target;
|
|
37964
39117
|
}
|
|
37965
39118
|
getObjects() {
|
|
@@ -37967,8 +39120,8 @@ void main() {
|
|
|
37967
39120
|
}
|
|
37968
39121
|
getVisibleObjects() {
|
|
37969
39122
|
const objects = [];
|
|
37970
|
-
this.scene.traverseVisible((object) => objects.push(object));
|
|
37971
|
-
return objects
|
|
39123
|
+
this.scene.traverseVisible((object) => object.userData.handle && objects.push(object));
|
|
39124
|
+
return objects;
|
|
37972
39125
|
}
|
|
37973
39126
|
getObjectsByHandles(handles) {
|
|
37974
39127
|
if (!Array.isArray(handles))
|
|
@@ -38322,6 +39475,7 @@ void main() {
|
|
|
38322
39475
|
this._nextObjectId = 1;
|
|
38323
39476
|
this.loadingAborted = false;
|
|
38324
39477
|
this.criticalError = null;
|
|
39478
|
+
this.embeddedBinaryChunk = null;
|
|
38325
39479
|
}
|
|
38326
39480
|
async initialize(loader) {
|
|
38327
39481
|
const json = await this.loadController.loadJson();
|
|
@@ -38330,28 +39484,72 @@ void main() {
|
|
|
38330
39484
|
}
|
|
38331
39485
|
this.json = json;
|
|
38332
39486
|
this.loader = loader;
|
|
38333
|
-
|
|
39487
|
+
const bufferUri = this.json.buffers?.[0]?.uri || "";
|
|
39488
|
+
if (bufferUri.startsWith("data:")) {
|
|
39489
|
+
this.embeddedBinaryChunk = await this._decodeDataUri(bufferUri);
|
|
39490
|
+
this.uri = "";
|
|
39491
|
+
} else {
|
|
39492
|
+
this.uri = bufferUri;
|
|
39493
|
+
}
|
|
39494
|
+
}
|
|
39495
|
+
async _decodeDataUri(dataUri) {
|
|
39496
|
+
try {
|
|
39497
|
+
const response = await fetch(dataUri);
|
|
39498
|
+
return await response.arrayBuffer();
|
|
39499
|
+
} catch (e) {
|
|
39500
|
+
throw new Error(`DynamicLoader: Failed to decode embedded data URI: ${e.message}`);
|
|
39501
|
+
}
|
|
38334
39502
|
}
|
|
38335
39503
|
clear() {
|
|
38336
|
-
this.json = null;
|
|
38337
|
-
this.loadController = null;
|
|
38338
|
-
this.pendingRequests = [];
|
|
38339
39504
|
if (this.batchTimeout) {
|
|
38340
39505
|
clearTimeout(this.batchTimeout);
|
|
38341
39506
|
this.batchTimeout = null;
|
|
38342
39507
|
}
|
|
38343
|
-
this.
|
|
38344
|
-
this.
|
|
38345
|
-
|
|
39508
|
+
this._rejectPendingRequests();
|
|
39509
|
+
if (this.disposeMaterials) {
|
|
39510
|
+
try {
|
|
39511
|
+
this.disposeMaterials();
|
|
39512
|
+
} catch (e) {
|
|
39513
|
+
console.warn("DynamicLoader: error during disposeMaterials in clear():", e);
|
|
39514
|
+
}
|
|
39515
|
+
}
|
|
39516
|
+
if (this.textureCache) this.textureCache.clear();
|
|
39517
|
+
if (this.materials) this.materials.clear();
|
|
39518
|
+
this.embeddedBinaryChunk = null;
|
|
39519
|
+
this.json = null;
|
|
39520
|
+
this.loadController = null;
|
|
39521
|
+
this.uri = "";
|
|
38346
39522
|
this.activeChunkLoads = 0;
|
|
38347
39523
|
this.chunkQueue = [];
|
|
38348
39524
|
this.loadingAborted = false;
|
|
38349
39525
|
this.criticalError = null;
|
|
38350
39526
|
}
|
|
39527
|
+
_rejectPendingRequests() {
|
|
39528
|
+
const pending = this.pendingRequests;
|
|
39529
|
+
this.pendingRequests = [];
|
|
39530
|
+
if (!pending || pending.length === 0) return;
|
|
39531
|
+
const cancelError = new Error("DynamicLoader: Structure cleared while requests pending");
|
|
39532
|
+
for (let i = 0; i < pending.length; i++) {
|
|
39533
|
+
const item = pending[i];
|
|
39534
|
+
if (item && typeof item._reject === "function") {
|
|
39535
|
+
try {
|
|
39536
|
+
item._reject(cancelError);
|
|
39537
|
+
} catch {
|
|
39538
|
+
}
|
|
39539
|
+
}
|
|
39540
|
+
}
|
|
39541
|
+
}
|
|
38351
39542
|
getJson() {
|
|
38352
39543
|
return this.json;
|
|
38353
39544
|
}
|
|
38354
39545
|
scheduleRequest(request) {
|
|
39546
|
+
if (this.embeddedBinaryChunk && !this.uri) {
|
|
39547
|
+
return Promise.resolve({
|
|
39548
|
+
buffer: this.embeddedBinaryChunk,
|
|
39549
|
+
relOffset: request.offset,
|
|
39550
|
+
length: request.length,
|
|
39551
|
+
});
|
|
39552
|
+
}
|
|
38355
39553
|
return new Promise((resolve, reject) => {
|
|
38356
39554
|
if (this.loadingAborted) {
|
|
38357
39555
|
reject(
|
|
@@ -38628,8 +39826,13 @@ void main() {
|
|
|
38628
39826
|
return await this.textureLoader.loadAsync(fullUrl);
|
|
38629
39827
|
} else if (image.bufferView !== undefined) {
|
|
38630
39828
|
const bufferView = this.json.bufferViews[image.bufferView];
|
|
38631
|
-
const
|
|
38632
|
-
|
|
39829
|
+
const { buffer, relOffset } = await this.getBufferView(
|
|
39830
|
+
bufferView.byteOffset || 0,
|
|
39831
|
+
bufferView.byteLength,
|
|
39832
|
+
5121
|
|
39833
|
+
);
|
|
39834
|
+
const imageBytes = new Uint8Array(buffer, relOffset, bufferView.byteLength);
|
|
39835
|
+
const blob = new Blob([imageBytes], { type: image.mimeType });
|
|
38633
39836
|
const url = URL.createObjectURL(blob);
|
|
38634
39837
|
const texture = await this.textureLoader.loadAsync(url);
|
|
38635
39838
|
URL.revokeObjectURL(url);
|
|
@@ -38659,6 +39862,7 @@ void main() {
|
|
|
38659
39862
|
})
|
|
38660
39863
|
);
|
|
38661
39864
|
}
|
|
39865
|
+
await this.flushBufferRequests();
|
|
38662
39866
|
await Promise.all(texturePromises);
|
|
38663
39867
|
}
|
|
38664
39868
|
loadMaterials() {
|
|
@@ -39016,6 +40220,7 @@ void main() {
|
|
|
39016
40220
|
return result;
|
|
39017
40221
|
}
|
|
39018
40222
|
|
|
40223
|
+
const DRACO_EXTENSION_NAME = "KHR_draco_mesh_compression";
|
|
39019
40224
|
const STRUCTURE_ID_SEPARATOR = ":";
|
|
39020
40225
|
class DynamicGltfLoader {
|
|
39021
40226
|
constructor(camera, scene, renderer) {
|
|
@@ -39090,6 +40295,189 @@ void main() {
|
|
|
39090
40295
|
this.transformData = null;
|
|
39091
40296
|
this.identityTransformData = null;
|
|
39092
40297
|
this.visibilityMaterials = new Set();
|
|
40298
|
+
this._dracoLoader = null;
|
|
40299
|
+
}
|
|
40300
|
+
setDracoLoader(loader = null) {
|
|
40301
|
+
this._dracoLoader = loader || null;
|
|
40302
|
+
}
|
|
40303
|
+
async _decodeDracoPrimitive(structure, primitive, dracoBufferData) {
|
|
40304
|
+
const dracoExt = primitive.extensions[DRACO_EXTENSION_NAME];
|
|
40305
|
+
const loader = this._dracoLoader;
|
|
40306
|
+
const attributeIDs = {};
|
|
40307
|
+
const attributeTypes = {};
|
|
40308
|
+
const gltfNameToThreeName = new Map();
|
|
40309
|
+
const threeNameToAccessor = new Map();
|
|
40310
|
+
for (const [gltfAttrName, dracoUniqueId] of Object.entries(dracoExt.attributes)) {
|
|
40311
|
+
const threeName = this._gltfAttributeNameToThreeName(gltfAttrName);
|
|
40312
|
+
attributeIDs[threeName] = dracoUniqueId;
|
|
40313
|
+
gltfNameToThreeName.set(gltfAttrName, threeName);
|
|
40314
|
+
const accessorIdx = primitive.attributes[gltfAttrName];
|
|
40315
|
+
if (accessorIdx !== undefined) {
|
|
40316
|
+
const accessor = structure.json.accessors[accessorIdx];
|
|
40317
|
+
attributeTypes[threeName] = this._gltfComponentTypeToTypedArrayName(accessor.componentType);
|
|
40318
|
+
threeNameToAccessor.set(threeName, accessor);
|
|
40319
|
+
}
|
|
40320
|
+
}
|
|
40321
|
+
const geometry = await loader.decodeGeometry(dracoBufferData, {
|
|
40322
|
+
attributeIDs,
|
|
40323
|
+
attributeTypes,
|
|
40324
|
+
useUniqueIDs: true,
|
|
40325
|
+
});
|
|
40326
|
+
for (const [threeName, accessor] of threeNameToAccessor) {
|
|
40327
|
+
const attribute = geometry.getAttribute(threeName);
|
|
40328
|
+
if (!attribute) continue;
|
|
40329
|
+
if (accessor.normalized === true) {
|
|
40330
|
+
attribute.normalized = true;
|
|
40331
|
+
}
|
|
40332
|
+
if (accessor.min) attribute.min = accessor.min;
|
|
40333
|
+
if (accessor.max) attribute.max = accessor.max;
|
|
40334
|
+
}
|
|
40335
|
+
for (const [threeName, accessor] of threeNameToAccessor) {
|
|
40336
|
+
const attribute = geometry.getAttribute(threeName);
|
|
40337
|
+
if (!attribute || !attribute.normalized) continue;
|
|
40338
|
+
const denom = this._normalizedDenominator(accessor.componentType);
|
|
40339
|
+
if (denom <= 0) continue;
|
|
40340
|
+
const src = attribute.array;
|
|
40341
|
+
const inv = 1 / denom;
|
|
40342
|
+
const isSigned = accessor.componentType === 5120 || accessor.componentType === 5122;
|
|
40343
|
+
const out = new Float32Array(src.length);
|
|
40344
|
+
for (let i = 0; i < src.length; i++) {
|
|
40345
|
+
let v = src[i] * inv;
|
|
40346
|
+
if (isSigned && v < -1) v = -1;
|
|
40347
|
+
out[i] = v;
|
|
40348
|
+
}
|
|
40349
|
+
const newAttr = new BufferAttribute(out, attribute.itemSize, false);
|
|
40350
|
+
if (accessor.min) newAttr.min = accessor.min;
|
|
40351
|
+
if (accessor.max) newAttr.max = accessor.max;
|
|
40352
|
+
geometry.setAttribute(threeName, newAttr);
|
|
40353
|
+
}
|
|
40354
|
+
return geometry;
|
|
40355
|
+
}
|
|
40356
|
+
_gltfComponentTypeToTypedArrayName(componentType) {
|
|
40357
|
+
switch (componentType) {
|
|
40358
|
+
case 5120:
|
|
40359
|
+
return "Int8Array";
|
|
40360
|
+
case 5121:
|
|
40361
|
+
return "Uint8Array";
|
|
40362
|
+
case 5122:
|
|
40363
|
+
return "Int16Array";
|
|
40364
|
+
case 5123:
|
|
40365
|
+
return "Uint16Array";
|
|
40366
|
+
case 5125:
|
|
40367
|
+
return "Uint32Array";
|
|
40368
|
+
case 5126:
|
|
40369
|
+
return "Float32Array";
|
|
40370
|
+
default:
|
|
40371
|
+
return "Float32Array";
|
|
40372
|
+
}
|
|
40373
|
+
}
|
|
40374
|
+
_normalizedDenominator(componentType) {
|
|
40375
|
+
switch (componentType) {
|
|
40376
|
+
case 5120:
|
|
40377
|
+
return 127;
|
|
40378
|
+
case 5121:
|
|
40379
|
+
return 255;
|
|
40380
|
+
case 5122:
|
|
40381
|
+
return 32767;
|
|
40382
|
+
case 5123:
|
|
40383
|
+
return 65535;
|
|
40384
|
+
default:
|
|
40385
|
+
return 0;
|
|
40386
|
+
}
|
|
40387
|
+
}
|
|
40388
|
+
_gltfAttributeNameToThreeName(name) {
|
|
40389
|
+
switch (name) {
|
|
40390
|
+
case "POSITION":
|
|
40391
|
+
return "position";
|
|
40392
|
+
case "NORMAL":
|
|
40393
|
+
return "normal";
|
|
40394
|
+
case "TANGENT":
|
|
40395
|
+
return "tangent";
|
|
40396
|
+
case "TEXCOORD_0":
|
|
40397
|
+
return "uv";
|
|
40398
|
+
case "TEXCOORD_1":
|
|
40399
|
+
return "uv2";
|
|
40400
|
+
case "COLOR_0":
|
|
40401
|
+
return "color";
|
|
40402
|
+
case "JOINTS_0":
|
|
40403
|
+
return "skinIndex";
|
|
40404
|
+
case "WEIGHTS_0":
|
|
40405
|
+
return "skinWeight";
|
|
40406
|
+
default:
|
|
40407
|
+
return name.toLowerCase();
|
|
40408
|
+
}
|
|
40409
|
+
}
|
|
40410
|
+
_buildAccessorRequest(structure, accessorIndex, type, primIdx) {
|
|
40411
|
+
const accessor = structure.json.accessors[accessorIndex];
|
|
40412
|
+
const bufferView = structure.json.bufferViews[accessor.bufferView];
|
|
40413
|
+
const components = structure.getNumComponents(accessor.type);
|
|
40414
|
+
const componentSize = structure.getComponentSize(accessor.componentType);
|
|
40415
|
+
const itemBytes = components * componentSize;
|
|
40416
|
+
const accessorByteOffset = accessor.byteOffset || 0;
|
|
40417
|
+
const bvByteOffset = bufferView.byteOffset || 0;
|
|
40418
|
+
const byteStride = bufferView.byteStride || 0;
|
|
40419
|
+
const interleaved = byteStride !== 0 && byteStride !== itemBytes;
|
|
40420
|
+
const offset = bvByteOffset + accessorByteOffset;
|
|
40421
|
+
let length;
|
|
40422
|
+
if (interleaved) {
|
|
40423
|
+
length = (accessor.count - 1) * byteStride + itemBytes;
|
|
40424
|
+
} else {
|
|
40425
|
+
length = accessor.count * itemBytes;
|
|
40426
|
+
}
|
|
40427
|
+
return {
|
|
40428
|
+
offset,
|
|
40429
|
+
length,
|
|
40430
|
+
componentType: accessor.componentType,
|
|
40431
|
+
accessorIndex,
|
|
40432
|
+
type,
|
|
40433
|
+
primIdx,
|
|
40434
|
+
_accessor: accessor,
|
|
40435
|
+
_components: components,
|
|
40436
|
+
_componentSize: componentSize,
|
|
40437
|
+
_itemBytes: itemBytes,
|
|
40438
|
+
_byteStride: byteStride,
|
|
40439
|
+
_interleaved: interleaved,
|
|
40440
|
+
};
|
|
40441
|
+
}
|
|
40442
|
+
_createGeometryAttribute(req) {
|
|
40443
|
+
const accessor = req._accessor;
|
|
40444
|
+
const components = req._components;
|
|
40445
|
+
const count = accessor.count;
|
|
40446
|
+
const stride = req._interleaved ? req._byteStride / req._componentSize : components;
|
|
40447
|
+
const normalized = accessor.normalized === true;
|
|
40448
|
+
const componentType = req.componentType;
|
|
40449
|
+
const src = req.data;
|
|
40450
|
+
if (!req._interleaved && !normalized) {
|
|
40451
|
+
return new BufferAttribute(src, components, false);
|
|
40452
|
+
}
|
|
40453
|
+
if (normalized) {
|
|
40454
|
+
const denom = this._normalizedDenominator(componentType);
|
|
40455
|
+
if (denom > 0) {
|
|
40456
|
+
const out = new Float32Array(count * components);
|
|
40457
|
+
const inv = 1 / denom;
|
|
40458
|
+
const isSignedNormalized = componentType === 5120 || componentType === 5122;
|
|
40459
|
+
for (let i = 0; i < count; i++) {
|
|
40460
|
+
const srcBase = i * stride;
|
|
40461
|
+
const dstBase = i * components;
|
|
40462
|
+
for (let c = 0; c < components; c++) {
|
|
40463
|
+
let v = src[srcBase + c] * inv;
|
|
40464
|
+
if (isSignedNormalized && v < -1) v = -1;
|
|
40465
|
+
out[dstBase + c] = v;
|
|
40466
|
+
}
|
|
40467
|
+
}
|
|
40468
|
+
return new BufferAttribute(out, components, false);
|
|
40469
|
+
}
|
|
40470
|
+
}
|
|
40471
|
+
const TypedArrayCtor = src.constructor;
|
|
40472
|
+
const out = new TypedArrayCtor(count * components);
|
|
40473
|
+
for (let i = 0; i < count; i++) {
|
|
40474
|
+
const srcBase = i * stride;
|
|
40475
|
+
const dstBase = i * components;
|
|
40476
|
+
for (let c = 0; c < components; c++) {
|
|
40477
|
+
out[dstBase + c] = src[srcBase + c];
|
|
40478
|
+
}
|
|
40479
|
+
}
|
|
40480
|
+
return new BufferAttribute(out, components, false);
|
|
39093
40481
|
}
|
|
39094
40482
|
createDummyTexture() {
|
|
39095
40483
|
const data = new Float32Array(16);
|
|
@@ -39161,7 +40549,7 @@ void main() {
|
|
|
39161
40549
|
if (!this.transformTexture) return;
|
|
39162
40550
|
this.transformTexture.needsUpdate = true;
|
|
39163
40551
|
}
|
|
39164
|
-
setVisibleEdges(visible) {
|
|
40552
|
+
setVisibleEdges(visible = true) {
|
|
39165
40553
|
this.visibleEdges = visible;
|
|
39166
40554
|
}
|
|
39167
40555
|
getAvailableMemory() {
|
|
@@ -39415,78 +40803,51 @@ void main() {
|
|
|
39415
40803
|
node.loading = true;
|
|
39416
40804
|
const meshDef = node.structure.getJson().meshes[node.meshIndex];
|
|
39417
40805
|
try {
|
|
40806
|
+
if (
|
|
40807
|
+
!this._dracoLoader &&
|
|
40808
|
+
meshDef.primitives &&
|
|
40809
|
+
meshDef.primitives.some((p) => p.extensions && p.extensions[DRACO_EXTENSION_NAME])
|
|
40810
|
+
) {
|
|
40811
|
+
throw new Error(
|
|
40812
|
+
"primitive uses KHR_draco_mesh_compression but no DRACOLoader is configured. " +
|
|
40813
|
+
"Inject one via dynamicLoader.setDracoLoader(new DRACOLoader()) before opening the file."
|
|
40814
|
+
);
|
|
40815
|
+
}
|
|
39418
40816
|
const bufferRequests = [];
|
|
39419
40817
|
const primitiveReqMap = new Map();
|
|
40818
|
+
const dracoPrimitives = new Map();
|
|
39420
40819
|
for (let primIdx = 0; primIdx < meshDef.primitives.length; primIdx++) {
|
|
39421
40820
|
const primitive = meshDef.primitives[primIdx];
|
|
39422
40821
|
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({
|
|
40822
|
+
const dracoExt = primitive.extensions && primitive.extensions[DRACO_EXTENSION_NAME];
|
|
40823
|
+
if (dracoExt) {
|
|
40824
|
+
const bufferView = node.structure.json.bufferViews[dracoExt.bufferView];
|
|
40825
|
+
const byteOffset = bufferView.byteOffset || 0;
|
|
40826
|
+
const byteLength = bufferView.byteLength;
|
|
40827
|
+
const dracoReq = {
|
|
39432
40828
|
offset: byteOffset,
|
|
39433
40829
|
length: byteLength,
|
|
39434
|
-
componentType:
|
|
39435
|
-
|
|
39436
|
-
type: "position",
|
|
40830
|
+
componentType: 5121,
|
|
40831
|
+
type: "draco",
|
|
39437
40832
|
primIdx,
|
|
39438
|
-
}
|
|
40833
|
+
};
|
|
40834
|
+
reqs.push(dracoReq);
|
|
40835
|
+
dracoPrimitives.set(primIdx, { req: dracoReq, primitive });
|
|
40836
|
+
primitiveReqMap.set(primIdx, reqs);
|
|
40837
|
+
bufferRequests.push(...reqs);
|
|
40838
|
+
continue;
|
|
40839
|
+
}
|
|
40840
|
+
if (primitive.attributes.POSITION !== undefined) {
|
|
40841
|
+
reqs.push(this._buildAccessorRequest(node.structure, primitive.attributes.POSITION, "position", primIdx));
|
|
39439
40842
|
}
|
|
39440
40843
|
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
|
-
});
|
|
40844
|
+
reqs.push(this._buildAccessorRequest(node.structure, primitive.attributes.NORMAL, "normal", primIdx));
|
|
39456
40845
|
}
|
|
39457
40846
|
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
|
-
});
|
|
40847
|
+
reqs.push(this._buildAccessorRequest(node.structure, primitive.attributes.TEXCOORD_0, "uv", primIdx));
|
|
39473
40848
|
}
|
|
39474
40849
|
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
|
-
});
|
|
40850
|
+
reqs.push(this._buildAccessorRequest(node.structure, primitive.indices, "index", primIdx));
|
|
39490
40851
|
}
|
|
39491
40852
|
primitiveReqMap.set(primIdx, reqs);
|
|
39492
40853
|
bufferRequests.push(...reqs);
|
|
@@ -39512,29 +40873,31 @@ void main() {
|
|
|
39512
40873
|
}
|
|
39513
40874
|
for (let primIdx = 0; primIdx < meshDef.primitives.length; primIdx++) {
|
|
39514
40875
|
const primitive = meshDef.primitives[primIdx];
|
|
39515
|
-
const geometry = new BufferGeometry();
|
|
39516
40876
|
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
|
-
|
|
40877
|
+
let geometry;
|
|
40878
|
+
if (dracoPrimitives.has(primIdx)) {
|
|
40879
|
+
const dracoReq = reqs.find((r) => r.type === "draco");
|
|
40880
|
+
const dracoBytes = new Uint8Array(dracoReq.data.buffer, dracoReq.data.byteOffset, dracoReq.data.byteLength);
|
|
40881
|
+
const dracoBuffer = dracoBytes.slice().buffer;
|
|
40882
|
+
geometry = await this._decodeDracoPrimitive(node.structure, primitive, dracoBuffer);
|
|
40883
|
+
} else {
|
|
40884
|
+
geometry = new BufferGeometry();
|
|
40885
|
+
if (primitive.attributes.POSITION !== undefined) {
|
|
40886
|
+
const req = reqs.find((r) => r.type === "position" && r.accessorIndex === primitive.attributes.POSITION);
|
|
40887
|
+
geometry.setAttribute("position", this._createGeometryAttribute(req));
|
|
40888
|
+
}
|
|
40889
|
+
if (primitive.attributes.NORMAL !== undefined) {
|
|
40890
|
+
const req = reqs.find((r) => r.type === "normal" && r.accessorIndex === primitive.attributes.NORMAL);
|
|
40891
|
+
geometry.setAttribute("normal", this._createGeometryAttribute(req));
|
|
40892
|
+
}
|
|
40893
|
+
if (primitive.attributes.TEXCOORD_0 !== undefined) {
|
|
40894
|
+
const req = reqs.find((r) => r.type === "uv" && r.accessorIndex === primitive.attributes.TEXCOORD_0);
|
|
40895
|
+
geometry.setAttribute("uv", this._createGeometryAttribute(req));
|
|
40896
|
+
}
|
|
40897
|
+
if (primitive.indices !== undefined) {
|
|
40898
|
+
const req = reqs.find((r) => r.type === "index" && r.accessorIndex === primitive.indices);
|
|
40899
|
+
geometry.setIndex(this._createGeometryAttribute(req));
|
|
40900
|
+
}
|
|
39538
40901
|
}
|
|
39539
40902
|
let material;
|
|
39540
40903
|
if (primitive.material !== undefined) {
|
|
@@ -39773,20 +41136,43 @@ void main() {
|
|
|
39773
41136
|
const nodeMatrix = new Matrix4();
|
|
39774
41137
|
const uniqueNodeId = `${structure.id}_${nodeId}`;
|
|
39775
41138
|
const meshDef = structure.json.meshes[nodeDef.mesh];
|
|
41139
|
+
if (!meshDef || !meshDef.primitives || meshDef.primitives.length === 0) {
|
|
41140
|
+
if (nodeDef.children) {
|
|
41141
|
+
for (const childId of nodeDef.children) {
|
|
41142
|
+
await this.processNodeHierarchy(structure, childId, nodeGroup || parentGroup);
|
|
41143
|
+
}
|
|
41144
|
+
}
|
|
41145
|
+
return nodeGroup;
|
|
41146
|
+
}
|
|
39776
41147
|
const geometryExtents = new Box3();
|
|
39777
41148
|
for (const primitive of meshDef.primitives) {
|
|
41149
|
+
if (!primitive.attributes) continue;
|
|
39778
41150
|
const positionAccessor = structure.json.accessors[primitive.attributes.POSITION];
|
|
39779
41151
|
if (positionAccessor && positionAccessor.min && positionAccessor.max) {
|
|
39780
|
-
const
|
|
39781
|
-
|
|
39782
|
-
|
|
39783
|
-
|
|
39784
|
-
|
|
41152
|
+
const minVec = new Vector3().fromArray(positionAccessor.min);
|
|
41153
|
+
const maxVec = new Vector3().fromArray(positionAccessor.max);
|
|
41154
|
+
if (positionAccessor.normalized === true) {
|
|
41155
|
+
const denom = this._normalizedDenominator(positionAccessor.componentType);
|
|
41156
|
+
if (denom > 0) {
|
|
41157
|
+
minVec.divideScalar(denom);
|
|
41158
|
+
maxVec.divideScalar(denom);
|
|
41159
|
+
if (positionAccessor.componentType === 5120 || positionAccessor.componentType === 5122) {
|
|
41160
|
+
minVec.x = Math.max(minVec.x, -1);
|
|
41161
|
+
minVec.y = Math.max(minVec.y, -1);
|
|
41162
|
+
minVec.z = Math.max(minVec.z, -1);
|
|
41163
|
+
maxVec.x = Math.max(maxVec.x, -1);
|
|
41164
|
+
maxVec.y = Math.max(maxVec.y, -1);
|
|
41165
|
+
maxVec.z = Math.max(maxVec.z, -1);
|
|
41166
|
+
}
|
|
41167
|
+
}
|
|
41168
|
+
}
|
|
41169
|
+
geometryExtents.union(new Box3(minVec, maxVec));
|
|
39785
41170
|
}
|
|
39786
41171
|
}
|
|
39787
41172
|
let isEdge = false;
|
|
39788
|
-
|
|
39789
|
-
|
|
41173
|
+
const firstPrimitive = meshDef.primitives[0];
|
|
41174
|
+
if (firstPrimitive && firstPrimitive.material !== undefined) {
|
|
41175
|
+
const material = structure.json.materials[firstPrimitive.material];
|
|
39790
41176
|
if (material?.name === "edges") {
|
|
39791
41177
|
isEdge = true;
|
|
39792
41178
|
}
|
|
@@ -40099,6 +41485,10 @@ void main() {
|
|
|
40099
41485
|
vec3 objectNormal = vec3( normal );
|
|
40100
41486
|
mat3 bm = mat3( batchingMatrix );
|
|
40101
41487
|
objectNormal = bm * objectNormal;
|
|
41488
|
+
#ifdef USE_TANGENT
|
|
41489
|
+
vec3 objectTangent = vec3( tangent.xyz );
|
|
41490
|
+
objectTangent = bm * objectTangent;
|
|
41491
|
+
#endif
|
|
40102
41492
|
`
|
|
40103
41493
|
);
|
|
40104
41494
|
}
|
|
@@ -41271,7 +42661,7 @@ void main() {
|
|
|
41271
42661
|
}
|
|
41272
42662
|
return extent;
|
|
41273
42663
|
}
|
|
41274
|
-
setMaxConcurrentChunks(maxChunks) {
|
|
42664
|
+
setMaxConcurrentChunks(maxChunks = 6) {
|
|
41275
42665
|
if (maxChunks < 1) {
|
|
41276
42666
|
console.warn("Max concurrent chunks must be at least 1");
|
|
41277
42667
|
return;
|
|
@@ -42710,8 +44100,10 @@ void main() {
|
|
|
42710
44100
|
this.manager = new GLTFLoadingManager(file, params);
|
|
42711
44101
|
const scene = new Group$1();
|
|
42712
44102
|
this.gltfLoader = new DynamicGltfLoader(this.viewer.camera, scene, this.viewer.renderer);
|
|
42713
|
-
this.gltfLoader.
|
|
42714
|
-
this.gltfLoader.
|
|
44103
|
+
this.gltfLoader.setMemoryLimit(this.viewer.options.memoryLimit);
|
|
44104
|
+
this.gltfLoader.setVisibleEdges(this.viewer.options.edgeModel);
|
|
44105
|
+
this.gltfLoader.setMaxConcurrentChunks(params.maxConcurrentChunks);
|
|
44106
|
+
this.gltfLoader.setDracoLoader(params.dracoLoader);
|
|
42715
44107
|
const modelImpl = new DynamicModelImpl(scene);
|
|
42716
44108
|
modelImpl.id = params.modelId || this.extractFileName(file);
|
|
42717
44109
|
modelImpl.gltfLoader = this.gltfLoader;
|
|
@@ -42798,8 +44190,10 @@ void main() {
|
|
|
42798
44190
|
async load(model, format, params = {}) {
|
|
42799
44191
|
const scene = new Group$1();
|
|
42800
44192
|
this.gltfLoader = new DynamicGltfLoader(this.viewer.camera, scene, this.viewer.renderer);
|
|
42801
|
-
this.gltfLoader.
|
|
44193
|
+
this.gltfLoader.setMemoryLimit(this.viewer.options.memoryLimit);
|
|
42802
44194
|
this.gltfLoader.setVisibleEdges(this.viewer.options.edgeModel);
|
|
44195
|
+
this.gltfLoader.setMaxConcurrentChunks(params.maxConcurrentChunks);
|
|
44196
|
+
this.gltfLoader.setDracoLoader(params.dracoLoader);
|
|
42803
44197
|
const modelImpl = new DynamicModelImpl(scene);
|
|
42804
44198
|
modelImpl.id = model.file.id;
|
|
42805
44199
|
modelImpl.gltfLoader = this.gltfLoader;
|
|
@@ -44015,186 +45409,133 @@ void main() {
|
|
|
44015
45409
|
}
|
|
44016
45410
|
|
|
44017
45411
|
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
|
-
}
|
|
45412
|
+
constructor( scene, camera, clearColor = 0x000000, clearAlpha = 0 ) {
|
|
45413
|
+
super();
|
|
45414
|
+
this.scene = scene;
|
|
45415
|
+
this.camera = camera;
|
|
45416
|
+
this.sampleLevel = 4;
|
|
45417
|
+
this.unbiased = true;
|
|
45418
|
+
this.stencilBuffer = false;
|
|
45419
|
+
this.clearColor = clearColor;
|
|
45420
|
+
this.clearAlpha = clearAlpha;
|
|
45421
|
+
this._sampleRenderTarget = null;
|
|
45422
|
+
this._oldClearColor = new Color();
|
|
45423
|
+
this._copyUniforms = UniformsUtils.clone( CopyShader.uniforms );
|
|
45424
|
+
this._copyMaterial = new ShaderMaterial( {
|
|
45425
|
+
uniforms: this._copyUniforms,
|
|
45426
|
+
vertexShader: CopyShader.vertexShader,
|
|
45427
|
+
fragmentShader: CopyShader.fragmentShader,
|
|
45428
|
+
transparent: true,
|
|
45429
|
+
depthTest: false,
|
|
45430
|
+
depthWrite: false,
|
|
45431
|
+
premultipliedAlpha: true,
|
|
45432
|
+
blending: AdditiveBlending
|
|
45433
|
+
} );
|
|
45434
|
+
this._fsQuad = new FullScreenQuad( this._copyMaterial );
|
|
45435
|
+
}
|
|
45436
|
+
dispose() {
|
|
45437
|
+
if ( this._sampleRenderTarget ) {
|
|
45438
|
+
this._sampleRenderTarget.dispose();
|
|
45439
|
+
this._sampleRenderTarget = null;
|
|
45440
|
+
}
|
|
45441
|
+
this._copyMaterial.dispose();
|
|
45442
|
+
this._fsQuad.dispose();
|
|
45443
|
+
}
|
|
45444
|
+
setSize( width, height ) {
|
|
45445
|
+
if ( this._sampleRenderTarget ) this._sampleRenderTarget.setSize( width, height );
|
|
45446
|
+
}
|
|
45447
|
+
render( renderer, writeBuffer, readBuffer ) {
|
|
45448
|
+
if ( ! this._sampleRenderTarget ) {
|
|
45449
|
+
this._sampleRenderTarget = new WebGLRenderTarget( readBuffer.width, readBuffer.height, { type: HalfFloatType, stencilBuffer: this.stencilBuffer } );
|
|
45450
|
+
this._sampleRenderTarget.texture.name = 'SSAARenderPass.sample';
|
|
45451
|
+
}
|
|
45452
|
+
const jitterOffsets = _JitterVectors[ Math.max( 0, Math.min( this.sampleLevel, 5 ) ) ];
|
|
45453
|
+
const autoClear = renderer.autoClear;
|
|
45454
|
+
renderer.autoClear = false;
|
|
45455
|
+
renderer.getClearColor( this._oldClearColor );
|
|
45456
|
+
const oldClearAlpha = renderer.getClearAlpha();
|
|
45457
|
+
const baseSampleWeight = 1.0 / jitterOffsets.length;
|
|
45458
|
+
const roundingRange = 1 / 32;
|
|
45459
|
+
this._copyUniforms[ 'tDiffuse' ].value = this._sampleRenderTarget.texture;
|
|
45460
|
+
const viewOffset = {
|
|
45461
|
+
fullWidth: readBuffer.width,
|
|
45462
|
+
fullHeight: readBuffer.height,
|
|
45463
|
+
offsetX: 0,
|
|
45464
|
+
offsetY: 0,
|
|
45465
|
+
width: readBuffer.width,
|
|
45466
|
+
height: readBuffer.height
|
|
45467
|
+
};
|
|
45468
|
+
const originalViewOffset = Object.assign( {}, this.camera.view );
|
|
45469
|
+
if ( originalViewOffset.enabled ) Object.assign( viewOffset, originalViewOffset );
|
|
45470
|
+
for ( let i = 0; i < jitterOffsets.length; i ++ ) {
|
|
45471
|
+
const jitterOffset = jitterOffsets[ i ];
|
|
45472
|
+
if ( this.camera.setViewOffset ) {
|
|
45473
|
+
this.camera.setViewOffset(
|
|
45474
|
+
viewOffset.fullWidth, viewOffset.fullHeight,
|
|
45475
|
+
viewOffset.offsetX + jitterOffset[ 0 ] * 0.0625, viewOffset.offsetY + jitterOffset[ 1 ] * 0.0625,
|
|
45476
|
+
viewOffset.width, viewOffset.height
|
|
45477
|
+
);
|
|
45478
|
+
}
|
|
45479
|
+
let sampleWeight = baseSampleWeight;
|
|
45480
|
+
if ( this.unbiased ) {
|
|
45481
|
+
const uniformCenteredDistribution = ( -0.5 + ( i + 0.5 ) / jitterOffsets.length );
|
|
45482
|
+
sampleWeight += roundingRange * uniformCenteredDistribution;
|
|
45483
|
+
}
|
|
45484
|
+
this._copyUniforms[ 'opacity' ].value = sampleWeight;
|
|
45485
|
+
renderer.setClearColor( this.clearColor, this.clearAlpha );
|
|
45486
|
+
renderer.setRenderTarget( this._sampleRenderTarget );
|
|
45487
|
+
renderer.clear();
|
|
45488
|
+
renderer.render( this.scene, this.camera );
|
|
45489
|
+
renderer.setRenderTarget( this.renderToScreen ? null : writeBuffer );
|
|
45490
|
+
if ( i === 0 ) {
|
|
45491
|
+
renderer.setClearColor( 0x000000, 0.0 );
|
|
45492
|
+
renderer.clear();
|
|
45493
|
+
}
|
|
45494
|
+
this._fsQuad.render( renderer );
|
|
45495
|
+
}
|
|
45496
|
+
if ( this.camera.setViewOffset && originalViewOffset.enabled ) {
|
|
45497
|
+
this.camera.setViewOffset(
|
|
45498
|
+
originalViewOffset.fullWidth, originalViewOffset.fullHeight,
|
|
45499
|
+
originalViewOffset.offsetX, originalViewOffset.offsetY,
|
|
45500
|
+
originalViewOffset.width, originalViewOffset.height
|
|
45501
|
+
);
|
|
45502
|
+
} else if ( this.camera.clearViewOffset ) {
|
|
45503
|
+
this.camera.clearViewOffset();
|
|
45504
|
+
}
|
|
45505
|
+
renderer.autoClear = autoClear;
|
|
45506
|
+
renderer.setClearColor( this._oldClearColor, oldClearAlpha );
|
|
45507
|
+
}
|
|
44123
45508
|
}
|
|
44124
45509
|
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
|
-
],
|
|
45510
|
+
[
|
|
45511
|
+
[ 0, 0 ]
|
|
45512
|
+
],
|
|
45513
|
+
[
|
|
45514
|
+
[ 4, 4 ], [ -4, -4 ]
|
|
45515
|
+
],
|
|
45516
|
+
[
|
|
45517
|
+
[ -2, -6 ], [ 6, -2 ], [ -6, 2 ], [ 2, 6 ]
|
|
45518
|
+
],
|
|
45519
|
+
[
|
|
45520
|
+
[ 1, -3 ], [ -1, 3 ], [ 5, 1 ], [ -3, -5 ],
|
|
45521
|
+
[ -5, 5 ], [ -7, -1 ], [ 3, 7 ], [ 7, -7 ]
|
|
45522
|
+
],
|
|
45523
|
+
[
|
|
45524
|
+
[ 1, 1 ], [ -1, -3 ], [ -3, 2 ], [ 4, -1 ],
|
|
45525
|
+
[ -5, -2 ], [ 2, 5 ], [ 5, 3 ], [ 3, -5 ],
|
|
45526
|
+
[ -2, 6 ], [ 0, -7 ], [ -4, -6 ], [ -6, 4 ],
|
|
45527
|
+
[ -8, 0 ], [ 7, -4 ], [ 6, 7 ], [ -7, -8 ]
|
|
45528
|
+
],
|
|
45529
|
+
[
|
|
45530
|
+
[ -4, -7 ], [ -7, -5 ], [ -3, -5 ], [ -5, -4 ],
|
|
45531
|
+
[ -1, -4 ], [ -2, -2 ], [ -6, -1 ], [ -4, 0 ],
|
|
45532
|
+
[ -7, 1 ], [ -1, 2 ], [ -6, 3 ], [ -3, 3 ],
|
|
45533
|
+
[ -7, 6 ], [ -3, 6 ], [ -5, 7 ], [ -1, 7 ],
|
|
45534
|
+
[ 5, -7 ], [ 1, -6 ], [ 6, -5 ], [ 4, -4 ],
|
|
45535
|
+
[ 2, -3 ], [ 7, -2 ], [ 1, -1 ], [ 4, -1 ],
|
|
45536
|
+
[ 2, 1 ], [ 6, 2 ], [ 0, 4 ], [ 4, 4 ],
|
|
45537
|
+
[ 2, 5 ], [ 7, 5 ], [ 5, 6 ], [ 3, 7 ]
|
|
45538
|
+
]
|
|
44198
45539
|
];
|
|
44199
45540
|
|
|
44200
45541
|
const OutputShader = {
|
|
@@ -57968,24 +59309,6 @@ js: import "konva/skia-backend";
|
|
|
57968
59309
|
}
|
|
57969
59310
|
}
|
|
57970
59311
|
|
|
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
59312
|
class Viewer extends EventEmitter2 {
|
|
57990
59313
|
constructor(client) {
|
|
57991
59314
|
super();
|
|
@@ -57999,9 +59322,9 @@ js: import "konva/skia-backend";
|
|
|
57999
59322
|
this.selected = [];
|
|
58000
59323
|
this.extents = new Box3();
|
|
58001
59324
|
this.target = new Vector3(0, 0, 0);
|
|
59325
|
+
this.clippingPlanes = [];
|
|
58002
59326
|
this._activeDragger = null;
|
|
58003
59327
|
this._components = [];
|
|
58004
|
-
this._updateDelay = 1000;
|
|
58005
59328
|
this._renderNeeded = false;
|
|
58006
59329
|
this._renderTime = 0;
|
|
58007
59330
|
this.render = this.render.bind(this);
|
|
@@ -58020,7 +59343,9 @@ js: import "konva/skia-backend";
|
|
|
58020
59343
|
initialize(canvas, onProgress) {
|
|
58021
59344
|
this.addEventListener("optionschange", (event) => this.syncOptions(event.data));
|
|
58022
59345
|
this.scene = new Scene();
|
|
58023
|
-
this.helpers = new
|
|
59346
|
+
this.helpers = new Group$1();
|
|
59347
|
+
this.helpers.name = "Helpers";
|
|
59348
|
+
this.scene.add(this.helpers);
|
|
58024
59349
|
const pixelRatio = window.devicePixelRatio;
|
|
58025
59350
|
const rect = canvas.parentElement.getBoundingClientRect();
|
|
58026
59351
|
const width = rect.width || 1;
|
|
@@ -58042,17 +59367,17 @@ js: import "konva/skia-backend";
|
|
|
58042
59367
|
this.renderer.setPixelRatio(pixelRatio);
|
|
58043
59368
|
this.renderer.setSize(width, height);
|
|
58044
59369
|
this.renderer.outputColorSpace = LinearSRGBColorSpace;
|
|
59370
|
+
this.renderer.localClippingEnabled = true;
|
|
58045
59371
|
this.renderPass = new RenderPass(this.scene, this.camera);
|
|
58046
|
-
this.helpersPass = new RenderPass(this.helpers, this.camera);
|
|
58047
|
-
this.helpersPass.clear = false;
|
|
58048
59372
|
this.fxaaPass = new FXAAPass();
|
|
58049
59373
|
this.smaaPass = new SMAAPass();
|
|
58050
|
-
this.ssaaRenderPass = new SSAARenderPass(
|
|
59374
|
+
this.ssaaRenderPass = new SSAARenderPass(this.scene, this.camera);
|
|
58051
59375
|
this.ssaaRenderPass.unbiased = true;
|
|
58052
59376
|
this.outputPass = new OutputPass();
|
|
58053
|
-
|
|
59377
|
+
const renderTarget = new WebGLRenderTarget(1, 1, { samples: 4 });
|
|
59378
|
+
renderTarget.texture.name = "EffectComposer.rt1";
|
|
59379
|
+
this.composer = new EffectComposer(this.renderer, renderTarget);
|
|
58054
59380
|
this.composer.addPass(this.renderPass);
|
|
58055
|
-
this.composer.addPass(this.helpersPass);
|
|
58056
59381
|
this.composer.addPass(this.smaaPass);
|
|
58057
59382
|
this.composer.addPass(this.fxaaPass);
|
|
58058
59383
|
this.composer.addPass(this.ssaaRenderPass);
|
|
@@ -58083,8 +59408,11 @@ js: import "konva/skia-backend";
|
|
|
58083
59408
|
this.removeAllListeners();
|
|
58084
59409
|
this.setActiveDragger();
|
|
58085
59410
|
this._components.forEach((component) => component.dispose());
|
|
58086
|
-
this._components =
|
|
58087
|
-
this._markup
|
|
59411
|
+
this._components.length = 0;
|
|
59412
|
+
if (this._markup) {
|
|
59413
|
+
this._markup.dispose();
|
|
59414
|
+
this._markup = undefined;
|
|
59415
|
+
}
|
|
58088
59416
|
if (this.canvas) {
|
|
58089
59417
|
this.canvasEvents.forEach((x) => this.canvas.removeEventListener(x, this.canvaseventlistener));
|
|
58090
59418
|
this.canvas = undefined;
|
|
@@ -58093,8 +59421,6 @@ js: import "konva/skia-backend";
|
|
|
58093
59421
|
this.composer.dispose();
|
|
58094
59422
|
if (this.renderPass)
|
|
58095
59423
|
this.renderPass.dispose();
|
|
58096
|
-
if (this.helpersPass)
|
|
58097
|
-
this.helpersPass.dispose();
|
|
58098
59424
|
if (this.fxaaPass)
|
|
58099
59425
|
this.fxaaPass.dispose();
|
|
58100
59426
|
if (this.smaaPass)
|
|
@@ -58110,7 +59436,6 @@ js: import "konva/skia-backend";
|
|
|
58110
59436
|
this.camera = undefined;
|
|
58111
59437
|
this.renderer = undefined;
|
|
58112
59438
|
this.renderPass = undefined;
|
|
58113
|
-
this.helpersPass = undefined;
|
|
58114
59439
|
this.fxaaPass = undefined;
|
|
58115
59440
|
this.smaaPass = undefined;
|
|
58116
59441
|
this.ssaaRenderPass = undefined;
|
|
@@ -58142,11 +59467,12 @@ js: import "konva/skia-backend";
|
|
|
58142
59467
|
}
|
|
58143
59468
|
update(force = false) {
|
|
58144
59469
|
const time = performance.now();
|
|
58145
|
-
|
|
59470
|
+
if (typeof force === "number" && time - this._renderTime >= force)
|
|
59471
|
+
force = true;
|
|
58146
59472
|
this._renderNeeded = true;
|
|
58147
59473
|
if (force)
|
|
58148
59474
|
this.render(time);
|
|
58149
|
-
this.emitEvent({ type: "update", force });
|
|
59475
|
+
this.emitEvent({ type: "update", force: !!force });
|
|
58150
59476
|
}
|
|
58151
59477
|
render(time, force = false) {
|
|
58152
59478
|
if (!this.renderer)
|
|
@@ -58160,13 +59486,7 @@ js: import "konva/skia-backend";
|
|
|
58160
59486
|
this._renderNeeded = false;
|
|
58161
59487
|
this.renderer.info.autoReset = false;
|
|
58162
59488
|
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
|
-
}
|
|
59489
|
+
this.composer.render(deltaTime);
|
|
58170
59490
|
this.emitEvent({ type: "render", time, deltaTime });
|
|
58171
59491
|
}
|
|
58172
59492
|
loadReferences(model) {
|
|
@@ -58226,11 +59546,12 @@ js: import "konva/skia-backend";
|
|
|
58226
59546
|
this.clearOverlay();
|
|
58227
59547
|
this.clearSelected();
|
|
58228
59548
|
this.loaders.forEach((loader) => loader.dispose());
|
|
58229
|
-
this.loaders =
|
|
59549
|
+
this.loaders.length = 0;
|
|
58230
59550
|
this.models.forEach((model) => model.dispose());
|
|
58231
|
-
this.models =
|
|
58232
|
-
this.scene.clear();
|
|
59551
|
+
this.models.length = 0;
|
|
58233
59552
|
this.helpers.clear();
|
|
59553
|
+
this.scene.clear();
|
|
59554
|
+
this.scene.add(this.helpers);
|
|
58234
59555
|
this.extents.makeEmpty();
|
|
58235
59556
|
this.syncOptions();
|
|
58236
59557
|
this.syncOverlay();
|
|
@@ -58247,8 +59568,15 @@ js: import "konva/skia-backend";
|
|
|
58247
59568
|
this.fxaaPass.enabled = options.antialiasing === "fxaa";
|
|
58248
59569
|
this.smaaPass.enabled = options.antialiasing === "smaa";
|
|
58249
59570
|
this.ssaaRenderPass.enabled = options.antialiasing === "ssaa";
|
|
58250
|
-
this.renderPass.enabled =
|
|
58251
|
-
|
|
59571
|
+
this.renderPass.enabled = options.antialiasing !== "ssaa";
|
|
59572
|
+
const samples = options.antialiasing === true || options.antialiasing === "msaa" ? 4 : 0;
|
|
59573
|
+
if (this.composer.renderTarget1.samples !== samples) {
|
|
59574
|
+
const size = this.renderer.getSize(new Vector2());
|
|
59575
|
+
const newRenderTarget = new WebGLRenderTarget(1, 1, { samples });
|
|
59576
|
+
newRenderTarget.texture.name = "EffectComposer.rt1";
|
|
59577
|
+
this.composer.reset(newRenderTarget);
|
|
59578
|
+
this.composer.setSize(size.x, size.y);
|
|
59579
|
+
}
|
|
58252
59580
|
this.update();
|
|
58253
59581
|
}
|
|
58254
59582
|
syncOverlay() {
|
|
@@ -58267,7 +59595,8 @@ js: import "konva/skia-backend";
|
|
|
58267
59595
|
clearSlices() {
|
|
58268
59596
|
if (!this.renderer)
|
|
58269
59597
|
return;
|
|
58270
|
-
this.
|
|
59598
|
+
this.clippingPlanes.length = 0;
|
|
59599
|
+
this.emitEvent({ type: "changecuttingplanes" });
|
|
58271
59600
|
this.emitEvent({ type: "clearslices" });
|
|
58272
59601
|
this.update();
|
|
58273
59602
|
}
|
|
@@ -58363,7 +59692,6 @@ js: import "konva/skia-backend";
|
|
|
58363
59692
|
camera.updateMatrixWorld();
|
|
58364
59693
|
this.camera = camera;
|
|
58365
59694
|
this.renderPass.camera = camera;
|
|
58366
|
-
this.helpersPass.camera = camera;
|
|
58367
59695
|
this.ssaaRenderPass.camera = camera;
|
|
58368
59696
|
this.options.cameraMode = "orthographic";
|
|
58369
59697
|
this.emitEvent({ type: "changecameramode", mode: "orthographic" });
|
|
@@ -58386,7 +59714,6 @@ js: import "konva/skia-backend";
|
|
|
58386
59714
|
camera.updateMatrixWorld();
|
|
58387
59715
|
this.camera = camera;
|
|
58388
59716
|
this.renderPass.camera = camera;
|
|
58389
|
-
this.helpersPass.camera = camera;
|
|
58390
59717
|
this.ssaaRenderPass.camera = camera;
|
|
58391
59718
|
this.options.cameraMode = "perspective";
|
|
58392
59719
|
this.emitEvent({ type: "changecameramode", mode: "perspective" });
|
|
@@ -58397,8 +59724,9 @@ js: import "konva/skia-backend";
|
|
|
58397
59724
|
clipping_planes.forEach((clipping_plane) => {
|
|
58398
59725
|
const plane = new Plane();
|
|
58399
59726
|
plane.setFromNormalAndCoplanarPoint(getVector3FromPoint3d(clipping_plane.direction), getVector3FromPoint3d(clipping_plane.location));
|
|
58400
|
-
this.
|
|
59727
|
+
this.clippingPlanes.push(plane);
|
|
58401
59728
|
});
|
|
59729
|
+
this.emitEvent({ type: "changecuttingplanes" });
|
|
58402
59730
|
}
|
|
58403
59731
|
};
|
|
58404
59732
|
const setSelection = (selection) => {
|
|
@@ -58453,7 +59781,7 @@ js: import "konva/skia-backend";
|
|
|
58453
59781
|
};
|
|
58454
59782
|
const getClippingPlanes = () => {
|
|
58455
59783
|
const clipping_planes = [];
|
|
58456
|
-
this.
|
|
59784
|
+
this.clippingPlanes.forEach((plane) => {
|
|
58457
59785
|
const clipping_plane = {
|
|
58458
59786
|
location: getPoint3dFromVector3(plane.coplanarPoint(new Vector3())),
|
|
58459
59787
|
direction: getPoint3dFromVector3(plane.normal),
|