@inweb/viewer-three 27.4.6 → 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 +1765 -438
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +4 -4
- package/dist/viewer-three.module.js +1302 -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 +75 -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 { buffer } = await this.getBufferView(
|
|
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);
|
|
@@ -39017,6 +40220,7 @@ void main() {
|
|
|
39017
40220
|
return result;
|
|
39018
40221
|
}
|
|
39019
40222
|
|
|
40223
|
+
const DRACO_EXTENSION_NAME = "KHR_draco_mesh_compression";
|
|
39020
40224
|
const STRUCTURE_ID_SEPARATOR = ":";
|
|
39021
40225
|
class DynamicGltfLoader {
|
|
39022
40226
|
constructor(camera, scene, renderer) {
|
|
@@ -39091,6 +40295,189 @@ void main() {
|
|
|
39091
40295
|
this.transformData = null;
|
|
39092
40296
|
this.identityTransformData = null;
|
|
39093
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);
|
|
39094
40481
|
}
|
|
39095
40482
|
createDummyTexture() {
|
|
39096
40483
|
const data = new Float32Array(16);
|
|
@@ -39162,7 +40549,7 @@ void main() {
|
|
|
39162
40549
|
if (!this.transformTexture) return;
|
|
39163
40550
|
this.transformTexture.needsUpdate = true;
|
|
39164
40551
|
}
|
|
39165
|
-
setVisibleEdges(visible) {
|
|
40552
|
+
setVisibleEdges(visible = true) {
|
|
39166
40553
|
this.visibleEdges = visible;
|
|
39167
40554
|
}
|
|
39168
40555
|
getAvailableMemory() {
|
|
@@ -39416,78 +40803,51 @@ void main() {
|
|
|
39416
40803
|
node.loading = true;
|
|
39417
40804
|
const meshDef = node.structure.getJson().meshes[node.meshIndex];
|
|
39418
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
|
+
}
|
|
39419
40816
|
const bufferRequests = [];
|
|
39420
40817
|
const primitiveReqMap = new Map();
|
|
40818
|
+
const dracoPrimitives = new Map();
|
|
39421
40819
|
for (let primIdx = 0; primIdx < meshDef.primitives.length; primIdx++) {
|
|
39422
40820
|
const primitive = meshDef.primitives[primIdx];
|
|
39423
40821
|
const reqs = [];
|
|
39424
|
-
|
|
39425
|
-
|
|
39426
|
-
const
|
|
39427
|
-
const
|
|
39428
|
-
const
|
|
39429
|
-
const
|
|
39430
|
-
const count = accessor.count;
|
|
39431
|
-
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
39432
|
-
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 = {
|
|
39433
40828
|
offset: byteOffset,
|
|
39434
40829
|
length: byteLength,
|
|
39435
|
-
componentType:
|
|
39436
|
-
|
|
39437
|
-
type: "position",
|
|
40830
|
+
componentType: 5121,
|
|
40831
|
+
type: "draco",
|
|
39438
40832
|
primIdx,
|
|
39439
|
-
}
|
|
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));
|
|
39440
40842
|
}
|
|
39441
40843
|
if (primitive.attributes.NORMAL !== undefined) {
|
|
39442
|
-
|
|
39443
|
-
const accessor = node.structure.json.accessors[accessorIndex];
|
|
39444
|
-
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
39445
|
-
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
39446
|
-
const components = node.structure.getNumComponents(accessor.type);
|
|
39447
|
-
const count = accessor.count;
|
|
39448
|
-
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
39449
|
-
reqs.push({
|
|
39450
|
-
offset: byteOffset,
|
|
39451
|
-
length: byteLength,
|
|
39452
|
-
componentType: accessor.componentType,
|
|
39453
|
-
accessorIndex,
|
|
39454
|
-
type: "normal",
|
|
39455
|
-
primIdx,
|
|
39456
|
-
});
|
|
40844
|
+
reqs.push(this._buildAccessorRequest(node.structure, primitive.attributes.NORMAL, "normal", primIdx));
|
|
39457
40845
|
}
|
|
39458
40846
|
if (primitive.attributes.TEXCOORD_0 !== undefined) {
|
|
39459
|
-
|
|
39460
|
-
const accessor = node.structure.json.accessors[accessorIndex];
|
|
39461
|
-
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
39462
|
-
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
39463
|
-
const components = node.structure.getNumComponents(accessor.type);
|
|
39464
|
-
const count = accessor.count;
|
|
39465
|
-
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
39466
|
-
reqs.push({
|
|
39467
|
-
offset: byteOffset,
|
|
39468
|
-
length: byteLength,
|
|
39469
|
-
componentType: accessor.componentType,
|
|
39470
|
-
accessorIndex,
|
|
39471
|
-
type: "uv",
|
|
39472
|
-
primIdx,
|
|
39473
|
-
});
|
|
40847
|
+
reqs.push(this._buildAccessorRequest(node.structure, primitive.attributes.TEXCOORD_0, "uv", primIdx));
|
|
39474
40848
|
}
|
|
39475
40849
|
if (primitive.indices !== undefined) {
|
|
39476
|
-
|
|
39477
|
-
const accessor = node.structure.json.accessors[accessorIndex];
|
|
39478
|
-
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
39479
|
-
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
39480
|
-
const components = node.structure.getNumComponents(accessor.type);
|
|
39481
|
-
const count = accessor.count;
|
|
39482
|
-
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
39483
|
-
reqs.push({
|
|
39484
|
-
offset: byteOffset,
|
|
39485
|
-
length: byteLength,
|
|
39486
|
-
componentType: accessor.componentType,
|
|
39487
|
-
accessorIndex,
|
|
39488
|
-
type: "index",
|
|
39489
|
-
primIdx,
|
|
39490
|
-
});
|
|
40850
|
+
reqs.push(this._buildAccessorRequest(node.structure, primitive.indices, "index", primIdx));
|
|
39491
40851
|
}
|
|
39492
40852
|
primitiveReqMap.set(primIdx, reqs);
|
|
39493
40853
|
bufferRequests.push(...reqs);
|
|
@@ -39513,29 +40873,31 @@ void main() {
|
|
|
39513
40873
|
}
|
|
39514
40874
|
for (let primIdx = 0; primIdx < meshDef.primitives.length; primIdx++) {
|
|
39515
40875
|
const primitive = meshDef.primitives[primIdx];
|
|
39516
|
-
const geometry = new BufferGeometry();
|
|
39517
40876
|
const reqs = primitiveReqMap.get(primIdx);
|
|
39518
|
-
|
|
39519
|
-
|
|
39520
|
-
const
|
|
39521
|
-
const
|
|
39522
|
-
|
|
39523
|
-
|
|
39524
|
-
|
|
39525
|
-
|
|
39526
|
-
|
|
39527
|
-
|
|
39528
|
-
|
|
39529
|
-
|
|
39530
|
-
|
|
39531
|
-
|
|
39532
|
-
|
|
39533
|
-
|
|
39534
|
-
|
|
39535
|
-
|
|
39536
|
-
|
|
39537
|
-
|
|
39538
|
-
|
|
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
|
+
}
|
|
39539
40901
|
}
|
|
39540
40902
|
let material;
|
|
39541
40903
|
if (primitive.material !== undefined) {
|
|
@@ -39774,20 +41136,43 @@ void main() {
|
|
|
39774
41136
|
const nodeMatrix = new Matrix4();
|
|
39775
41137
|
const uniqueNodeId = `${structure.id}_${nodeId}`;
|
|
39776
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
|
+
}
|
|
39777
41147
|
const geometryExtents = new Box3();
|
|
39778
41148
|
for (const primitive of meshDef.primitives) {
|
|
41149
|
+
if (!primitive.attributes) continue;
|
|
39779
41150
|
const positionAccessor = structure.json.accessors[primitive.attributes.POSITION];
|
|
39780
41151
|
if (positionAccessor && positionAccessor.min && positionAccessor.max) {
|
|
39781
|
-
const
|
|
39782
|
-
|
|
39783
|
-
|
|
39784
|
-
|
|
39785
|
-
|
|
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));
|
|
39786
41170
|
}
|
|
39787
41171
|
}
|
|
39788
41172
|
let isEdge = false;
|
|
39789
|
-
|
|
39790
|
-
|
|
41173
|
+
const firstPrimitive = meshDef.primitives[0];
|
|
41174
|
+
if (firstPrimitive && firstPrimitive.material !== undefined) {
|
|
41175
|
+
const material = structure.json.materials[firstPrimitive.material];
|
|
39791
41176
|
if (material?.name === "edges") {
|
|
39792
41177
|
isEdge = true;
|
|
39793
41178
|
}
|
|
@@ -40100,6 +41485,10 @@ void main() {
|
|
|
40100
41485
|
vec3 objectNormal = vec3( normal );
|
|
40101
41486
|
mat3 bm = mat3( batchingMatrix );
|
|
40102
41487
|
objectNormal = bm * objectNormal;
|
|
41488
|
+
#ifdef USE_TANGENT
|
|
41489
|
+
vec3 objectTangent = vec3( tangent.xyz );
|
|
41490
|
+
objectTangent = bm * objectTangent;
|
|
41491
|
+
#endif
|
|
40103
41492
|
`
|
|
40104
41493
|
);
|
|
40105
41494
|
}
|
|
@@ -41272,7 +42661,7 @@ void main() {
|
|
|
41272
42661
|
}
|
|
41273
42662
|
return extent;
|
|
41274
42663
|
}
|
|
41275
|
-
setMaxConcurrentChunks(maxChunks) {
|
|
42664
|
+
setMaxConcurrentChunks(maxChunks = 6) {
|
|
41276
42665
|
if (maxChunks < 1) {
|
|
41277
42666
|
console.warn("Max concurrent chunks must be at least 1");
|
|
41278
42667
|
return;
|
|
@@ -42711,8 +44100,10 @@ void main() {
|
|
|
42711
44100
|
this.manager = new GLTFLoadingManager(file, params);
|
|
42712
44101
|
const scene = new Group$1();
|
|
42713
44102
|
this.gltfLoader = new DynamicGltfLoader(this.viewer.camera, scene, this.viewer.renderer);
|
|
42714
|
-
this.gltfLoader.
|
|
42715
|
-
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);
|
|
42716
44107
|
const modelImpl = new DynamicModelImpl(scene);
|
|
42717
44108
|
modelImpl.id = params.modelId || this.extractFileName(file);
|
|
42718
44109
|
modelImpl.gltfLoader = this.gltfLoader;
|
|
@@ -42799,8 +44190,10 @@ void main() {
|
|
|
42799
44190
|
async load(model, format, params = {}) {
|
|
42800
44191
|
const scene = new Group$1();
|
|
42801
44192
|
this.gltfLoader = new DynamicGltfLoader(this.viewer.camera, scene, this.viewer.renderer);
|
|
42802
|
-
this.gltfLoader.
|
|
44193
|
+
this.gltfLoader.setMemoryLimit(this.viewer.options.memoryLimit);
|
|
42803
44194
|
this.gltfLoader.setVisibleEdges(this.viewer.options.edgeModel);
|
|
44195
|
+
this.gltfLoader.setMaxConcurrentChunks(params.maxConcurrentChunks);
|
|
44196
|
+
this.gltfLoader.setDracoLoader(params.dracoLoader);
|
|
42804
44197
|
const modelImpl = new DynamicModelImpl(scene);
|
|
42805
44198
|
modelImpl.id = model.file.id;
|
|
42806
44199
|
modelImpl.gltfLoader = this.gltfLoader;
|
|
@@ -44016,186 +45409,133 @@ void main() {
|
|
|
44016
45409
|
}
|
|
44017
45410
|
|
|
44018
45411
|
class SSAARenderPass extends Pass {
|
|
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
|
-
|
|
44115
|
-
originalViewOffset.width,
|
|
44116
|
-
originalViewOffset.height
|
|
44117
|
-
);
|
|
44118
|
-
} else if (this.camera.clearViewOffset) {
|
|
44119
|
-
this.camera.clearViewOffset();
|
|
44120
|
-
}
|
|
44121
|
-
renderer.autoClear = autoClear;
|
|
44122
|
-
renderer.setClearColor(this._oldClearColor, oldClearAlpha);
|
|
44123
|
-
}
|
|
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
|
+
}
|
|
44124
45508
|
}
|
|
44125
45509
|
const _JitterVectors = [
|
|
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
|
-
|
|
44155
|
-
[3, -5],
|
|
44156
|
-
[-2, 6],
|
|
44157
|
-
[0, -7],
|
|
44158
|
-
[-4, -6],
|
|
44159
|
-
[-6, 4],
|
|
44160
|
-
[-8, 0],
|
|
44161
|
-
[7, -4],
|
|
44162
|
-
[6, 7],
|
|
44163
|
-
[-7, -8],
|
|
44164
|
-
],
|
|
44165
|
-
[
|
|
44166
|
-
[-4, -7],
|
|
44167
|
-
[-7, -5],
|
|
44168
|
-
[-3, -5],
|
|
44169
|
-
[-5, -4],
|
|
44170
|
-
[-1, -4],
|
|
44171
|
-
[-2, -2],
|
|
44172
|
-
[-6, -1],
|
|
44173
|
-
[-4, 0],
|
|
44174
|
-
[-7, 1],
|
|
44175
|
-
[-1, 2],
|
|
44176
|
-
[-6, 3],
|
|
44177
|
-
[-3, 3],
|
|
44178
|
-
[-7, 6],
|
|
44179
|
-
[-3, 6],
|
|
44180
|
-
[-5, 7],
|
|
44181
|
-
[-1, 7],
|
|
44182
|
-
[5, -7],
|
|
44183
|
-
[1, -6],
|
|
44184
|
-
[6, -5],
|
|
44185
|
-
[4, -4],
|
|
44186
|
-
[2, -3],
|
|
44187
|
-
[7, -2],
|
|
44188
|
-
[1, -1],
|
|
44189
|
-
[4, -1],
|
|
44190
|
-
[2, 1],
|
|
44191
|
-
[6, 2],
|
|
44192
|
-
[0, 4],
|
|
44193
|
-
[4, 4],
|
|
44194
|
-
[2, 5],
|
|
44195
|
-
[7, 5],
|
|
44196
|
-
[5, 6],
|
|
44197
|
-
[3, 7],
|
|
44198
|
-
],
|
|
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
|
+
]
|
|
44199
45539
|
];
|
|
44200
45540
|
|
|
44201
45541
|
const OutputShader = {
|
|
@@ -57969,24 +59309,6 @@ js: import "konva/skia-backend";
|
|
|
57969
59309
|
}
|
|
57970
59310
|
}
|
|
57971
59311
|
|
|
57972
|
-
class Helpers extends Scene {
|
|
57973
|
-
constructor() {
|
|
57974
|
-
super(...arguments);
|
|
57975
|
-
this.oldAutoClear = false;
|
|
57976
|
-
this.oldClippingPlanes = [];
|
|
57977
|
-
}
|
|
57978
|
-
onBeforeRender(renderer) {
|
|
57979
|
-
this.oldAutoClear = renderer.autoClear;
|
|
57980
|
-
this.oldClippingPlanes = renderer.clippingPlanes;
|
|
57981
|
-
renderer.autoClear = false;
|
|
57982
|
-
renderer.clippingPlanes = [];
|
|
57983
|
-
}
|
|
57984
|
-
onAfterRender(renderer) {
|
|
57985
|
-
renderer.clippingPlanes = this.oldClippingPlanes;
|
|
57986
|
-
renderer.autoClear = this.oldAutoClear;
|
|
57987
|
-
}
|
|
57988
|
-
}
|
|
57989
|
-
|
|
57990
59312
|
class Viewer extends EventEmitter2 {
|
|
57991
59313
|
constructor(client) {
|
|
57992
59314
|
super();
|
|
@@ -58000,9 +59322,9 @@ js: import "konva/skia-backend";
|
|
|
58000
59322
|
this.selected = [];
|
|
58001
59323
|
this.extents = new Box3();
|
|
58002
59324
|
this.target = new Vector3(0, 0, 0);
|
|
59325
|
+
this.clippingPlanes = [];
|
|
58003
59326
|
this._activeDragger = null;
|
|
58004
59327
|
this._components = [];
|
|
58005
|
-
this._updateDelay = 1000;
|
|
58006
59328
|
this._renderNeeded = false;
|
|
58007
59329
|
this._renderTime = 0;
|
|
58008
59330
|
this.render = this.render.bind(this);
|
|
@@ -58021,7 +59343,9 @@ js: import "konva/skia-backend";
|
|
|
58021
59343
|
initialize(canvas, onProgress) {
|
|
58022
59344
|
this.addEventListener("optionschange", (event) => this.syncOptions(event.data));
|
|
58023
59345
|
this.scene = new Scene();
|
|
58024
|
-
this.helpers = new
|
|
59346
|
+
this.helpers = new Group$1();
|
|
59347
|
+
this.helpers.name = "Helpers";
|
|
59348
|
+
this.scene.add(this.helpers);
|
|
58025
59349
|
const pixelRatio = window.devicePixelRatio;
|
|
58026
59350
|
const rect = canvas.parentElement.getBoundingClientRect();
|
|
58027
59351
|
const width = rect.width || 1;
|
|
@@ -58043,17 +59367,17 @@ js: import "konva/skia-backend";
|
|
|
58043
59367
|
this.renderer.setPixelRatio(pixelRatio);
|
|
58044
59368
|
this.renderer.setSize(width, height);
|
|
58045
59369
|
this.renderer.outputColorSpace = LinearSRGBColorSpace;
|
|
59370
|
+
this.renderer.localClippingEnabled = true;
|
|
58046
59371
|
this.renderPass = new RenderPass(this.scene, this.camera);
|
|
58047
|
-
this.helpersPass = new RenderPass(this.helpers, this.camera);
|
|
58048
|
-
this.helpersPass.clear = false;
|
|
58049
59372
|
this.fxaaPass = new FXAAPass();
|
|
58050
59373
|
this.smaaPass = new SMAAPass();
|
|
58051
|
-
this.ssaaRenderPass = new SSAARenderPass(
|
|
59374
|
+
this.ssaaRenderPass = new SSAARenderPass(this.scene, this.camera);
|
|
58052
59375
|
this.ssaaRenderPass.unbiased = true;
|
|
58053
59376
|
this.outputPass = new OutputPass();
|
|
58054
|
-
|
|
59377
|
+
const renderTarget = new WebGLRenderTarget(1, 1, { samples: 4 });
|
|
59378
|
+
renderTarget.texture.name = "EffectComposer.rt1";
|
|
59379
|
+
this.composer = new EffectComposer(this.renderer, renderTarget);
|
|
58055
59380
|
this.composer.addPass(this.renderPass);
|
|
58056
|
-
this.composer.addPass(this.helpersPass);
|
|
58057
59381
|
this.composer.addPass(this.smaaPass);
|
|
58058
59382
|
this.composer.addPass(this.fxaaPass);
|
|
58059
59383
|
this.composer.addPass(this.ssaaRenderPass);
|
|
@@ -58084,8 +59408,11 @@ js: import "konva/skia-backend";
|
|
|
58084
59408
|
this.removeAllListeners();
|
|
58085
59409
|
this.setActiveDragger();
|
|
58086
59410
|
this._components.forEach((component) => component.dispose());
|
|
58087
|
-
this._components =
|
|
58088
|
-
this._markup
|
|
59411
|
+
this._components.length = 0;
|
|
59412
|
+
if (this._markup) {
|
|
59413
|
+
this._markup.dispose();
|
|
59414
|
+
this._markup = undefined;
|
|
59415
|
+
}
|
|
58089
59416
|
if (this.canvas) {
|
|
58090
59417
|
this.canvasEvents.forEach((x) => this.canvas.removeEventListener(x, this.canvaseventlistener));
|
|
58091
59418
|
this.canvas = undefined;
|
|
@@ -58094,8 +59421,6 @@ js: import "konva/skia-backend";
|
|
|
58094
59421
|
this.composer.dispose();
|
|
58095
59422
|
if (this.renderPass)
|
|
58096
59423
|
this.renderPass.dispose();
|
|
58097
|
-
if (this.helpersPass)
|
|
58098
|
-
this.helpersPass.dispose();
|
|
58099
59424
|
if (this.fxaaPass)
|
|
58100
59425
|
this.fxaaPass.dispose();
|
|
58101
59426
|
if (this.smaaPass)
|
|
@@ -58111,7 +59436,6 @@ js: import "konva/skia-backend";
|
|
|
58111
59436
|
this.camera = undefined;
|
|
58112
59437
|
this.renderer = undefined;
|
|
58113
59438
|
this.renderPass = undefined;
|
|
58114
|
-
this.helpersPass = undefined;
|
|
58115
59439
|
this.fxaaPass = undefined;
|
|
58116
59440
|
this.smaaPass = undefined;
|
|
58117
59441
|
this.ssaaRenderPass = undefined;
|
|
@@ -58143,11 +59467,12 @@ js: import "konva/skia-backend";
|
|
|
58143
59467
|
}
|
|
58144
59468
|
update(force = false) {
|
|
58145
59469
|
const time = performance.now();
|
|
58146
|
-
|
|
59470
|
+
if (typeof force === "number" && time - this._renderTime >= force)
|
|
59471
|
+
force = true;
|
|
58147
59472
|
this._renderNeeded = true;
|
|
58148
59473
|
if (force)
|
|
58149
59474
|
this.render(time);
|
|
58150
|
-
this.emitEvent({ type: "update", force });
|
|
59475
|
+
this.emitEvent({ type: "update", force: !!force });
|
|
58151
59476
|
}
|
|
58152
59477
|
render(time, force = false) {
|
|
58153
59478
|
if (!this.renderer)
|
|
@@ -58161,13 +59486,7 @@ js: import "konva/skia-backend";
|
|
|
58161
59486
|
this._renderNeeded = false;
|
|
58162
59487
|
this.renderer.info.autoReset = false;
|
|
58163
59488
|
this.renderer.info.reset();
|
|
58164
|
-
|
|
58165
|
-
this.renderer.render(this.scene, this.camera);
|
|
58166
|
-
this.renderer.render(this.helpers, this.camera);
|
|
58167
|
-
}
|
|
58168
|
-
else {
|
|
58169
|
-
this.composer.render(deltaTime);
|
|
58170
|
-
}
|
|
59489
|
+
this.composer.render(deltaTime);
|
|
58171
59490
|
this.emitEvent({ type: "render", time, deltaTime });
|
|
58172
59491
|
}
|
|
58173
59492
|
loadReferences(model) {
|
|
@@ -58227,11 +59546,12 @@ js: import "konva/skia-backend";
|
|
|
58227
59546
|
this.clearOverlay();
|
|
58228
59547
|
this.clearSelected();
|
|
58229
59548
|
this.loaders.forEach((loader) => loader.dispose());
|
|
58230
|
-
this.loaders =
|
|
59549
|
+
this.loaders.length = 0;
|
|
58231
59550
|
this.models.forEach((model) => model.dispose());
|
|
58232
|
-
this.models =
|
|
58233
|
-
this.scene.clear();
|
|
59551
|
+
this.models.length = 0;
|
|
58234
59552
|
this.helpers.clear();
|
|
59553
|
+
this.scene.clear();
|
|
59554
|
+
this.scene.add(this.helpers);
|
|
58235
59555
|
this.extents.makeEmpty();
|
|
58236
59556
|
this.syncOptions();
|
|
58237
59557
|
this.syncOverlay();
|
|
@@ -58248,8 +59568,15 @@ js: import "konva/skia-backend";
|
|
|
58248
59568
|
this.fxaaPass.enabled = options.antialiasing === "fxaa";
|
|
58249
59569
|
this.smaaPass.enabled = options.antialiasing === "smaa";
|
|
58250
59570
|
this.ssaaRenderPass.enabled = options.antialiasing === "ssaa";
|
|
58251
|
-
this.renderPass.enabled =
|
|
58252
|
-
|
|
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
|
+
}
|
|
58253
59580
|
this.update();
|
|
58254
59581
|
}
|
|
58255
59582
|
syncOverlay() {
|
|
@@ -58268,7 +59595,8 @@ js: import "konva/skia-backend";
|
|
|
58268
59595
|
clearSlices() {
|
|
58269
59596
|
if (!this.renderer)
|
|
58270
59597
|
return;
|
|
58271
|
-
this.
|
|
59598
|
+
this.clippingPlanes.length = 0;
|
|
59599
|
+
this.emitEvent({ type: "changecuttingplanes" });
|
|
58272
59600
|
this.emitEvent({ type: "clearslices" });
|
|
58273
59601
|
this.update();
|
|
58274
59602
|
}
|
|
@@ -58364,7 +59692,6 @@ js: import "konva/skia-backend";
|
|
|
58364
59692
|
camera.updateMatrixWorld();
|
|
58365
59693
|
this.camera = camera;
|
|
58366
59694
|
this.renderPass.camera = camera;
|
|
58367
|
-
this.helpersPass.camera = camera;
|
|
58368
59695
|
this.ssaaRenderPass.camera = camera;
|
|
58369
59696
|
this.options.cameraMode = "orthographic";
|
|
58370
59697
|
this.emitEvent({ type: "changecameramode", mode: "orthographic" });
|
|
@@ -58387,7 +59714,6 @@ js: import "konva/skia-backend";
|
|
|
58387
59714
|
camera.updateMatrixWorld();
|
|
58388
59715
|
this.camera = camera;
|
|
58389
59716
|
this.renderPass.camera = camera;
|
|
58390
|
-
this.helpersPass.camera = camera;
|
|
58391
59717
|
this.ssaaRenderPass.camera = camera;
|
|
58392
59718
|
this.options.cameraMode = "perspective";
|
|
58393
59719
|
this.emitEvent({ type: "changecameramode", mode: "perspective" });
|
|
@@ -58398,8 +59724,9 @@ js: import "konva/skia-backend";
|
|
|
58398
59724
|
clipping_planes.forEach((clipping_plane) => {
|
|
58399
59725
|
const plane = new Plane();
|
|
58400
59726
|
plane.setFromNormalAndCoplanarPoint(getVector3FromPoint3d(clipping_plane.direction), getVector3FromPoint3d(clipping_plane.location));
|
|
58401
|
-
this.
|
|
59727
|
+
this.clippingPlanes.push(plane);
|
|
58402
59728
|
});
|
|
59729
|
+
this.emitEvent({ type: "changecuttingplanes" });
|
|
58403
59730
|
}
|
|
58404
59731
|
};
|
|
58405
59732
|
const setSelection = (selection) => {
|
|
@@ -58454,7 +59781,7 @@ js: import "konva/skia-backend";
|
|
|
58454
59781
|
};
|
|
58455
59782
|
const getClippingPlanes = () => {
|
|
58456
59783
|
const clipping_planes = [];
|
|
58457
|
-
this.
|
|
59784
|
+
this.clippingPlanes.forEach((plane) => {
|
|
58458
59785
|
const clipping_plane = {
|
|
58459
59786
|
location: getPoint3dFromVector3(plane.coplanarPoint(new Vector3())),
|
|
58460
59787
|
direction: getPoint3dFromVector3(plane.normal),
|