fl-web-component 2.0.0-beta.9 → 2.0.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.
Files changed (34) hide show
  1. package/README.md +5 -0
  2. package/dist/fl-web-component.common.js +34766 -1686
  3. package/dist/fl-web-component.common.js.map +1 -1
  4. package/dist/fl-web-component.css +1 -1
  5. package/package.json +4 -15
  6. package/packages/components/com-card/index.vue +1 -1
  7. package/packages/components/com-flcanvas/components/bspline.js +31 -34
  8. package/packages/components/com-flcanvas/components/entityFormatting.js +810 -823
  9. package/packages/components/com-flcanvas/components/round10.js +17 -17
  10. package/packages/components/com-flcanvas/index.vue +314 -333
  11. package/packages/components/com-formDialog/index.vue +6 -4
  12. package/packages/components/com-graphics/component/ann-tool.vue +263 -208
  13. package/packages/components/com-graphics/index.vue +374 -773
  14. package/packages/components/com-graphics/pid.vue +304 -295
  15. package/packages/components/com-table/column-default.vue +2 -3
  16. package/packages/components/com-table/column-dynamic.vue +7 -4
  17. package/packages/components/com-table/column.vue +1 -2
  18. package/packages/components/com-table/index.vue +6 -5
  19. package/packages/components/com-tabs/index.vue +1 -2
  20. package/packages/components/com-tiles/index.vue +134 -136
  21. package/packages/components/com-treeDynamic/index.vue +1 -1
  22. package/packages/utils/StreamLoader.js +95 -36
  23. package/packages/utils/StreamLoaderParser.worker.js +9 -14
  24. package/src/main.js +2 -8
  25. package/src/utils/cloud.js +28 -28
  26. package/src/utils/cursor.js +11 -9
  27. package/src/utils/flgltf-parser.js +257 -245
  28. package/src/utils/instance-parser.js +20 -22
  29. package/src/utils/mini-devtool.js +94 -39
  30. package/src/utils/threejs/measure-angle.js +51 -13
  31. package/src/utils/threejs/measure-area.js +44 -13
  32. package/src/utils/threejs/measure-distance.js +43 -12
  33. package/src/utils/threejs/rain-shader.js +10 -10
  34. package/src/utils/threejs/snow-shader.js +9 -9
@@ -33,14 +33,7 @@ var [
33
33
  while (true) yield v;
34
34
  })(null);
35
35
 
36
- var [
37
- lastTime,
38
- firstTime,
39
- fpsClock,
40
- timeStamp,
41
- progress,
42
- lastMiddleClickTime,
43
- ] = (function* (v) {
36
+ var [lastTime, firstTime, fpsClock, timeStamp, progress, lastMiddleClickTime] = (function* (v) {
44
37
  while (true) yield v;
45
38
  })(0);
46
39
  var singleFrameTime = 1 / 30;
@@ -66,14 +59,7 @@ var [spaceUp] = (function* (v) {
66
59
  const renderedThisFrame = new Set();
67
60
 
68
61
  function markRendered(mesh) {
69
- mesh.onBeforeRender = function (
70
- renderer,
71
- scene,
72
- camera,
73
- geometry,
74
- material,
75
- group,
76
- ) {
62
+ mesh.onBeforeRender = function (renderer, scene, camera, geometry, material, group) {
77
63
  renderedThisFrame.add(mesh);
78
64
  };
79
65
  }
@@ -145,11 +131,7 @@ import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';
145
131
  import MeasureDistance from '@/utils/threejs/measure-distance.js';
146
132
  import MeasureArea from '@/utils/threejs/measure-area.js';
147
133
  import MeasureAngle from '@/utils/threejs/measure-angle.js';
148
- import {
149
- parseData,
150
- processMeshData,
151
- processNodeData,
152
- } from '@/utils/flgltf-parser';
134
+ import { parseData, processMeshData, processNodeData } from '@/utils/flgltf-parser';
153
135
  import {
154
136
  handleInstancedMeshModel,
155
137
  resetProcessingState,
@@ -171,9 +153,7 @@ import boxJson from './box.json';
171
153
  import { StreamLoader } from '../../utils/StreamLoader.js';
172
154
  import StreamLoaderParserWorker from '../../utils/StreamLoaderParser.worker.js';
173
155
 
174
- const isDebug =
175
- process.env.NODE_ENV !== 'production' ||
176
- process.env.VUE_APP_IS_WATCH === true;
156
+ const isDebug = process.env.NODE_ENV !== 'production' || process.env.VUE_APP_IS_WATCH === true;
177
157
  // const isDebug = false;
178
158
 
179
159
  export default {
@@ -285,17 +265,13 @@ export default {
285
265
  raycaster = new this.THREE.Raycaster();
286
266
  sceneClock = new this.THREE.Clock();
287
267
  mouse = new this.THREE.Vector2();
288
- renderTarget = new this.THREE.WebGLRenderTarget(
289
- window.innerWidth,
290
- window.innerHeight,
291
- {
292
- minFilter: this.THREE.LinearFilter,
293
- magFilter: this.THREE.LinearFilter,
294
- format: this.THREE.RGBAFormat,
295
- stencilBuffer: true,
296
- samples: 0,
297
- },
298
- );
268
+ renderTarget = new this.THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, {
269
+ minFilter: this.THREE.LinearFilter,
270
+ magFilter: this.THREE.LinearFilter,
271
+ format: this.THREE.RGBAFormat,
272
+ stencilBuffer: true,
273
+ samples: 0,
274
+ });
299
275
  },
300
276
  mounted() {
301
277
  instructions = document.getElementById('fl-model');
@@ -314,11 +290,7 @@ export default {
314
290
  let isMobileDevice = this.isMobileDevice();
315
291
  if (isMobileDevice) {
316
292
  renderer.domElement.addEventListener('pointerup', this.mouseClick, false);
317
- renderer.domElement.addEventListener(
318
- 'pointerdown',
319
- this.mouseDown,
320
- false,
321
- );
293
+ renderer.domElement.addEventListener('pointerdown', this.mouseDown, false);
322
294
  } else {
323
295
  renderer.domElement.addEventListener('mouseup', this.mouseClick, false);
324
296
  renderer.domElement.addEventListener('mousedown', this.mouseDown, false);
@@ -334,8 +306,7 @@ export default {
334
306
  return `${instancedMesh.uuid}:${instanceIndex}`;
335
307
  },
336
308
  ensureOutlineInstanceProxy(instancedMesh, instanceIndex) {
337
- if (!scene || !instancedMesh || !instancedMesh.isInstancedMesh)
338
- return null;
309
+ if (!scene || !instancedMesh || !instancedMesh.isInstancedMesh) return null;
339
310
  const state = this.noObserver;
340
311
  if (!state || !state.outlineInstanceProxyMap) return null;
341
312
 
@@ -379,8 +350,7 @@ export default {
379
350
  },
380
351
  removeOutlineInstanceProxy(instancedMesh, instanceIndex) {
381
352
  const state = this.noObserver;
382
- if (!state || !state.outlineInstanceProxyMap || !instancedMesh)
383
- return null;
353
+ if (!state || !state.outlineInstanceProxyMap || !instancedMesh) return null;
384
354
  const key = this.getOutlineInstanceProxyKey(instancedMesh, instanceIndex);
385
355
  const proxy = state.outlineInstanceProxyMap.get(key);
386
356
  if (!proxy) return null;
@@ -435,8 +405,7 @@ export default {
435
405
  let throttleTimer = null;
436
406
 
437
407
  return function (...args) {
438
- const currentDelay =
439
- typeof delay === 'function' ? delay(...args) : delay;
408
+ const currentDelay = typeof delay === 'function' ? delay(...args) : delay;
440
409
 
441
410
  // 如果返回 'throttle' 策略,则执行节流逻辑 (默认间隔 300ms,或可扩展)
442
411
  if (
@@ -444,9 +413,7 @@ export default {
444
413
  (typeof currentDelay === 'object' && currentDelay.type === 'throttle')
445
414
  ) {
446
415
  const limit =
447
- typeof currentDelay === 'object' && currentDelay.limit
448
- ? currentDelay.limit
449
- : 300;
416
+ typeof currentDelay === 'object' && currentDelay.limit ? currentDelay.limit : 300;
450
417
  const now = Date.now();
451
418
 
452
419
  // 清除之前的防抖定时器,避免冲突
@@ -494,7 +461,7 @@ export default {
494
461
  error: 'Worker is not initialized',
495
462
  });
496
463
  }
497
- return new Promise((resolve) => {
464
+ return new Promise(resolve => {
498
465
  const id = state.occlusionWorkerRequestId++;
499
466
  state.occlusionWorkerRequestMap.set(id, { resolve });
500
467
  state.occlusionWorker.postMessage({ id, type, data }, transferable);
@@ -503,8 +470,7 @@ export default {
503
470
  scanOcclusionBufferSync(buffer, sw, sh, stride, maxIdx, minSampleCount) {
504
471
  const indices = [];
505
472
  if (!buffer || !sw || !sh || !maxIdx) return { indices };
506
- const view =
507
- buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
473
+ const view = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
508
474
  const step = Math.max(1, stride || 1);
509
475
  const minCount = Math.max(1, minSampleCount || 1);
510
476
  const counts = new Uint32Array(maxIdx + 1);
@@ -526,8 +492,7 @@ export default {
526
492
  },
527
493
  async scanOcclusionIndices(buffer, sw, sh, stride, maxIdx, minSampleCount) {
528
494
  const state = this.noObserver;
529
- const canWorker =
530
- state && state.occlusionWorker && buffer && buffer.buffer;
495
+ const canWorker = state && state.occlusionWorker && buffer && buffer.buffer;
531
496
  if (canWorker) {
532
497
  const response = await this.occlusionWorkerRequest(
533
498
  'occlusionScan',
@@ -539,12 +504,9 @@ export default {
539
504
  maxIdx,
540
505
  minSampleCount,
541
506
  },
542
- [buffer.buffer],
507
+ [buffer.buffer]
543
508
  );
544
- const restored =
545
- response && response.buffer
546
- ? new Uint8Array(response.buffer)
547
- : buffer;
509
+ const restored = response && response.buffer ? new Uint8Array(response.buffer) : buffer;
548
510
  if (response && response.type === 'success' && response.result) {
549
511
  return {
550
512
  indices: response.result.indices || [],
@@ -557,18 +519,11 @@ export default {
557
519
  sh,
558
520
  stride,
559
521
  maxIdx,
560
- minSampleCount,
522
+ minSampleCount
561
523
  );
562
524
  return { indices: syncRes.indices, buffer: restored.buffer };
563
525
  }
564
- const syncRes = this.scanOcclusionBufferSync(
565
- buffer,
566
- sw,
567
- sh,
568
- stride,
569
- maxIdx,
570
- minSampleCount,
571
- );
526
+ const syncRes = this.scanOcclusionBufferSync(buffer, sw, sh, stride, maxIdx, minSampleCount);
572
527
  return {
573
528
  indices: syncRes.indices,
574
529
  buffer: buffer && buffer.buffer ? buffer.buffer : null,
@@ -595,7 +550,7 @@ export default {
595
550
 
596
551
  const box = new this.THREE.Box3(
597
552
  new this.THREE.Vector3(minX, minY, minZ),
598
- new this.THREE.Vector3(maxX, maxY, maxZ),
553
+ new this.THREE.Vector3(maxX, maxY, maxZ)
599
554
  ).applyMatrix4(bizToThreeMatrix);
600
555
  this.noObserver.sceneBoxes.set(documentId, box);
601
556
  } else {
@@ -665,28 +620,16 @@ export default {
665
620
  // 如果是 flag=3,解析并存储中心点、半轴长、旋转矩阵
666
621
  else if (it.flag === 3 && it.obb && it.obb.length === 15) {
667
622
  const obbData = it.obb;
668
- const center = new this.THREE.Vector3(
669
- obbData[0],
670
- obbData[1],
671
- obbData[2],
672
- );
673
- const halfSize = new this.THREE.Vector3(
674
- obbData[3],
675
- obbData[4],
676
- obbData[5],
677
- );
678
- const rotation = new this.THREE.Matrix3().fromArray(
679
- obbData.slice(6, 15),
680
- );
623
+ const center = new this.THREE.Vector3(obbData[0], obbData[1], obbData[2]);
624
+ const halfSize = new this.THREE.Vector3(obbData[3], obbData[4], obbData[5]);
625
+ const rotation = new this.THREE.Matrix3().fromArray(obbData.slice(6, 15));
681
626
 
682
627
  // 预计算局部到世界的变换矩阵 (不含 bizToThreeMatrix,后续渲染时统一处理)
683
- const rotationMatrix4 = new this.THREE.Matrix4().setFromMatrix3(
684
- rotation,
685
- );
628
+ const rotationMatrix4 = new this.THREE.Matrix4().setFromMatrix3(rotation);
686
629
  const obbMatrix = new this.THREE.Matrix4().makeTranslation(
687
630
  center.x,
688
631
  center.y,
689
- center.z,
632
+ center.z
690
633
  );
691
634
  obbMatrix.multiply(rotationMatrix4);
692
635
 
@@ -701,16 +644,8 @@ export default {
701
644
  const subBoxes = [];
702
645
  for (let k = 0; k < it.obb.length; k += 6) {
703
646
  if (k + 5 < it.obb.length) {
704
- const min = new this.THREE.Vector3(
705
- it.obb[k],
706
- it.obb[k + 1],
707
- it.obb[k + 2],
708
- );
709
- const max = new this.THREE.Vector3(
710
- it.obb[k + 3],
711
- it.obb[k + 4],
712
- it.obb[k + 5],
713
- );
647
+ const min = new this.THREE.Vector3(it.obb[k], it.obb[k + 1], it.obb[k + 2]);
648
+ const max = new this.THREE.Vector3(it.obb[k + 3], it.obb[k + 4], it.obb[k + 5]);
714
649
  subBoxes.push({ min, max });
715
650
  }
716
651
  }
@@ -727,7 +662,7 @@ export default {
727
662
  } else {
728
663
  const modelIds = this.noObserver.documentModelIds.get(documentId);
729
664
  if (modelIds) {
730
- modelIds.forEach((id) => {
665
+ modelIds.forEach(id => {
731
666
  this._boxIndex.delete(id);
732
667
  });
733
668
  this.noObserver.documentModelIds.delete(documentId);
@@ -741,6 +676,13 @@ export default {
741
676
  this.buildOctreeFromBoxIndex();
742
677
  console.log('time end', Date.now());
743
678
  },
679
+ tryInitialCenterAfterBoundsReady() {
680
+ if (hasExecutedCentering || userInteracting) return;
681
+ if (!sceneBoundingBox || !sceneBoundingBox.isBox3 || sceneBoundingBox.isEmpty()) return;
682
+ if (!this._boxIndex || this._boxIndex.size === 0) return;
683
+
684
+ this.smartModelCenter(sceneBoundingBox, 0);
685
+ },
744
686
  buildOctreeFromBoxIndex() {
745
687
  if (!this._boxIndex || this._boxIndex.size === 0) {
746
688
  this._octree = null;
@@ -752,7 +694,7 @@ export default {
752
694
  let maxX = -Infinity,
753
695
  maxY = -Infinity,
754
696
  maxZ = -Infinity;
755
- this._boxIndex.forEach((box) => {
697
+ this._boxIndex.forEach(box => {
756
698
  if (!box || !box.isBox3) return;
757
699
  const mn = box.min;
758
700
  const mx = box.max;
@@ -765,7 +707,7 @@ export default {
765
707
  });
766
708
  const rootBox = new this.THREE.Box3(
767
709
  new this.THREE.Vector3(minX, minY, minZ),
768
- new this.THREE.Vector3(maxX, maxY, maxZ),
710
+ new this.THREE.Vector3(maxX, maxY, maxZ)
769
711
  );
770
712
  this._octreeMaxItems = 64;
771
713
  this._octreeMaxDepth = 12;
@@ -780,7 +722,7 @@ export default {
780
722
  const mid = new this.THREE.Vector3(
781
723
  (min.x + max.x) * 0.5,
782
724
  (min.y + max.y) * 0.5,
783
- (min.z + max.z) * 0.5,
725
+ (min.z + max.z) * 0.5
784
726
  );
785
727
  const children = [];
786
728
  for (let i = 0; i < 8; i++) {
@@ -822,10 +764,7 @@ export default {
822
764
  _octreeInsert(node, id, box) {
823
765
  if (!node.children) {
824
766
  node.items.push({ id, box });
825
- if (
826
- node.items.length > this._octreeMaxItems &&
827
- node.depth < this._octreeMaxDepth
828
- ) {
767
+ if (node.items.length > this._octreeMaxItems && node.depth < this._octreeMaxDepth) {
829
768
  this._octreeSubdivide(node);
830
769
  }
831
770
  return;
@@ -848,7 +787,7 @@ export default {
848
787
  const frustum = new this.THREE.Frustum();
849
788
  const vpMatrix = new this.THREE.Matrix4().multiplyMatrices(
850
789
  camera.projectionMatrix,
851
- camera.matrixWorldInverse,
790
+ camera.matrixWorldInverse
852
791
  );
853
792
  frustum.setFromProjectionMatrix(vpMatrix);
854
793
  return frustum;
@@ -876,8 +815,7 @@ export default {
876
815
  if (node.items && node.items.length) {
877
816
  for (let k = 0; k < node.items.length; k++) {
878
817
  const it = node.items[k];
879
- if (excludeSet && excludeSet.size > 0 && excludeSet.has(it.id))
880
- continue;
818
+ if (excludeSet && excludeSet.size > 0 && excludeSet.has(it.id)) continue;
881
819
 
882
820
  // 1. 粗测:World AABB
883
821
  if (frustum.intersectsBox(it.box)) {
@@ -930,9 +868,7 @@ export default {
930
868
 
931
869
  // 获取最新相机位置
932
870
  camera.updateMatrixWorld(true);
933
- const camPos = new this.THREE.Vector3().setFromMatrixPosition(
934
- camera.matrixWorld,
935
- );
871
+ const camPos = new this.THREE.Vector3().setFromMatrixPosition(camera.matrixWorld);
936
872
 
937
873
  const min = sceneBoundingBox.min;
938
874
  const max = sceneBoundingBox.max;
@@ -999,7 +935,7 @@ export default {
999
935
  const ndcBase = new this.THREE.Vector3(
1000
936
  (x / width) * 2 - 1,
1001
937
  -(y / height) * 2 + 1,
1002
- undefined,
938
+ undefined
1003
939
  );
1004
940
 
1005
941
  const ndcNear = ndcBase.clone();
@@ -1029,14 +965,9 @@ export default {
1029
965
  frustumPoints[4],
1030
966
  frustumPoints[6],
1031
967
  ];
1032
- const farCorners = [
1033
- frustumPoints[1],
1034
- frustumPoints[3],
1035
- frustumPoints[5],
1036
- frustumPoints[7],
1037
- ];
968
+ const farCorners = [frustumPoints[1], frustumPoints[3], frustumPoints[5], frustumPoints[7]];
1038
969
  const volumeCorners = nearCorners.concat(farCorners);
1039
- const projectedPoints = volumeCorners.map((p) => {
970
+ const projectedPoints = volumeCorners.map(p => {
1040
971
  const yProj = -(a * p.x + c * p.z + d) / b;
1041
972
  return new this.THREE.Vector3(p.x, yProj, p.z);
1042
973
  });
@@ -1050,8 +981,8 @@ export default {
1050
981
  function computePlaneMinYOverBox(plane, box) {
1051
982
  const nearIndices = [0, 2, 4, 6];
1052
983
  const farIndices = [1, 3, 5, 7];
1053
- const nearYs = nearIndices.map((i) => frustumPoints[i].y);
1054
- const farYs = farIndices.map((i) => frustumPoints[i].y);
984
+ const nearYs = nearIndices.map(i => frustumPoints[i].y);
985
+ const farYs = farIndices.map(i => frustumPoints[i].y);
1055
986
  const minY = Math.min(...nearYs, ...farYs);
1056
987
  const maxY = Math.max(...nearYs, ...farYs);
1057
988
  return { min: minY, max: maxY };
@@ -1093,9 +1024,7 @@ export default {
1093
1024
  if (camera.projectionMatrixNeedsUpdate) camera.updateProjectionMatrix();
1094
1025
 
1095
1026
  // 相机世界位置
1096
- const cameraPosition = new this.THREE.Vector3().setFromMatrixPosition(
1097
- camera.matrixWorld,
1098
- );
1027
+ const cameraPosition = new this.THREE.Vector3().setFromMatrixPosition(camera.matrixWorld);
1099
1028
 
1100
1029
  // 从相机指向目标点的射线方向(优先使用 cameraControls._target)
1101
1030
  const rayDirection = new this.THREE.Vector3();
@@ -1105,18 +1034,12 @@ export default {
1105
1034
  cameraControls.enabled &&
1106
1035
  cameraControls._target
1107
1036
  ) {
1108
- rayDirection
1109
- .copy(cameraControls._target)
1110
- .sub(cameraPosition)
1111
- .normalize();
1037
+ rayDirection.copy(cameraControls._target).sub(cameraPosition).normalize();
1112
1038
  } else {
1113
1039
  camera.getWorldDirection(rayDirection); // -Z 方向(世界坐标)
1114
1040
  }
1115
1041
 
1116
- const ray = new this.THREE.Ray(
1117
- cameraPosition.clone(),
1118
- rayDirection.clone(),
1119
- );
1042
+ const ray = new this.THREE.Ray(cameraPosition.clone(), rayDirection.clone());
1120
1043
 
1121
1044
  // 准备/计算场景包围盒
1122
1045
  // if (!sceneBoundingBox) {
@@ -1135,9 +1058,7 @@ export default {
1135
1058
  // 若包围盒不存在或为空,兜底从模型组/场景计算一次
1136
1059
  if (
1137
1060
  !sceneBoundingBox ||
1138
- (sceneBoundingBox.isBox3 &&
1139
- sceneBoundingBox.isEmpty &&
1140
- sceneBoundingBox.isEmpty())
1061
+ (sceneBoundingBox.isBox3 && sceneBoundingBox.isEmpty && sceneBoundingBox.isEmpty())
1141
1062
  ) {
1142
1063
  const obj =
1143
1064
  typeof modelGroup !== 'undefined' &&
@@ -1151,10 +1072,7 @@ export default {
1151
1072
  }
1152
1073
  }
1153
1074
  if (sceneBoundingBox && sceneBoundingBox.isBox3) {
1154
- boxHitPoint = ray.intersectBox(
1155
- sceneBoundingBox,
1156
- new this.THREE.Vector3(),
1157
- );
1075
+ boxHitPoint = ray.intersectBox(sceneBoundingBox, new this.THREE.Vector3());
1158
1076
  }
1159
1077
 
1160
1078
  // targetPoint 保留原平面回退逻辑(用于其他需要点位的场景)
@@ -1173,9 +1091,7 @@ export default {
1173
1091
  }
1174
1092
 
1175
1093
  // 以相机为原点,到包围盒交点的直线距离(若无交点则为 null)
1176
- const distanceToBox = boxHitPoint
1177
- ? cameraPosition.distanceTo(boxHitPoint)
1178
- : null;
1094
+ const distanceToBox = boxHitPoint ? cameraPosition.distanceTo(boxHitPoint) : null;
1179
1095
 
1180
1096
  return {
1181
1097
  targetPoint,
@@ -1203,7 +1119,7 @@ export default {
1203
1119
  frustum = new this.THREE.Frustum();
1204
1120
  const matrix = new this.THREE.Matrix4().multiplyMatrices(
1205
1121
  camera.projectionMatrix,
1206
- camera.matrixWorldInverse,
1122
+ camera.matrixWorldInverse
1207
1123
  );
1208
1124
  frustum.setFromProjectionMatrix(matrix);
1209
1125
  }
@@ -1280,7 +1196,7 @@ export default {
1280
1196
  const frustum = new this.THREE.Frustum();
1281
1197
  const vpMatrix = new this.THREE.Matrix4().multiplyMatrices(
1282
1198
  camera.projectionMatrix,
1283
- camera.matrixWorldInverse,
1199
+ camera.matrixWorldInverse
1284
1200
  );
1285
1201
  frustum.setFromProjectionMatrix(vpMatrix);
1286
1202
 
@@ -1320,7 +1236,7 @@ export default {
1320
1236
  const globalFrustum = this._frustum;
1321
1237
  const globalVpMatrix = this._vpMatrix.multiplyMatrices(
1322
1238
  camera.projectionMatrix,
1323
- camera.matrixWorldInverse,
1239
+ camera.matrixWorldInverse
1324
1240
  );
1325
1241
  globalFrustum.setFromProjectionMatrix(globalVpMatrix);
1326
1242
 
@@ -1330,7 +1246,7 @@ export default {
1330
1246
  const visibleIds = [];
1331
1247
  const candidates = [];
1332
1248
  if (bypassList && bypassList.size > 0) {
1333
- bypassList.forEach((id) => visibleIds.push(id));
1249
+ bypassList.forEach(id => visibleIds.push(id));
1334
1250
  }
1335
1251
  const visibleIdSet = new Set(visibleIds);
1336
1252
  if (this._octree) {
@@ -1338,30 +1254,22 @@ export default {
1338
1254
  const exclude = bypassList || new Set();
1339
1255
  const hits = this.queryOctreeByFrustum(frustum, exclude);
1340
1256
  for (let i = 0; i < hits.length; i++) {
1341
- if (
1342
- hits[i].box &&
1343
- hits[i].box.userData &&
1344
- hits[i].box.userData.visible === false
1345
- )
1257
+ if (hits[i].box && hits[i].box.userData && hits[i].box.userData.visible === false)
1346
1258
  continue;
1347
1259
  candidates.push(hits[i]);
1348
1260
  }
1349
1261
  } else if (this._boxIndex && this._boxIndex.size > 0) {
1350
1262
  this._boxIndex.forEach((box, modelId) => {
1351
- if (bypassList && bypassList.size > 0 && bypassList.has(modelId))
1352
- return;
1263
+ if (bypassList && bypassList.size > 0 && bypassList.has(modelId)) return;
1353
1264
  if (box.userData && box.userData.visible === false) return;
1354
1265
  if (this.isBoxInFrustum(box)) {
1355
1266
  candidates.push({ modelId, box });
1356
1267
  }
1357
1268
  });
1358
1269
  }
1359
- const occlusionState = this.noObserver
1360
- ? this.noObserver.occlusionState
1361
- : this.occlusionState;
1270
+ const occlusionState = this.noObserver ? this.noObserver.occlusionState : this.occlusionState;
1362
1271
  // 从响应式对象获取开关状态
1363
- const occlusionEnabled =
1364
- this.occlusionState && this.occlusionState.enabled;
1272
+ const occlusionEnabled = this.occlusionState && this.occlusionState.enabled;
1365
1273
 
1366
1274
  if (occlusionEnabled) {
1367
1275
  const state = occlusionState;
@@ -1371,9 +1279,7 @@ export default {
1371
1279
  : 0;
1372
1280
  const h =
1373
1281
  renderer && renderer.domElement
1374
- ? renderer.domElement.clientHeight ||
1375
- renderer.domElement.height ||
1376
- 0
1282
+ ? renderer.domElement.clientHeight || renderer.domElement.height || 0
1377
1283
  : 0;
1378
1284
  // bufferWidth/Height 仍从响应式对象读取以支持动态修改
1379
1285
  // 性能优化:使用降采样缓冲区进行遮挡剔除,大幅减少 readPixels 耗时 (从全屏降至约 256px 宽)
@@ -1402,10 +1308,7 @@ export default {
1402
1308
  state._rtW = sw;
1403
1309
  state._rtH = sh;
1404
1310
  state._colorBuffer = new Uint8Array(sw * sh * 4);
1405
- } else if (
1406
- !state._colorBuffer ||
1407
- state._colorBuffer.length !== sw * sh * 4
1408
- ) {
1311
+ } else if (!state._colorBuffer || state._colorBuffer.length !== sw * sh * 4) {
1409
1312
  state._colorBuffer = new Uint8Array(sw * sh * 4);
1410
1313
  }
1411
1314
 
@@ -1427,10 +1330,7 @@ export default {
1427
1330
  const opaqueCandidates = [];
1428
1331
  const transparentCandidates = [];
1429
1332
  for (let i = 0; i < candidates.length; i++) {
1430
- if (
1431
- candidates[i].box.userData &&
1432
- candidates[i].box.userData.transparent
1433
- ) {
1333
+ if (candidates[i].box.userData && candidates[i].box.userData.transparent) {
1434
1334
  transparentCandidates.push(candidates[i]);
1435
1335
  } else {
1436
1336
  opaqueCandidates.push(candidates[i]);
@@ -1444,13 +1344,11 @@ export default {
1444
1344
  ? state._occIdIndexArr
1445
1345
  : (state._occIdIndexArr = []);
1446
1346
  const transparentIdIndexArr =
1447
- state._occTransparentIdIndexArr &&
1448
- Array.isArray(state._occTransparentIdIndexArr)
1347
+ state._occTransparentIdIndexArr && Array.isArray(state._occTransparentIdIndexArr)
1449
1348
  ? state._occTransparentIdIndexArr
1450
1349
  : (state._occTransparentIdIndexArr = []);
1451
1350
 
1452
- if (!state._occRenderObjects)
1453
- state._occRenderObjects = Object.create(null);
1351
+ if (!state._occRenderObjects) state._occRenderObjects = Object.create(null);
1454
1352
  const occObjs = state._occRenderObjects;
1455
1353
  if (!occObjs._initialized) {
1456
1354
  state._occScene.clear();
@@ -1477,7 +1375,7 @@ export default {
1477
1375
  this.occlusionState.asyncBuildEnabled &&
1478
1376
  !!window.requestAnimationFrame;
1479
1377
 
1480
- const _occBuild = (opaqueList) => {
1378
+ const _occBuild = opaqueList => {
1481
1379
  const tBuild0 = performance.now();
1482
1380
 
1483
1381
  const flag1Items = [];
@@ -1486,8 +1384,7 @@ export default {
1486
1384
  let globalIdx = 1;
1487
1385
  for (let i = 0; i < opaqueList.length; i++) {
1488
1386
  const c = opaqueList[i];
1489
- const obbData =
1490
- c.box && c.box.userData ? c.box.userData.obbData : null;
1387
+ const obbData = c.box && c.box.userData ? c.box.userData.obbData : null;
1491
1388
  if (!obbData || !obbData.length) continue;
1492
1389
  const idx = globalIdx++;
1493
1390
  activeIdIndexArr[idx] = this.formatModelId(c.modelId);
@@ -1503,39 +1400,25 @@ export default {
1503
1400
  activeIdIndexArr.length = maxIdx + 1;
1504
1401
 
1505
1402
  const _tempMatrix =
1506
- occObjs._tempMatrix ||
1507
- (occObjs._tempMatrix = new this.THREE.Matrix4());
1508
- const _tempColor =
1509
- occObjs._tempColor ||
1510
- (occObjs._tempColor = new this.THREE.Color());
1403
+ occObjs._tempMatrix || (occObjs._tempMatrix = new this.THREE.Matrix4());
1404
+ const _tempColor = occObjs._tempColor || (occObjs._tempColor = new this.THREE.Color());
1511
1405
  const _tempScale =
1512
- occObjs._tempScale ||
1513
- (occObjs._tempScale = new this.THREE.Vector3());
1514
- const _tempVec3 =
1515
- occObjs._tempVec3 ||
1516
- (occObjs._tempVec3 = new this.THREE.Vector3());
1517
- const _tempMatA =
1518
- occObjs._tempMatA ||
1519
- (occObjs._tempMatA = new this.THREE.Matrix4());
1406
+ occObjs._tempScale || (occObjs._tempScale = new this.THREE.Vector3());
1407
+ const _tempVec3 = occObjs._tempVec3 || (occObjs._tempVec3 = new this.THREE.Vector3());
1408
+ const _tempMatA = occObjs._tempMatA || (occObjs._tempMatA = new this.THREE.Matrix4());
1520
1409
 
1521
1410
  let boxes = occObjs.boxes;
1522
1411
  const boxCount = flag3Items.length;
1523
1412
  if (boxCount > 0) {
1524
1413
  const needCapacity = boxCount;
1525
- const capacity =
1526
- boxes && typeof boxes.capacity === 'number'
1527
- ? boxes.capacity
1528
- : 0;
1414
+ const capacity = boxes && typeof boxes.capacity === 'number' ? boxes.capacity : 0;
1529
1415
  if (!boxes || capacity < needCapacity) {
1530
1416
  if (boxes && boxes.mesh) {
1531
1417
  state._occScene.remove(boxes.mesh);
1532
1418
  if (boxes.mesh.geometry) boxes.mesh.geometry.dispose();
1533
1419
  if (boxes.mesh.material) boxes.mesh.material.dispose();
1534
1420
  }
1535
- const nextCap = Math.max(
1536
- needCapacity,
1537
- capacity > 0 ? capacity * 2 : 256,
1538
- );
1421
+ const nextCap = Math.max(needCapacity, capacity > 0 ? capacity * 2 : 256);
1539
1422
  const geometry = new this.THREE.BoxGeometry(1, 1, 1);
1540
1423
  const mat = new this.THREE.MeshBasicMaterial({
1541
1424
  color: 0xffffff,
@@ -1545,11 +1428,7 @@ export default {
1545
1428
  depthWrite: true,
1546
1429
  toneMapped: false,
1547
1430
  });
1548
- const mesh = new this.THREE.InstancedMesh(
1549
- geometry,
1550
- mat,
1551
- nextCap,
1552
- );
1431
+ const mesh = new this.THREE.InstancedMesh(geometry, mat, nextCap);
1553
1432
  mesh.frustumCulled = false;
1554
1433
  mesh.matrixAutoUpdate = false;
1555
1434
  state._occScene.add(mesh);
@@ -1570,10 +1449,7 @@ export default {
1570
1449
  _tempScale.copy(halfSize).multiplyScalar(2);
1571
1450
  _tempMatrix.copy(matrix);
1572
1451
  _tempMatrix.scale(_tempScale);
1573
- if (
1574
- typeof bizToThreeMatrix !== 'undefined' &&
1575
- bizToThreeMatrix
1576
- ) {
1452
+ if (typeof bizToThreeMatrix !== 'undefined' && bizToThreeMatrix) {
1577
1453
  _tempMatrix.premultiply(bizToThreeMatrix);
1578
1454
  }
1579
1455
 
@@ -1581,8 +1457,7 @@ export default {
1581
1457
  boxes.mesh.setColorAt(i, _tempColor);
1582
1458
  }
1583
1459
  boxes.mesh.instanceMatrix.needsUpdate = true;
1584
- if (boxes.mesh.instanceColor)
1585
- boxes.mesh.instanceColor.needsUpdate = true;
1460
+ if (boxes.mesh.instanceColor) boxes.mesh.instanceColor.needsUpdate = true;
1586
1461
  boxes.mesh.visible = true;
1587
1462
  } else if (boxes && boxes.mesh) {
1588
1463
  boxes.mesh.count = 0;
@@ -1607,8 +1482,7 @@ export default {
1607
1482
  const needIdx = totalIdx;
1608
1483
 
1609
1484
  const ensureBatch1 = () => {
1610
- if (batch1 && batch1.mesh && batch1.geometry && batch1.material)
1611
- return;
1485
+ if (batch1 && batch1.mesh && batch1.geometry && batch1.material) return;
1612
1486
  const geometry = new this.THREE.BufferGeometry();
1613
1487
  const material = new this.THREE.MeshBasicMaterial({
1614
1488
  vertexColors: true,
@@ -1636,14 +1510,8 @@ export default {
1636
1510
  }
1637
1511
 
1638
1512
  if (batch1.posCap < needPos || batch1.idxCap < needIdx) {
1639
- batch1.posCap = Math.max(
1640
- needPos,
1641
- batch1.posCap > 0 ? batch1.posCap * 2 : needPos,
1642
- );
1643
- batch1.idxCap = Math.max(
1644
- needIdx,
1645
- batch1.idxCap > 0 ? batch1.idxCap * 2 : needIdx,
1646
- );
1513
+ batch1.posCap = Math.max(needPos, batch1.posCap > 0 ? batch1.posCap * 2 : needPos);
1514
+ batch1.idxCap = Math.max(needIdx, batch1.idxCap > 0 ? batch1.idxCap * 2 : needIdx);
1647
1515
 
1648
1516
  const positions = new Float32Array(batch1.posCap);
1649
1517
  const colors = new Float32Array(batch1.posCap);
@@ -1694,10 +1562,7 @@ export default {
1694
1562
  } else {
1695
1563
  _tempMatA.identity();
1696
1564
  }
1697
- if (
1698
- typeof bizToThreeMatrix !== 'undefined' &&
1699
- bizToThreeMatrix
1700
- ) {
1565
+ if (typeof bizToThreeMatrix !== 'undefined' && bizToThreeMatrix) {
1701
1566
  _tempMatA.premultiply(bizToThreeMatrix);
1702
1567
  }
1703
1568
  }
@@ -1771,8 +1636,7 @@ export default {
1771
1636
 
1772
1637
  if (totalInstances > 0) {
1773
1638
  if (asyncBuildEnabled && state._occHasBuiltOnce) {
1774
- if (!state._occAsyncBuild)
1775
- state._occAsyncBuild = { pending: false, token: 0 };
1639
+ if (!state._occAsyncBuild) state._occAsyncBuild = { pending: false, token: 0 };
1776
1640
  const asyncState = state._occAsyncBuild;
1777
1641
  if (!asyncState.pending) {
1778
1642
  asyncState.pending = true;
@@ -1785,10 +1649,7 @@ export default {
1785
1649
  try {
1786
1650
  _occBuild(opaqueSnapshot);
1787
1651
  } finally {
1788
- if (
1789
- state._occAsyncBuild &&
1790
- state._occAsyncBuild.token === token
1791
- ) {
1652
+ if (state._occAsyncBuild && state._occAsyncBuild.token === token) {
1792
1653
  state._occAsyncBuild.pending = false;
1793
1654
  }
1794
1655
  }
@@ -1798,16 +1659,13 @@ export default {
1798
1659
  _occBuild(opaqueCandidates);
1799
1660
  }
1800
1661
  } else {
1801
- if (occObjs.boxes && occObjs.boxes.mesh)
1802
- occObjs.boxes.mesh.visible = false;
1803
- if (occObjs.batch1 && occObjs.batch1.mesh)
1804
- occObjs.batch1.mesh.visible = false;
1662
+ if (occObjs.boxes && occObjs.boxes.mesh) occObjs.boxes.mesh.visible = false;
1663
+ if (occObjs.batch1 && occObjs.batch1.mesh) occObjs.batch1.mesh.visible = false;
1805
1664
  state._occMaxIdx = 0;
1806
1665
  activeIdIndexArr.length = 0;
1807
1666
  }
1808
1667
 
1809
- if (!state._occTransparentScene)
1810
- state._occTransparentScene = new this.THREE.Scene();
1668
+ if (!state._occTransparentScene) state._occTransparentScene = new this.THREE.Scene();
1811
1669
  let transparentMesh = state._occTransparentMesh;
1812
1670
  const transparentCapacity =
1813
1671
  transparentMesh &&
@@ -1823,7 +1681,7 @@ export default {
1823
1681
  }
1824
1682
  const nextCap = Math.max(
1825
1683
  transparentTotal,
1826
- transparentCapacity > 0 ? transparentCapacity * 2 : 256,
1684
+ transparentCapacity > 0 ? transparentCapacity * 2 : 256
1827
1685
  );
1828
1686
  const geometry = new this.THREE.BoxGeometry(1, 1, 1);
1829
1687
  const material = new this.THREE.MeshBasicMaterial({
@@ -1834,11 +1692,7 @@ export default {
1834
1692
  depthWrite: false,
1835
1693
  toneMapped: false,
1836
1694
  });
1837
- transparentMesh = new this.THREE.InstancedMesh(
1838
- geometry,
1839
- material,
1840
- nextCap,
1841
- );
1695
+ transparentMesh = new this.THREE.InstancedMesh(geometry, material, nextCap);
1842
1696
  transparentMesh.frustumCulled = false;
1843
1697
  transparentMesh.matrixAutoUpdate = false;
1844
1698
  transparentMesh.userData.capacity = nextCap;
@@ -1866,10 +1720,7 @@ export default {
1866
1720
  tempMatrix.copy(matrix);
1867
1721
  tempScale.copy(halfSize).multiplyScalar(2);
1868
1722
  tempMatrix.scale(tempScale);
1869
- if (
1870
- typeof bizToThreeMatrix !== 'undefined' &&
1871
- bizToThreeMatrix
1872
- ) {
1723
+ if (typeof bizToThreeMatrix !== 'undefined' && bizToThreeMatrix) {
1873
1724
  tempMatrix.premultiply(bizToThreeMatrix);
1874
1725
  }
1875
1726
  } else {
@@ -1886,8 +1737,7 @@ export default {
1886
1737
  transparentMesh.count = transparentTotal;
1887
1738
  transparentMesh.visible = true;
1888
1739
  transparentMesh.instanceMatrix.needsUpdate = true;
1889
- if (transparentMesh.instanceColor)
1890
- transparentMesh.instanceColor.needsUpdate = true;
1740
+ if (transparentMesh.instanceColor) transparentMesh.instanceColor.needsUpdate = true;
1891
1741
  const tMaxIdx = tIdx - 1;
1892
1742
  transparentIdIndexArr.length = tMaxIdx + 1;
1893
1743
  state._occTransparentMaxIdx = tMaxIdx;
@@ -1900,18 +1750,14 @@ export default {
1900
1750
 
1901
1751
  // console.log('renderer', renderer)
1902
1752
  const prevToneMapping = renderer.toneMapping;
1903
- const prevTarget = renderer.getRenderTarget
1904
- ? renderer.getRenderTarget()
1905
- : null;
1753
+ const prevTarget = renderer.getRenderTarget ? renderer.getRenderTarget() : null;
1906
1754
  let prevClearColorHex = 0x000000;
1907
1755
  let prevClearAlpha = 0;
1908
1756
  try {
1909
1757
  const c = renderer.getClearColor ? renderer.getClearColor() : null;
1910
1758
  if (c && c.isColor) prevClearColorHex = c.getHex();
1911
1759
  prevClearAlpha =
1912
- typeof renderer.getClearAlpha === 'function'
1913
- ? renderer.getClearAlpha()
1914
- : 0;
1760
+ typeof renderer.getClearAlpha === 'function' ? renderer.getClearAlpha() : 0;
1915
1761
  } catch (_) {}
1916
1762
  renderer.toneMapping = this.THREE.NoToneMapping;
1917
1763
  renderer.setRenderTarget(rt);
@@ -1919,9 +1765,7 @@ export default {
1919
1765
  renderer.clear(true, true, false);
1920
1766
  camera.updateMatrixWorld(true);
1921
1767
  renderer.render(state._occScene, camera);
1922
- sceneBoundingBox = new this.THREE.Box3().setFromObject(
1923
- state._occScene,
1924
- );
1768
+ sceneBoundingBox = new this.THREE.Box3().setFromObject(state._occScene);
1925
1769
  // const t1 = performance.now();
1926
1770
  // 从响应式对象读取 previewEnabled
1927
1771
  this.$emit('updateBoundingBox');
@@ -1940,10 +1784,7 @@ export default {
1940
1784
  state._previewCanvas = cvs;
1941
1785
  state._previewCtx = cvs.getContext('2d');
1942
1786
  }
1943
- if (
1944
- !state._previewBuffer ||
1945
- state._previewBuffer.length !== sw * sh * 4
1946
- ) {
1787
+ if (!state._previewBuffer || state._previewBuffer.length !== sw * sh * 4) {
1947
1788
  state._previewBuffer = new Uint8Array(sw * sh * 4);
1948
1789
  }
1949
1790
  state._previewCanvas.width = sw;
@@ -1952,23 +1793,13 @@ export default {
1952
1793
  const cssH = Math.min(renderer.domElement.height / 5);
1953
1794
  state._previewCanvas.style.width = cssW + 'px';
1954
1795
  state._previewCanvas.style.height = cssH + 'px';
1955
- renderer.readRenderTargetPixels(
1956
- rt,
1957
- 0,
1958
- 0,
1959
- sw,
1960
- sh,
1961
- state._previewBuffer,
1962
- );
1796
+ renderer.readRenderTargetPixels(rt, 0, 0, sw, sh, state._previewBuffer);
1963
1797
  if (
1964
1798
  !state._previewImageData ||
1965
1799
  state._previewImageData.width !== sw ||
1966
1800
  state._previewImageData.height !== sh
1967
1801
  ) {
1968
- state._previewImageData = state._previewCtx.createImageData(
1969
- sw,
1970
- sh,
1971
- );
1802
+ state._previewImageData = state._previewCtx.createImageData(sw, sh);
1972
1803
  }
1973
1804
  const dst = state._previewImageData.data;
1974
1805
  const src = state._previewBuffer;
@@ -1981,9 +1812,7 @@ export default {
1981
1812
  } else {
1982
1813
  if (state._previewCanvas) {
1983
1814
  if (state._previewCanvas.parentNode)
1984
- state._previewCanvas.parentNode.removeChild(
1985
- state._previewCanvas,
1986
- );
1815
+ state._previewCanvas.parentNode.removeChild(state._previewCanvas);
1987
1816
  state._previewCanvas = null;
1988
1817
  state._previewCtx = null;
1989
1818
  state._previewBuffer = null;
@@ -1995,13 +1824,12 @@ export default {
1995
1824
  renderer.readRenderTargetPixels(rt, 0, 0, sw, sh, state._colorBuffer);
1996
1825
 
1997
1826
  const idIndexArr = activeIdIndexArr;
1998
- const maxIdx =
1999
- typeof state._occMaxIdx === 'number' ? state._occMaxIdx : 0;
1827
+ const maxIdx = typeof state._occMaxIdx === 'number' ? state._occMaxIdx : 0;
2000
1828
  const totalPixels = sw * sh;
2001
1829
  const targetSamples = totalPixels;
2002
1830
  const baseStride = Math.max(
2003
1831
  1,
2004
- Math.floor(Math.sqrt(totalPixels / Math.max(1, targetSamples))),
1832
+ Math.floor(Math.sqrt(totalPixels / Math.max(1, targetSamples)))
2005
1833
  );
2006
1834
  const extraStride =
2007
1835
  this.occlusionState && this.occlusionState.sampleStride
@@ -2018,13 +1846,12 @@ export default {
2018
1846
  sh,
2019
1847
  stride,
2020
1848
  maxIdx,
2021
- minSampleCount,
1849
+ minSampleCount
2022
1850
  );
2023
1851
  if (scanResult && scanResult.buffer) {
2024
1852
  state._colorBuffer = new Uint8Array(scanResult.buffer);
2025
1853
  }
2026
- const indices =
2027
- scanResult && scanResult.indices ? scanResult.indices : [];
1854
+ const indices = scanResult && scanResult.indices ? scanResult.indices : [];
2028
1855
  for (let i = 0; i < indices.length; i++) {
2029
1856
  const id = idIndexArr[indices[i]];
2030
1857
  if (typeof id !== 'undefined') {
@@ -2033,25 +1860,12 @@ export default {
2033
1860
  }
2034
1861
 
2035
1862
  const transparentMaxIdx =
2036
- typeof state._occTransparentMaxIdx === 'number'
2037
- ? state._occTransparentMaxIdx
2038
- : 0;
2039
- if (
2040
- transparentMaxIdx > 0 &&
2041
- transparentMesh &&
2042
- transparentMesh.visible
2043
- ) {
1863
+ typeof state._occTransparentMaxIdx === 'number' ? state._occTransparentMaxIdx : 0;
1864
+ if (transparentMaxIdx > 0 && transparentMesh && transparentMesh.visible) {
2044
1865
  renderer.setClearColor(new this.THREE.Color(0, 0, 0), 0);
2045
1866
  renderer.clear(true, false, false);
2046
1867
  renderer.render(state._occTransparentScene, camera);
2047
- renderer.readRenderTargetPixels(
2048
- rt,
2049
- 0,
2050
- 0,
2051
- sw,
2052
- sh,
2053
- state._colorBuffer,
2054
- );
1868
+ renderer.readRenderTargetPixels(rt, 0, 0, sw, sh, state._colorBuffer);
2055
1869
 
2056
1870
  const tIdIndexArr = transparentIdIndexArr;
2057
1871
  const tScanResult = await this.scanOcclusionIndices(
@@ -2060,13 +1874,12 @@ export default {
2060
1874
  sh,
2061
1875
  stride,
2062
1876
  transparentMaxIdx,
2063
- minSampleCount,
1877
+ minSampleCount
2064
1878
  );
2065
1879
  if (tScanResult && tScanResult.buffer) {
2066
1880
  state._colorBuffer = new Uint8Array(tScanResult.buffer);
2067
1881
  }
2068
- const tIndices =
2069
- tScanResult && tScanResult.indices ? tScanResult.indices : [];
1882
+ const tIndices = tScanResult && tScanResult.indices ? tScanResult.indices : [];
2070
1883
  for (let i = 0; i < tIndices.length; i++) {
2071
1884
  const id = tIdIndexArr[tIndices[i]];
2072
1885
  if (typeof id !== 'undefined') {
@@ -2089,17 +1902,15 @@ export default {
2089
1902
  }
2090
1903
  }
2091
1904
  visibleIds.length = 0;
2092
- visibleIdSet.forEach((id) => visibleIds.push(id));
1905
+ visibleIdSet.forEach(id => visibleIds.push(id));
2093
1906
  const toLoadSet = new Set(visibleIdSet);
2094
1907
  const parentsToCheck = new Set();
2095
- scene.traverse((child) => {
1908
+ scene.traverse(child => {
2096
1909
  if (!child.isInstancedMesh) return;
2097
1910
  // 如果复用数量等于大于2个,则跳过裁剪和剔除处理(始终保留)
2098
1911
  if (child.count >= 2) {
2099
1912
  let instancesMap =
2100
- child &&
2101
- child.userData &&
2102
- child.userData.instancesMap instanceof Map
1913
+ child && child.userData && child.userData.instancesMap instanceof Map
2103
1914
  ? child.userData.instancesMap
2104
1915
  : child.parent &&
2105
1916
  child.parent.userData &&
@@ -2120,8 +1931,7 @@ export default {
2120
1931
  return;
2121
1932
  }
2122
1933
 
2123
- if (bypassList && bypassList.size > 0 && bypassList.has(modelId))
2124
- return;
1934
+ if (bypassList && bypassList.size > 0 && bypassList.has(modelId)) return;
2125
1935
 
2126
1936
  const instanceInfo = instancesMap.get(modelId);
2127
1937
  const instanceIndex =
@@ -2129,11 +1939,7 @@ export default {
2129
1939
  ? instanceInfo.instanceIndex
2130
1940
  : null;
2131
1941
 
2132
- const inFrustum = this.isModelInFrustum(
2133
- child,
2134
- instanceIndex,
2135
- globalFrustum,
2136
- );
1942
+ const inFrustum = this.isModelInFrustum(child, instanceIndex, globalFrustum);
2137
1943
  const modelInVisible = toLoadSet.has(modelId);
2138
1944
  // console.log('modelId', modelId, 'inFrustum', inFrustum, 'modelInVisible', modelInVisible)
2139
1945
 
@@ -2162,13 +1968,10 @@ export default {
2162
1968
  return;
2163
1969
  }
2164
1970
  const modelId =
2165
- child.parent &&
2166
- child.parent.userData &&
2167
- child.parent.userData.instanceId
1971
+ child.parent && child.parent.userData && child.parent.userData.instanceId
2168
1972
  ? child.parent.userData.instanceId
2169
1973
  : child.uuid;
2170
- if (bypassList && bypassList.size > 0 && bypassList.has(modelId))
2171
- return;
1974
+ if (bypassList && bypassList.size > 0 && bypassList.has(modelId)) return;
2172
1975
 
2173
1976
  const inFrustum = this.isModelInFrustum(child, null, globalFrustum);
2174
1977
  let modelInVisible = toLoadSet.has(modelId);
@@ -2184,22 +1987,20 @@ export default {
2184
1987
  this.unloadInstancedModel(modelId, child);
2185
1988
  }
2186
1989
  if (scene) {
2187
- parentsToCheck.forEach((group) => {
1990
+ parentsToCheck.forEach(group => {
2188
1991
  if (group && group.children && group.children.length === 0) {
2189
1992
  group.removeFromParent();
2190
1993
  }
2191
1994
  });
2192
1995
  }
2193
- this.modelStateManager.isloadedModelsIds = Object.freeze(
2194
- Array.from(toLoadSet),
2195
- );
1996
+ this.modelStateManager.isloadedModelsIds = Object.freeze(Array.from(toLoadSet));
2196
1997
  },
2197
1998
  isBoxInFrustum(box) {
2198
1999
  if (!camera) return true;
2199
2000
  const frustum = new this.THREE.Frustum();
2200
2001
  const vpMatrix = new this.THREE.Matrix4().multiplyMatrices(
2201
2002
  camera.projectionMatrix,
2202
- camera.matrixWorldInverse,
2003
+ camera.matrixWorldInverse
2203
2004
  );
2204
2005
  frustum.setFromProjectionMatrix(vpMatrix);
2205
2006
  return frustum.intersectsBox(box);
@@ -2217,8 +2018,7 @@ export default {
2217
2018
 
2218
2019
  // 卸载前内存快照
2219
2020
  // this.logRendererMemory(`before unload modelId=${modelId}`);
2220
- const { instanceIndex } =
2221
- instancedMesh.userData.instancesMap.get(modelId) || 0;
2021
+ const { instanceIndex } = instancedMesh.userData.instancesMap.get(modelId) || 0;
2222
2022
  // const instanceIndex = instancedMesh.userData.instanceIndex || 0;
2223
2023
 
2224
2024
  this.removeOutlineInstanceProxy(instancedMesh, instanceIndex);
@@ -2246,8 +2046,7 @@ export default {
2246
2046
  instancedMesh.parent && instancedMesh.parent.matrixWorld
2247
2047
  ? instancedMesh.parent.matrixWorld.clone()
2248
2048
  : new this.THREE.Matrix4();
2249
- instanceInfo.count =
2250
- typeof instancedMesh.count === 'number' ? instancedMesh.count : 1;
2049
+ instanceInfo.count = typeof instancedMesh.count === 'number' ? instancedMesh.count : 1;
2251
2050
 
2252
2051
  const parentGroup = instancedMesh.parent;
2253
2052
  if (parentGroup) {
@@ -2269,7 +2068,7 @@ export default {
2269
2068
 
2270
2069
  if (material) {
2271
2070
  if (Array.isArray(material)) {
2272
- material.forEach((m) => {
2071
+ material.forEach(m => {
2273
2072
  // if (m && !this.isMaterialShared(m)) m.dispose();
2274
2073
  if (m) m.dispose();
2275
2074
  });
@@ -2315,16 +2114,13 @@ export default {
2315
2114
  projectId,
2316
2115
  debug: isDebug,
2317
2116
  renderModelData: this.renderModelData.bind(this),
2318
- ensureNotInteracting: async (abortSignal) => {
2319
- if (
2320
- userInteracting ||
2321
- this.noObserver.batchLoadingState.interactionState.isInteracting
2322
- ) {
2323
- await new Promise((resolve) => setTimeout(resolve, 0));
2117
+ ensureNotInteracting: async abortSignal => {
2118
+ if (userInteracting || this.noObserver.batchLoadingState.interactionState.isInteracting) {
2119
+ await new Promise(resolve => setTimeout(resolve, 0));
2324
2120
  }
2325
2121
  },
2326
2122
  batchSize: this.noObserver.batchLoadingState.batchSize,
2327
- onCancelRequestId: async (requestId) => {
2123
+ onCancelRequestId: async requestId => {
2328
2124
  if (modelApi && typeof modelApi.postCanceledRequest === 'function') {
2329
2125
  return await modelApi.postCanceledRequest(requestId);
2330
2126
  }
@@ -2338,11 +2134,9 @@ export default {
2338
2134
  this.noObserver.occlusionWorker = streamLoader.worker;
2339
2135
  this.noObserver.occlusionWorkerRequestId = 0;
2340
2136
  this.noObserver.occlusionWorkerRequestMap = new Map();
2341
- streamLoader.worker.addEventListener('message', (e) => {
2137
+ streamLoader.worker.addEventListener('message', e => {
2342
2138
  const payload = e.data || {};
2343
- const pending = this.noObserver.occlusionWorkerRequestMap.get(
2344
- payload.id,
2345
- );
2139
+ const pending = this.noObserver.occlusionWorkerRequestMap.get(payload.id);
2346
2140
  if (!pending) return;
2347
2141
  this.noObserver.occlusionWorkerRequestMap.delete(payload.id);
2348
2142
  pending.resolve(payload);
@@ -2372,11 +2166,7 @@ export default {
2372
2166
  */
2373
2167
  async batchLoadRegions(item, divideData, materialData) {
2374
2168
  if (this.noObserver.streamLoader) {
2375
- await this.noObserver.streamLoader.batchLoadRegions(
2376
- item,
2377
- divideData,
2378
- materialData,
2379
- );
2169
+ await this.noObserver.streamLoader.batchLoadRegions(item, divideData, materialData);
2380
2170
  }
2381
2171
  },
2382
2172
 
@@ -2398,10 +2188,7 @@ export default {
2398
2188
  * 处理单个模型项加载(供外部调用)
2399
2189
  */
2400
2190
  async processModelItem(item, options = {}) {
2401
- const res = await this.noObserver.streamLoader.processModelItem(
2402
- item,
2403
- options,
2404
- );
2191
+ const res = await this.noObserver.streamLoader.processModelItem(item, options);
2405
2192
  // item.id is the documentId
2406
2193
  if (item && item.id) {
2407
2194
  if (res && res.sceneBox) {
@@ -2410,6 +2197,7 @@ export default {
2410
2197
  if (res && res.boxIndex) {
2411
2198
  this.setBoxIndex(res.boxIndex, item.id, true);
2412
2199
  }
2200
+ this.tryInitialCenterAfterBoundsReady();
2413
2201
  // this.setBoxIndex(boxJson.data, item.id, true);
2414
2202
  }
2415
2203
 
@@ -2432,23 +2220,32 @@ export default {
2432
2220
  this.setSceneBox(null, documentId, false);
2433
2221
  this.setBoxIndex(null, documentId, false);
2434
2222
  },
2223
+ /**
2224
+ * 同步获取当前WebGL画面的截图数据,解决preserveDrawingBuffer为false时html2canvas截黑屏的问题
2225
+ */
2226
+ getScreenshotDataURL() {
2227
+ if (!renderer || !scene || !camera) return null;
2435
2228
 
2229
+ // 强制渲染一帧
2230
+ if (outlineComposer) {
2231
+ outlineComposer.render();
2232
+ } else {
2233
+ renderer.render(scene, camera);
2234
+ }
2235
+
2236
+ // 立即同步提取像素数据
2237
+ return renderer.domElement.toDataURL('image/png', 1.0);
2238
+ },
2436
2239
  /**
2437
2240
  * 内部渲染流式数据方法
2438
2241
  */
2439
- renderModelData(
2440
- meshes,
2441
- primitives,
2442
- list,
2443
- range,
2444
- onComplete,
2445
- immediateUpdate,
2446
- ) {
2242
+ renderModelData(meshes, primitives, list, range, onComplete, immediateUpdate) {
2447
2243
  // 构造 drawModel 需要的数据格式
2448
2244
  const modelRegistry = this.noObserver.streamLoader.modelRegistry;
2449
2245
  const modelRecords = Array.from(modelRegistry.values());
2450
2246
  const material = [];
2451
- modelRecords.forEach((record) => {
2247
+ const mergeMaterial = [];
2248
+ modelRecords.forEach(record => {
2452
2249
  if (record.materialData) {
2453
2250
  if (Array.isArray(record.materialData)) {
2454
2251
  material.push(...record.materialData);
@@ -2456,10 +2253,19 @@ export default {
2456
2253
  material.push(record.materialData);
2457
2254
  }
2458
2255
  }
2256
+
2257
+ if (record.mergeMaterialData) {
2258
+ if (Array.isArray(record.mergeMaterialData)) {
2259
+ mergeMaterial.push(...record.mergeMaterialData);
2260
+ } else {
2261
+ mergeMaterial.push(record.mergeMaterialData);
2262
+ }
2263
+ }
2459
2264
  });
2460
2265
 
2461
2266
  const regionModelData = {
2462
2267
  material,
2268
+ mergeMaterial,
2463
2269
  primitive: primitives,
2464
2270
  mesh: meshes, // 注意这里 meshes 对应 drawModel 的 data.mesh (如果它是单个) 或处理逻辑
2465
2271
  };
@@ -2598,7 +2404,7 @@ export default {
2598
2404
  outlinePass = new OutlinePass(
2599
2405
  new this.THREE.Vector2(window.innerWidth, window.innerHeight),
2600
2406
  scene,
2601
- camera,
2407
+ camera
2602
2408
  );
2603
2409
  outlinePass.edgeStrength = 3;
2604
2410
  outlinePass.edgeGlow = 0.5; // 边缘模糊度
@@ -2623,7 +2429,7 @@ export default {
2623
2429
  45,
2624
2430
  window.innerWidth / window.innerHeight,
2625
2431
  0.1,
2626
- 1000000,
2432
+ 1000000
2627
2433
  );
2628
2434
  // camera.position.set(0, 100, 150);
2629
2435
  },
@@ -2655,7 +2461,7 @@ export default {
2655
2461
 
2656
2462
  // 1. 创建统一的响应触发器 (Debounced)
2657
2463
  this._cameraChangeObserver = this.debounce(
2658
- async (source) => {
2464
+ async source => {
2659
2465
  // 如果观察者被禁用,则不执行后续逻辑
2660
2466
  if (!this.noObserver.isObserverEnabled) {
2661
2467
  return;
@@ -2690,14 +2496,14 @@ export default {
2690
2496
  this.getRangeStream(false);
2691
2497
  }
2692
2498
  },
2693
- (source) => {
2499
+ source => {
2694
2500
  // 漫游模式下,或者第一人称移动时,使用节流策略(每300ms触发一次)
2695
2501
  // 避免在持续运动中因防抖重置定时器而无法触发
2696
2502
  if (source === 'roam' || source === 'firstPersonMove') {
2697
2503
  return { type: 'throttle', limit: 1000 };
2698
2504
  }
2699
2505
  return 300; // 默认防抖 300ms
2700
- },
2506
+ }
2701
2507
  );
2702
2508
 
2703
2509
  // 2. 公开API:允许外部或业务逻辑手动触发更新
@@ -2706,7 +2512,7 @@ export default {
2706
2512
  };
2707
2513
 
2708
2514
  // 3. 监听器 - Wheel (用户滚轮)
2709
- this._wheelHandler = (res) => {
2515
+ this._wheelHandler = res => {
2710
2516
  this.$emit('wheelStart', res);
2711
2517
 
2712
2518
  // 统一交互开始处理
@@ -2717,8 +2523,7 @@ export default {
2717
2523
 
2718
2524
  // 滚轮逻辑:infinityDolly 与 maxDollyDistance 控制
2719
2525
  const event = res;
2720
- const deltaY =
2721
- event && typeof event.deltaY === 'number' ? event.deltaY : 0;
2526
+ const deltaY = event && typeof event.deltaY === 'number' ? event.deltaY : 0;
2722
2527
  const isZoomOut = deltaY > 0; // 远离
2723
2528
  const isZoomIn = deltaY < 0; // 靠近
2724
2529
 
@@ -2733,13 +2538,10 @@ export default {
2733
2538
  if (sceneBoundingBox && isFinite(maxDollyDistance)) {
2734
2539
  if (isZoomOut) {
2735
2540
  camera.updateMatrixWorld(true);
2736
- const currentDistance = camera.position.distanceTo(
2737
- cameraControls._target,
2738
- );
2541
+ const currentDistance = camera.position.distanceTo(cameraControls._target);
2739
2542
  if (currentDistance >= maxDollyDistance) {
2740
2543
  event.preventDefault && event.preventDefault();
2741
- event.stopImmediatePropagation &&
2742
- event.stopImmediatePropagation();
2544
+ event.stopImmediatePropagation && event.stopImmediatePropagation();
2743
2545
  return;
2744
2546
  }
2745
2547
  }
@@ -2754,7 +2556,7 @@ export default {
2754
2556
  renderer.domElement.addEventListener('wheel', this._wheelHandler);
2755
2557
 
2756
2558
  // 4. 监听器 - Controls (用户拖拽/操作)
2757
- this._onControlStart = (res) => {
2559
+ this._onControlStart = res => {
2758
2560
  this.noObserver.isControlActive = true;
2759
2561
 
2760
2562
  // 统一交互开始处理(相机)
@@ -2770,7 +2572,7 @@ export default {
2770
2572
  }
2771
2573
  };
2772
2574
 
2773
- this._onControlEnd = (res) => {
2575
+ this._onControlEnd = res => {
2774
2576
  this.noObserver.isControlActive = false;
2775
2577
 
2776
2578
  this.$emit('controlEnd', res);
@@ -2821,10 +2623,7 @@ export default {
2821
2623
  // 初始化光源
2822
2624
  initLight() {
2823
2625
  const pmremGenerator = new this.THREE.PMREMGenerator(renderer);
2824
- scene.environment = pmremGenerator.fromScene(
2825
- new RoomEnvironment(),
2826
- 0.04,
2827
- ).texture;
2626
+ scene.environment = pmremGenerator.fromScene(new RoomEnvironment(), 0.04).texture;
2828
2627
  },
2829
2628
  // 初始化文字画布
2830
2629
  initLabelRender() {
@@ -2851,16 +2650,16 @@ export default {
2851
2650
  color,
2852
2651
  meshNameConfig,
2853
2652
  options,
2854
- (progress) => {
2653
+ progress => {
2855
2654
  // 触发原有的进度事件
2856
2655
  this.$emit('loadProgress', progress);
2857
2656
  },
2858
- (complete) => {
2657
+ complete => {
2859
2658
  options?.onComplete?.(complete);
2860
2659
  console.log('加载完成');
2861
2660
  // 触发原有的完成事件
2862
2661
  this.$emit('loadComplete');
2863
- },
2662
+ }
2864
2663
  );
2865
2664
  },
2866
2665
  // 动态设置视角滚轮的距离
@@ -2917,24 +2716,15 @@ export default {
2917
2716
  mouse.x = (x / rect.width) * 2 - 1;
2918
2717
  mouse.y = -(y / rect.height) * 2 + 1;
2919
2718
  raycaster.setFromCamera(mouse, camera);
2920
- return scene && scene.children
2921
- ? raycaster.intersectObjects(scene.children, true)
2922
- : [];
2719
+ return scene && scene.children ? raycaster.intersectObjects(scene.children, true) : [];
2923
2720
  },
2924
2721
  getInstanceId(instancedMesh, instanceIndex, options) {
2925
- if (
2926
- !instancedMesh ||
2927
- instanceIndex === undefined ||
2928
- instanceIndex === null
2929
- ) {
2722
+ if (!instancedMesh || instanceIndex === undefined || instanceIndex === null) {
2930
2723
  return null;
2931
2724
  }
2932
2725
  const meshName = instancedMesh.name;
2933
2726
  for (const props of instancedMesh.userData.instancesMap.values()) {
2934
- if (
2935
- props.instancedMeshId === meshName &&
2936
- props.instanceIndex === instanceIndex
2937
- ) {
2727
+ if (props.instancedMeshId === meshName && props.instanceIndex === instanceIndex) {
2938
2728
  return props.instanceId;
2939
2729
  }
2940
2730
  }
@@ -2968,10 +2758,7 @@ export default {
2968
2758
  };
2969
2759
  if (intersects.length > 0) {
2970
2760
  this.clearBypassCullingModelIds();
2971
- const instanceId = this.getInstanceId(
2972
- intersects[0].object,
2973
- intersects[0].instanceId,
2974
- );
2761
+ const instanceId = this.getInstanceId(intersects[0].object, intersects[0].instanceId);
2975
2762
  params = {
2976
2763
  objects: [intersects[0].object],
2977
2764
  mousePosition: { x: event.clientX, y: event.clientY },
@@ -3136,31 +2923,18 @@ export default {
3136
2923
  for (const key in ele.attr) {
3137
2924
  switch (key) {
3138
2925
  case 'color':
3139
- targetObj.forEach((children) => {
2926
+ targetObj.forEach(children => {
3140
2927
  if (children.isMesh) {
3141
- const { instanceIndex } = children.userData.instancesMap.get(
3142
- instanceId,
3143
- );
3144
- children.setColorAt(
3145
- instanceIndex,
3146
- new this.THREE.Color(ele.attr[key]),
3147
- );
2928
+ const { instanceIndex } = children.userData.instancesMap.get(instanceId);
2929
+ children.setColorAt(instanceIndex, new this.THREE.Color(ele.attr[key]));
3148
2930
  children.instanceColor.needsUpdate = true;
3149
2931
  if (outlinePass) {
3150
2932
  if (children.isInstancedMesh) {
3151
- const proxy = this.ensureOutlineInstanceProxy(
3152
- children,
3153
- instanceIndex,
3154
- );
3155
- if (
3156
- proxy &&
3157
- !outlinePass.selectedObjects.includes(proxy)
3158
- ) {
2933
+ const proxy = this.ensureOutlineInstanceProxy(children, instanceIndex);
2934
+ if (proxy && !outlinePass.selectedObjects.includes(proxy)) {
3159
2935
  outlinePass.selectedObjects.push(proxy);
3160
2936
  }
3161
- } else if (
3162
- !outlinePass.selectedObjects.includes(children)
3163
- ) {
2937
+ } else if (!outlinePass.selectedObjects.includes(children)) {
3164
2938
  outlinePass.selectedObjects.push(children);
3165
2939
  }
3166
2940
  }
@@ -3177,14 +2951,10 @@ export default {
3177
2951
  boxData.userData.visible = ele.attr[key];
3178
2952
  }
3179
2953
  }
3180
- targetObj.forEach((children) => {
3181
- const { instanceIndex } = children.userData.instancesMap.get(
3182
- instanceId,
3183
- );
2954
+ targetObj.forEach(children => {
2955
+ const { instanceIndex } = children.userData.instancesMap.get(instanceId);
3184
2956
  if (ele.attr[key]) {
3185
- const restoreMatrix = new this.THREE.Matrix4().copy(
3186
- children.userData.copyMatrix,
3187
- );
2957
+ const restoreMatrix = new this.THREE.Matrix4().copy(children.userData.copyMatrix);
3188
2958
  children.setMatrixAt(instanceIndex, restoreMatrix);
3189
2959
  // if (outlinePass) {
3190
2960
  // if (children.isInstancedMesh) {
@@ -3206,8 +2976,7 @@ export default {
3206
2976
  this.removeOutlineInstanceProxy(children, instanceIndex);
3207
2977
  } else {
3208
2978
  const idx = outlinePass.selectedObjects.indexOf(children);
3209
- if (idx !== -1)
3210
- outlinePass.selectedObjects.splice(idx, 1);
2979
+ if (idx !== -1) outlinePass.selectedObjects.splice(idx, 1);
3211
2980
  }
3212
2981
  }
3213
2982
  }
@@ -3216,24 +2985,18 @@ export default {
3216
2985
  this.notifyCameraChange(); // 触发场景更新
3217
2986
  break;
3218
2987
  case 'opacity':
3219
- targetObj.forEach((children) => {
2988
+ targetObj.forEach(children => {
3220
2989
  if (children.isMesh) {
3221
2990
  const opacity = children.geometry.attributes.opacity.array;
3222
- const { instanceIndex } = children.userData.instancesMap.get(
3223
- instanceId,
3224
- );
2991
+ const { instanceIndex } = children.userData.instancesMap.get(instanceId);
3225
2992
  opacity[instanceIndex] = ele.attr[key];
3226
2993
  children.geometry.attributes.opacity.needsUpdate = true;
3227
2994
  }
3228
2995
  });
3229
2996
  break;
3230
2997
  case 'position':
3231
- targetObj.forEach((children) => {
3232
- children.position.set(
3233
- ele.attr[key].x,
3234
- ele.attr[key].y,
3235
- ele.attr[key].z,
3236
- );
2998
+ targetObj.forEach(children => {
2999
+ children.position.set(ele.attr[key].x, ele.attr[key].y, ele.attr[key].z);
3237
3000
  });
3238
3001
  break;
3239
3002
  }
@@ -3245,19 +3008,56 @@ export default {
3245
3008
  this.buildOctreeFromBoxIndex();
3246
3009
  }
3247
3010
  },
3011
+ setAllModelVisible(visible) {
3012
+ const isVisible = Boolean(visible);
3013
+ const matrixCache = new this.THREE.Matrix4();
3014
+
3015
+ if (this._boxIndex && this._boxIndex.size > 0) {
3016
+ this._boxIndex.forEach(box => {
3017
+ if (!box || !box.userData) return;
3018
+ box.userData.visible = isVisible;
3019
+ });
3020
+ }
3021
+
3022
+ if (scene) {
3023
+ scene.traverse(child => {
3024
+ if (!child || !child.isInstancedMesh) return;
3025
+ const userData = child.userData || {};
3026
+ if (!(userData.instancesMap instanceof Map) || userData.instancesMap.size === 0) return;
3027
+ if (!userData.copyMatrix) return;
3028
+
3029
+ userData.instancesMap.forEach(instanceInfo => {
3030
+ const instanceIndex =
3031
+ instanceInfo && typeof instanceInfo.instanceIndex === 'number'
3032
+ ? instanceInfo.instanceIndex
3033
+ : null;
3034
+ if (instanceIndex === null) return;
3035
+
3036
+ if (isVisible) {
3037
+ matrixCache.copy(userData.copyMatrix);
3038
+ child.setMatrixAt(instanceIndex, matrixCache);
3039
+ } else {
3040
+ matrixCache.copy(userData.copyMatrix).makeTranslation(9999999, 9999999, 9999999);
3041
+ child.setMatrixAt(instanceIndex, matrixCache);
3042
+ }
3043
+ });
3044
+ child.instanceMatrix.needsUpdate = true;
3045
+ });
3046
+ }
3047
+
3048
+ this.notifyCameraChange();
3049
+ if (this._boxIndex) {
3050
+ this.buildOctreeFromBoxIndex();
3051
+ }
3052
+ },
3248
3053
  showOutlinePass(instanceId) {
3249
3054
  let targetObj = this.getObjectByName(instanceId);
3250
- targetObj.forEach((children) => {
3055
+ targetObj.forEach(children => {
3251
3056
  if (children.isMesh) {
3252
- const { instanceIndex } = children.userData.instancesMap.get(
3253
- instanceId,
3254
- );
3057
+ const { instanceIndex } = children.userData.instancesMap.get(instanceId);
3255
3058
  if (outlinePass) {
3256
3059
  if (children.isInstancedMesh) {
3257
- const proxy = this.ensureOutlineInstanceProxy(
3258
- children,
3259
- instanceIndex,
3260
- );
3060
+ const proxy = this.ensureOutlineInstanceProxy(children, instanceIndex);
3261
3061
  if (proxy && !outlinePass.selectedObjects.includes(proxy)) {
3262
3062
  outlinePass.selectedObjects.push(proxy);
3263
3063
  }
@@ -3270,11 +3070,9 @@ export default {
3270
3070
  },
3271
3071
  hideOutlinePass(instanceId) {
3272
3072
  let targetObj = this.getObjectByName(instanceId);
3273
- targetObj.forEach((children) => {
3073
+ targetObj.forEach(children => {
3274
3074
  if (children.isMesh) {
3275
- const { instanceIndex } = children.userData.instancesMap.get(
3276
- instanceId,
3277
- );
3075
+ const { instanceIndex } = children.userData.instancesMap.get(instanceId);
3278
3076
  if (outlinePass) {
3279
3077
  if (children.isInstancedMesh) {
3280
3078
  this.removeOutlineInstanceProxy(children, instanceIndex);
@@ -3312,11 +3110,9 @@ export default {
3312
3110
  for (const key in ele.attr) {
3313
3111
  switch (key) {
3314
3112
  case 'nColor':
3315
- targetObj.forEach((children) => {
3113
+ targetObj.forEach(children => {
3316
3114
  if (children.isMesh) {
3317
- children.material.userData[key] = new this.THREE.Color(
3318
- ele.attr[key],
3319
- );
3115
+ children.material.userData[key] = new this.THREE.Color(ele.attr[key]);
3320
3116
  }
3321
3117
  });
3322
3118
  break;
@@ -3334,18 +3130,12 @@ export default {
3334
3130
  for (const key in ele.attr) {
3335
3131
  switch (key) {
3336
3132
  case 'nColor':
3337
- targetObj.forEach((children) => {
3133
+ targetObj.forEach(children => {
3338
3134
  if (children.isMesh) {
3339
- const { instanceIndex } = children.userData.instancesMap.get(
3340
- instanceId,
3341
- );
3342
- children.setColorAt(
3343
- instanceIndex,
3344
- children.material.userData['oColor'],
3345
- );
3135
+ const { instanceIndex } = children.userData.instancesMap.get(instanceId);
3136
+ children.setColorAt(instanceIndex, children.material.userData['oColor']);
3346
3137
  children.instanceColor.needsUpdate = true;
3347
- children.material.userData[key] =
3348
- children.material.userData['oColor'];
3138
+ children.material.userData[key] = children.material.userData['oColor'];
3349
3139
  }
3350
3140
  });
3351
3141
  break;
@@ -3363,55 +3153,37 @@ export default {
3363
3153
  for (const key in ele.attr) {
3364
3154
  switch (key) {
3365
3155
  case 'color':
3366
- obj.forEach((children) => {
3156
+ obj.forEach(children => {
3367
3157
  if (children.isMesh) {
3368
- const {
3369
- instanceIndex,
3370
- } = children.userData.instancesMap.get(instanceId);
3371
- children.setColorAt(
3372
- instanceIndex,
3373
- children.material.userData.nColor,
3374
- );
3158
+ const { instanceIndex } = children.userData.instancesMap.get(instanceId);
3159
+ children.setColorAt(instanceIndex, children.material.userData.nColor);
3375
3160
  children.instanceColor.needsUpdate = true;
3376
3161
  if (outlinePass) {
3377
3162
  if (children.isInstancedMesh) {
3378
- this.removeOutlineInstanceProxy(
3379
- children,
3380
- instanceIndex,
3381
- );
3163
+ this.removeOutlineInstanceProxy(children, instanceIndex);
3382
3164
  } else {
3383
- const idx = outlinePass.selectedObjects.indexOf(
3384
- children,
3385
- );
3386
- if (idx !== -1)
3387
- outlinePass.selectedObjects.splice(idx, 1);
3165
+ const idx = outlinePass.selectedObjects.indexOf(children);
3166
+ if (idx !== -1) outlinePass.selectedObjects.splice(idx, 1);
3388
3167
  }
3389
3168
  }
3390
3169
  }
3391
3170
  });
3392
3171
  break;
3393
3172
  case 'visible':
3394
- obj.forEach((children) => {
3395
- const {
3396
- instanceIndex,
3397
- copyMatrix,
3398
- } = children.userData.instancesMap.get(instanceId);
3399
- const restoreMatrix = new this.THREE.Matrix4().copy(
3400
- copyMatrix,
3401
- );
3173
+ obj.forEach(children => {
3174
+ const { instanceIndex, copyMatrix } =
3175
+ children.userData.instancesMap.get(instanceId);
3176
+ const restoreMatrix = new this.THREE.Matrix4().copy(copyMatrix);
3402
3177
  children.setMatrixAt(instanceIndex, restoreMatrix);
3403
3178
  children.instanceMatrix.needsUpdate = true;
3404
3179
  });
3405
3180
  break;
3406
3181
  case 'opacity':
3407
- obj.forEach((children) => {
3182
+ obj.forEach(children => {
3408
3183
  if (children.isMesh) {
3409
- const {
3410
- instanceIndex,
3411
- } = children.userData.instancesMap.get(instanceId);
3184
+ const { instanceIndex } = children.userData.instancesMap.get(instanceId);
3412
3185
  const opacity = children.geometry.attributes.opacity.array;
3413
- opacity[instanceIndex] =
3414
- children.material.userData.nOpacity;
3186
+ opacity[instanceIndex] = children.material.userData.nOpacity;
3415
3187
  children.geometry.attributes.opacity.needsUpdate = true;
3416
3188
  }
3417
3189
  });
@@ -3426,9 +3198,9 @@ export default {
3426
3198
  if (!scene) return;
3427
3199
  if (Array.isArray(name)) {
3428
3200
  const box3 = new this.THREE.Box3();
3429
- name.forEach((n) => {
3201
+ name.forEach(n => {
3430
3202
  const arr = this.getObjectByName(n);
3431
- arr.forEach((o) => {
3203
+ arr.forEach(o => {
3432
3204
  box3.expandByObject(o);
3433
3205
  });
3434
3206
  });
@@ -3466,17 +3238,14 @@ export default {
3466
3238
  */
3467
3239
  updatePropertyByCustom(params) {
3468
3240
  if (!scene) return;
3469
- scene.traverse((child) => {
3470
- if (
3471
- child.isMesh &&
3472
- child.userData[params.customName] === params.customValue
3473
- ) {
3241
+ scene.traverse(child => {
3242
+ if (child.isMesh && child.userData[params.customName] === params.customValue) {
3474
3243
  for (const key in params.attr) {
3475
3244
  switch (key) {
3476
3245
  case 'color':
3477
3246
  child.setColorAt(
3478
3247
  obj.userData.instanceIndex,
3479
- new this.THREE.Color(params.attr[key]),
3248
+ new this.THREE.Color(params.attr[key])
3480
3249
  );
3481
3250
  child.instanceColor.needsUpdate = true;
3482
3251
  break;
@@ -3508,7 +3277,7 @@ export default {
3508
3277
  params.heading,
3509
3278
  params.pitch,
3510
3279
  params.roll,
3511
- enableTransition,
3280
+ enableTransition
3512
3281
  );
3513
3282
  cameraControls.update(0);
3514
3283
  },
@@ -3533,14 +3302,10 @@ export default {
3533
3302
  let distance = Math.min(maxDim * 100, baseDistance);
3534
3303
  let direction = new this.THREE.Vector3(1, 1, 1).normalize();
3535
3304
 
3536
- let p = new this.THREE.Vector3()
3537
- .copy(center)
3538
- .add(direction.multiplyScalar(distance));
3305
+ let p = new this.THREE.Vector3().copy(center).add(direction.multiplyScalar(distance));
3539
3306
  let cameraCenter = viewAll
3540
3307
  ? new this.THREE.Vector3(p.x, p.y, p.z)
3541
- : new this.THREE.Vector3(p.x, p.y, p.z).addScalar(
3542
- Math.max(size.x, size.y, size.z),
3543
- );
3308
+ : new this.THREE.Vector3(p.x, p.y, p.z).addScalar(Math.max(size.x, size.y, size.z));
3544
3309
  cameraControls.setLookAt(
3545
3310
  cameraCenter.x,
3546
3311
  cameraCenter.y,
@@ -3548,7 +3313,7 @@ export default {
3548
3313
  center.x,
3549
3314
  center.y,
3550
3315
  center.z,
3551
- true,
3316
+ true
3552
3317
  );
3553
3318
  },
3554
3319
  // 添加广告牌
@@ -3577,14 +3342,9 @@ export default {
3577
3342
  if (!scene) return [];
3578
3343
  let object = [];
3579
3344
  const instancedMeshProps = instanceToInstancedMeshMap.get(name);
3580
- scene.traverse((item) => {
3581
- const tempName = instancedMeshProps
3582
- ? instancedMeshProps.drawObjectId
3583
- : name;
3584
- if (
3585
- item.name == tempName &&
3586
- item.type.toLowerCase() != passType.toLowerCase()
3587
- ) {
3345
+ scene.traverse(item => {
3346
+ const tempName = instancedMeshProps ? instancedMeshProps.drawObjectId : name;
3347
+ if (item.name == tempName && item.type.toLowerCase() != passType.toLowerCase()) {
3588
3348
  object.push(item);
3589
3349
  }
3590
3350
  });
@@ -3607,7 +3367,7 @@ export default {
3607
3367
  : this.modelStateManager;
3608
3368
  if (!modelIds) return;
3609
3369
  if (Array.isArray(modelIds)) {
3610
- modelIds.forEach((id) => {
3370
+ modelIds.forEach(id => {
3611
3371
  const modelId = this.formatModelId(id);
3612
3372
  modelState.bypassCullingModelIds.add(modelId);
3613
3373
  });
@@ -3628,7 +3388,7 @@ export default {
3628
3388
  : this.modelStateManager;
3629
3389
  if (!modelIds) return;
3630
3390
  if (Array.isArray(modelIds)) {
3631
- modelIds.forEach((id) => {
3391
+ modelIds.forEach(id => {
3632
3392
  const modelId = this.formatModelId(id);
3633
3393
  modelState.bypassCullingModelIds.delete(modelId);
3634
3394
  });
@@ -3647,7 +3407,7 @@ export default {
3647
3407
  removeObjectById(id) {
3648
3408
  if (!scene) return;
3649
3409
  let array = this.getObjectByName(id);
3650
- array.forEach((item) => {
3410
+ array.forEach(item => {
3651
3411
  if (item.name === id) {
3652
3412
  item.material && item.material.dispose();
3653
3413
  item.geometry && item.geometry.dispose();
@@ -3662,7 +3422,7 @@ export default {
3662
3422
  removeObjectByName(name) {
3663
3423
  if (!scene) return;
3664
3424
  let array = this.getObjectByName(name);
3665
- array.forEach((item) => {
3425
+ array.forEach(item => {
3666
3426
  item.material && item.material.dispose();
3667
3427
  item.geometry && item.geometry.dispose();
3668
3428
  if (item.isMesh) {
@@ -3673,7 +3433,7 @@ export default {
3673
3433
  },
3674
3434
  // 删除场景中所有的实体
3675
3435
  removeAll() {
3676
- return new Promise((resolve) => {
3436
+ return new Promise(resolve => {
3677
3437
  if (scene) {
3678
3438
  this.removeTraverse();
3679
3439
  this.removeModelByDocumentId();
@@ -3689,7 +3449,7 @@ export default {
3689
3449
  if (length > 0) {
3690
3450
  let list = modelGroup.children[0];
3691
3451
  if (!list) return;
3692
- list.traverse((item) => {
3452
+ list.traverse(item => {
3693
3453
  if (item.isMesh) {
3694
3454
  item.material && item.material.dispose();
3695
3455
  item.geometry && item.geometry.dispose();
@@ -3716,14 +3476,13 @@ export default {
3716
3476
  cancelAnimationFrame(animateId);
3717
3477
 
3718
3478
  if (this.noObserver && this.noObserver.outlineInstanceProxyMap) {
3719
- this.noObserver.outlineInstanceProxyMap.forEach((proxy) => {
3479
+ this.noObserver.outlineInstanceProxyMap.forEach(proxy => {
3720
3480
  if (outlinePass) {
3721
3481
  const idx = outlinePass.selectedObjects.indexOf(proxy);
3722
3482
  if (idx !== -1) outlinePass.selectedObjects.splice(idx, 1);
3723
3483
  }
3724
3484
  if (scene) scene.remove(proxy);
3725
- if (proxy && proxy.material && proxy.material.dispose)
3726
- proxy.material.dispose();
3485
+ if (proxy && proxy.material && proxy.material.dispose) proxy.material.dispose();
3727
3486
  });
3728
3487
  this.noObserver.outlineInstanceProxyMap.clear();
3729
3488
  }
@@ -3778,36 +3537,17 @@ export default {
3778
3537
 
3779
3538
  // 移除鼠标点击/按下事件监听器
3780
3539
  if (renderer && renderer.domElement) {
3781
- renderer.domElement.removeEventListener(
3782
- 'mouseup',
3783
- this.mouseClick,
3784
- false,
3785
- );
3786
- renderer.domElement.removeEventListener(
3787
- 'mousedown',
3788
- this.mouseDown,
3789
- false,
3790
- );
3791
- renderer.domElement.removeEventListener(
3792
- 'pointerup',
3793
- this.mouseClick,
3794
- false,
3795
- );
3796
- renderer.domElement.removeEventListener(
3797
- 'pointerdown',
3798
- this.mouseDown,
3799
- false,
3800
- );
3540
+ renderer.domElement.removeEventListener('mouseup', this.mouseClick, false);
3541
+ renderer.domElement.removeEventListener('mousedown', this.mouseDown, false);
3542
+ renderer.domElement.removeEventListener('pointerup', this.mouseClick, false);
3543
+ renderer.domElement.removeEventListener('pointerdown', this.mouseDown, false);
3801
3544
  }
3802
3545
 
3803
3546
  // 取消 pointer lock 并移除相关键盘事件
3804
3547
  if (pointControls) {
3805
3548
  if (this._onFirstPersonChange) {
3806
3549
  try {
3807
- pointControls.removeEventListener(
3808
- 'change',
3809
- this._onFirstPersonChange,
3810
- );
3550
+ pointControls.removeEventListener('change', this._onFirstPersonChange);
3811
3551
  } catch (e) {}
3812
3552
  this._onFirstPersonChange = null;
3813
3553
  }
@@ -3833,10 +3573,7 @@ export default {
3833
3573
  // 移除 cameraControls 事件监听
3834
3574
  if (cameraControls) {
3835
3575
  if (this._onControlStart)
3836
- cameraControls.removeEventListener(
3837
- 'controlstart',
3838
- this._onControlStart,
3839
- );
3576
+ cameraControls.removeEventListener('controlstart', this._onControlStart);
3840
3577
  if (this._onControlEnd)
3841
3578
  cameraControls.removeEventListener('controlend', this._onControlEnd);
3842
3579
  this._onControlStart = null;
@@ -3871,14 +3608,12 @@ export default {
3871
3608
  drawCurve(params) {
3872
3609
  this.removeObjectByName(params.name);
3873
3610
  const route = [];
3874
- params.path.forEach((element) => {
3611
+ params.path.forEach(element => {
3875
3612
  route.push(new this.THREE.Vector3(element.x, element.y, element.z));
3876
3613
  });
3877
3614
  if (route.length > 1) {
3878
3615
  curve = new this.THREE.CatmullRomCurve3(route);
3879
- const geometryLine = new this.THREE.BufferGeometry().setFromPoints(
3880
- curve.getPoints(5000),
3881
- );
3616
+ const geometryLine = new this.THREE.BufferGeometry().setFromPoints(curve.getPoints(5000));
3882
3617
  const materialLine = new this.THREE.LineBasicMaterial({
3883
3618
  color: params.color,
3884
3619
  depthTest: false,
@@ -3900,7 +3635,7 @@ export default {
3900
3635
  drawTextureCurve(params) {
3901
3636
  this.removeObjectByName(params.name);
3902
3637
  const route = [];
3903
- params.path.forEach((element) => {
3638
+ params.path.forEach(element => {
3904
3639
  route.push(new this.THREE.Vector3(element.x, element.y, element.z));
3905
3640
  });
3906
3641
  // 画曲线
@@ -3909,9 +3644,7 @@ export default {
3909
3644
  curve = new this.THREE.CatmullRomCurve3(route, false, 'catmullrom', 0);
3910
3645
  const geometry = new this.THREE.TubeGeometry(curve, 5000, 0.5, 4);
3911
3646
  //加载纹理
3912
- lineTexture = new this.THREE.TextureLoader().load(
3913
- '/static/arrow/arrow-right.png',
3914
- );
3647
+ lineTexture = new this.THREE.TextureLoader().load('/static/arrow/arrow-right.png');
3915
3648
  lineTexture.wrapS = this.THREE.RepeatWrapping;
3916
3649
  lineTexture.wrapT = this.THREE.RepeatWrapping;
3917
3650
  lineTexture.repeat.set(20, 1); //水平重复20次
@@ -3986,12 +3719,7 @@ export default {
3986
3719
  camera.position.set(point.x, point.y + 5, point.z);
3987
3720
  camera.lookAt(pointBox.x, pointBox.y + 5, pointBox.z);
3988
3721
  cameraControls.setPosition(point.x, point.y + 5, point.z, false);
3989
- cameraControls.setTarget(
3990
- pointBox.x,
3991
- pointBox.y + 5,
3992
- pointBox.z,
3993
- false,
3994
- );
3722
+ cameraControls.setTarget(pointBox.x, pointBox.y + 5, pointBox.z, false);
3995
3723
  progress += roamConfig.speed / 300;
3996
3724
 
3997
3725
  if (typeof this._cameraChangeObserver === 'function') {
@@ -4016,7 +3744,7 @@ export default {
4016
3744
  if (scene.children.length === 0) return;
4017
3745
  for (let i = 0; i < scene.children.length; i++) {
4018
3746
  console.log('scene', scene);
4019
- scene.children[i].traverse((item) => {
3747
+ scene.children[i].traverse(item => {
4020
3748
  if (!item.isMesh || !item.worldDir) return;
4021
3749
  // 爆炸公式
4022
3750
  this.computedBomb(item, val);
@@ -4048,7 +3776,7 @@ export default {
4048
3776
  },
4049
3777
  getClippingPlanes() {
4050
3778
  let clippingPlanesConstant = [];
4051
- renderer.clippingPlanes.forEach((item) => {
3779
+ renderer.clippingPlanes.forEach(item => {
4052
3780
  clippingPlanesConstant.push(item.constant);
4053
3781
  });
4054
3782
  return clippingPlanesConstant;
@@ -4065,39 +3793,27 @@ export default {
4065
3793
  const clippingPlanes = [
4066
3794
  new this.THREE.Plane(
4067
3795
  new this.THREE.Vector3(-1, 0, 0),
4068
- this.clippingPlanesConstants
4069
- ? this.clippingPlanesConstants[0]
4070
- : Math.ceil(max.x),
3796
+ this.clippingPlanesConstants ? this.clippingPlanesConstants[0] : Math.ceil(max.x)
4071
3797
  ),
4072
3798
  new this.THREE.Plane(
4073
3799
  new this.THREE.Vector3(0, -1, 0),
4074
- this.clippingPlanesConstants
4075
- ? this.clippingPlanesConstants[1]
4076
- : Math.ceil(max.y),
3800
+ this.clippingPlanesConstants ? this.clippingPlanesConstants[1] : Math.ceil(max.y)
4077
3801
  ),
4078
3802
  new this.THREE.Plane(
4079
3803
  new this.THREE.Vector3(0, 0, -1),
4080
- this.clippingPlanesConstants
4081
- ? this.clippingPlanesConstants[2]
4082
- : Math.ceil(max.z),
3804
+ this.clippingPlanesConstants ? this.clippingPlanesConstants[2] : Math.ceil(max.z)
4083
3805
  ),
4084
3806
  new this.THREE.Plane(
4085
3807
  new this.THREE.Vector3(1, 0, 0),
4086
- this.clippingPlanesConstants
4087
- ? this.clippingPlanesConstants[3]
4088
- : Math.ceil(-min.x),
3808
+ this.clippingPlanesConstants ? this.clippingPlanesConstants[3] : Math.ceil(-min.x)
4089
3809
  ),
4090
3810
  new this.THREE.Plane(
4091
3811
  new this.THREE.Vector3(0, 1, 0),
4092
- this.clippingPlanesConstants
4093
- ? this.clippingPlanesConstants[4]
4094
- : Math.ceil(-min.y),
3812
+ this.clippingPlanesConstants ? this.clippingPlanesConstants[4] : Math.ceil(-min.y)
4095
3813
  ),
4096
3814
  new this.THREE.Plane(
4097
3815
  new this.THREE.Vector3(0, 0, 1),
4098
- this.clippingPlanesConstants
4099
- ? this.clippingPlanesConstants[5]
4100
- : Math.ceil(-min.z),
3816
+ this.clippingPlanesConstants ? this.clippingPlanesConstants[5] : Math.ceil(-min.z)
4101
3817
  ),
4102
3818
  ];
4103
3819
 
@@ -4126,7 +3842,7 @@ export default {
4126
3842
  z: min.y,
4127
3843
  },
4128
3844
  },
4129
- clippingPlanes,
3845
+ clippingPlanes
4130
3846
  );
4131
3847
  }
4132
3848
  return {
@@ -4173,30 +3889,12 @@ export default {
4173
3889
  const boundingBox = new this.THREE.Box3().copy(obj.boundingBox);
4174
3890
  boundingBox.applyMatrix4(obj.matrixWorld);
4175
3891
  let clippingPlanes = [
4176
- new this.THREE.Plane(
4177
- new this.THREE.Vector3(-1, 0, 0),
4178
- Math.ceil(boundingBox.max.x),
4179
- ),
4180
- new this.THREE.Plane(
4181
- new this.THREE.Vector3(0, -1, 0),
4182
- Math.ceil(boundingBox.max.y),
4183
- ),
4184
- new this.THREE.Plane(
4185
- new this.THREE.Vector3(0, 0, -1),
4186
- Math.ceil(boundingBox.max.z),
4187
- ),
4188
- new this.THREE.Plane(
4189
- new this.THREE.Vector3(1, 0, 0),
4190
- -Math.floor(boundingBox.min.x),
4191
- ),
4192
- new this.THREE.Plane(
4193
- new this.THREE.Vector3(0, 1, 0),
4194
- -Math.floor(boundingBox.min.y),
4195
- ),
4196
- new this.THREE.Plane(
4197
- new this.THREE.Vector3(0, 0, 1),
4198
- -Math.floor(boundingBox.min.z),
4199
- ),
3892
+ new this.THREE.Plane(new this.THREE.Vector3(-1, 0, 0), Math.ceil(boundingBox.max.x)),
3893
+ new this.THREE.Plane(new this.THREE.Vector3(0, -1, 0), Math.ceil(boundingBox.max.y)),
3894
+ new this.THREE.Plane(new this.THREE.Vector3(0, 0, -1), Math.ceil(boundingBox.max.z)),
3895
+ new this.THREE.Plane(new this.THREE.Vector3(1, 0, 0), -Math.floor(boundingBox.min.x)),
3896
+ new this.THREE.Plane(new this.THREE.Vector3(0, 1, 0), -Math.floor(boundingBox.min.y)),
3897
+ new this.THREE.Plane(new this.THREE.Vector3(0, 0, 1), -Math.floor(boundingBox.min.z)),
4200
3898
  ];
4201
3899
  obj.material.clippingPlanes = clippingPlanes;
4202
3900
  obj.material.needsUpdate = true;
@@ -4217,7 +3915,7 @@ export default {
4217
3915
  y: Math.floor(boundingBox.min.z),
4218
3916
  z: Math.floor(boundingBox.min.y),
4219
3917
  },
4220
- obj.material.clippingPlanes,
3918
+ obj.material.clippingPlanes
4221
3919
  );
4222
3920
  // cube.material.clippingPlanes
4223
3921
  }
@@ -4255,7 +3953,7 @@ export default {
4255
3953
  '-z轴': 0,
4256
3954
  };
4257
3955
  gui && gui.destroy();
4258
- clippingMesh.forEach((item) => {
3956
+ clippingMesh.forEach(item => {
4259
3957
  item.material.clippingPlanes = Object.freeze([]);
4260
3958
  item.material.needsUpdate = true;
4261
3959
  });
@@ -4271,7 +3969,7 @@ export default {
4271
3969
  .step(0.001)
4272
3970
  .min(boudingValue.min.x)
4273
3971
  .max(boudingValue.max.x)
4274
- .onChange((d) => {
3972
+ .onChange(d => {
4275
3973
  objClipp1[0].constant = d;
4276
3974
  objClipp2 && (objClipp2[0].constant = d);
4277
3975
  });
@@ -4280,7 +3978,7 @@ export default {
4280
3978
  .step(0.001)
4281
3979
  .min(boudingValue.min.x)
4282
3980
  .max(boudingValue.max.x)
4283
- .onChange((d) => {
3981
+ .onChange(d => {
4284
3982
  objClipp1[3].constant = -d;
4285
3983
  objClipp2 && (objClipp2[3].constant = -d);
4286
3984
  });
@@ -4289,7 +3987,7 @@ export default {
4289
3987
  .step(0.001)
4290
3988
  .min(boudingValue.min.y)
4291
3989
  .max(boudingValue.max.y)
4292
- .onChange((d) => {
3990
+ .onChange(d => {
4293
3991
  objClipp1[2].constant = d;
4294
3992
  objClipp2 && (objClipp2[2].constant = d);
4295
3993
  });
@@ -4298,7 +3996,7 @@ export default {
4298
3996
  .step(0.001)
4299
3997
  .min(boudingValue.min.y)
4300
3998
  .max(boudingValue.max.y)
4301
- .onChange((d) => {
3999
+ .onChange(d => {
4302
4000
  objClipp1[5].constant = -d;
4303
4001
  objClipp2 && (objClipp2[5].constant = -d);
4304
4002
  });
@@ -4307,7 +4005,7 @@ export default {
4307
4005
  .step(0.001)
4308
4006
  .min(boudingValue.min.z)
4309
4007
  .max(boudingValue.max.z)
4310
- .onChange((d) => {
4008
+ .onChange(d => {
4311
4009
  objClipp1[1].constant = d;
4312
4010
  objClipp2 && (objClipp2[1].constant = d);
4313
4011
  });
@@ -4316,7 +4014,7 @@ export default {
4316
4014
  .step(0.001)
4317
4015
  .min(boudingValue.min.z)
4318
4016
  .max(boudingValue.max.z)
4319
- .onChange((d) => {
4017
+ .onChange(d => {
4320
4018
  objClipp1[4].constant = -d;
4321
4019
  objClipp2 && (objClipp2[4].constant = -d);
4322
4020
  });
@@ -4332,7 +4030,7 @@ export default {
4332
4030
  new this.THREE.Vector3(),
4333
4031
  new this.THREE.Vector3(0, -1, 0),
4334
4032
  0,
4335
- 10,
4033
+ 10
4336
4034
  );
4337
4035
  velocity = new this.THREE.Vector3(); //移动速度变量
4338
4036
  direction = new this.THREE.Vector3(); //移动的方向变量
@@ -4364,16 +4062,8 @@ export default {
4364
4062
  cameraControls.enabled = false;
4365
4063
  window.addEventListener('keydown', this.onKeyDown, false);
4366
4064
  window.addEventListener('keyup', this.onKeyUp, false);
4367
- renderer.domElement.removeEventListener(
4368
- 'mouseup',
4369
- this.mouseClick,
4370
- false,
4371
- );
4372
- renderer.domElement.removeEventListener(
4373
- 'mousedown',
4374
- this.mouseDown,
4375
- false,
4376
- );
4065
+ renderer.domElement.removeEventListener('mouseup', this.mouseClick, false);
4066
+ renderer.domElement.removeEventListener('mousedown', this.mouseDown, false);
4377
4067
  if (typeof this._cameraChangeObserver === 'function') {
4378
4068
  this._cameraChangeObserver('firstPersonLock');
4379
4069
  }
@@ -4386,10 +4076,7 @@ export default {
4386
4076
  this.home();
4387
4077
  try {
4388
4078
  if (this._onFirstPersonChange && pointControls) {
4389
- pointControls.removeEventListener(
4390
- 'change',
4391
- this._onFirstPersonChange,
4392
- );
4079
+ pointControls.removeEventListener('change', this._onFirstPersonChange);
4393
4080
  }
4394
4081
  } catch (e) {}
4395
4082
  if (this.noObserver) {
@@ -4398,16 +4085,8 @@ export default {
4398
4085
  setTimeout(() => {
4399
4086
  window.removeEventListener('keydown', this.onKeyDown);
4400
4087
  window.removeEventListener('keyup', this.onKeyUp);
4401
- renderer.domElement.addEventListener(
4402
- 'mouseup',
4403
- this.mouseClick,
4404
- false,
4405
- );
4406
- renderer.domElement.addEventListener(
4407
- 'mousedown',
4408
- this.mouseDown,
4409
- false,
4410
- );
4088
+ renderer.domElement.addEventListener('mouseup', this.mouseClick, false);
4089
+ renderer.domElement.addEventListener('mousedown', this.mouseDown, false);
4411
4090
  // this.timeRender()
4412
4091
  }, 0);
4413
4092
  if (typeof this._cameraChangeObserver === 'function') {
@@ -4433,10 +4112,8 @@ export default {
4433
4112
  direction.x = Number(moveRight) - Number(moveLeft);
4434
4113
  // 将法向量的值归一化
4435
4114
  direction.normalize();
4436
- if (moveForward || moveBackward)
4437
- velocity.z -= direction.z * removeSpeed * delta;
4438
- if (moveLeft || moveRight)
4439
- velocity.x -= direction.x * removeSpeed * delta;
4115
+ if (moveForward || moveBackward) velocity.z -= direction.z * removeSpeed * delta;
4116
+ if (moveLeft || moveRight) velocity.x -= direction.x * removeSpeed * delta;
4440
4117
  // }
4441
4118
  // 复制相机的位置
4442
4119
  downRaycaster.ray.origin.copy(control.position);
@@ -4444,9 +4121,7 @@ export default {
4444
4121
  downRaycaster.ray.origin.y += 5;
4445
4122
  // 判断是否停留在了立方体上面
4446
4123
  let intersections =
4447
- scene && scene.children
4448
- ? downRaycaster.intersectObjects(scene.children, true)
4449
- : [];
4124
+ scene && scene.children ? downRaycaster.intersectObjects(scene.children, true) : [];
4450
4125
  var onObject = intersections.length > 0;
4451
4126
  if (onObject === true) {
4452
4127
  velocity.y = Math.max(0, velocity.y);
@@ -4464,14 +4139,10 @@ export default {
4464
4139
  }
4465
4140
  if (this.noObserver) {
4466
4141
  if (!this.noObserver._firstPersonLastPos) {
4467
- this.noObserver._firstPersonLastPos = new this.THREE.Vector3().copy(
4468
- control.position,
4469
- );
4142
+ this.noObserver._firstPersonLastPos = new this.THREE.Vector3().copy(control.position);
4470
4143
  }
4471
4144
  const moved =
4472
- this.noObserver._firstPersonLastPos.distanceToSquared(
4473
- control.position,
4474
- ) > 1e-8;
4145
+ this.noObserver._firstPersonLastPos.distanceToSquared(control.position) > 1e-8;
4475
4146
  if (moved) {
4476
4147
  this.noObserver._firstPersonLastPos.copy(control.position);
4477
4148
  if (typeof this._cameraChangeObserver === 'function') {
@@ -4588,7 +4259,7 @@ export default {
4588
4259
  scene,
4589
4260
  camera,
4590
4261
  instructions.offsetWidth,
4591
- instructions.offsetHeight,
4262
+ instructions.offsetHeight
4592
4263
  );
4593
4264
  threeMeasure.start();
4594
4265
  break;
@@ -4598,7 +4269,7 @@ export default {
4598
4269
  scene,
4599
4270
  camera,
4600
4271
  instructions.offsetWidth,
4601
- instructions.offsetHeight,
4272
+ instructions.offsetHeight
4602
4273
  );
4603
4274
  threeMeasure.start();
4604
4275
  break;
@@ -4608,7 +4279,7 @@ export default {
4608
4279
  scene,
4609
4280
  camera,
4610
4281
  instructions.offsetWidth,
4611
- instructions.offsetHeight,
4282
+ instructions.offsetHeight
4612
4283
  );
4613
4284
  threeMeasure.start();
4614
4285
  break;
@@ -4648,11 +4319,9 @@ export default {
4648
4319
  let translateMatrix = new this.THREE.Matrix4().makeTranslation(
4649
4320
  distance.x,
4650
4321
  distance.y,
4651
- distance.z,
4322
+ distance.z
4652
4323
  );
4653
- let translateMatrixInvert = new this.THREE.Matrix4()
4654
- .copy(translateMatrix)
4655
- .invert();
4324
+ let translateMatrixInvert = new this.THREE.Matrix4().copy(translateMatrix).invert();
4656
4325
  if (object.userData.translateMatrixInvert) {
4657
4326
  object.applyMatrix4(object.userData.translateMatrixInvert);
4658
4327
  }
@@ -4672,38 +4341,22 @@ export default {
4672
4341
  // 原始向量 = 变化后的向量 * 逆矩阵
4673
4342
  let center = object.userData.center;
4674
4343
  let v = new this.THREE.Vector3(center.x, center.y, center.z).negate();
4675
- let translateMatrix = new this.THREE.Matrix4().makeTranslation(
4676
- v.x,
4677
- v.y,
4678
- v.z,
4679
- );
4680
- let rotateX = new this.THREE.Matrix4().makeRotationX(
4681
- degrees.x * (Math.PI / 180),
4682
- );
4683
- let rotateY = new this.THREE.Matrix4().makeRotationY(
4684
- degrees.y * (Math.PI / 180),
4685
- );
4686
- let rotateZ = new this.THREE.Matrix4().makeRotationZ(
4687
- degrees.z * (Math.PI / 180),
4688
- );
4344
+ let translateMatrix = new this.THREE.Matrix4().makeTranslation(v.x, v.y, v.z);
4345
+ let rotateX = new this.THREE.Matrix4().makeRotationX(degrees.x * (Math.PI / 180));
4346
+ let rotateY = new this.THREE.Matrix4().makeRotationY(degrees.y * (Math.PI / 180));
4347
+ let rotateZ = new this.THREE.Matrix4().makeRotationZ(degrees.z * (Math.PI / 180));
4689
4348
  let combineMatrix = new this.THREE.Matrix4()
4690
4349
  .multiply(rotateX)
4691
4350
  .multiply(rotateY)
4692
4351
  .multiply(rotateZ);
4693
4352
  object.applyMatrix4(translateMatrix);
4694
- let combineMatrixInvert = new this.THREE.Matrix4()
4695
- .copy(combineMatrix)
4696
- .invert();
4353
+ let combineMatrixInvert = new this.THREE.Matrix4().copy(combineMatrix).invert();
4697
4354
  if (object.userData.combineMatrixInvert) {
4698
4355
  object.applyMatrix4(object.userData.combineMatrixInvert);
4699
4356
  }
4700
4357
  object.userData.combineMatrixInvert = combineMatrixInvert;
4701
4358
  object.applyMatrix4(combineMatrix);
4702
- let translateM = new this.THREE.Matrix4().makeTranslation(
4703
- center.x,
4704
- center.y,
4705
- center.z,
4706
- );
4359
+ let translateM = new this.THREE.Matrix4().makeTranslation(center.x, center.y, center.z);
4707
4360
  object.applyMatrix4(translateM);
4708
4361
  object.userData.position = new this.THREE.Vector3().copy(object.position);
4709
4362
  object.userData.rotate = degrees;
@@ -4715,7 +4368,7 @@ export default {
4715
4368
  isolate(object) {
4716
4369
  if (!scene) return;
4717
4370
  // 隔离 将目标实体以外的实体隐藏掉
4718
- scene.traverse((item) => {
4371
+ scene.traverse(item => {
4719
4372
  if (item.isMesh && item.name !== object.name) {
4720
4373
  const offsetMatrix = new this.THREE.Matrix4()
4721
4374
  .copy(item.userData.copyMatrix)
@@ -4728,12 +4381,9 @@ export default {
4728
4381
  // 还原操作 将修改过的实体进行恢复
4729
4382
  restore() {
4730
4383
  if (!scene) return;
4731
- scene.traverse((item) => {
4384
+ scene.traverse(item => {
4732
4385
  if (item.isMesh) {
4733
- item.setColorAt(
4734
- item.userData.instanceIndex,
4735
- item.material.userData.nColor,
4736
- );
4386
+ item.setColorAt(item.userData.instanceIndex, item.material.userData.nColor);
4737
4387
  item.instanceColor.needsUpdate = true;
4738
4388
  item.userData.translate = {
4739
4389
  x: 0,
@@ -4757,26 +4407,17 @@ export default {
4757
4407
  });
4758
4408
  item.userData.combineMatrixInvert = null;
4759
4409
  }
4760
- const offsetMatrix = new this.THREE.Matrix4().copy(
4761
- item.userData.copyMatrix,
4762
- );
4410
+ const offsetMatrix = new this.THREE.Matrix4().copy(item.userData.copyMatrix);
4763
4411
  item.setMatrixAt(item.userData.instanceIndex, offsetMatrix);
4764
4412
  item.instanceMatrix.needsUpdate = true;
4765
4413
  }
4766
4414
  });
4767
4415
  },
4768
4416
  // 添加自定义模型, 暂时只支持glb、gltf格式
4769
- addCustomModel(
4770
- name,
4771
- position,
4772
- url,
4773
- scale = 1,
4774
- immediately = false,
4775
- callback,
4776
- ) {
4417
+ addCustomModel(name, position, url, scale = 1, immediately = false, callback) {
4777
4418
  const loader = new GLTFLoader();
4778
4419
  let locationModel = null;
4779
- loader.load(url, (gltf) => {
4420
+ loader.load(url, gltf => {
4780
4421
  locationModel = gltf.scene;
4781
4422
  locationModel.scale.set(scale, scale, scale);
4782
4423
  locationModel.updateMatrixWorld();
@@ -4788,9 +4429,7 @@ export default {
4788
4429
  locationModel.userData.cull = false;
4789
4430
  locationModel.name = name;
4790
4431
  if (scene) scene.add(locationModel);
4791
- locationModel.position.copy(
4792
- new this.THREE.Vector3(position.x, position.y, position.z),
4793
- );
4432
+ locationModel.position.copy(new this.THREE.Vector3(position.x, position.y, position.z));
4794
4433
  if (gltf.animations.length > 0) {
4795
4434
  let actionMixer = new this.THREE.AnimationMixer(gltf.scene);
4796
4435
  const walkActive = actionMixer.clipAction(gltf.animations[0]);
@@ -4810,7 +4449,7 @@ export default {
4810
4449
  modelActions[index].uncacheRoot(item);
4811
4450
  modelActions[index].uncacheRoot(modelActive[index]);
4812
4451
  }
4813
- item.traverse((child) => {
4452
+ item.traverse(child => {
4814
4453
  if (child instanceof this.THREE.Mesh) {
4815
4454
  child.geometry.dispose();
4816
4455
  child.material.dispose();
@@ -4840,14 +4479,14 @@ export default {
4840
4479
  scenePass = new ShaderPass(RainShader);
4841
4480
  scenePass.uniforms['iResolution'].value = new this.THREE.Vector2(
4842
4481
  window.innerWidth,
4843
- window.innerHeight,
4482
+ window.innerHeight
4844
4483
  );
4845
4484
  outlineComposer.addPass(scenePass);
4846
4485
  } else if (type === 'snow') {
4847
4486
  scenePass = new ShaderPass(SnowShader);
4848
4487
  scenePass.uniforms['iResolution'].value = new this.THREE.Vector2(
4849
4488
  window.innerWidth,
4850
- window.innerHeight,
4489
+ window.innerHeight
4851
4490
  );
4852
4491
  outlineComposer.addPass(scenePass);
4853
4492
  }
@@ -4864,7 +4503,7 @@ export default {
4864
4503
  if (isBox3Info) {
4865
4504
  box3 = new this.THREE.Box3(
4866
4505
  new this.THREE.Vector3(obj.min[0], obj.min[1], obj.min[2]),
4867
- new this.THREE.Vector3(obj.max[0], obj.max[1], obj.max[2]),
4506
+ new this.THREE.Vector3(obj.max[0], obj.max[1], obj.max[2])
4868
4507
  );
4869
4508
  }
4870
4509
  let center = new this.THREE.Vector3();
@@ -4879,7 +4518,7 @@ export default {
4879
4518
  if (isBox3Info) {
4880
4519
  box3 = new this.THREE.Box3(
4881
4520
  new this.THREE.Vector3(obj.min[0], obj.min[1], obj.min[2]),
4882
- new this.THREE.Vector3(obj.max[0], obj.max[1], obj.max[2]),
4521
+ new this.THREE.Vector3(obj.max[0], obj.max[1], obj.max[2])
4883
4522
  );
4884
4523
  }
4885
4524
  let size = new this.THREE.Vector3();
@@ -4903,7 +4542,7 @@ export default {
4903
4542
 
4904
4543
  if (timeStamp > singleFrameTime) {
4905
4544
  if (modelActions.length > 0) {
4906
- modelActions.forEach((item) => {
4545
+ modelActions.forEach(item => {
4907
4546
  item.update(timeStamp);
4908
4547
  });
4909
4548
  }
@@ -4923,9 +4562,7 @@ export default {
4923
4562
  ? this.noObserver.batchLoadingState
4924
4563
  : this.batchLoadingState;
4925
4564
  const shouldSkipRendering =
4926
- skipNextRenderFrame ||
4927
- forceSkipRendering ||
4928
- loadingState.interactionState.isInteracting;
4565
+ skipNextRenderFrame || forceSkipRendering || loadingState.interactionState.isInteracting;
4929
4566
 
4930
4567
  if (shouldSkipRendering) {
4931
4568
  // 重置单次跳过标记
@@ -5063,7 +4700,7 @@ export default {
5063
4700
  meshNameConfig = {},
5064
4701
  options = {},
5065
4702
  onProgress = null,
5066
- onComplete = null,
4703
+ onComplete = null
5067
4704
  ) {
5068
4705
  const loadingState = this.noObserver
5069
4706
  ? this.noObserver.batchLoadingState
@@ -5105,10 +4742,7 @@ export default {
5105
4742
  loadingState.currentBatch = 0;
5106
4743
  loadingState.totalCount = filteredInstances.length;
5107
4744
  loadingState.loadedCount = 0;
5108
- loadingState.pendingData = this.createBatches(
5109
- filteredInstances,
5110
- filteredDrawObjs,
5111
- );
4745
+ loadingState.pendingData = this.createBatches(filteredInstances, filteredDrawObjs);
5112
4746
  loadingState.onProgress = onProgress;
5113
4747
  loadingState.onComplete = onComplete;
5114
4748
 
@@ -5145,13 +4779,13 @@ export default {
5145
4779
 
5146
4780
  // 按drawObject分组
5147
4781
  const drawObjMap = new Map();
5148
- drawObjs.forEach((obj) => {
4782
+ drawObjs.forEach(obj => {
5149
4783
  drawObjMap.set(obj.drawObjId, obj);
5150
4784
  });
5151
4785
 
5152
4786
  // 按drawObject ID分组instances
5153
4787
  const instancesByDrawObj = new Map();
5154
- instances.forEach((inst) => {
4788
+ instances.forEach(inst => {
5155
4789
  if (!instancesByDrawObj.has(inst.drawObject)) {
5156
4790
  instancesByDrawObj.set(inst.drawObject, []);
5157
4791
  }
@@ -5169,7 +4803,7 @@ export default {
5169
4803
  if (!drawObj) {
5170
4804
  for (const value of drawObjMap.values()) {
5171
4805
  if (value && Array.isArray(value.geoms)) {
5172
- const found = value.geoms.some((g) => g.prmid === drawObjId);
4806
+ const found = value.geoms.some(g => g.prmid === drawObjId);
5173
4807
  if (found) {
5174
4808
  drawObj = value;
5175
4809
  break;
@@ -5181,13 +4815,10 @@ export default {
5181
4815
  if (!drawObj) continue;
5182
4816
 
5183
4817
  // 如果当前批次加上这个drawObject会超过限制,先保存当前批次
5184
- if (
5185
- currentBatchSize + objInstances.length > batchSize &&
5186
- currentBatch.length > 0
5187
- ) {
4818
+ if (currentBatchSize + objInstances.length > batchSize && currentBatch.length > 0) {
5188
4819
  batches.push({
5189
- instances: currentBatch.flatMap((item) => item.instances),
5190
- drawObjs: currentBatch.map((item) => item.drawObj),
4820
+ instances: currentBatch.flatMap(item => item.instances),
4821
+ drawObjs: currentBatch.map(item => item.drawObj),
5191
4822
  });
5192
4823
  currentBatch = [];
5193
4824
  currentBatchSize = 0;
@@ -5202,8 +4833,8 @@ export default {
5202
4833
  // 如果当前批次已满,保存并开始新批次
5203
4834
  if (currentBatchSize >= batchSize) {
5204
4835
  batches.push({
5205
- instances: currentBatch.flatMap((item) => item.instances),
5206
- drawObjs: currentBatch.map((item) => item.drawObj),
4836
+ instances: currentBatch.flatMap(item => item.instances),
4837
+ drawObjs: currentBatch.map(item => item.drawObj),
5207
4838
  });
5208
4839
  currentBatch = [];
5209
4840
  currentBatchSize = 0;
@@ -5213,8 +4844,8 @@ export default {
5213
4844
  // 保存最后一个批次
5214
4845
  if (currentBatch.length > 0) {
5215
4846
  batches.push({
5216
- instances: currentBatch.flatMap((item) => item.instances),
5217
- drawObjs: currentBatch.map((item) => item.drawObj),
4847
+ instances: currentBatch.flatMap(item => item.instances),
4848
+ drawObjs: currentBatch.map(item => item.drawObj),
5218
4849
  });
5219
4850
  }
5220
4851
 
@@ -5228,10 +4859,7 @@ export default {
5228
4859
  const loadingState = this.noObserver
5229
4860
  ? this.noObserver.batchLoadingState
5230
4861
  : this.batchLoadingState;
5231
- if (
5232
- !loadingState.isLoading ||
5233
- loadingState.currentBatch >= loadingState.pendingData.length
5234
- ) {
4862
+ if (!loadingState.isLoading || loadingState.currentBatch >= loadingState.pendingData.length) {
5235
4863
  this.completeBatchLoading();
5236
4864
  return;
5237
4865
  }
@@ -5313,14 +4941,14 @@ export default {
5313
4941
  loadingState.color,
5314
4942
  loadingState.meshNameConfig,
5315
4943
  '',
5316
- loadingState.options,
4944
+ loadingState.options
5317
4945
  );
5318
4946
  isDebug && performance.mark('handleInstancedMeshModel-end');
5319
4947
  isDebug &&
5320
4948
  performance.measure(
5321
4949
  'handleInstancedMeshModel',
5322
4950
  'handleInstancedMeshModel-start',
5323
- 'handleInstancedMeshModel-end',
4951
+ 'handleInstancedMeshModel-end'
5324
4952
  );
5325
4953
  },
5326
4954
 
@@ -5357,7 +4985,7 @@ export default {
5357
4985
  .addVectors(modelBox3.max, modelBox3.min)
5358
4986
  .multiplyScalar(0.5);
5359
4987
  modelGroup.userData.modelWorldPs = modelWorldPs;
5360
- modelGroup.traverse((child) => {
4988
+ modelGroup.traverse(child => {
5361
4989
  if (child.isMesh && !child.userData.batchInitDone) {
5362
4990
  markRendered(child);
5363
4991
  const json = this.getMeshCenterAndVolume(child);
@@ -5367,18 +4995,12 @@ export default {
5367
4995
  .addVectors(meshBox3.max, meshBox3.min)
5368
4996
  .multiplyScalar(0.5);
5369
4997
  if (isNaN(worldPs.x)) return;
5370
- child.worldDir = new this.THREE.Vector3()
5371
- .subVectors(worldPs, modelWorldPs)
5372
- .normalize();
4998
+ child.worldDir = new this.THREE.Vector3().subVectors(worldPs, modelWorldPs).normalize();
5373
4999
  child.userData.center = json.center;
5374
5000
  child.userData.worldPs = worldPs;
5375
- child.userData.oldPs = child.getWorldPosition(
5376
- new this.THREE.Vector3(),
5377
- );
5001
+ child.userData.oldPs = child.getWorldPosition(new this.THREE.Vector3());
5378
5002
  child.userData.box = json.box;
5379
- child.userData.position = new this.THREE.Vector3().copy(
5380
- child.position,
5381
- );
5003
+ child.userData.position = new this.THREE.Vector3().copy(child.position);
5382
5004
  child.userData.translate = { x: 0, y: 0, z: 0 };
5383
5005
  child.userData.rotate = { x: 0, y: 0, z: 0 };
5384
5006
  child.userData.modelWorldPs = modelWorldPs;
@@ -5441,7 +5063,7 @@ export default {
5441
5063
  meshNameConfig = {},
5442
5064
  options = {},
5443
5065
  onProgress = null,
5444
- onComplete = null,
5066
+ onComplete = null
5445
5067
  ) {
5446
5068
  if (Object.keys(data).length === 0) {
5447
5069
  onComplete && onComplete();
@@ -5454,14 +5076,7 @@ export default {
5454
5076
  }
5455
5077
 
5456
5078
  // 启动分帧加载
5457
- this.startBatchLoading(
5458
- data,
5459
- color,
5460
- meshNameConfig,
5461
- options,
5462
- onProgress,
5463
- onComplete,
5464
- );
5079
+ this.startBatchLoading(data, color, meshNameConfig, options, onProgress, onComplete);
5465
5080
  },
5466
5081
 
5467
5082
  /**
@@ -5516,10 +5131,7 @@ export default {
5516
5131
  // 5. 联动 StreamLoader (如果存在实例)
5517
5132
  // 确保网络流式加载也同步暂停
5518
5133
  const streamLoader = this.noObserver.streamLoader;
5519
- if (
5520
- streamLoader &&
5521
- typeof streamLoader.handleControlStart === 'function'
5522
- ) {
5134
+ if (streamLoader && typeof streamLoader.handleControlStart === 'function') {
5523
5135
  streamLoader.handleControlStart();
5524
5136
  }
5525
5137
  } else {
@@ -5555,19 +5167,13 @@ export default {
5555
5167
  forceSkipRendering = false;
5556
5168
 
5557
5169
  // 恢复本地批量加载 (如果未完成)
5558
- if (
5559
- loadingState.isLoading &&
5560
- loadingState.currentBatch < loadingState.totalBatches
5561
- ) {
5170
+ if (loadingState.isLoading && loadingState.currentBatch < loadingState.totalBatches) {
5562
5171
  this.loadNextBatch();
5563
5172
  }
5564
5173
 
5565
5174
  // 恢复 StreamLoader
5566
5175
  const streamLoader = this.noObserver.streamLoader;
5567
- if (
5568
- streamLoader &&
5569
- typeof streamLoader.handleControlEnd === 'function'
5570
- ) {
5176
+ if (streamLoader && typeof streamLoader.handleControlEnd === 'function') {
5571
5177
  // StreamLoader 内部通常有防抖或延迟,这里直接通知结束即可
5572
5178
  streamLoader.handleControlEnd();
5573
5179
  }
@@ -5603,12 +5209,7 @@ export default {
5603
5209
  * 交互开始
5604
5210
  */
5605
5211
  beginInteraction(type = 'user') {
5606
- const reason =
5607
- type === 'wheel'
5608
- ? 'wheel'
5609
- : type === 'camera'
5610
- ? 'camera'
5611
- : 'user_interaction';
5212
+ const reason = type === 'wheel' ? 'wheel' : type === 'camera' ? 'camera' : 'user_interaction';
5612
5213
  this.setSystemInterruption(true, reason);
5613
5214
  },
5614
5215