@inweb/viewer-three 27.2.4 → 27.3.1
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/LICENSE +2 -2
- package/README.md +1 -1
- package/dist/extensions/components/AxesHelperComponent.js +2 -2
- package/dist/extensions/components/AxesHelperComponent.js.map +1 -1
- package/dist/extensions/components/AxesHelperComponent.min.js +2 -2
- package/dist/extensions/components/AxesHelperComponent.module.js +2 -2
- package/dist/extensions/components/AxesHelperComponent.module.js.map +1 -1
- package/dist/extensions/components/ExtentsHelperComponent.js +2 -2
- package/dist/extensions/components/ExtentsHelperComponent.js.map +1 -1
- package/dist/extensions/components/ExtentsHelperComponent.min.js +2 -2
- package/dist/extensions/components/ExtentsHelperComponent.module.js +2 -2
- package/dist/extensions/components/ExtentsHelperComponent.module.js.map +1 -1
- package/dist/extensions/components/GridHelperComponent.js +2 -2
- package/dist/extensions/components/GridHelperComponent.js.map +1 -1
- package/dist/extensions/components/GridHelperComponent.min.js +2 -2
- package/dist/extensions/components/GridHelperComponent.module.js +2 -2
- package/dist/extensions/components/GridHelperComponent.module.js.map +1 -1
- package/dist/extensions/components/InfoPanelComponent.js +2 -2
- package/dist/extensions/components/InfoPanelComponent.js.map +1 -1
- package/dist/extensions/components/InfoPanelComponent.min.js +2 -2
- package/dist/extensions/components/InfoPanelComponent.module.js +2 -2
- package/dist/extensions/components/InfoPanelComponent.module.js.map +1 -1
- package/dist/extensions/components/LightHelperComponent.js +2 -2
- package/dist/extensions/components/LightHelperComponent.js.map +1 -1
- package/dist/extensions/components/LightHelperComponent.min.js +2 -2
- package/dist/extensions/components/LightHelperComponent.module.js +2 -2
- package/dist/extensions/components/LightHelperComponent.module.js.map +1 -1
- package/dist/extensions/components/RoomEnvironmentComponent.js +2 -2
- package/dist/extensions/components/RoomEnvironmentComponent.js.map +1 -1
- package/dist/extensions/components/RoomEnvironmentComponent.min.js +2 -2
- package/dist/extensions/components/RoomEnvironmentComponent.module.js +2 -2
- package/dist/extensions/components/RoomEnvironmentComponent.module.js.map +1 -1
- package/dist/extensions/components/StatsPanelComponent.js +2 -2
- package/dist/extensions/components/StatsPanelComponent.js.map +1 -1
- package/dist/extensions/components/StatsPanelComponent.min.js +2 -2
- package/dist/extensions/components/StatsPanelComponent.module.js +2 -2
- package/dist/extensions/components/StatsPanelComponent.module.js.map +1 -1
- package/dist/extensions/loaders/GLTFCloudLoader.js +2 -2
- package/dist/extensions/loaders/GLTFCloudLoader.js.map +1 -1
- package/dist/extensions/loaders/GLTFCloudLoader.min.js +2 -2
- package/dist/extensions/loaders/GLTFCloudLoader.module.js +2 -2
- package/dist/extensions/loaders/GLTFCloudLoader.module.js.map +1 -1
- package/dist/extensions/loaders/GLTFFileLoader.js +2 -2
- package/dist/extensions/loaders/GLTFFileLoader.js.map +1 -1
- package/dist/extensions/loaders/GLTFFileLoader.min.js +2 -2
- package/dist/extensions/loaders/GLTFFileLoader.module.js +2 -2
- package/dist/extensions/loaders/GLTFFileLoader.module.js.map +1 -1
- package/dist/extensions/loaders/IFCXLoader.js +2 -2
- package/dist/extensions/loaders/IFCXLoader.js.map +1 -1
- package/dist/extensions/loaders/IFCXLoader.min.js +2 -2
- package/dist/extensions/loaders/IFCXLoader.module.js +2 -2
- package/dist/extensions/loaders/IFCXLoader.module.js.map +1 -1
- package/dist/extensions/loaders/PotreeLoader.js +2 -2
- package/dist/extensions/loaders/PotreeLoader.js.map +1 -1
- package/dist/extensions/loaders/PotreeLoader.min.js +2 -2
- package/dist/extensions/loaders/PotreeLoader.module.js +2 -2
- package/dist/extensions/loaders/PotreeLoader.module.js.map +1 -1
- package/dist/viewer-three.js +755 -362
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +5 -5
- package/dist/viewer-three.module.js +756 -363
- package/dist/viewer-three.module.js.map +1 -1
- package/extensions/components/AxesHelperComponent.ts +2 -2
- package/extensions/components/ExtentsHelperComponent.ts +2 -2
- package/extensions/components/GridHelperComponent.ts +2 -2
- package/extensions/components/InfoPanelComponent.ts +2 -2
- package/extensions/components/LightHelperComponent.ts +2 -2
- package/extensions/components/RoomEnvironmentComponent.ts +2 -2
- package/extensions/components/StatsPanelComponent.ts +2 -2
- package/extensions/loaders/GLTFCloudLoader.ts +2 -2
- package/extensions/loaders/GLTFFileLoader.ts +2 -2
- package/extensions/loaders/IFCX/IFCXCloudLoader.ts +2 -2
- package/extensions/loaders/IFCX/IFCXFileLoader.ts +2 -2
- package/extensions/loaders/IFCX/IFCXLoader.ts +2 -2
- package/extensions/loaders/IFCX/index.ts +2 -2
- package/extensions/loaders/IFCX/render.js +2 -2
- package/extensions/loaders/Potree/PotreeFileLoader.ts +2 -2
- package/extensions/loaders/Potree/PotreeModelImpl.ts +2 -2
- package/extensions/loaders/Potree/index.ts +2 -2
- package/lib/Viewer/controls/WalkControls.d.ts +8 -0
- package/lib/Viewer/draggers/CuttingPlaneDragger.d.ts +23 -5
- package/lib/Viewer/helpers/PlaneHelper2.d.ts +8 -4
- package/lib/Viewer/measurement/Snapper.d.ts +1 -1
- package/package.json +5 -5
- package/src/Viewer/Viewer.ts +2 -2
- package/src/Viewer/commands/ApplyModelTransform.ts +2 -2
- package/src/Viewer/commands/ClearMarkup.ts +2 -2
- package/src/Viewer/commands/ClearSelected.ts +2 -2
- package/src/Viewer/commands/ClearSlices.ts +2 -2
- package/src/Viewer/commands/Explode.ts +2 -2
- package/src/Viewer/commands/GetDefaultViewPositions.ts +2 -2
- package/src/Viewer/commands/GetModels.ts +2 -2
- package/src/Viewer/commands/GetSelected.ts +2 -2
- package/src/Viewer/commands/GetSelected2.ts +2 -2
- package/src/Viewer/commands/GetSnapshot.ts +2 -2
- package/src/Viewer/commands/HideSelected.ts +2 -2
- package/src/Viewer/commands/IsolateSelected.ts +2 -2
- package/src/Viewer/commands/RegenerateAll.ts +2 -2
- package/src/Viewer/commands/ResetView.ts +2 -2
- package/src/Viewer/commands/SelectModel.ts +2 -2
- package/src/Viewer/commands/SetActiveDragger.ts +2 -2
- package/src/Viewer/commands/SetDefaultViewPosition.ts +2 -2
- package/src/Viewer/commands/SetMarkupColor.ts +2 -2
- package/src/Viewer/commands/SetSelected.ts +2 -2
- package/src/Viewer/commands/SetSelected2.ts +2 -2
- package/src/Viewer/commands/ShowAll.ts +2 -2
- package/src/Viewer/commands/ZoomTo.ts +2 -2
- package/src/Viewer/commands/ZoomToExtents.ts +2 -2
- package/src/Viewer/commands/ZoomToObjects.ts +2 -2
- package/src/Viewer/commands/ZoomToSelected.ts +2 -2
- package/src/Viewer/commands/index.ts +2 -2
- package/src/Viewer/components/BackgroundComponent.ts +2 -2
- package/src/Viewer/components/CameraComponent.ts +2 -2
- package/src/Viewer/components/CanvasRemoveComponent.ts +2 -2
- package/src/Viewer/components/CanvasResizeComponent.ts +2 -2
- package/src/Viewer/components/ExtentsComponent.ts +2 -2
- package/src/Viewer/components/HighlighterComponent.ts +2 -2
- package/src/Viewer/components/HighlighterUtils.ts +2 -2
- package/src/Viewer/components/InfoComponent.ts +2 -2
- package/src/Viewer/components/LightComponent.ts +2 -2
- package/src/Viewer/components/RenderLoopComponent.ts +2 -2
- package/src/Viewer/components/ResetComponent.ts +2 -2
- package/src/Viewer/components/SelectionComponent.ts +3 -3
- package/src/Viewer/components/ViewPositionComponent.ts +2 -2
- package/src/Viewer/components/WCSHelperComponent.ts +2 -2
- package/src/Viewer/components/index.ts +2 -2
- package/src/Viewer/controls/FlyControls.ts +2 -2
- package/src/Viewer/controls/JoyStickControls.ts +2 -2
- package/src/Viewer/controls/WalkControls.ts +52 -6
- package/src/Viewer/draggers/CuttingPlaneDragger.ts +193 -33
- package/src/Viewer/draggers/CuttingPlaneXAxis.ts +4 -5
- package/src/Viewer/draggers/CuttingPlaneYAxis.ts +4 -5
- package/src/Viewer/draggers/CuttingPlaneZAxis.ts +4 -5
- package/src/Viewer/draggers/FlyDragger.ts +2 -2
- package/src/Viewer/draggers/MeasureLineDragger.ts +2 -2
- package/src/Viewer/draggers/OrbitDragger.ts +2 -2
- package/src/Viewer/draggers/PanDragger.ts +2 -2
- package/src/Viewer/draggers/WalkDragger.ts +2 -2
- package/src/Viewer/draggers/ZoomDragger.ts +2 -2
- package/src/Viewer/draggers/index.ts +4 -2
- package/src/Viewer/helpers/PlaneHelper2.ts +32 -19
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +495 -182
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.ts +46 -35
- package/src/Viewer/loaders/GLTFBinaryParser.ts +2 -2
- package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +2 -2
- package/src/Viewer/loaders/GLTFFileDynamicLoader.ts +2 -2
- package/src/Viewer/loaders/GLTFLoadingManager.ts +2 -2
- package/src/Viewer/loaders/JSONStreamParser.ts +2 -2
- package/src/Viewer/loaders/RangesLoader.ts +2 -2
- package/src/Viewer/loaders/index.ts +2 -2
- package/src/Viewer/measurement/Snapper.ts +15 -7
- package/src/Viewer/measurement/UnitConverter.ts +2 -2
- package/src/Viewer/measurement/UnitFormatter.ts +2 -2
- package/src/Viewer/models/IModelImpl.ts +2 -2
- package/src/Viewer/models/ModelImpl.ts +15 -12
- package/src/Viewer/postprocessing/SSAARenderPass.js +2 -2
- package/src/Viewer/scenes/Helpers.ts +2 -2
- package/src/index-umd.ts +2 -2
- package/src/index.ts +2 -2
package/dist/viewer-three.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
-
// Copyright (C) 2002-
|
|
2
|
+
// Copyright (C) 2002-2026, Open Design Alliance (the "Alliance").
|
|
3
3
|
// All rights reserved.
|
|
4
4
|
//
|
|
5
5
|
// This software and its documentation and related materials are owned by
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
//
|
|
15
15
|
// This application incorporates Open Design Alliance software pursuant to a
|
|
16
16
|
// license agreement with Open Design Alliance.
|
|
17
|
-
// Open Design Alliance Copyright (C) 2002-
|
|
17
|
+
// Open Design Alliance Copyright (C) 2002-2026 by Open Design Alliance.
|
|
18
18
|
// All rights reserved.
|
|
19
19
|
//
|
|
20
20
|
// By use of this software, its documentation or related materials, you
|
|
@@ -33644,41 +33644,6 @@ void main() {
|
|
|
33644
33644
|
}
|
|
33645
33645
|
}
|
|
33646
33646
|
|
|
33647
|
-
class PlaneHelper2 extends Line$1 {
|
|
33648
|
-
constructor(size = 1, color = 0xc0c0c0) {
|
|
33649
|
-
const positions = [1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0, 1, 1, 0];
|
|
33650
|
-
const geometry = new BufferGeometry();
|
|
33651
|
-
geometry.setAttribute("position", new Float32BufferAttribute(positions, 3));
|
|
33652
|
-
geometry.computeBoundingSphere();
|
|
33653
|
-
super(geometry, new LineBasicMaterial({ color, toneMapped: false }));
|
|
33654
|
-
this.type = "PlaneHelper2";
|
|
33655
|
-
this.size = size;
|
|
33656
|
-
const positions2 = [1, 1, 0, -1, 1, 0, -1, -1, 0, 1, 1, 0, -1, -1, 0, 1, -1, 0];
|
|
33657
|
-
const geometry2 = new BufferGeometry();
|
|
33658
|
-
geometry2.setAttribute("position", new Float32BufferAttribute(positions2, 3));
|
|
33659
|
-
geometry2.computeBoundingSphere();
|
|
33660
|
-
this.helper = new Mesh(geometry2, new MeshBasicMaterial({
|
|
33661
|
-
color,
|
|
33662
|
-
opacity: 0.2,
|
|
33663
|
-
transparent: true,
|
|
33664
|
-
depthWrite: false,
|
|
33665
|
-
toneMapped: false,
|
|
33666
|
-
side: DoubleSide,
|
|
33667
|
-
}));
|
|
33668
|
-
this.add(this.helper);
|
|
33669
|
-
}
|
|
33670
|
-
dispose() {
|
|
33671
|
-
this.geometry.dispose();
|
|
33672
|
-
this.material.dispose();
|
|
33673
|
-
this.helper.geometry.dispose();
|
|
33674
|
-
this.helper.material.dispose();
|
|
33675
|
-
}
|
|
33676
|
-
updateMatrixWorld(force) {
|
|
33677
|
-
this.scale.set(0.5 * this.size, 0.5 * this.size, 1);
|
|
33678
|
-
super.updateMatrixWorld(force);
|
|
33679
|
-
}
|
|
33680
|
-
}
|
|
33681
|
-
|
|
33682
33647
|
const _changeEvent = { type: "change" };
|
|
33683
33648
|
const _startEvent = { type: "start" };
|
|
33684
33649
|
const _endEvent = { type: "end" };
|
|
@@ -34337,6 +34302,166 @@ void main() {
|
|
|
34337
34302
|
}
|
|
34338
34303
|
}
|
|
34339
34304
|
|
|
34305
|
+
class PlaneHelper2 extends Object3D {
|
|
34306
|
+
constructor(size = 1, color = 0xf0f0f0, opacity = 0.15) {
|
|
34307
|
+
super();
|
|
34308
|
+
this.type = "PlaneHelper2";
|
|
34309
|
+
this.size = size;
|
|
34310
|
+
const positions = [1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0, 1, 1, 0];
|
|
34311
|
+
const geometry = new BufferGeometry();
|
|
34312
|
+
geometry.setAttribute("position", new Float32BufferAttribute(positions, 3));
|
|
34313
|
+
geometry.computeBoundingSphere();
|
|
34314
|
+
this.outline = new Line$1(geometry, new LineBasicMaterial({ color, toneMapped: false }));
|
|
34315
|
+
const positions2 = [1, 1, 0, -1, 1, 0, -1, -1, 0, 1, 1, 0, -1, -1, 0, 1, -1, 0];
|
|
34316
|
+
const geometry2 = new BufferGeometry();
|
|
34317
|
+
geometry2.setAttribute("position", new Float32BufferAttribute(positions2, 3));
|
|
34318
|
+
geometry2.computeBoundingSphere();
|
|
34319
|
+
this.mesh = new Mesh(geometry2, new MeshBasicMaterial({
|
|
34320
|
+
color,
|
|
34321
|
+
opacity,
|
|
34322
|
+
transparent: true,
|
|
34323
|
+
depthWrite: false,
|
|
34324
|
+
toneMapped: false,
|
|
34325
|
+
side: DoubleSide,
|
|
34326
|
+
}));
|
|
34327
|
+
this.add(this.outline);
|
|
34328
|
+
this.add(this.mesh);
|
|
34329
|
+
}
|
|
34330
|
+
dispose() {
|
|
34331
|
+
this.outline.geometry.dispose();
|
|
34332
|
+
this.outline.material.dispose();
|
|
34333
|
+
this.mesh.geometry.dispose();
|
|
34334
|
+
this.mesh.material.dispose();
|
|
34335
|
+
}
|
|
34336
|
+
updateMatrixWorld(force) {
|
|
34337
|
+
this.scale.set(0.5 * this.size, 0.5 * this.size, 1);
|
|
34338
|
+
super.updateMatrixWorld(force);
|
|
34339
|
+
}
|
|
34340
|
+
getLineMaterial() {
|
|
34341
|
+
return this.outline.material;
|
|
34342
|
+
}
|
|
34343
|
+
getMeshMaterial() {
|
|
34344
|
+
return this.mesh.material;
|
|
34345
|
+
}
|
|
34346
|
+
}
|
|
34347
|
+
|
|
34348
|
+
const DESKTOP_SNAP_DISTANCE = 10;
|
|
34349
|
+
const MOBILE_SNAP_DISTANCE = 50;
|
|
34350
|
+
const _vertex = new Vector3();
|
|
34351
|
+
const _start$1 = new Vector3();
|
|
34352
|
+
const _end$1 = new Vector3();
|
|
34353
|
+
const _line = new Line3();
|
|
34354
|
+
const _center = new Vector3();
|
|
34355
|
+
const _projection = new Vector3();
|
|
34356
|
+
class Snapper {
|
|
34357
|
+
constructor(camera, renderer, canvas) {
|
|
34358
|
+
this.camera = camera;
|
|
34359
|
+
this.renderer = renderer;
|
|
34360
|
+
this.canvas = canvas;
|
|
34361
|
+
this.threshold = 0.0001;
|
|
34362
|
+
this.raycaster = new Raycaster();
|
|
34363
|
+
this.detectRadiusInPixels = this.isMobile() ? MOBILE_SNAP_DISTANCE : DESKTOP_SNAP_DISTANCE;
|
|
34364
|
+
this.edgesCache = new WeakMap();
|
|
34365
|
+
}
|
|
34366
|
+
isMobile() {
|
|
34367
|
+
if (typeof navigator === "undefined")
|
|
34368
|
+
return false;
|
|
34369
|
+
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
|
|
34370
|
+
}
|
|
34371
|
+
getMousePosition(event, target) {
|
|
34372
|
+
return target.set(event.clientX, event.clientY);
|
|
34373
|
+
}
|
|
34374
|
+
getPointerIntersects(mouse, objects, recursive = false, clip = true) {
|
|
34375
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
34376
|
+
const x = ((mouse.x - rect.left) / rect.width) * 2 - 1;
|
|
34377
|
+
const y = (-(mouse.y - rect.top) / rect.height) * 2 + 1;
|
|
34378
|
+
const coords = new Vector2(x, y);
|
|
34379
|
+
this.raycaster.setFromCamera(coords, this.camera);
|
|
34380
|
+
this.raycaster.params = {
|
|
34381
|
+
Mesh: {},
|
|
34382
|
+
Line: { threshold: this.threshold },
|
|
34383
|
+
Line2: { threshold: this.threshold },
|
|
34384
|
+
LOD: {},
|
|
34385
|
+
Points: { threshold: this.threshold },
|
|
34386
|
+
Sprite: {},
|
|
34387
|
+
};
|
|
34388
|
+
let intersects = this.raycaster.intersectObjects(objects, recursive);
|
|
34389
|
+
if (clip) {
|
|
34390
|
+
const clippingPlanes = this.renderer.clippingPlanes || [];
|
|
34391
|
+
clippingPlanes.forEach((plane) => {
|
|
34392
|
+
intersects = intersects.filter((intersect) => plane.distanceToPoint(intersect.point) >= 0);
|
|
34393
|
+
});
|
|
34394
|
+
}
|
|
34395
|
+
return intersects;
|
|
34396
|
+
}
|
|
34397
|
+
getDetectRadius(point) {
|
|
34398
|
+
const camera = this.camera;
|
|
34399
|
+
if (camera.isOrthographicCamera) {
|
|
34400
|
+
const fieldHeight = (camera.top - camera.bottom) / camera.zoom;
|
|
34401
|
+
const canvasHeight = this.canvas.height;
|
|
34402
|
+
const worldUnitsPerPixel = fieldHeight / canvasHeight;
|
|
34403
|
+
return this.detectRadiusInPixels * worldUnitsPerPixel;
|
|
34404
|
+
}
|
|
34405
|
+
if (camera.isPerspectiveCamera) {
|
|
34406
|
+
const distance = camera.position.distanceTo(point);
|
|
34407
|
+
const fieldHeight = 2 * Math.tan(MathUtils.degToRad(camera.fov * 0.5)) * distance;
|
|
34408
|
+
const canvasHeight = this.canvas.height;
|
|
34409
|
+
const worldUnitsPerPixel = fieldHeight / canvasHeight;
|
|
34410
|
+
return this.detectRadiusInPixels * worldUnitsPerPixel;
|
|
34411
|
+
}
|
|
34412
|
+
return 0.1;
|
|
34413
|
+
}
|
|
34414
|
+
getSnapPoint(mouse, objects) {
|
|
34415
|
+
const intersections = this.getPointerIntersects(mouse, objects);
|
|
34416
|
+
if (intersections.length === 0)
|
|
34417
|
+
return undefined;
|
|
34418
|
+
const object = intersections[0].object;
|
|
34419
|
+
const intersectionPoint = intersections[0].point;
|
|
34420
|
+
const localPoint = object.worldToLocal(intersectionPoint.clone());
|
|
34421
|
+
let snapPoint;
|
|
34422
|
+
let snapDistance = this.getDetectRadius(intersectionPoint);
|
|
34423
|
+
const geometry = object.geometry;
|
|
34424
|
+
const positions = geometry.attributes.position.array;
|
|
34425
|
+
for (let i = 0; i < positions.length; i += 3) {
|
|
34426
|
+
_vertex.set(positions[i], positions[i + 1], positions[i + 2]);
|
|
34427
|
+
const distance = _vertex.distanceTo(localPoint);
|
|
34428
|
+
if (distance < snapDistance) {
|
|
34429
|
+
snapDistance = distance;
|
|
34430
|
+
snapPoint = _vertex.clone();
|
|
34431
|
+
}
|
|
34432
|
+
}
|
|
34433
|
+
if (snapPoint)
|
|
34434
|
+
return object.localToWorld(snapPoint);
|
|
34435
|
+
let edges = this.edgesCache.get(geometry);
|
|
34436
|
+
if (!edges) {
|
|
34437
|
+
edges = new EdgesGeometry(geometry);
|
|
34438
|
+
this.edgesCache.set(geometry, edges);
|
|
34439
|
+
}
|
|
34440
|
+
const edgePositions = edges.attributes.position.array;
|
|
34441
|
+
for (let i = 0; i < edgePositions.length; i += 6) {
|
|
34442
|
+
_start$1.set(edgePositions[i], edgePositions[i + 1], edgePositions[i + 2]);
|
|
34443
|
+
_end$1.set(edgePositions[i + 3], edgePositions[i + 4], edgePositions[i + 5]);
|
|
34444
|
+
_line.set(_start$1, _end$1);
|
|
34445
|
+
_line.getCenter(_center);
|
|
34446
|
+
const centerDistance = _center.distanceTo(localPoint);
|
|
34447
|
+
if (centerDistance < snapDistance) {
|
|
34448
|
+
snapDistance = centerDistance;
|
|
34449
|
+
snapPoint = _center.clone();
|
|
34450
|
+
continue;
|
|
34451
|
+
}
|
|
34452
|
+
_line.closestPointToPoint(localPoint, true, _projection);
|
|
34453
|
+
const lineDistance = _projection.distanceTo(localPoint);
|
|
34454
|
+
if (lineDistance < snapDistance) {
|
|
34455
|
+
snapDistance = lineDistance;
|
|
34456
|
+
snapPoint = _projection.clone();
|
|
34457
|
+
}
|
|
34458
|
+
}
|
|
34459
|
+
if (snapPoint)
|
|
34460
|
+
return object.localToWorld(snapPoint);
|
|
34461
|
+
return intersectionPoint.clone();
|
|
34462
|
+
}
|
|
34463
|
+
}
|
|
34464
|
+
|
|
34340
34465
|
class OrbitDragger {
|
|
34341
34466
|
constructor(viewer) {
|
|
34342
34467
|
this.updateControls = () => {
|
|
@@ -34429,12 +34554,18 @@ void main() {
|
|
|
34429
34554
|
}
|
|
34430
34555
|
|
|
34431
34556
|
class CuttingPlaneDragger extends OrbitDragger {
|
|
34432
|
-
constructor(viewer
|
|
34557
|
+
constructor(viewer) {
|
|
34433
34558
|
super(viewer);
|
|
34559
|
+
this.helpers = [];
|
|
34560
|
+
this.activeHelper = null;
|
|
34434
34561
|
this.transformChange = () => {
|
|
34435
|
-
|
|
34436
|
-
|
|
34562
|
+
if (!this.activeHelper)
|
|
34563
|
+
return;
|
|
34564
|
+
const plane = this.activeHelper.plane;
|
|
34565
|
+
plane.normal.copy(new Vector3(0, 0, -1)).applyQuaternion(this.activeHelper.quaternion);
|
|
34566
|
+
plane.constant = -this.activeHelper.position.dot(plane.normal);
|
|
34437
34567
|
this.viewer.update();
|
|
34568
|
+
this.changed = true;
|
|
34438
34569
|
};
|
|
34439
34570
|
this.translateDrag = (event) => {
|
|
34440
34571
|
this.orbit.enabled = !event.value;
|
|
@@ -34445,45 +34576,83 @@ void main() {
|
|
|
34445
34576
|
this.translate.enabled = !event.value;
|
|
34446
34577
|
};
|
|
34447
34578
|
this.updatePlaneSize = () => {
|
|
34448
|
-
|
|
34579
|
+
const extentsSize = this.viewer.extents.getSize(new Vector3()).length() || 1;
|
|
34580
|
+
this.helpers.forEach((planeHelper) => (planeHelper.size = extentsSize));
|
|
34449
34581
|
this.viewer.update();
|
|
34450
34582
|
};
|
|
34451
34583
|
this.updateTransformCamera = () => {
|
|
34452
34584
|
this.translate.camera = this.viewer.camera;
|
|
34453
34585
|
this.rotate.camera = this.viewer.camera;
|
|
34586
|
+
this.snapper.camera = this.viewer.camera;
|
|
34587
|
+
};
|
|
34588
|
+
this.clearHelpers = () => {
|
|
34589
|
+
this.setActiveHelper();
|
|
34590
|
+
this.helpers.forEach((helper) => {
|
|
34591
|
+
helper.removeFromParent();
|
|
34592
|
+
helper.dispose();
|
|
34593
|
+
});
|
|
34594
|
+
this.helpers = [];
|
|
34595
|
+
this.viewer.update();
|
|
34454
34596
|
};
|
|
34455
34597
|
this.onKeyDown = (event) => {
|
|
34456
34598
|
if (event.key === "Shift")
|
|
34457
34599
|
this.rotate.setRotationSnap(Math.PI / 4);
|
|
34600
|
+
if (event.key === "Delete" || event.key === "Backspace")
|
|
34601
|
+
this.deleteActivePlane();
|
|
34602
|
+
if (event.key === "Escape" && (this.translate.dragging || this.rotate.dragging))
|
|
34603
|
+
this.reset();
|
|
34458
34604
|
};
|
|
34459
34605
|
this.onKeyUp = (event) => {
|
|
34460
34606
|
if (event.key === "Shift")
|
|
34461
34607
|
this.rotate.setRotationSnap(null);
|
|
34462
34608
|
};
|
|
34609
|
+
this.onPointerDown = (event) => {
|
|
34610
|
+
if (event.button !== 0 || !event.isPrimary)
|
|
34611
|
+
return;
|
|
34612
|
+
this.snapper.getMousePosition(event, this.downPosition);
|
|
34613
|
+
this.saveState();
|
|
34614
|
+
};
|
|
34615
|
+
this.onPointerUp = (event) => {
|
|
34616
|
+
if (event.button !== 0)
|
|
34617
|
+
return;
|
|
34618
|
+
const upPosition = this.snapper.getMousePosition(event, new Vector2());
|
|
34619
|
+
if (upPosition.distanceTo(this.downPosition) !== 0)
|
|
34620
|
+
return;
|
|
34621
|
+
const intersects = this.snapper.getPointerIntersects(upPosition, this.helpers, true, false);
|
|
34622
|
+
if (intersects.length === 0)
|
|
34623
|
+
return;
|
|
34624
|
+
this.setActiveHelper(intersects[0].object.parent);
|
|
34625
|
+
};
|
|
34626
|
+
this.onPointerCancel = (event) => {
|
|
34627
|
+
this.viewer.canvas.dispatchEvent(new PointerEvent("pointerup", event));
|
|
34628
|
+
};
|
|
34463
34629
|
this.onDoubleClick = (event) => {
|
|
34464
|
-
|
|
34465
|
-
|
|
34630
|
+
if (!this.activeHelper)
|
|
34631
|
+
return;
|
|
34632
|
+
const mousePosition = this.snapper.getMousePosition(event, new Vector2());
|
|
34633
|
+
const intersects = this.snapper.getPointerIntersects(mousePosition, [this.activeHelper], true, false);
|
|
34634
|
+
if (intersects.length === 0)
|
|
34635
|
+
return;
|
|
34636
|
+
this.activeHelper.rotateOnAxis(new Vector3(0, 1, 0), Math.PI);
|
|
34466
34637
|
this.transformChange();
|
|
34638
|
+
event.stopPropagation();
|
|
34467
34639
|
};
|
|
34468
|
-
const extentsSize = viewer.extents.getSize(new Vector3()).length() || 1;
|
|
34469
|
-
const extentsCenter = viewer.extents.getCenter(new Vector3());
|
|
34470
|
-
const constant = -extentsCenter.dot(normal);
|
|
34471
|
-
this.plane = new Plane(normal, constant);
|
|
34472
34640
|
if (!viewer.renderer.clippingPlanes)
|
|
34473
34641
|
viewer.renderer.clippingPlanes = [];
|
|
34474
|
-
viewer.renderer.clippingPlanes
|
|
34475
|
-
this.
|
|
34476
|
-
|
|
34477
|
-
this.
|
|
34478
|
-
this.
|
|
34479
|
-
this.
|
|
34480
|
-
this.
|
|
34642
|
+
this.clippingPlanes = viewer.renderer.clippingPlanes;
|
|
34643
|
+
this.clippingPlanes.forEach((plane) => this.addHelper(plane));
|
|
34644
|
+
const extentsSize = viewer.extents.getSize(new Vector3()).length() || 1;
|
|
34645
|
+
this.snapper = new Snapper(viewer.camera, viewer.renderer, viewer.canvas);
|
|
34646
|
+
this.snapper.threshold = extentsSize / 10000;
|
|
34647
|
+
this.downPosition = new Vector2();
|
|
34648
|
+
this.position0 = new Vector3();
|
|
34649
|
+
this.quaternion0 = new Quaternion();
|
|
34481
34650
|
this.translate = new TransformControls(viewer.camera, viewer.canvas);
|
|
34651
|
+
this.translate.setMode("translate");
|
|
34482
34652
|
this.translate.setSpace("local");
|
|
34483
34653
|
this.translate.showX = false;
|
|
34484
34654
|
this.translate.showY = false;
|
|
34485
34655
|
this.translate.showZ = true;
|
|
34486
|
-
this.translate.attach(this.planeCenter);
|
|
34487
34656
|
this.translate.addEventListener("change", this.transformChange);
|
|
34488
34657
|
this.translate.addEventListener("dragging-changed", this.translateDrag);
|
|
34489
34658
|
this.viewer.helpers.add(this.translate.getHelper());
|
|
@@ -34493,14 +34662,18 @@ void main() {
|
|
|
34493
34662
|
this.rotate.showX = true;
|
|
34494
34663
|
this.rotate.showY = true;
|
|
34495
34664
|
this.rotate.showZ = false;
|
|
34496
|
-
this.rotate.attach(this.planeCenter);
|
|
34497
34665
|
this.rotate.addEventListener("change", this.transformChange);
|
|
34498
34666
|
this.rotate.addEventListener("dragging-changed", this.rotateDrag);
|
|
34499
34667
|
this.viewer.helpers.add(this.rotate.getHelper());
|
|
34668
|
+
this.setActiveHelper(this.helpers[this.helpers.length - 1]);
|
|
34500
34669
|
this.viewer.addEventListener("explode", this.updatePlaneSize);
|
|
34501
34670
|
this.viewer.addEventListener("show", this.updatePlaneSize);
|
|
34502
34671
|
this.viewer.addEventListener("showall", this.updatePlaneSize);
|
|
34503
34672
|
this.viewer.addEventListener("changecameramode", this.updateTransformCamera);
|
|
34673
|
+
this.viewer.addEventListener("clearslices", this.clearHelpers);
|
|
34674
|
+
this.viewer.canvas.addEventListener("pointerdown", this.onPointerDown, true);
|
|
34675
|
+
this.viewer.canvas.addEventListener("pointerup", this.onPointerUp, true);
|
|
34676
|
+
this.viewer.canvas.addEventListener("pointercancel", this.onPointerCancel, true);
|
|
34504
34677
|
this.viewer.canvas.addEventListener("dblclick", this.onDoubleClick, true);
|
|
34505
34678
|
window.addEventListener("keydown", this.onKeyDown);
|
|
34506
34679
|
window.addEventListener("keyup", this.onKeyUp);
|
|
@@ -34511,6 +34684,10 @@ void main() {
|
|
|
34511
34684
|
this.viewer.removeEventListener("show", this.updatePlaneSize);
|
|
34512
34685
|
this.viewer.removeEventListener("showall", this.updatePlaneSize);
|
|
34513
34686
|
this.viewer.removeEventListener("changecameramode", this.updateTransformCamera);
|
|
34687
|
+
this.viewer.removeEventListener("clearslices", this.clearHelpers);
|
|
34688
|
+
this.viewer.canvas.removeEventListener("pointerdown", this.onPointerDown, true);
|
|
34689
|
+
this.viewer.canvas.removeEventListener("pointerup", this.onPointerUp, true);
|
|
34690
|
+
this.viewer.canvas.removeEventListener("pointercancel", this.onPointerCancel, true);
|
|
34514
34691
|
this.viewer.canvas.removeEventListener("dblclick", this.onDoubleClick, true);
|
|
34515
34692
|
window.removeEventListener("keydown", this.onKeyDown);
|
|
34516
34693
|
window.removeEventListener("keyup", this.onKeyUp);
|
|
@@ -34524,28 +34701,108 @@ void main() {
|
|
|
34524
34701
|
this.rotate.getHelper().removeFromParent();
|
|
34525
34702
|
this.rotate.detach();
|
|
34526
34703
|
this.rotate.dispose();
|
|
34527
|
-
this.
|
|
34528
|
-
|
|
34529
|
-
|
|
34704
|
+
this.helpers.forEach((helper) => {
|
|
34705
|
+
helper.removeFromParent();
|
|
34706
|
+
helper.dispose();
|
|
34707
|
+
});
|
|
34708
|
+
this.helpers = [];
|
|
34709
|
+
this.activeHelper = null;
|
|
34530
34710
|
super.dispose();
|
|
34531
34711
|
}
|
|
34712
|
+
addHelper(plane) {
|
|
34713
|
+
const extentsSize = this.viewer.extents.getSize(new Vector3()).length() || 1;
|
|
34714
|
+
const extentsCenter = this.viewer.extents.getCenter(new Vector3());
|
|
34715
|
+
const helper = new PlaneHelper2(extentsSize);
|
|
34716
|
+
helper.plane = plane;
|
|
34717
|
+
helper.position.copy(plane.projectPoint(extentsCenter, new Vector3()));
|
|
34718
|
+
helper.quaternion.setFromUnitVectors(new Vector3(0, 0, -1), plane.normal);
|
|
34719
|
+
this.helpers.push(helper);
|
|
34720
|
+
this.viewer.helpers.add(helper);
|
|
34721
|
+
return helper;
|
|
34722
|
+
}
|
|
34723
|
+
setActiveHelper(helper) {
|
|
34724
|
+
if (helper === this.activeHelper)
|
|
34725
|
+
return;
|
|
34726
|
+
if (this.activeHelper) {
|
|
34727
|
+
this.activeHelper.getLineMaterial().color.setHex(0xf0f0f0);
|
|
34728
|
+
this.activeHelper.getMeshMaterial().opacity = 0.15;
|
|
34729
|
+
this.translate.detach();
|
|
34730
|
+
this.rotate.detach();
|
|
34731
|
+
}
|
|
34732
|
+
this.activeHelper = helper;
|
|
34733
|
+
if (this.activeHelper) {
|
|
34734
|
+
this.activeHelper.getLineMaterial().color.setHex(0xd0d0d0);
|
|
34735
|
+
this.activeHelper.getMeshMaterial().opacity = 0.3;
|
|
34736
|
+
this.translate.attach(this.activeHelper);
|
|
34737
|
+
this.rotate.attach(this.activeHelper);
|
|
34738
|
+
}
|
|
34739
|
+
this.viewer.update();
|
|
34740
|
+
}
|
|
34741
|
+
saveState() {
|
|
34742
|
+
if (!this.activeHelper)
|
|
34743
|
+
return;
|
|
34744
|
+
this.position0.copy(this.activeHelper.position);
|
|
34745
|
+
this.quaternion0.copy(this.activeHelper.quaternion);
|
|
34746
|
+
}
|
|
34747
|
+
reset() {
|
|
34748
|
+
if (!this.activeHelper)
|
|
34749
|
+
return;
|
|
34750
|
+
this.translate.dragging = false;
|
|
34751
|
+
this.rotate.dragging = false;
|
|
34752
|
+
this.orbit.state = STATE.NONE;
|
|
34753
|
+
this.activeHelper.position.copy(this.position0);
|
|
34754
|
+
this.activeHelper.quaternion.copy(this.quaternion0);
|
|
34755
|
+
this.transformChange();
|
|
34756
|
+
}
|
|
34757
|
+
addPlane(normal) {
|
|
34758
|
+
const extentsCenter = this.viewer.extents.getCenter(new Vector3());
|
|
34759
|
+
const constant = -extentsCenter.dot(normal);
|
|
34760
|
+
const plane = new Plane(normal, constant);
|
|
34761
|
+
this.clippingPlanes.push(plane);
|
|
34762
|
+
const helper = this.addHelper(plane);
|
|
34763
|
+
this.setActiveHelper(helper);
|
|
34764
|
+
}
|
|
34765
|
+
addPlaneX() {
|
|
34766
|
+
this.addPlane(new Vector3(-1, 0, 0));
|
|
34767
|
+
}
|
|
34768
|
+
addPlaneY() {
|
|
34769
|
+
this.addPlane(new Vector3(0, -1, 0));
|
|
34770
|
+
}
|
|
34771
|
+
addPlaneZ() {
|
|
34772
|
+
this.addPlane(new Vector3(0, 0, -1));
|
|
34773
|
+
}
|
|
34774
|
+
deleteActivePlane() {
|
|
34775
|
+
if (!this.activeHelper)
|
|
34776
|
+
return;
|
|
34777
|
+
const helper = this.activeHelper;
|
|
34778
|
+
const index = this.clippingPlanes.indexOf(helper.plane);
|
|
34779
|
+
if (index !== -1)
|
|
34780
|
+
this.clippingPlanes.splice(index, 1);
|
|
34781
|
+
this.helpers = this.helpers.filter((x) => x !== helper);
|
|
34782
|
+
helper.removeFromParent();
|
|
34783
|
+
helper.dispose();
|
|
34784
|
+
this.setActiveHelper(this.helpers[this.helpers.length - 1]);
|
|
34785
|
+
}
|
|
34532
34786
|
}
|
|
34533
34787
|
|
|
34534
34788
|
class CuttingPlaneXAxisDragger extends CuttingPlaneDragger {
|
|
34535
34789
|
constructor(viewer) {
|
|
34536
|
-
super(viewer
|
|
34790
|
+
super(viewer);
|
|
34791
|
+
this.addPlaneX();
|
|
34537
34792
|
}
|
|
34538
34793
|
}
|
|
34539
34794
|
|
|
34540
34795
|
class CuttingPlaneYAxisDragger extends CuttingPlaneDragger {
|
|
34541
34796
|
constructor(viewer) {
|
|
34542
|
-
super(viewer
|
|
34797
|
+
super(viewer);
|
|
34798
|
+
this.addPlaneY();
|
|
34543
34799
|
}
|
|
34544
34800
|
}
|
|
34545
34801
|
|
|
34546
34802
|
class CuttingPlaneZAxisDragger extends CuttingPlaneDragger {
|
|
34547
34803
|
constructor(viewer) {
|
|
34548
|
-
super(viewer
|
|
34804
|
+
super(viewer);
|
|
34805
|
+
this.addPlaneZ();
|
|
34549
34806
|
}
|
|
34550
34807
|
}
|
|
34551
34808
|
|
|
@@ -34622,120 +34879,6 @@ void main() {
|
|
|
34622
34879
|
}
|
|
34623
34880
|
}
|
|
34624
34881
|
|
|
34625
|
-
const DESKTOP_SNAP_DISTANCE = 10;
|
|
34626
|
-
const MOBILE_SNAP_DISTANCE = 50;
|
|
34627
|
-
const _vertex = new Vector3();
|
|
34628
|
-
const _start$1 = new Vector3();
|
|
34629
|
-
const _end$1 = new Vector3();
|
|
34630
|
-
const _line = new Line3();
|
|
34631
|
-
const _center = new Vector3();
|
|
34632
|
-
const _projection = new Vector3();
|
|
34633
|
-
class Snapper {
|
|
34634
|
-
constructor(camera, renderer, canvas) {
|
|
34635
|
-
this.camera = camera;
|
|
34636
|
-
this.renderer = renderer;
|
|
34637
|
-
this.canvas = canvas;
|
|
34638
|
-
this.threshold = 0.0001;
|
|
34639
|
-
this.raycaster = new Raycaster();
|
|
34640
|
-
this.detectRadiusInPixels = this.isMobile() ? MOBILE_SNAP_DISTANCE : DESKTOP_SNAP_DISTANCE;
|
|
34641
|
-
this.edgesCache = new WeakMap();
|
|
34642
|
-
}
|
|
34643
|
-
isMobile() {
|
|
34644
|
-
if (typeof navigator === "undefined")
|
|
34645
|
-
return false;
|
|
34646
|
-
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
|
|
34647
|
-
}
|
|
34648
|
-
getMousePosition(event, target) {
|
|
34649
|
-
return target.set(event.clientX, event.clientY);
|
|
34650
|
-
}
|
|
34651
|
-
getPointerIntersects(mouse, objects) {
|
|
34652
|
-
const rect = this.canvas.getBoundingClientRect();
|
|
34653
|
-
const x = ((mouse.x - rect.left) / rect.width) * 2 - 1;
|
|
34654
|
-
const y = (-(mouse.y - rect.top) / rect.height) * 2 + 1;
|
|
34655
|
-
const coords = new Vector2(x, y);
|
|
34656
|
-
this.raycaster.setFromCamera(coords, this.camera);
|
|
34657
|
-
this.raycaster.params = {
|
|
34658
|
-
Mesh: {},
|
|
34659
|
-
Line: { threshold: this.threshold },
|
|
34660
|
-
Line2: { threshold: this.threshold },
|
|
34661
|
-
LOD: {},
|
|
34662
|
-
Points: { threshold: this.threshold },
|
|
34663
|
-
Sprite: {},
|
|
34664
|
-
};
|
|
34665
|
-
let intersects = this.raycaster.intersectObjects(objects, false);
|
|
34666
|
-
(this.renderer.clippingPlanes || []).forEach((plane) => {
|
|
34667
|
-
intersects = intersects.filter((intersect) => plane.distanceToPoint(intersect.point) >= 0);
|
|
34668
|
-
});
|
|
34669
|
-
return intersects;
|
|
34670
|
-
}
|
|
34671
|
-
getDetectRadius(point) {
|
|
34672
|
-
const camera = this.camera;
|
|
34673
|
-
if (camera.isOrthographicCamera) {
|
|
34674
|
-
const fieldHeight = (camera.top - camera.bottom) / camera.zoom;
|
|
34675
|
-
const canvasHeight = this.canvas.height;
|
|
34676
|
-
const worldUnitsPerPixel = fieldHeight / canvasHeight;
|
|
34677
|
-
return this.detectRadiusInPixels * worldUnitsPerPixel;
|
|
34678
|
-
}
|
|
34679
|
-
if (camera.isPerspectiveCamera) {
|
|
34680
|
-
const distance = camera.position.distanceTo(point);
|
|
34681
|
-
const fieldHeight = 2 * Math.tan(MathUtils.degToRad(camera.fov * 0.5)) * distance;
|
|
34682
|
-
const canvasHeight = this.canvas.height;
|
|
34683
|
-
const worldUnitsPerPixel = fieldHeight / canvasHeight;
|
|
34684
|
-
return this.detectRadiusInPixels * worldUnitsPerPixel;
|
|
34685
|
-
}
|
|
34686
|
-
return 0.1;
|
|
34687
|
-
}
|
|
34688
|
-
getSnapPoint(mouse, objects) {
|
|
34689
|
-
const intersections = this.getPointerIntersects(mouse, objects);
|
|
34690
|
-
if (intersections.length === 0)
|
|
34691
|
-
return undefined;
|
|
34692
|
-
const object = intersections[0].object;
|
|
34693
|
-
const intersectionPoint = intersections[0].point;
|
|
34694
|
-
const localPoint = object.worldToLocal(intersectionPoint.clone());
|
|
34695
|
-
let snapPoint;
|
|
34696
|
-
let snapDistance = this.getDetectRadius(intersectionPoint);
|
|
34697
|
-
const geometry = object.geometry;
|
|
34698
|
-
const positions = geometry.attributes.position.array;
|
|
34699
|
-
for (let i = 0; i < positions.length; i += 3) {
|
|
34700
|
-
_vertex.set(positions[i], positions[i + 1], positions[i + 2]);
|
|
34701
|
-
const distance = _vertex.distanceTo(localPoint);
|
|
34702
|
-
if (distance < snapDistance) {
|
|
34703
|
-
snapDistance = distance;
|
|
34704
|
-
snapPoint = _vertex.clone();
|
|
34705
|
-
}
|
|
34706
|
-
}
|
|
34707
|
-
if (snapPoint)
|
|
34708
|
-
return object.localToWorld(snapPoint);
|
|
34709
|
-
let edges = this.edgesCache.get(geometry);
|
|
34710
|
-
if (!edges) {
|
|
34711
|
-
edges = new EdgesGeometry(geometry);
|
|
34712
|
-
this.edgesCache.set(geometry, edges);
|
|
34713
|
-
}
|
|
34714
|
-
const edgePositions = edges.attributes.position.array;
|
|
34715
|
-
for (let i = 0; i < edgePositions.length; i += 6) {
|
|
34716
|
-
_start$1.set(edgePositions[i], edgePositions[i + 1], edgePositions[i + 2]);
|
|
34717
|
-
_end$1.set(edgePositions[i + 3], edgePositions[i + 4], edgePositions[i + 5]);
|
|
34718
|
-
_line.set(_start$1, _end$1);
|
|
34719
|
-
_line.getCenter(_center);
|
|
34720
|
-
const centerDistance = _center.distanceTo(localPoint);
|
|
34721
|
-
if (centerDistance < snapDistance) {
|
|
34722
|
-
snapDistance = centerDistance;
|
|
34723
|
-
snapPoint = _center.clone();
|
|
34724
|
-
continue;
|
|
34725
|
-
}
|
|
34726
|
-
_line.closestPointToPoint(localPoint, true, _projection);
|
|
34727
|
-
const lineDistance = _projection.distanceTo(localPoint);
|
|
34728
|
-
if (lineDistance < snapDistance) {
|
|
34729
|
-
snapDistance = lineDistance;
|
|
34730
|
-
snapPoint = _projection.clone();
|
|
34731
|
-
}
|
|
34732
|
-
}
|
|
34733
|
-
if (snapPoint)
|
|
34734
|
-
return object.localToWorld(snapPoint);
|
|
34735
|
-
return intersectionPoint.clone();
|
|
34736
|
-
}
|
|
34737
|
-
}
|
|
34738
|
-
|
|
34739
34882
|
const _downPoint = new Vector2();
|
|
34740
34883
|
class MeasureLineDragger extends OrbitDragger {
|
|
34741
34884
|
constructor(viewer) {
|
|
@@ -35147,6 +35290,12 @@ void main() {
|
|
|
35147
35290
|
this.movementSpeed = 0.1;
|
|
35148
35291
|
this.multiplier = 3;
|
|
35149
35292
|
this.groundFollowingSkippedFrames = 0;
|
|
35293
|
+
this.GROUND_BOX_HALF_SIZE = 20;
|
|
35294
|
+
this.GROUND_BOX_REFRESH_THRESHOLD = 0.3;
|
|
35295
|
+
this._groundObjectBoxes = new Map();
|
|
35296
|
+
this._activeGroundObjects = [];
|
|
35297
|
+
this._groundBox = new Box3();
|
|
35298
|
+
this._groundBoxCenter = new Vector3();
|
|
35150
35299
|
this.moveWheel = 0;
|
|
35151
35300
|
this.mouseDragOn = false;
|
|
35152
35301
|
this._up = new Vector3();
|
|
@@ -35213,11 +35362,20 @@ void main() {
|
|
|
35213
35362
|
}
|
|
35214
35363
|
};
|
|
35215
35364
|
this.onKeyUp = (event) => {
|
|
35216
|
-
if (this.moveKeys.delete(event.code))
|
|
35365
|
+
if (this.moveKeys.delete(event.code)) {
|
|
35366
|
+
if (this.moveKeys.size === 0) {
|
|
35367
|
+
this._rebuildGroundBox(this.object.position);
|
|
35368
|
+
}
|
|
35217
35369
|
this.update();
|
|
35370
|
+
}
|
|
35218
35371
|
};
|
|
35219
35372
|
this.camera = camera;
|
|
35220
35373
|
this.groundObjects = groundObjects;
|
|
35374
|
+
for (const obj of groundObjects) {
|
|
35375
|
+
this._groundObjectBoxes.set(obj, new Box3().setFromObject(obj));
|
|
35376
|
+
}
|
|
35377
|
+
const pos = this.object.position;
|
|
35378
|
+
this._rebuildGroundBox(pos);
|
|
35221
35379
|
this.raycaster = new Raycaster();
|
|
35222
35380
|
this.raycaster.near = 0;
|
|
35223
35381
|
this.raycaster.far = this.EYE_HEIGHT + this.FAILING_DISTANCE;
|
|
@@ -35252,10 +35410,29 @@ void main() {
|
|
|
35252
35410
|
window.removeEventListener("keyup", this.onKeyUp);
|
|
35253
35411
|
super.dispose();
|
|
35254
35412
|
}
|
|
35413
|
+
_rebuildGroundBox(center) {
|
|
35414
|
+
const h = this.GROUND_BOX_HALF_SIZE;
|
|
35415
|
+
this._groundBoxCenter.copy(center);
|
|
35416
|
+
this._groundBox.set(new Vector3(center.x - h, center.y - h * 4, center.z - h), new Vector3(center.x + h, center.y + h * 4, center.z + h));
|
|
35417
|
+
this._activeGroundObjects = this.groundObjects.filter((obj) => {
|
|
35418
|
+
const objectBox = this._groundObjectBoxes.get(obj);
|
|
35419
|
+
return objectBox !== undefined && this._groundBox.intersectsBox(objectBox);
|
|
35420
|
+
});
|
|
35421
|
+
}
|
|
35422
|
+
_needsGroundBoxRebuild(pos) {
|
|
35423
|
+
if (this._activeGroundObjects.length === 0 && this.groundObjects.length > 0)
|
|
35424
|
+
return true;
|
|
35425
|
+
const threshold = this.GROUND_BOX_HALF_SIZE * this.GROUND_BOX_REFRESH_THRESHOLD;
|
|
35426
|
+
return (Math.abs(pos.x - this._groundBoxCenter.x) > threshold || Math.abs(pos.z - this._groundBoxCenter.z) > threshold);
|
|
35427
|
+
}
|
|
35255
35428
|
updateGroundFollowing() {
|
|
35429
|
+
const pos = this.object.position;
|
|
35430
|
+
if (this._needsGroundBoxRebuild(pos)) {
|
|
35431
|
+
this._rebuildGroundBox(pos);
|
|
35432
|
+
}
|
|
35256
35433
|
this._up.copy(this.camera.up).negate();
|
|
35257
|
-
this.raycaster.set(
|
|
35258
|
-
const intersects = this.raycaster.intersectObjects(this.
|
|
35434
|
+
this.raycaster.set(pos, this._up);
|
|
35435
|
+
const intersects = this.raycaster.intersectObjects(this._activeGroundObjects, false);
|
|
35259
35436
|
if (intersects.length > 0) {
|
|
35260
35437
|
const groundY = intersects[0].point.y;
|
|
35261
35438
|
const targetY = groundY + this.EYE_HEIGHT;
|
|
@@ -35807,6 +35984,7 @@ void main() {
|
|
|
35807
35984
|
draggers.registerDragger("Orbit", (viewer) => new OrbitDragger(viewer));
|
|
35808
35985
|
draggers.registerDragger("Zoom", (viewer) => new ZoomDragger(viewer));
|
|
35809
35986
|
draggers.registerDragger("MeasureLine", (viewer) => new MeasureLineDragger(viewer));
|
|
35987
|
+
draggers.registerDragger("CuttingPlane", (viewer) => new CuttingPlaneDragger(viewer));
|
|
35810
35988
|
draggers.registerDragger("CuttingPlaneXAxis", (viewer) => new CuttingPlaneXAxisDragger(viewer));
|
|
35811
35989
|
draggers.registerDragger("CuttingPlaneYAxis", (viewer) => new CuttingPlaneYAxisDragger(viewer));
|
|
35812
35990
|
draggers.registerDragger("CuttingPlaneZAxis", (viewer) => new CuttingPlaneZAxisDragger(viewer));
|
|
@@ -37341,7 +37519,7 @@ void main() {
|
|
|
37341
37519
|
this.getMousePosition(event, this.downPosition);
|
|
37342
37520
|
};
|
|
37343
37521
|
this.onPointerUp = (event) => {
|
|
37344
|
-
if (!event.isPrimary)
|
|
37522
|
+
if (!event.isPrimary || event.button !== 0)
|
|
37345
37523
|
return;
|
|
37346
37524
|
const upPosition = this.getMousePosition(event, new Vector2());
|
|
37347
37525
|
if (upPosition.distanceTo(this.downPosition) !== 0)
|
|
@@ -37870,19 +38048,19 @@ void main() {
|
|
|
37870
38048
|
return this;
|
|
37871
38049
|
}
|
|
37872
38050
|
explode(scale = 0, coeff = 4) {
|
|
37873
|
-
const
|
|
37874
|
-
const
|
|
38051
|
+
const centersCache = new Map();
|
|
38052
|
+
const calcObjectCenter = (object, target) => {
|
|
37875
38053
|
const extents = new Box3().setFromObject(object);
|
|
37876
38054
|
const handle = object.userData.handle;
|
|
37877
38055
|
if (!handle)
|
|
37878
38056
|
return extents.getCenter(target);
|
|
37879
|
-
const center =
|
|
38057
|
+
const center = centersCache.get(handle);
|
|
37880
38058
|
if (center)
|
|
37881
38059
|
return target.copy(center);
|
|
37882
38060
|
const objects = this.getObjectsByHandles(handle);
|
|
37883
38061
|
objects.forEach((x) => extents.expandByObject(x));
|
|
37884
38062
|
extents.getCenter(target);
|
|
37885
|
-
|
|
38063
|
+
centersCache.set(handle, target.clone());
|
|
37886
38064
|
return target;
|
|
37887
38065
|
};
|
|
37888
38066
|
function calcExplodeDepth(object, depth) {
|
|
@@ -37893,13 +38071,14 @@ void main() {
|
|
|
37893
38071
|
result = objectDepth;
|
|
37894
38072
|
});
|
|
37895
38073
|
object.userData.originalPosition = object.position.clone();
|
|
37896
|
-
object.userData.originalCenter =
|
|
38074
|
+
object.userData.originalCenter = calcObjectCenter(object, new Vector3());
|
|
37897
38075
|
return result;
|
|
37898
38076
|
}
|
|
37899
38077
|
const explodeScale = scale / 100;
|
|
37900
38078
|
const explodeRoot = this.scene;
|
|
37901
|
-
if (!explodeRoot.userData.explodeDepth)
|
|
38079
|
+
if (!explodeRoot.userData.explodeDepth) {
|
|
37902
38080
|
explodeRoot.userData.explodeDepth = calcExplodeDepth(explodeRoot, 1);
|
|
38081
|
+
}
|
|
37903
38082
|
const maxDepth = explodeRoot.userData.explodeDepth;
|
|
37904
38083
|
const scaledExplodeDepth = explodeScale * maxDepth + 1;
|
|
37905
38084
|
const explodeDepth = 0 | scaledExplodeDepth;
|
|
@@ -37916,8 +38095,8 @@ void main() {
|
|
|
37916
38095
|
objectScale *= currentSegmentFraction;
|
|
37917
38096
|
const parentCenter = object.parent.userData.originalCenter;
|
|
37918
38097
|
const objectCenter = object.userData.originalCenter;
|
|
37919
|
-
const
|
|
37920
|
-
object.position.add(
|
|
38098
|
+
const localOffset = objectCenter.clone().sub(parentCenter).multiplyScalar(objectScale);
|
|
38099
|
+
object.position.add(localOffset);
|
|
37921
38100
|
}
|
|
37922
38101
|
object.children.forEach((x) => explodeObject(x, depth + 1));
|
|
37923
38102
|
}
|
|
@@ -38009,67 +38188,73 @@ void main() {
|
|
|
38009
38188
|
return this;
|
|
38010
38189
|
}
|
|
38011
38190
|
explode(scale = 0, coeff = 4) {
|
|
38012
|
-
const
|
|
38191
|
+
const centersCache = new Map();
|
|
38013
38192
|
const calcObjectCenter = (object, target) => {
|
|
38014
38193
|
const extents = new Box3().setFromObject(object);
|
|
38015
38194
|
const handle = object.userData.handle;
|
|
38016
38195
|
if (!handle)
|
|
38017
38196
|
return extents.getCenter(target);
|
|
38018
|
-
const center =
|
|
38197
|
+
const center = centersCache.get(handle);
|
|
38019
38198
|
if (center)
|
|
38020
38199
|
return target.copy(center);
|
|
38021
38200
|
const objects = this.getObjectsByHandles(handle);
|
|
38022
38201
|
objects.forEach((x) => extents.expandByObject(x));
|
|
38023
38202
|
extents.getCenter(target);
|
|
38024
|
-
|
|
38203
|
+
centersCache.set(handle, target.clone());
|
|
38025
38204
|
return target;
|
|
38026
38205
|
};
|
|
38027
|
-
|
|
38028
|
-
|
|
38029
|
-
|
|
38030
|
-
|
|
38031
|
-
|
|
38032
|
-
|
|
38033
|
-
if (result < objectDepth)
|
|
38034
|
-
result = objectDepth;
|
|
38035
|
-
});
|
|
38206
|
+
const calcObjectDepth = (object) => {
|
|
38207
|
+
if (object.userData.depth !== undefined)
|
|
38208
|
+
return object.userData.depth;
|
|
38209
|
+
const parent = object.parent;
|
|
38210
|
+
const depth = parent && object !== explodeRoot ? calcObjectDepth(parent) + 1 : 0;
|
|
38211
|
+
object.userData.depth = depth;
|
|
38036
38212
|
object.userData.originalPosition = object.position.clone();
|
|
38037
38213
|
object.userData.originalCenter = calcObjectCenter(object, new Vector3());
|
|
38038
|
-
return
|
|
38039
|
-
}
|
|
38214
|
+
return depth;
|
|
38215
|
+
};
|
|
38040
38216
|
const explodeScale = scale / 100;
|
|
38041
38217
|
const explodeRoot = this.scene.children[0];
|
|
38042
|
-
if (!explodeRoot.userData.explodeDepth)
|
|
38043
|
-
|
|
38218
|
+
if (!explodeRoot.userData.explodeDepth) {
|
|
38219
|
+
let maxDepth = 0;
|
|
38220
|
+
this.gltfLoader.originalObjects.forEach((object) => {
|
|
38221
|
+
const depth = calcObjectDepth(object);
|
|
38222
|
+
if (depth > maxDepth)
|
|
38223
|
+
maxDepth = depth;
|
|
38224
|
+
});
|
|
38225
|
+
explodeRoot.userData.explodeDepth = maxDepth;
|
|
38226
|
+
}
|
|
38044
38227
|
const maxDepth = explodeRoot.userData.explodeDepth;
|
|
38045
38228
|
const scaledExplodeDepth = explodeScale * maxDepth + 1;
|
|
38046
38229
|
const explodeDepth = 0 | scaledExplodeDepth;
|
|
38047
38230
|
const currentSegmentFraction = scaledExplodeDepth - explodeDepth;
|
|
38048
|
-
const
|
|
38049
|
-
|
|
38050
|
-
if (object
|
|
38051
|
-
return;
|
|
38052
|
-
|
|
38053
|
-
|
|
38054
|
-
|
|
38055
|
-
|
|
38231
|
+
const offsetCache = new Map();
|
|
38232
|
+
const calcObjectOffset = (object, target) => {
|
|
38233
|
+
if (offsetCache.has(object))
|
|
38234
|
+
return target.copy(offsetCache.get(object));
|
|
38235
|
+
const parent = object.parent;
|
|
38236
|
+
if (parent && object !== explodeRoot)
|
|
38237
|
+
calcObjectOffset(parent, target);
|
|
38238
|
+
const depth = object.userData.depth;
|
|
38239
|
+
if (depth > 0 && depth <= explodeDepth) {
|
|
38056
38240
|
let objectScale = explodeScale * coeff;
|
|
38057
38241
|
if (depth === explodeDepth)
|
|
38058
38242
|
objectScale *= currentSegmentFraction;
|
|
38059
|
-
const parentCenter =
|
|
38243
|
+
const parentCenter = parent.userData.originalCenter;
|
|
38060
38244
|
const objectCenter = object.userData.originalCenter;
|
|
38061
|
-
const
|
|
38062
|
-
|
|
38063
|
-
const matrix = new Matrix4().makeTranslation(objectOffset.x, objectOffset.y, objectOffset.z);
|
|
38064
|
-
transformMap.set(object, matrix);
|
|
38245
|
+
const localOffset = objectCenter.clone().sub(parentCenter).multiplyScalar(objectScale);
|
|
38246
|
+
target.add(localOffset);
|
|
38065
38247
|
}
|
|
38066
|
-
object.
|
|
38067
|
-
|
|
38068
|
-
|
|
38069
|
-
|
|
38070
|
-
|
|
38071
|
-
|
|
38248
|
+
offsetCache.set(object, target.clone());
|
|
38249
|
+
return target;
|
|
38250
|
+
};
|
|
38251
|
+
const transformMap = new Map();
|
|
38252
|
+
this.gltfLoader.originalObjects.forEach((object) => {
|
|
38253
|
+
const globalOffset = calcObjectOffset(object, new Vector3());
|
|
38254
|
+
transformMap.set(object, new Matrix4().makeTranslation(globalOffset));
|
|
38255
|
+
});
|
|
38072
38256
|
this.gltfLoader.applyObjectTransforms(transformMap);
|
|
38257
|
+
this.scene.updateMatrixWorld();
|
|
38073
38258
|
return this;
|
|
38074
38259
|
}
|
|
38075
38260
|
}
|
|
@@ -38795,6 +38980,8 @@ void main() {
|
|
|
38795
38980
|
this.oldOptimizeObjects = new Set();
|
|
38796
38981
|
this.objectTransforms = new Map();
|
|
38797
38982
|
this.transformedGeometries = new Map();
|
|
38983
|
+
this.syncTransformsToOriginalObjects = true;
|
|
38984
|
+
this._originalObjectMatrices = new Map();
|
|
38798
38985
|
this.activeChunkLoads = 0;
|
|
38799
38986
|
this.chunkQueue = [];
|
|
38800
38987
|
this.objectIdToIndex = new Map();
|
|
@@ -38804,6 +38991,81 @@ void main() {
|
|
|
38804
38991
|
this.mergedObjectMap = new Map();
|
|
38805
38992
|
this.mergedGeometryVisibility = new Map();
|
|
38806
38993
|
this._webglInfoCache = null;
|
|
38994
|
+
this.transformTextureSize = 1024;
|
|
38995
|
+
this.transformTexture = this.createDummyTexture();
|
|
38996
|
+
this.transformData = null;
|
|
38997
|
+
this.identityTransformData = null;
|
|
38998
|
+
this.visibilityMaterials = new Set();
|
|
38999
|
+
}
|
|
39000
|
+
createDummyTexture() {
|
|
39001
|
+
const data = new Float32Array(16);
|
|
39002
|
+
const identity = new Matrix4();
|
|
39003
|
+
identity.toArray(data);
|
|
39004
|
+
const dummyData = new Float32Array(16);
|
|
39005
|
+
identity.toArray(dummyData);
|
|
39006
|
+
const dummyTexture = new DataTexture(dummyData, 4, 1, RGBAFormat, FloatType);
|
|
39007
|
+
dummyTexture.minFilter = NearestFilter;
|
|
39008
|
+
dummyTexture.magFilter = NearestFilter;
|
|
39009
|
+
dummyTexture.needsUpdate = true;
|
|
39010
|
+
return dummyTexture;
|
|
39011
|
+
}
|
|
39012
|
+
initTransformTexture() {
|
|
39013
|
+
if (this.transformTexture) {
|
|
39014
|
+
this.transformTexture.dispose();
|
|
39015
|
+
}
|
|
39016
|
+
const maxInstanceCount = this.maxObjectId + 1;
|
|
39017
|
+
let size = Math.sqrt(maxInstanceCount * 4);
|
|
39018
|
+
size = Math.ceil(size / 4) * 4;
|
|
39019
|
+
size = Math.max(size, 4);
|
|
39020
|
+
this.transformTextureSize = size;
|
|
39021
|
+
const arraySize = size * size * 4;
|
|
39022
|
+
this.transformData = new Float32Array(arraySize);
|
|
39023
|
+
this.identityTransformData = new Float32Array(arraySize);
|
|
39024
|
+
for (let i = 0; i <= this.maxObjectId; i++) {
|
|
39025
|
+
const base = i * 16;
|
|
39026
|
+
if (base + 15 < arraySize) {
|
|
39027
|
+
this.identityTransformData[base + 0] = 1;
|
|
39028
|
+
this.identityTransformData[base + 5] = 1;
|
|
39029
|
+
this.identityTransformData[base + 10] = 1;
|
|
39030
|
+
this.identityTransformData[base + 15] = 1;
|
|
39031
|
+
}
|
|
39032
|
+
}
|
|
39033
|
+
this._resetTransformData(false);
|
|
39034
|
+
this.transformTexture = new DataTexture(this.transformData, size, size, RGBAFormat, FloatType);
|
|
39035
|
+
this.transformTexture.needsUpdate = true;
|
|
39036
|
+
this.transformTexture.generateMipmaps = false;
|
|
39037
|
+
console.log(`Initialized transform texture: ${size}x${size} for ${maxInstanceCount} objects`);
|
|
39038
|
+
this.updateMaterialUniforms();
|
|
39039
|
+
this.visibilityMaterials.forEach((material) => {
|
|
39040
|
+
material.needsUpdate = true;
|
|
39041
|
+
});
|
|
39042
|
+
}
|
|
39043
|
+
_resetTransformData(updateTexture = true) {
|
|
39044
|
+
if (!this.transformData || !this.identityTransformData) return;
|
|
39045
|
+
this.transformData.set(this.identityTransformData);
|
|
39046
|
+
if (updateTexture) {
|
|
39047
|
+
this.updateTransformTexture();
|
|
39048
|
+
}
|
|
39049
|
+
}
|
|
39050
|
+
updateMaterialUniforms() {
|
|
39051
|
+
if (
|
|
39052
|
+
this._lastTransformTexture === this.transformTexture &&
|
|
39053
|
+
this._lastTransformTextureSize === this.transformTextureSize
|
|
39054
|
+
) {
|
|
39055
|
+
return;
|
|
39056
|
+
}
|
|
39057
|
+
this._lastTransformTexture = this.transformTexture;
|
|
39058
|
+
this._lastTransformTextureSize = this.transformTextureSize;
|
|
39059
|
+
this.visibilityMaterials.forEach((material) => {
|
|
39060
|
+
if (material.userData && material.userData.visibilityUniforms) {
|
|
39061
|
+
material.userData.visibilityUniforms.transformTexture.value = this.transformTexture;
|
|
39062
|
+
material.userData.visibilityUniforms.transformTextureSize.value = this.transformTextureSize;
|
|
39063
|
+
}
|
|
39064
|
+
});
|
|
39065
|
+
}
|
|
39066
|
+
updateTransformTexture() {
|
|
39067
|
+
if (!this.transformTexture) return;
|
|
39068
|
+
this.transformTexture.needsUpdate = true;
|
|
38807
39069
|
}
|
|
38808
39070
|
setVisibleEdges(visible) {
|
|
38809
39071
|
this.visibleEdges = visible;
|
|
@@ -39693,36 +39955,82 @@ void main() {
|
|
|
39693
39955
|
}
|
|
39694
39956
|
}
|
|
39695
39957
|
createVisibilityMaterial(material) {
|
|
39958
|
+
this.visibilityMaterials.add(material);
|
|
39959
|
+
const uniforms = {
|
|
39960
|
+
transformTexture: { value: this.transformTexture },
|
|
39961
|
+
transformTextureSize: { value: this.transformTextureSize },
|
|
39962
|
+
};
|
|
39963
|
+
material.userData.visibilityUniforms = uniforms;
|
|
39696
39964
|
material.onBeforeCompile = (shader) => {
|
|
39965
|
+
shader.uniforms.transformTexture = uniforms.transformTexture;
|
|
39966
|
+
shader.uniforms.transformTextureSize = uniforms.transformTextureSize;
|
|
39697
39967
|
shader.vertexShader = shader.vertexShader.replace(
|
|
39698
39968
|
"#include <common>",
|
|
39699
39969
|
`
|
|
39700
39970
|
#include <common>
|
|
39971
|
+
|
|
39701
39972
|
attribute float visibility;
|
|
39973
|
+
attribute float objectId;
|
|
39702
39974
|
varying float vVisibility;
|
|
39703
|
-
|
|
39704
|
-
|
|
39705
|
-
|
|
39706
|
-
|
|
39707
|
-
|
|
39708
|
-
|
|
39709
|
-
|
|
39975
|
+
uniform highp sampler2D transformTexture;
|
|
39976
|
+
uniform float transformTextureSize;
|
|
39977
|
+
|
|
39978
|
+
mat4 getTransformMatrix(float instanceId) {
|
|
39979
|
+
int size = int(transformTextureSize);
|
|
39980
|
+
int index = int(instanceId) * 4;
|
|
39981
|
+
|
|
39982
|
+
int x0 = index % size;
|
|
39983
|
+
int y0 = index / size;
|
|
39984
|
+
|
|
39985
|
+
vec4 row0 = texelFetch(transformTexture, ivec2(x0, y0), 0);
|
|
39986
|
+
vec4 row1 = texelFetch(transformTexture, ivec2(x0 + 1, y0), 0);
|
|
39987
|
+
vec4 row2 = texelFetch(transformTexture, ivec2(x0 + 2, y0), 0);
|
|
39988
|
+
vec4 row3 = texelFetch(transformTexture, ivec2(x0 + 3, y0), 0);
|
|
39989
|
+
|
|
39990
|
+
return mat4(row0, row1, row2, row3);
|
|
39991
|
+
}
|
|
39710
39992
|
`
|
|
39711
39993
|
);
|
|
39712
39994
|
shader.vertexShader = shader.vertexShader.replace(
|
|
39713
39995
|
"void main() {",
|
|
39714
39996
|
`
|
|
39715
39997
|
void main() {
|
|
39716
|
-
|
|
39998
|
+
mat4 batchingMatrix = getTransformMatrix(objectId);
|
|
39999
|
+
vVisibility = visibility;
|
|
39717
40000
|
`
|
|
39718
40001
|
);
|
|
39719
|
-
|
|
39720
|
-
|
|
40002
|
+
if (shader.vertexShader.includes("#include <beginnormal_vertex>")) {
|
|
40003
|
+
shader.vertexShader = shader.vertexShader.replace(
|
|
40004
|
+
"#include <beginnormal_vertex>",
|
|
40005
|
+
`
|
|
40006
|
+
vec3 objectNormal = vec3( normal );
|
|
40007
|
+
mat3 bm = mat3( batchingMatrix );
|
|
40008
|
+
objectNormal = bm * objectNormal;
|
|
39721
40009
|
`
|
|
40010
|
+
);
|
|
40011
|
+
}
|
|
40012
|
+
shader.vertexShader = shader.vertexShader.replace(
|
|
40013
|
+
"#include <begin_vertex>",
|
|
40014
|
+
`
|
|
40015
|
+
vec3 transformed = vec3( position );
|
|
40016
|
+
transformed = ( batchingMatrix * vec4( transformed, 1.0 ) ).xyz;
|
|
40017
|
+
`
|
|
40018
|
+
);
|
|
40019
|
+
shader.fragmentShader = shader.fragmentShader
|
|
40020
|
+
.replace(
|
|
40021
|
+
"#include <common>",
|
|
40022
|
+
`
|
|
40023
|
+
#include <common>
|
|
40024
|
+
varying float vVisibility;
|
|
40025
|
+
`
|
|
40026
|
+
)
|
|
40027
|
+
.replace(
|
|
40028
|
+
"void main() {",
|
|
40029
|
+
`
|
|
39722
40030
|
void main() {
|
|
39723
40031
|
if (vVisibility < 0.5) discard;
|
|
39724
40032
|
`
|
|
39725
|
-
|
|
40033
|
+
);
|
|
39726
40034
|
};
|
|
39727
40035
|
material.needsUpdate = true;
|
|
39728
40036
|
return material;
|
|
@@ -39828,6 +40136,7 @@ void main() {
|
|
|
39828
40136
|
this.isolatedObjects = [];
|
|
39829
40137
|
this.objectTransforms.clear();
|
|
39830
40138
|
this.transformedGeometries.clear();
|
|
40139
|
+
this._originalObjectMatrices.clear();
|
|
39831
40140
|
this.totalLoadedObjects = 0;
|
|
39832
40141
|
this.currentMemoryUsage = 0;
|
|
39833
40142
|
this.pendingMemoryUsage = 0;
|
|
@@ -39837,6 +40146,8 @@ void main() {
|
|
|
39837
40146
|
this.objectIdToIndex.clear();
|
|
39838
40147
|
this.maxObjectId = 0;
|
|
39839
40148
|
this.objectVisibility = new Float32Array();
|
|
40149
|
+
this.meshToNodeMap = null;
|
|
40150
|
+
this.visibilityMaterials.clear();
|
|
39840
40151
|
}
|
|
39841
40152
|
setStructureTransform(structureId, matrix) {
|
|
39842
40153
|
const rootGroup = this.structureRoots.get(structureId);
|
|
@@ -39952,12 +40263,15 @@ void main() {
|
|
|
39952
40263
|
});
|
|
39953
40264
|
this.originalObjects.clear();
|
|
39954
40265
|
this.originalObjectsToSelection.clear();
|
|
40266
|
+
this.objectIdToIndex.clear();
|
|
40267
|
+
this.maxObjectId = 0;
|
|
39955
40268
|
const structureGroups = new Map();
|
|
39956
40269
|
this.dispatchEvent("optimizationprogress", {
|
|
39957
40270
|
phase: "collecting",
|
|
39958
40271
|
progress: 5,
|
|
39959
40272
|
message: "Collecting scene objects...",
|
|
39960
40273
|
});
|
|
40274
|
+
let totalObjectsToMerge = 0;
|
|
39961
40275
|
this.scene.traverse((object) => {
|
|
39962
40276
|
if (object.userData.structureId) {
|
|
39963
40277
|
const structureId = object.userData.structureId;
|
|
@@ -39975,17 +40289,32 @@ void main() {
|
|
|
39975
40289
|
});
|
|
39976
40290
|
}
|
|
39977
40291
|
const group = structureGroups.get(structureId);
|
|
40292
|
+
let added = false;
|
|
39978
40293
|
if (object instanceof Mesh) {
|
|
39979
40294
|
this.addToMaterialGroup(object, group.mapMeshes, group.meshes);
|
|
40295
|
+
added = true;
|
|
39980
40296
|
} else if (object instanceof LineSegments) {
|
|
39981
40297
|
this.addToMaterialGroup(object, group.mapLineSegments, group.lineSegments);
|
|
40298
|
+
added = true;
|
|
39982
40299
|
} else if (object instanceof Line$1) {
|
|
39983
40300
|
this.addToMaterialGroup(object, group.mapLines, group.lines);
|
|
40301
|
+
added = true;
|
|
39984
40302
|
} else if (object instanceof Points) {
|
|
39985
40303
|
this.addToMaterialGroup(object, group.mapPoints, group.points);
|
|
40304
|
+
added = true;
|
|
40305
|
+
}
|
|
40306
|
+
if (added) {
|
|
40307
|
+
totalObjectsToMerge++;
|
|
39986
40308
|
}
|
|
39987
40309
|
}
|
|
39988
40310
|
});
|
|
40311
|
+
if (totalObjectsToMerge > 0) {
|
|
40312
|
+
console.log(`Pre-allocating transform texture for ${totalObjectsToMerge} objects`);
|
|
40313
|
+
this.maxObjectId = totalObjectsToMerge;
|
|
40314
|
+
this.initTransformTexture();
|
|
40315
|
+
this.initializeObjectVisibility();
|
|
40316
|
+
this.maxObjectId = 0;
|
|
40317
|
+
}
|
|
39989
40318
|
let processedGroups = 0;
|
|
39990
40319
|
const totalGroups = structureGroups.size;
|
|
39991
40320
|
this.dispatchEvent("optimizationprogress", {
|
|
@@ -40030,7 +40359,6 @@ void main() {
|
|
|
40030
40359
|
this.originalObjectsToSelection.add(obj);
|
|
40031
40360
|
}
|
|
40032
40361
|
});
|
|
40033
|
-
this.initializeObjectVisibility();
|
|
40034
40362
|
console.log(`Optimization complete. Total objects: ${this.maxObjectId}`);
|
|
40035
40363
|
this.dispatchEvent("optimizationprogress", {
|
|
40036
40364
|
phase: "complete",
|
|
@@ -40099,6 +40427,7 @@ void main() {
|
|
|
40099
40427
|
}
|
|
40100
40428
|
const visibilityMaterial = this.createVisibilityMaterial(group.material);
|
|
40101
40429
|
const mergedMesh = new Mesh(mergedGeometry, visibilityMaterial);
|
|
40430
|
+
mergedMesh.frustumCulled = false;
|
|
40102
40431
|
mergedMesh.userData.isOptimized = true;
|
|
40103
40432
|
rootGroup.add(mergedMesh);
|
|
40104
40433
|
this.mergedMesh.add(mergedMesh);
|
|
@@ -40215,6 +40544,7 @@ void main() {
|
|
|
40215
40544
|
geometry.setAttribute("visibility", new BufferAttribute(visibilityArray, 1));
|
|
40216
40545
|
const visibilityMaterial = this.createVisibilityMaterial(group.material);
|
|
40217
40546
|
const mergedLine = new LineSegments(geometry, visibilityMaterial);
|
|
40547
|
+
mergedLine.frustumCulled = false;
|
|
40218
40548
|
mergedLine.userData.isEdge = isEdge;
|
|
40219
40549
|
mergedLine.userData.isOptimized = true;
|
|
40220
40550
|
const mergedObjects = [mergedLine];
|
|
@@ -40303,6 +40633,7 @@ void main() {
|
|
|
40303
40633
|
mergedGeometry.setAttribute("visibility", new BufferAttribute(visibilityArray, 1));
|
|
40304
40634
|
const visibilityMaterial = this.createVisibilityMaterial(group.material);
|
|
40305
40635
|
const mergedLine = new LineSegments(mergedGeometry, visibilityMaterial);
|
|
40636
|
+
mergedLine.frustumCulled = false;
|
|
40306
40637
|
mergedLine.userData.isEdge = isEdge;
|
|
40307
40638
|
mergedLine.userData.isOptimized = true;
|
|
40308
40639
|
if (this.useVAO) {
|
|
@@ -40372,7 +40703,27 @@ void main() {
|
|
|
40372
40703
|
const mergedObjects = [];
|
|
40373
40704
|
if (geometries.length > 0) {
|
|
40374
40705
|
const mergedGeometry = mergeGeometries(geometries, false);
|
|
40375
|
-
const
|
|
40706
|
+
const totalVertices = mergedGeometry.attributes.position.count;
|
|
40707
|
+
const objectIds = new Float32Array(totalVertices);
|
|
40708
|
+
let vertexOffset = 0;
|
|
40709
|
+
group.objects.forEach((points) => {
|
|
40710
|
+
const handle = points.userData.handle;
|
|
40711
|
+
if (!this.objectIdToIndex.has(handle)) {
|
|
40712
|
+
this.objectIdToIndex.set(handle, this.maxObjectId++);
|
|
40713
|
+
}
|
|
40714
|
+
const objectId = this.objectIdToIndex.get(handle);
|
|
40715
|
+
const count = points.geometry.attributes.position.count;
|
|
40716
|
+
for (let i = 0; i < count; i++) {
|
|
40717
|
+
objectIds[vertexOffset++] = objectId;
|
|
40718
|
+
}
|
|
40719
|
+
});
|
|
40720
|
+
mergedGeometry.setAttribute("objectId", new BufferAttribute(objectIds, 1));
|
|
40721
|
+
const visibilityArray = new Float32Array(totalVertices);
|
|
40722
|
+
visibilityArray.fill(1.0);
|
|
40723
|
+
mergedGeometry.setAttribute("visibility", new BufferAttribute(visibilityArray, 1));
|
|
40724
|
+
const visibilityMaterial = this.createVisibilityMaterial(group.material);
|
|
40725
|
+
const mergedPoints = new Points(mergedGeometry, visibilityMaterial);
|
|
40726
|
+
mergedPoints.frustumCulled = false;
|
|
40376
40727
|
mergedPoints.userData.isOptimized = true;
|
|
40377
40728
|
if (this.useVAO) {
|
|
40378
40729
|
this.createVAO(mergedPoints);
|
|
@@ -40441,13 +40792,33 @@ void main() {
|
|
|
40441
40792
|
geometriesWithIndex.push(clonedGeometry);
|
|
40442
40793
|
});
|
|
40443
40794
|
const finalGeometry = mergeGeometries(geometriesWithIndex, false);
|
|
40795
|
+
const totalVertices = finalGeometry.attributes.position.count;
|
|
40796
|
+
const objectIds = new Float32Array(totalVertices);
|
|
40797
|
+
let vertexOffset = 0;
|
|
40798
|
+
lineSegmentsArray.forEach((segment) => {
|
|
40799
|
+
const handle = segment.userData.handle;
|
|
40800
|
+
if (!this.objectIdToIndex.has(handle)) {
|
|
40801
|
+
this.objectIdToIndex.set(handle, this.maxObjectId++);
|
|
40802
|
+
}
|
|
40803
|
+
const objectId = this.objectIdToIndex.get(handle);
|
|
40804
|
+
const count = segment.geometry.attributes.position.count;
|
|
40805
|
+
for (let i = 0; i < count; i++) {
|
|
40806
|
+
objectIds[vertexOffset++] = objectId;
|
|
40807
|
+
}
|
|
40808
|
+
});
|
|
40809
|
+
finalGeometry.setAttribute("objectId", new BufferAttribute(objectIds, 1));
|
|
40810
|
+
const visibilityArray = new Float32Array(totalVertices);
|
|
40811
|
+
visibilityArray.fill(1.0);
|
|
40812
|
+
finalGeometry.setAttribute("visibility", new BufferAttribute(visibilityArray, 1));
|
|
40444
40813
|
const material = new LineBasicMaterial({
|
|
40445
40814
|
vertexColors: true,
|
|
40446
40815
|
});
|
|
40816
|
+
const visibilityMaterial = this.createVisibilityMaterial(material);
|
|
40447
40817
|
if (this.useVAO) {
|
|
40448
40818
|
this.createVAO(finalGeometry);
|
|
40449
40819
|
}
|
|
40450
|
-
const mergedLine = new LineSegments(finalGeometry,
|
|
40820
|
+
const mergedLine = new LineSegments(finalGeometry, visibilityMaterial);
|
|
40821
|
+
mergedLine.frustumCulled = false;
|
|
40451
40822
|
mergedLine.userData.structureId = structureId;
|
|
40452
40823
|
mergedLine.userData.isOptimized = true;
|
|
40453
40824
|
rootGroup.add(mergedLine);
|
|
@@ -40566,18 +40937,91 @@ void main() {
|
|
|
40566
40937
|
console.warn("No merged objects to transform");
|
|
40567
40938
|
return;
|
|
40568
40939
|
}
|
|
40569
|
-
this.
|
|
40570
|
-
|
|
40571
|
-
|
|
40940
|
+
if (!this.transformData) {
|
|
40941
|
+
console.warn("Transform texture not initialized");
|
|
40942
|
+
return;
|
|
40572
40943
|
}
|
|
40573
|
-
|
|
40574
|
-
|
|
40944
|
+
this.objectTransforms = objectTransformMap;
|
|
40945
|
+
this._resetTransformData(false);
|
|
40946
|
+
const transformData = this.transformData;
|
|
40947
|
+
const objectIdToIndex = this.objectIdToIndex;
|
|
40948
|
+
let textureNeedsUpdate = false;
|
|
40949
|
+
if (objectTransformMap instanceof Map) {
|
|
40950
|
+
for (const [object, matrix] of objectTransformMap.entries()) {
|
|
40951
|
+
const userData = object.userData;
|
|
40952
|
+
if (!userData) continue;
|
|
40953
|
+
const handle = userData.handle;
|
|
40954
|
+
if (handle === undefined) continue;
|
|
40955
|
+
const objectId = objectIdToIndex.get(handle);
|
|
40956
|
+
if (objectId !== undefined) {
|
|
40957
|
+
transformData.set(matrix.elements, objectId * 16);
|
|
40958
|
+
textureNeedsUpdate = true;
|
|
40959
|
+
}
|
|
40960
|
+
}
|
|
40961
|
+
} else {
|
|
40962
|
+
const len = objectTransformMap.length;
|
|
40963
|
+
for (let i = 0; i < len; i++) {
|
|
40964
|
+
const pair = objectTransformMap[i];
|
|
40965
|
+
const userData = pair[0].userData;
|
|
40966
|
+
if (!userData) continue;
|
|
40967
|
+
const handle = userData.handle;
|
|
40968
|
+
if (handle === undefined) continue;
|
|
40969
|
+
const objectId = objectIdToIndex.get(handle);
|
|
40970
|
+
if (objectId !== undefined) {
|
|
40971
|
+
transformData.set(pair[1].elements, objectId * 16);
|
|
40972
|
+
textureNeedsUpdate = true;
|
|
40973
|
+
}
|
|
40974
|
+
}
|
|
40575
40975
|
}
|
|
40576
|
-
|
|
40577
|
-
this.
|
|
40976
|
+
if (textureNeedsUpdate) {
|
|
40977
|
+
this.updateTransformTexture();
|
|
40978
|
+
if (
|
|
40979
|
+
this._lastTransformTexture !== this.transformTexture ||
|
|
40980
|
+
this._lastTransformTextureSize !== this.transformTextureSize
|
|
40981
|
+
) {
|
|
40982
|
+
this.updateMaterialUniforms();
|
|
40983
|
+
}
|
|
40578
40984
|
}
|
|
40579
|
-
|
|
40580
|
-
this.
|
|
40985
|
+
if (this.syncTransformsToOriginalObjects) {
|
|
40986
|
+
this._syncOriginalObjectTransforms(objectTransformMap);
|
|
40987
|
+
}
|
|
40988
|
+
}
|
|
40989
|
+
_syncOriginalObjectTransforms(objectTransformMap) {
|
|
40990
|
+
for (const [obj, savedPos] of this._originalObjectMatrices) {
|
|
40991
|
+
obj.position.copy(savedPos);
|
|
40992
|
+
if (obj.userData.highlight) {
|
|
40993
|
+
obj.userData.highlight.position.copy(savedPos);
|
|
40994
|
+
}
|
|
40995
|
+
}
|
|
40996
|
+
this._originalObjectMatrices.clear();
|
|
40997
|
+
const _offset = new Vector3();
|
|
40998
|
+
const _parentInverse = new Matrix4();
|
|
40999
|
+
if (objectTransformMap instanceof Map) {
|
|
41000
|
+
for (const [object, matrix] of objectTransformMap.entries()) {
|
|
41001
|
+
if (!object.userData?.handle) continue;
|
|
41002
|
+
if (!this._originalObjectMatrices.has(object)) {
|
|
41003
|
+
this._originalObjectMatrices.set(object, object.position.clone());
|
|
41004
|
+
}
|
|
41005
|
+
_offset.setFromMatrixPosition(matrix);
|
|
41006
|
+
if (object.userData.structureId) {
|
|
41007
|
+
const rootGroup = this.structureRoots.get(object.userData.structureId);
|
|
41008
|
+
if (rootGroup && object.parent && object.parent !== rootGroup) {
|
|
41009
|
+
const origin = new Vector3(0, 0, 0);
|
|
41010
|
+
origin.applyMatrix4(rootGroup.matrixWorld);
|
|
41011
|
+
_offset.applyMatrix4(rootGroup.matrixWorld);
|
|
41012
|
+
_offset.sub(origin);
|
|
41013
|
+
const parentOrigin = new Vector3(0, 0, 0);
|
|
41014
|
+
_parentInverse.copy(object.parent.matrixWorld).invert();
|
|
41015
|
+
parentOrigin.applyMatrix4(_parentInverse);
|
|
41016
|
+
_offset.applyMatrix4(_parentInverse);
|
|
41017
|
+
_offset.sub(parentOrigin);
|
|
41018
|
+
}
|
|
41019
|
+
}
|
|
41020
|
+
object.position.add(_offset);
|
|
41021
|
+
if (object.userData.highlight) {
|
|
41022
|
+
object.userData.highlight.position.copy(object.position);
|
|
41023
|
+
}
|
|
41024
|
+
}
|
|
40581
41025
|
}
|
|
40582
41026
|
}
|
|
40583
41027
|
createExplodeTransforms(objects = null, explodeCenter = null, explodeFactor = 1.5) {
|
|
@@ -40594,21 +41038,66 @@ void main() {
|
|
|
40594
41038
|
? objects
|
|
40595
41039
|
: Array.from(objects)
|
|
40596
41040
|
: Array.from(this.originalObjects);
|
|
41041
|
+
const structureInverseMatrices = new Map();
|
|
41042
|
+
if (!this.meshToNodeMap) {
|
|
41043
|
+
this.meshToNodeMap = new Map();
|
|
41044
|
+
for (const node of this.nodes.values()) {
|
|
41045
|
+
if (node.object) {
|
|
41046
|
+
this.meshToNodeMap.set(node.object, node);
|
|
41047
|
+
}
|
|
41048
|
+
}
|
|
41049
|
+
}
|
|
40597
41050
|
for (const obj of objectsArray) {
|
|
40598
41051
|
if (!obj.geometry || !obj.geometry.attributes.position) continue;
|
|
40599
|
-
|
|
40600
|
-
|
|
40601
|
-
|
|
41052
|
+
if (!obj.userData.explodeVector) {
|
|
41053
|
+
let center = null;
|
|
41054
|
+
const node = this.meshToNodeMap.get(obj);
|
|
41055
|
+
if (node && node.geometryExtents) {
|
|
41056
|
+
const box = node.geometryExtents.clone();
|
|
41057
|
+
box.applyMatrix4(obj.matrixWorld);
|
|
41058
|
+
center = new Vector3();
|
|
41059
|
+
box.getCenter(center);
|
|
41060
|
+
}
|
|
41061
|
+
if (!center) {
|
|
41062
|
+
if (!obj.geometry.boundingBox) obj.geometry.computeBoundingBox();
|
|
41063
|
+
const box = obj.geometry.boundingBox.clone();
|
|
41064
|
+
box.applyMatrix4(obj.matrixWorld);
|
|
41065
|
+
center = new Vector3();
|
|
41066
|
+
box.getCenter(center);
|
|
41067
|
+
}
|
|
41068
|
+
const explodeVector = center.sub(explodeCenter);
|
|
41069
|
+
obj.userData.explodeVector = explodeVector;
|
|
40602
41070
|
}
|
|
40603
|
-
|
|
40604
|
-
const
|
|
40605
|
-
boundingBox.getCenter(objectCenter);
|
|
40606
|
-
const direction = objectCenter.clone().sub(explodeCenter);
|
|
40607
|
-
const distance = direction.length();
|
|
41071
|
+
const explodeVector = obj.userData.explodeVector;
|
|
41072
|
+
const distance = explodeVector.length();
|
|
40608
41073
|
if (distance > 0) {
|
|
40609
|
-
|
|
40610
|
-
const
|
|
40611
|
-
|
|
41074
|
+
const offset = explodeVector.clone().multiplyScalar(explodeFactor - 1.0);
|
|
41075
|
+
const localOffset = offset.clone();
|
|
41076
|
+
if (obj.userData.structureId) {
|
|
41077
|
+
const structureId = obj.userData.structureId;
|
|
41078
|
+
let inverseMatrix = structureInverseMatrices.get(structureId);
|
|
41079
|
+
if (!inverseMatrix) {
|
|
41080
|
+
const rootGroup = this.structureRoots.get(structureId);
|
|
41081
|
+
if (rootGroup) {
|
|
41082
|
+
if (!rootGroup.userData.inverseWorldMatrix) {
|
|
41083
|
+
rootGroup.userData.inverseWorldMatrix = new Matrix4().copy(rootGroup.matrixWorld).invert();
|
|
41084
|
+
}
|
|
41085
|
+
inverseMatrix = rootGroup.userData.inverseWorldMatrix;
|
|
41086
|
+
structureInverseMatrices.set(structureId, inverseMatrix);
|
|
41087
|
+
}
|
|
41088
|
+
}
|
|
41089
|
+
if (inverseMatrix) {
|
|
41090
|
+
const zero = new Vector3(0, 0, 0).applyMatrix4(inverseMatrix);
|
|
41091
|
+
const vec = offset.clone().applyMatrix4(inverseMatrix).sub(zero);
|
|
41092
|
+
localOffset.copy(vec);
|
|
41093
|
+
}
|
|
41094
|
+
}
|
|
41095
|
+
let matrix = obj.userData.explodeMatrix;
|
|
41096
|
+
if (!matrix) {
|
|
41097
|
+
matrix = new Matrix4();
|
|
41098
|
+
obj.userData.explodeMatrix = matrix;
|
|
41099
|
+
}
|
|
41100
|
+
matrix.makeTranslation(localOffset.x, localOffset.y, localOffset.z);
|
|
40612
41101
|
transformMap.set(obj, matrix);
|
|
40613
41102
|
}
|
|
40614
41103
|
}
|
|
@@ -40616,115 +41105,19 @@ void main() {
|
|
|
40616
41105
|
}
|
|
40617
41106
|
clearTransforms() {
|
|
40618
41107
|
this.objectTransforms.clear();
|
|
40619
|
-
|
|
40620
|
-
|
|
40621
|
-
|
|
40622
|
-
|
|
40623
|
-
|
|
40624
|
-
|
|
40625
|
-
for (const lineSegment of this.mergedLineSegments) {
|
|
40626
|
-
this._restoreOriginalGeometry(lineSegment);
|
|
40627
|
-
}
|
|
40628
|
-
for (const point of this.mergedPoints) {
|
|
40629
|
-
this._restoreOriginalGeometry(point);
|
|
40630
|
-
}
|
|
40631
|
-
}
|
|
40632
|
-
clearHandleTransforms() {
|
|
40633
|
-
this.clearTransforms();
|
|
40634
|
-
}
|
|
40635
|
-
_applyTransformToMergedObject(mergedObject) {
|
|
40636
|
-
const objectData = this.mergedObjectMap.get(mergedObject.uuid);
|
|
40637
|
-
if (!objectData || !objectData.objectMapping) return;
|
|
40638
|
-
const geometry = mergedObject.geometry;
|
|
40639
|
-
if (!geometry || !geometry.attributes.position) return;
|
|
40640
|
-
const positionAttr = geometry.attributes.position;
|
|
40641
|
-
const positions = positionAttr.array;
|
|
40642
|
-
if (!this.transformedGeometries.has(mergedObject.uuid)) {
|
|
40643
|
-
this.transformedGeometries.set(mergedObject.uuid, new Float32Array(positions));
|
|
40644
|
-
}
|
|
40645
|
-
const originalPositions = this.transformedGeometries.get(mergedObject.uuid);
|
|
40646
|
-
const tempVector = new Vector3();
|
|
40647
|
-
for (const [originalMesh, mappingData] of objectData.objectMapping) {
|
|
40648
|
-
const transform = this.objectTransforms.get(originalMesh);
|
|
40649
|
-
if (!transform) {
|
|
40650
|
-
const startIdx = mappingData.startVertexIndex * 3;
|
|
40651
|
-
const endIdx = (mappingData.startVertexIndex + mappingData.vertexCount) * 3;
|
|
40652
|
-
for (let i = startIdx; i < endIdx; i++) {
|
|
40653
|
-
positions[i] = originalPositions[i];
|
|
40654
|
-
}
|
|
40655
|
-
continue;
|
|
40656
|
-
}
|
|
40657
|
-
const startVertex = mappingData.startVertexIndex;
|
|
40658
|
-
const vertexCount = mappingData.vertexCount;
|
|
40659
|
-
for (let i = 0; i < vertexCount; i++) {
|
|
40660
|
-
const idx = (startVertex + i) * 3;
|
|
40661
|
-
tempVector.set(originalPositions[idx], originalPositions[idx + 1], originalPositions[idx + 2]);
|
|
40662
|
-
tempVector.applyMatrix4(transform);
|
|
40663
|
-
positions[idx] = tempVector.x;
|
|
40664
|
-
positions[idx + 1] = tempVector.y;
|
|
40665
|
-
positions[idx + 2] = tempVector.z;
|
|
40666
|
-
}
|
|
40667
|
-
}
|
|
40668
|
-
if (geometry.attributes.normal) {
|
|
40669
|
-
this._updateNormalsForTransform(geometry, objectData, originalPositions);
|
|
40670
|
-
}
|
|
40671
|
-
positionAttr.needsUpdate = true;
|
|
40672
|
-
geometry.computeBoundingSphere();
|
|
40673
|
-
geometry.computeBoundingBox();
|
|
40674
|
-
}
|
|
40675
|
-
_updateNormalsForTransform(geometry, objectData, originalPositions) {
|
|
40676
|
-
const normalAttr = geometry.attributes.normal;
|
|
40677
|
-
if (!normalAttr) return;
|
|
40678
|
-
const normals = normalAttr.array;
|
|
40679
|
-
const tempVector = new Vector3();
|
|
40680
|
-
const normalMatrix = new Matrix4();
|
|
40681
|
-
const normalsKey = `${geometry.uuid}_normals`;
|
|
40682
|
-
if (!this.transformedGeometries.has(normalsKey)) {
|
|
40683
|
-
this.transformedGeometries.set(normalsKey, new Float32Array(normals));
|
|
40684
|
-
}
|
|
40685
|
-
const originalNormals = this.transformedGeometries.get(normalsKey);
|
|
40686
|
-
for (const [originalMesh, mappingData] of objectData.objectMapping) {
|
|
40687
|
-
const transform = this.objectTransforms.get(originalMesh);
|
|
40688
|
-
if (!transform) {
|
|
40689
|
-
const startIdx = mappingData.startVertexIndex * 3;
|
|
40690
|
-
const endIdx = (mappingData.startVertexIndex + mappingData.vertexCount) * 3;
|
|
40691
|
-
for (let i = startIdx; i < endIdx; i++) {
|
|
40692
|
-
normals[i] = originalNormals[i];
|
|
41108
|
+
this._resetTransformData(true);
|
|
41109
|
+
if (this.syncTransformsToOriginalObjects) {
|
|
41110
|
+
for (const [obj, savedPos] of this._originalObjectMatrices) {
|
|
41111
|
+
obj.position.copy(savedPos);
|
|
41112
|
+
if (obj.userData.highlight) {
|
|
41113
|
+
obj.userData.highlight.position.copy(savedPos);
|
|
40693
41114
|
}
|
|
40694
|
-
continue;
|
|
40695
|
-
}
|
|
40696
|
-
normalMatrix.copy(transform).invert().transpose();
|
|
40697
|
-
const startVertex = mappingData.startVertexIndex;
|
|
40698
|
-
const vertexCount = mappingData.vertexCount;
|
|
40699
|
-
for (let i = 0; i < vertexCount; i++) {
|
|
40700
|
-
const idx = (startVertex + i) * 3;
|
|
40701
|
-
tempVector.set(originalNormals[idx], originalNormals[idx + 1], originalNormals[idx + 2]);
|
|
40702
|
-
tempVector.applyMatrix4(normalMatrix).normalize();
|
|
40703
|
-
normals[idx] = tempVector.x;
|
|
40704
|
-
normals[idx + 1] = tempVector.y;
|
|
40705
|
-
normals[idx + 2] = tempVector.z;
|
|
40706
41115
|
}
|
|
41116
|
+
this._originalObjectMatrices.clear();
|
|
40707
41117
|
}
|
|
40708
|
-
normalAttr.needsUpdate = true;
|
|
40709
41118
|
}
|
|
40710
|
-
|
|
40711
|
-
|
|
40712
|
-
if (!geometry || !geometry.attributes.position) return;
|
|
40713
|
-
const originalPositions = this.transformedGeometries.get(mergedObject.uuid);
|
|
40714
|
-
if (originalPositions) {
|
|
40715
|
-
const positions = geometry.attributes.position.array;
|
|
40716
|
-
positions.set(originalPositions);
|
|
40717
|
-
geometry.attributes.position.needsUpdate = true;
|
|
40718
|
-
}
|
|
40719
|
-
const normalsKey = `${geometry.uuid}_normals`;
|
|
40720
|
-
const originalNormals = this.transformedGeometries.get(normalsKey);
|
|
40721
|
-
if (originalNormals && geometry.attributes.normal) {
|
|
40722
|
-
const normals = geometry.attributes.normal.array;
|
|
40723
|
-
normals.set(originalNormals);
|
|
40724
|
-
geometry.attributes.normal.needsUpdate = true;
|
|
40725
|
-
}
|
|
40726
|
-
geometry.computeBoundingSphere();
|
|
40727
|
-
geometry.computeBoundingBox();
|
|
41119
|
+
clearHandleTransforms() {
|
|
41120
|
+
this.clearTransforms();
|
|
40728
41121
|
}
|
|
40729
41122
|
syncHiddenObjects() {
|
|
40730
41123
|
if (this.mergedObjectMap.size === 0) {
|