fl-web-component 2.0.6 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/fl-web-component.common.js +1229 -1213
- package/dist/fl-web-component.common.js.map +1 -1
- package/dist/fl-web-component.css +1 -1
- package/package.json +1 -1
- package/packages/components/com-graphics/index.vue +897 -770
- package/src/utils/threejs/measure-angle.js +17 -15
- package/src/utils/threejs/measure-area.js +17 -14
- package/src/utils/threejs/measure-distance.js +16 -14
- package/src/utils/threejs/measure-height.js +14 -12
|
@@ -1,60 +1,66 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div id="fl-model"></div>
|
|
2
|
+
<div :id="containId" class="fl-model-containor"></div>
|
|
3
3
|
</template>
|
|
4
4
|
<script>
|
|
5
|
-
var [
|
|
6
|
-
renderer,
|
|
7
|
-
scene,
|
|
8
|
-
camera,
|
|
9
|
-
cameraControls,
|
|
10
|
-
instructions,
|
|
11
|
-
raycaster,
|
|
12
|
-
mouse,
|
|
13
|
-
labelRenderer,
|
|
14
|
-
lineTexture,
|
|
15
|
-
curve,
|
|
16
|
-
downRaycaster,
|
|
17
|
-
velocity,
|
|
18
|
-
direction,
|
|
19
|
-
clock,
|
|
20
|
-
pointControls,
|
|
21
|
-
threeMeasure,
|
|
22
|
-
modelGroup,
|
|
23
|
-
animateId,
|
|
24
|
-
scenePass,
|
|
25
|
-
outlineComposer,
|
|
26
|
-
outlinePass,
|
|
27
|
-
renderTarget,
|
|
28
|
-
sceneClock,
|
|
29
|
-
bizToThreeMatrix,
|
|
30
|
-
threeToBizMatrix,
|
|
31
|
-
stats,
|
|
32
|
-
] = (function* (v) {
|
|
33
|
-
while (true) yield v;
|
|
34
|
-
})(null);
|
|
35
|
-
|
|
36
|
-
var [lastTime, firstTime, fpsClock, timeStamp, progress, lastMiddleClickTime] = (function* (v) {
|
|
37
|
-
while (true) yield v;
|
|
38
|
-
})(0);
|
|
39
5
|
var singleFrameTime = 1 / 30;
|
|
6
|
+
var dragThreshold = 5; // 拖拽阈值,像素单位
|
|
40
7
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
8
|
+
// 根据场景包围盒动态计算的最大dolly距离(对角线长度)
|
|
9
|
+
let maxDollyDistance = Infinity;
|
|
10
|
+
|
|
11
|
+
// var lastMiddleClickTime = 0;
|
|
12
|
+
// var [
|
|
13
|
+
// renderer,
|
|
14
|
+
// scene,
|
|
15
|
+
// camera,
|
|
16
|
+
// cameraControls,
|
|
17
|
+
// instructions,
|
|
18
|
+
// raycaster,
|
|
19
|
+
// mouse,
|
|
20
|
+
// labelRenderer,
|
|
21
|
+
// lineTexture,
|
|
22
|
+
// curve,
|
|
23
|
+
// downRaycaster,
|
|
24
|
+
// velocity,
|
|
25
|
+
// direction,
|
|
26
|
+
// clock,
|
|
27
|
+
// pointControls,
|
|
28
|
+
// threeMeasure,
|
|
29
|
+
// modelGroup,
|
|
30
|
+
// animateId,
|
|
31
|
+
// scenePass,
|
|
32
|
+
// outlineComposer,
|
|
33
|
+
// outlinePass,
|
|
34
|
+
// renderTarget,
|
|
35
|
+
// sceneClock,
|
|
36
|
+
// bizToThreeMatrix,
|
|
37
|
+
// threeToBizMatrix,
|
|
38
|
+
// stats,
|
|
39
|
+
// ] = (function* (v) {
|
|
40
|
+
// while (true) yield v;
|
|
41
|
+
// })(null);
|
|
42
|
+
|
|
43
|
+
// var [tlastTime, firstTime, fpsClock,timeStamp, progress, lastMiddleClickTime] = (function* (v) {
|
|
44
|
+
// while (true) yield v;
|
|
45
|
+
// })(0);
|
|
46
|
+
|
|
47
|
+
// var [
|
|
48
|
+
// roaming,
|
|
49
|
+
// firstPerSign,
|
|
50
|
+
// canJump,
|
|
51
|
+
// moveForward,
|
|
52
|
+
// moveBackward,
|
|
53
|
+
// moveLeft,
|
|
54
|
+
// moveRight,
|
|
55
|
+
// measureFlag,
|
|
56
|
+
// // rotatedSceneFlag,
|
|
57
|
+
// ] = (function* (v) {
|
|
58
|
+
// while (true) yield v;
|
|
59
|
+
// })(false);
|
|
60
|
+
|
|
61
|
+
// var [spaceUp] = (function* (v) {
|
|
62
|
+
// while (true) yield v;
|
|
63
|
+
// })(true);
|
|
58
64
|
|
|
59
65
|
const renderedThisFrame = new Set();
|
|
60
66
|
|
|
@@ -65,9 +71,9 @@ function markRendered(mesh) {
|
|
|
65
71
|
}
|
|
66
72
|
|
|
67
73
|
// 交互期间丢弃当前帧渲染的标记
|
|
68
|
-
let skipNextRenderFrame = false;
|
|
74
|
+
// let skipNextRenderFrame = false;
|
|
69
75
|
// 增强的交互检测标记
|
|
70
|
-
let forceSkipRendering = false;
|
|
76
|
+
// let forceSkipRendering = false;
|
|
71
77
|
// let interactionFrameCount = 0; // 交互期间跳过的帧数计数
|
|
72
78
|
|
|
73
79
|
var clippingMesh = [],
|
|
@@ -82,15 +88,11 @@ var clippingMesh = [],
|
|
|
82
88
|
mouseDownPosition = { x: 0, y: 0 }, // 鼠标按下时的位置
|
|
83
89
|
mouseUpPosition = { x: 0, y: 0 }, // 鼠标抬起时的位置
|
|
84
90
|
isDragging = false, // 是否正在拖拽
|
|
85
|
-
dragThreshold = 5, // 拖拽阈值,像素单位
|
|
86
91
|
sceneBoundingBox = null, // 场景包围盒
|
|
87
92
|
// 包围盒显示相关变量
|
|
88
93
|
sceneBoundingBoxHelper = null, // 场景包围盒辅助线
|
|
89
94
|
boundingBoxVisible = false; // 包围盒是否可见
|
|
90
95
|
|
|
91
|
-
// 根据场景包围盒动态计算的最大dolly距离(对角线长度)
|
|
92
|
-
let maxDollyDistance = Infinity;
|
|
93
|
-
|
|
94
96
|
var removeSpeed = 200,
|
|
95
97
|
upSpeed = 200; //控制器移动速度 , //控制跳起时的速度
|
|
96
98
|
var roamConfig = {
|
|
@@ -166,6 +168,10 @@ export default {
|
|
|
166
168
|
return {};
|
|
167
169
|
},
|
|
168
170
|
},
|
|
171
|
+
containId: {
|
|
172
|
+
type: String,
|
|
173
|
+
default: 'fl-model',
|
|
174
|
+
},
|
|
169
175
|
},
|
|
170
176
|
data() {
|
|
171
177
|
return {
|
|
@@ -196,7 +202,90 @@ export default {
|
|
|
196
202
|
},
|
|
197
203
|
};
|
|
198
204
|
},
|
|
205
|
+
beforeCreate() {
|
|
206
|
+
this.spaceUp = true;
|
|
207
|
+
let arr = [
|
|
208
|
+
'renderer',
|
|
209
|
+
'scene',
|
|
210
|
+
'camera',
|
|
211
|
+
'cameraControls',
|
|
212
|
+
'instructions',
|
|
213
|
+
'raycaster',
|
|
214
|
+
'mouse',
|
|
215
|
+
'labelRenderer',
|
|
216
|
+
'lineTexture',
|
|
217
|
+
'curve',
|
|
218
|
+
'downRaycaster',
|
|
219
|
+
'velocity',
|
|
220
|
+
'direction',
|
|
221
|
+
'clock',
|
|
222
|
+
'pointControls',
|
|
223
|
+
'threeMeasure',
|
|
224
|
+
'modelGroup',
|
|
225
|
+
'animateId',
|
|
226
|
+
'scenePass',
|
|
227
|
+
'outlineComposer',
|
|
228
|
+
'outlinePass',
|
|
229
|
+
'renderTarget',
|
|
230
|
+
'sceneClock',
|
|
231
|
+
'bizToThreeMatrix',
|
|
232
|
+
'threeToBizMatrix',
|
|
233
|
+
'stats',
|
|
234
|
+
'centeringDebounceTimer',
|
|
235
|
+
'sceneBoundingBox',
|
|
236
|
+
'sceneBoundingBoxHelper',
|
|
237
|
+
];
|
|
238
|
+
arr.forEach(item => {
|
|
239
|
+
this[item] = null;
|
|
240
|
+
});
|
|
241
|
+
[
|
|
242
|
+
'roaming',
|
|
243
|
+
'firstPerSign',
|
|
244
|
+
'canJump',
|
|
245
|
+
'moveForward',
|
|
246
|
+
'moveBackward',
|
|
247
|
+
'moveLeft',
|
|
248
|
+
'moveRight',
|
|
249
|
+
'measureFlag',
|
|
250
|
+
'skipNextRenderFrame',
|
|
251
|
+
'forceSkipRendering',
|
|
252
|
+
'userInteracting',
|
|
253
|
+
'hasExecutedCentering',
|
|
254
|
+
'needsCenteringAfterInteraction',
|
|
255
|
+
'isDragging',
|
|
256
|
+
'boundingBoxVisible',
|
|
257
|
+
].forEach(item => {
|
|
258
|
+
this[item] = false;
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
['clippingMesh', 'modelActive'].forEach(item => {
|
|
262
|
+
this[item] = [];
|
|
263
|
+
});
|
|
264
|
+
['removeSpeed', 'upSpeed'].forEach(item => {
|
|
265
|
+
this[item] = 200;
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
this.gui = null;
|
|
269
|
+
this.roamConfig = {
|
|
270
|
+
loop: false,
|
|
271
|
+
speed: 0, // 最大值为3
|
|
272
|
+
name: '',
|
|
273
|
+
};
|
|
274
|
+
this.guiParams = {
|
|
275
|
+
x轴: 0,
|
|
276
|
+
y轴: 0,
|
|
277
|
+
z轴: 0,
|
|
278
|
+
'-x轴': 0,
|
|
279
|
+
'-y轴': 0,
|
|
280
|
+
'-z轴': 0,
|
|
281
|
+
};
|
|
282
|
+
},
|
|
199
283
|
created() {
|
|
284
|
+
['lastTime', 'firstTime', 'fpsClock', 'timeStamp', 'progress'].forEach(item => {
|
|
285
|
+
this[item] = 0;
|
|
286
|
+
});
|
|
287
|
+
this.mouseDownPosition = { x: 0, y: 0 };
|
|
288
|
+
this.mouseUpPosition = { x: 0, y: 0 };
|
|
200
289
|
// 初始化非响应式的高频状态对象
|
|
201
290
|
this.noObserver = {
|
|
202
291
|
modelStateManager: {
|
|
@@ -256,20 +345,19 @@ export default {
|
|
|
256
345
|
occlusionWorkerRequestMap: new Map(),
|
|
257
346
|
occlusionWorkerRequestId: 0,
|
|
258
347
|
};
|
|
259
|
-
|
|
348
|
+
this.modelGroups = [];
|
|
349
|
+
this.modelActions = [];
|
|
350
|
+
this.lastMiddleClickTime = 0;
|
|
260
351
|
CameraControls.install({ THREE: this.THREE });
|
|
261
|
-
bizToThreeMatrix = new this.THREE.Matrix4();
|
|
262
|
-
bizToThreeMatrix.makeRotationX(-Math.PI / 2);
|
|
263
|
-
threeToBizMatrix = new this.THREE.Matrix4();
|
|
264
|
-
threeToBizMatrix.makeRotationX(Math.PI / 2);
|
|
265
|
-
fpsClock = new this.THREE.Clock();
|
|
266
|
-
raycaster = new this.THREE.Raycaster();
|
|
267
|
-
sceneClock = new this.THREE.Clock();
|
|
268
|
-
mouse = new this.THREE.Vector2();
|
|
269
|
-
|
|
270
|
-
? instructions.getBoundingClientRect()
|
|
271
|
-
: { width: window.innerWidth, height: window.innerHeight };
|
|
272
|
-
renderTarget = new this.THREE.WebGLRenderTarget(initialRect.width, initialRect.height, {
|
|
352
|
+
this.bizToThreeMatrix = new this.THREE.Matrix4();
|
|
353
|
+
this.bizToThreeMatrix.makeRotationX(-Math.PI / 2);
|
|
354
|
+
this.threeToBizMatrix = new this.THREE.Matrix4();
|
|
355
|
+
this.threeToBizMatrix.makeRotationX(Math.PI / 2);
|
|
356
|
+
this.fpsClock = new this.THREE.Clock();
|
|
357
|
+
this.raycaster = new this.THREE.Raycaster();
|
|
358
|
+
this.sceneClock = new this.THREE.Clock();
|
|
359
|
+
this.mouse = new this.THREE.Vector2();
|
|
360
|
+
this.renderTarget = new this.THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, {
|
|
273
361
|
minFilter: this.THREE.LinearFilter,
|
|
274
362
|
magFilter: this.THREE.LinearFilter,
|
|
275
363
|
format: this.THREE.RGBAFormat,
|
|
@@ -278,7 +366,7 @@ export default {
|
|
|
278
366
|
});
|
|
279
367
|
},
|
|
280
368
|
mounted() {
|
|
281
|
-
instructions = document.getElementById('fl-model'
|
|
369
|
+
this.instructions = document.getElementById(this.containId); // 'fl-model'
|
|
282
370
|
this.initRender();
|
|
283
371
|
this.initScene();
|
|
284
372
|
this.initCamera();
|
|
@@ -293,11 +381,11 @@ export default {
|
|
|
293
381
|
// 判断是设备是手机还是电脑
|
|
294
382
|
let isMobileDevice = this.isMobileDevice();
|
|
295
383
|
if (isMobileDevice) {
|
|
296
|
-
renderer.domElement.addEventListener('pointerup', this.mouseClick, false);
|
|
297
|
-
renderer.domElement.addEventListener('pointerdown', this.mouseDown, false);
|
|
384
|
+
this.renderer.domElement.addEventListener('pointerup', this.mouseClick, false);
|
|
385
|
+
this.renderer.domElement.addEventListener('pointerdown', this.mouseDown, false);
|
|
298
386
|
} else {
|
|
299
|
-
renderer.domElement.addEventListener('mouseup', this.mouseClick, false);
|
|
300
|
-
renderer.domElement.addEventListener('mousedown', this.mouseDown, false);
|
|
387
|
+
this.renderer.domElement.addEventListener('mouseup', this.mouseClick, false);
|
|
388
|
+
this.renderer.domElement.addEventListener('mousedown', this.mouseDown, false);
|
|
301
389
|
}
|
|
302
390
|
this.animate();
|
|
303
391
|
},
|
|
@@ -336,13 +424,13 @@ export default {
|
|
|
336
424
|
return instancedMesh ? instancedMesh.visible === false : false;
|
|
337
425
|
},
|
|
338
426
|
pushOutlineTarget(target) {
|
|
339
|
-
if (!outlinePass || !target) return;
|
|
340
|
-
if (!outlinePass.selectedObjects.includes(target)) {
|
|
341
|
-
outlinePass.selectedObjects.push(target);
|
|
427
|
+
if (!this.outlinePass || !target) return;
|
|
428
|
+
if (!this.outlinePass.selectedObjects.includes(target)) {
|
|
429
|
+
this.outlinePass.selectedObjects.push(target);
|
|
342
430
|
}
|
|
343
431
|
},
|
|
344
432
|
ensureOutlineInstanceProxy(instancedMesh, instanceIndex) {
|
|
345
|
-
if (!scene || !instancedMesh || !instancedMesh.isInstancedMesh) return null;
|
|
433
|
+
if (!this.scene || !instancedMesh || !instancedMesh.isInstancedMesh) return null;
|
|
346
434
|
const state = this.noObserver;
|
|
347
435
|
if (!state || !state.outlineInstanceProxyMap) return null;
|
|
348
436
|
const instanceId = this.getInstanceId(instancedMesh, instanceIndex);
|
|
@@ -382,7 +470,7 @@ export default {
|
|
|
382
470
|
instanceIndex,
|
|
383
471
|
};
|
|
384
472
|
|
|
385
|
-
scene.add(proxy);
|
|
473
|
+
this.scene.add(proxy);
|
|
386
474
|
state.outlineInstanceProxyMap.set(key, proxy);
|
|
387
475
|
return proxy;
|
|
388
476
|
},
|
|
@@ -394,11 +482,11 @@ export default {
|
|
|
394
482
|
if (!proxy) return null;
|
|
395
483
|
|
|
396
484
|
state.outlineInstanceProxyMap.delete(key);
|
|
397
|
-
if (outlinePass) {
|
|
398
|
-
const idx = outlinePass.selectedObjects.indexOf(proxy);
|
|
399
|
-
if (idx !== -1) outlinePass.selectedObjects.splice(idx, 1);
|
|
485
|
+
if (this.outlinePass) {
|
|
486
|
+
const idx = this.outlinePass.selectedObjects.indexOf(proxy);
|
|
487
|
+
if (idx !== -1) this.outlinePass.selectedObjects.splice(idx, 1);
|
|
400
488
|
}
|
|
401
|
-
if (scene) scene.remove(proxy);
|
|
489
|
+
if (this.scene) this.scene.remove(proxy);
|
|
402
490
|
if (proxy.material) proxy.material.dispose && proxy.material.dispose();
|
|
403
491
|
return proxy;
|
|
404
492
|
},
|
|
@@ -589,7 +677,7 @@ export default {
|
|
|
589
677
|
const box = new this.THREE.Box3(
|
|
590
678
|
new this.THREE.Vector3(minX, minY, minZ),
|
|
591
679
|
new this.THREE.Vector3(maxX, maxY, maxZ)
|
|
592
|
-
).applyMatrix4(bizToThreeMatrix);
|
|
680
|
+
).applyMatrix4(this.bizToThreeMatrix);
|
|
593
681
|
this.noObserver.sceneBoxes.set(documentId, box);
|
|
594
682
|
} else {
|
|
595
683
|
this.noObserver.sceneBoxes.delete(documentId);
|
|
@@ -605,8 +693,8 @@ export default {
|
|
|
605
693
|
if (occScene && occScene.children && occScene.children.length > 0) {
|
|
606
694
|
const occBox = new this.THREE.Box3().setFromObject(occScene);
|
|
607
695
|
if (!occBox.isEmpty()) {
|
|
608
|
-
sceneBoundingBox = occBox;
|
|
609
|
-
return sceneBoundingBox;
|
|
696
|
+
this.sceneBoundingBox = occBox;
|
|
697
|
+
return this.sceneBoundingBox;
|
|
610
698
|
}
|
|
611
699
|
}
|
|
612
700
|
|
|
@@ -637,11 +725,11 @@ export default {
|
|
|
637
725
|
Number.isFinite(maxY) &&
|
|
638
726
|
Number.isFinite(maxZ)
|
|
639
727
|
) {
|
|
640
|
-
sceneBoundingBox = new this.THREE.Box3(
|
|
728
|
+
this.sceneBoundingBox = new this.THREE.Box3(
|
|
641
729
|
new this.THREE.Vector3(minX, minY, minZ),
|
|
642
730
|
new this.THREE.Vector3(maxX, maxY, maxZ)
|
|
643
731
|
);
|
|
644
|
-
return sceneBoundingBox;
|
|
732
|
+
return this.sceneBoundingBox;
|
|
645
733
|
}
|
|
646
734
|
}
|
|
647
735
|
|
|
@@ -651,12 +739,12 @@ export default {
|
|
|
651
739
|
for (let i = 1; i < boxes.length; i++) {
|
|
652
740
|
firstBox.union(boxes[i]);
|
|
653
741
|
}
|
|
654
|
-
sceneBoundingBox = firstBox;
|
|
655
|
-
return sceneBoundingBox;
|
|
742
|
+
this.sceneBoundingBox = firstBox;
|
|
743
|
+
return this.sceneBoundingBox;
|
|
656
744
|
}
|
|
657
745
|
|
|
658
|
-
sceneBoundingBox = new this.THREE.Box3();
|
|
659
|
-
return sceneBoundingBox;
|
|
746
|
+
this.sceneBoundingBox = new this.THREE.Box3();
|
|
747
|
+
return this.sceneBoundingBox;
|
|
660
748
|
},
|
|
661
749
|
setBoxIndex(boxJson, documentId, isAdd = true) {
|
|
662
750
|
if (!this._boxIndex) this._boxIndex = new Map();
|
|
@@ -665,7 +753,7 @@ export default {
|
|
|
665
753
|
if (this.noObserver && this.noObserver.documentModelIds) {
|
|
666
754
|
this.noObserver.documentModelIds.clear();
|
|
667
755
|
}
|
|
668
|
-
hasExecutedCentering = false;
|
|
756
|
+
this.hasExecutedCentering = false;
|
|
669
757
|
this.buildOctreeFromBoxIndex();
|
|
670
758
|
return;
|
|
671
759
|
}
|
|
@@ -687,13 +775,13 @@ export default {
|
|
|
687
775
|
if (hasMatrix && it.matrix.length >= 16) {
|
|
688
776
|
const matrix = new this.THREE.Matrix4().fromArray(it.matrix);
|
|
689
777
|
const worldMatrix = matrix.clone();
|
|
690
|
-
if (bizToThreeMatrix) {
|
|
691
|
-
worldMatrix.premultiply(bizToThreeMatrix);
|
|
778
|
+
if (this.bizToThreeMatrix) {
|
|
779
|
+
worldMatrix.premultiply(this.bizToThreeMatrix);
|
|
692
780
|
}
|
|
693
781
|
boxThree.applyMatrix4(worldMatrix);
|
|
694
|
-
} else if (bizToThreeMatrix) {
|
|
782
|
+
} else if (this.bizToThreeMatrix) {
|
|
695
783
|
// 注意:applyMatrix4 会重新计算 AABB
|
|
696
|
-
boxThree.applyMatrix4(bizToThreeMatrix);
|
|
784
|
+
boxThree.applyMatrix4(this.bizToThreeMatrix);
|
|
697
785
|
}
|
|
698
786
|
|
|
699
787
|
const userData = {
|
|
@@ -760,7 +848,7 @@ export default {
|
|
|
760
848
|
|
|
761
849
|
// 当前无模型了,重置相机中心状态
|
|
762
850
|
if (this.noObserver.documentModelIds.size == 0) {
|
|
763
|
-
hasExecutedCentering = false;
|
|
851
|
+
this.hasExecutedCentering = false;
|
|
764
852
|
}
|
|
765
853
|
}
|
|
766
854
|
}
|
|
@@ -768,11 +856,16 @@ export default {
|
|
|
768
856
|
console.log('time end', Date.now());
|
|
769
857
|
},
|
|
770
858
|
tryInitialCenterAfterBoundsReady() {
|
|
771
|
-
if (hasExecutedCentering || userInteracting) return;
|
|
772
|
-
if (
|
|
859
|
+
if (this.hasExecutedCentering || this.userInteracting) return;
|
|
860
|
+
if (
|
|
861
|
+
!this.sceneBoundingBox ||
|
|
862
|
+
!this.sceneBoundingBox.isBox3 ||
|
|
863
|
+
this.sceneBoundingBox.isEmpty()
|
|
864
|
+
)
|
|
865
|
+
return;
|
|
773
866
|
if (!this._boxIndex || this._boxIndex.size === 0) return;
|
|
774
867
|
|
|
775
|
-
this.smartModelCenter(sceneBoundingBox, 0);
|
|
868
|
+
this.smartModelCenter(this.sceneBoundingBox, 0);
|
|
776
869
|
},
|
|
777
870
|
buildOctreeFromBoxIndex() {
|
|
778
871
|
if (!this._boxIndex || this._boxIndex.size === 0) {
|
|
@@ -801,7 +894,7 @@ export default {
|
|
|
801
894
|
new this.THREE.Vector3(minX, minY, minZ),
|
|
802
895
|
new this.THREE.Vector3(maxX, maxY, maxZ)
|
|
803
896
|
);
|
|
804
|
-
sceneBoundingBox = rootBox.clone();
|
|
897
|
+
this.sceneBoundingBox = rootBox.clone();
|
|
805
898
|
this._octreeMaxItems = 64;
|
|
806
899
|
this._octreeMaxDepth = 12;
|
|
807
900
|
this._octree = { box: rootBox, items: [], children: null, depth: 0 };
|
|
@@ -874,14 +967,14 @@ export default {
|
|
|
874
967
|
},
|
|
875
968
|
_getCurrentFrustum() {
|
|
876
969
|
// 确保相机矩阵是最新的
|
|
877
|
-
if (camera) {
|
|
878
|
-
camera.updateMatrixWorld();
|
|
879
|
-
camera.matrixWorldInverse.copy(camera.matrixWorld).invert();
|
|
970
|
+
if (this.camera) {
|
|
971
|
+
this.camera.updateMatrixWorld();
|
|
972
|
+
this.camera.matrixWorldInverse.copy(this.camera.matrixWorld).invert();
|
|
880
973
|
}
|
|
881
974
|
const frustum = new this.THREE.Frustum();
|
|
882
975
|
const vpMatrix = new this.THREE.Matrix4().multiplyMatrices(
|
|
883
|
-
camera.projectionMatrix,
|
|
884
|
-
camera.matrixWorldInverse
|
|
976
|
+
this.camera.projectionMatrix,
|
|
977
|
+
this.camera.matrixWorldInverse
|
|
885
978
|
);
|
|
886
979
|
frustum.setFromProjectionMatrix(vpMatrix);
|
|
887
980
|
return frustum;
|
|
@@ -946,26 +1039,26 @@ export default {
|
|
|
946
1039
|
return results;
|
|
947
1040
|
},
|
|
948
1041
|
setCameraFar() {
|
|
949
|
-
const bbox = sceneBoundingBox;
|
|
1042
|
+
const bbox = this.sceneBoundingBox;
|
|
950
1043
|
const center = bbox.getCenter(new this.THREE.Vector3());
|
|
951
1044
|
const size = bbox.getSize(new this.THREE.Vector3());
|
|
952
1045
|
const maxDist = size.length();
|
|
953
|
-
// const distance = camera.position.distanceTo(center);
|
|
954
|
-
camera.far = maxDist * 2;
|
|
955
|
-
// camera.far = 100;
|
|
956
|
-
camera.updateProjectionMatrix();
|
|
1046
|
+
// const distance = this.camera.position.distanceTo(center);
|
|
1047
|
+
this.camera.far = maxDist * 2;
|
|
1048
|
+
// this.camera.far = 100;
|
|
1049
|
+
this.camera.updateProjectionMatrix();
|
|
957
1050
|
},
|
|
958
1051
|
// 新增:当相机位于场景包围盒内时,动态调整相机远裁剪面
|
|
959
1052
|
adjustCameraFarPlaneForSceneBox() {
|
|
960
1053
|
try {
|
|
961
|
-
if (!camera || !sceneBoundingBox || !sceneBoundingBox.isBox3) return;
|
|
1054
|
+
if (!this.camera || !this.sceneBoundingBox || !this.sceneBoundingBox.isBox3) return;
|
|
962
1055
|
|
|
963
1056
|
// 获取最新相机位置
|
|
964
|
-
camera.updateMatrixWorld(true);
|
|
965
|
-
const camPos = new this.THREE.Vector3().setFromMatrixPosition(camera.matrixWorld);
|
|
1057
|
+
this.camera.updateMatrixWorld(true);
|
|
1058
|
+
const camPos = new this.THREE.Vector3().setFromMatrixPosition(this.camera.matrixWorld);
|
|
966
1059
|
|
|
967
|
-
const min = sceneBoundingBox.min;
|
|
968
|
-
const max = sceneBoundingBox.max;
|
|
1060
|
+
const min = this.sceneBoundingBox.min;
|
|
1061
|
+
const max = this.sceneBoundingBox.max;
|
|
969
1062
|
|
|
970
1063
|
// 包围盒八个顶点
|
|
971
1064
|
const vertices = [
|
|
@@ -987,13 +1080,13 @@ export default {
|
|
|
987
1080
|
}
|
|
988
1081
|
|
|
989
1082
|
// 确保 newFar > near,且更新投影矩阵
|
|
990
|
-
const newFar = Math.max(maxDistance, camera.near + 0.1);
|
|
991
|
-
if (Math.abs(camera.far - newFar) > 1e-6) {
|
|
992
|
-
camera.far = newFar;
|
|
993
|
-
camera.updateProjectionMatrix();
|
|
1083
|
+
const newFar = Math.max(maxDistance, this.camera.near + 0.1);
|
|
1084
|
+
if (Math.abs(this.camera.far - newFar) > 1e-6) {
|
|
1085
|
+
this.camera.far = newFar;
|
|
1086
|
+
this.camera.updateProjectionMatrix();
|
|
994
1087
|
}
|
|
995
1088
|
|
|
996
|
-
// console.log('camera.far', camera.far)
|
|
1089
|
+
// console.log('this.camera.far', this.camera.far)
|
|
997
1090
|
} catch (e) {
|
|
998
1091
|
// 防御式处理,避免交互中断
|
|
999
1092
|
}
|
|
@@ -1002,7 +1095,7 @@ export default {
|
|
|
1002
1095
|
* 计算当前相机视口在指定平面上的投影范围,并返回视椎体高度(min/max)。
|
|
1003
1096
|
* frustumY.min 会被限制:不小于平面在视椎体 x/z 范围内的最低 y 值(如果可计算)。
|
|
1004
1097
|
*
|
|
1005
|
-
* @param {THREE.Camera} camera
|
|
1098
|
+
* @param {THREE.Camera} this.camera
|
|
1006
1099
|
* @param {number} width
|
|
1007
1100
|
* @param {number} height
|
|
1008
1101
|
* @param {THREE.Plane} plane - three.js 的 Plane,方程为: normal.dot(p) + constant = 0
|
|
@@ -1013,8 +1106,8 @@ export default {
|
|
|
1013
1106
|
getScreenPlaneBounds(camera, width, height, plane, opts = {}) {
|
|
1014
1107
|
const { includeFrustumY = false } = opts;
|
|
1015
1108
|
|
|
1016
|
-
camera.updateMatrixWorld();
|
|
1017
|
-
if (camera.projectionMatrixNeedsUpdate) camera.updateProjectionMatrix();
|
|
1109
|
+
this.camera.updateMatrixWorld();
|
|
1110
|
+
if (this.camera.projectionMatrixNeedsUpdate) this.camera.updateProjectionMatrix();
|
|
1018
1111
|
|
|
1019
1112
|
const screenCorners = [
|
|
1020
1113
|
[0, 0], // 左下
|
|
@@ -1034,11 +1127,11 @@ export default {
|
|
|
1034
1127
|
|
|
1035
1128
|
const ndcNear = ndcBase.clone();
|
|
1036
1129
|
ndcNear.z = -1;
|
|
1037
|
-
frustumPoints.push(ndcNear.clone().unproject(camera));
|
|
1130
|
+
frustumPoints.push(ndcNear.clone().unproject(this.camera));
|
|
1038
1131
|
|
|
1039
1132
|
const ndcFar = ndcBase.clone();
|
|
1040
1133
|
ndcFar.z = 1;
|
|
1041
|
-
frustumPoints.push(ndcFar.clone().unproject(camera));
|
|
1134
|
+
frustumPoints.push(ndcFar.clone().unproject(this.camera));
|
|
1042
1135
|
}
|
|
1043
1136
|
|
|
1044
1137
|
const frustumBox = new this.THREE.Box3().setFromPoints(frustumPoints);
|
|
@@ -1085,14 +1178,14 @@ export default {
|
|
|
1085
1178
|
// 基于远/近裁剪面角点计算在 Y 轴的投影范围(min/max)
|
|
1086
1179
|
const nearFarY = computePlaneMinYOverBox(plane, frustumBox);
|
|
1087
1180
|
|
|
1088
|
-
const target = this.getCameraTargetOnPlane(camera, plane);
|
|
1181
|
+
const target = this.getCameraTargetOnPlane(this.camera, plane);
|
|
1089
1182
|
|
|
1090
|
-
// 将最终范围限制在 sceneBoundingBox 内(若已存在)
|
|
1183
|
+
// 将最终范围限制在 this.sceneBoundingBox 内(若已存在)
|
|
1091
1184
|
let finalMinY = nearFarY.min;
|
|
1092
1185
|
let finalMaxY = nearFarY.max;
|
|
1093
|
-
if (sceneBoundingBox && sceneBoundingBox.isBox3) {
|
|
1094
|
-
finalMinY = Math.max(finalMinY, sceneBoundingBox.min.y);
|
|
1095
|
-
finalMaxY = Math.min(finalMaxY, sceneBoundingBox.max.y);
|
|
1186
|
+
if (this.sceneBoundingBox && this.sceneBoundingBox.isBox3) {
|
|
1187
|
+
finalMinY = Math.max(finalMinY, this.sceneBoundingBox.min.y);
|
|
1188
|
+
finalMaxY = Math.min(finalMaxY, this.sceneBoundingBox.max.y);
|
|
1096
1189
|
}
|
|
1097
1190
|
|
|
1098
1191
|
return {
|
|
@@ -1104,46 +1197,48 @@ export default {
|
|
|
1104
1197
|
},
|
|
1105
1198
|
|
|
1106
1199
|
/**
|
|
1107
|
-
* 计算相机射线与场景包围盒(sceneBoundingBox)的交点,以及该点到视椎体近裁剪面。
|
|
1108
|
-
* 优先使用相机的目标点(cameraControls._target)确定射线方向;若不可用则回退为相机世界前向。
|
|
1200
|
+
* 计算相机射线与场景包围盒(this.sceneBoundingBox)的交点,以及该点到视椎体近裁剪面。
|
|
1201
|
+
* 优先使用相机的目标点(this.cameraControls._target)确定射线方向;若不可用则回退为相机世界前向。
|
|
1109
1202
|
* 若包围盒为空,回退为根据当前模型组/场景计算一次包围盒。
|
|
1110
1203
|
* 若与包围盒无交点且提供了平面参数,则回退为与该平面的交点;仍无交点则将相机位置投影到该平面。
|
|
1111
1204
|
*
|
|
1112
|
-
* @param {THREE.Camera} camera - 相机对象
|
|
1205
|
+
* @param {THREE.Camera} this.camera - 相机对象
|
|
1113
1206
|
* @param {THREE.Plane} [plane] - 可选,用于无包围盒交点时的回退平面
|
|
1114
1207
|
* @returns {Object} { targetPoint: THREE.Vector3, distanceToNearPlane: number, cameraPosition: THREE.Vector3, nearPlanePoint: THREE.Vector3 }
|
|
1115
1208
|
*/
|
|
1116
1209
|
getCameraTargetOnPlane(camera, plane) {
|
|
1117
|
-
camera.updateMatrixWorld();
|
|
1118
|
-
if (camera.projectionMatrixNeedsUpdate) camera.updateProjectionMatrix();
|
|
1210
|
+
this.camera.updateMatrixWorld();
|
|
1211
|
+
if (this.camera.projectionMatrixNeedsUpdate) this.camera.updateProjectionMatrix();
|
|
1119
1212
|
|
|
1120
1213
|
// 相机世界位置
|
|
1121
|
-
const cameraPosition = new this.THREE.Vector3().setFromMatrixPosition(
|
|
1214
|
+
const cameraPosition = new this.THREE.Vector3().setFromMatrixPosition(
|
|
1215
|
+
this.camera.matrixWorld
|
|
1216
|
+
);
|
|
1122
1217
|
|
|
1123
|
-
// 从相机指向目标点的射线方向(优先使用 cameraControls._target)
|
|
1218
|
+
// 从相机指向目标点的射线方向(优先使用 this.cameraControls._target)
|
|
1124
1219
|
const rayDirection = new this.THREE.Vector3();
|
|
1125
1220
|
if (
|
|
1126
|
-
typeof cameraControls !== 'undefined' &&
|
|
1127
|
-
cameraControls &&
|
|
1128
|
-
cameraControls.enabled &&
|
|
1129
|
-
cameraControls._target
|
|
1221
|
+
typeof this.cameraControls !== 'undefined' &&
|
|
1222
|
+
this.cameraControls &&
|
|
1223
|
+
this.cameraControls.enabled &&
|
|
1224
|
+
this.cameraControls._target
|
|
1130
1225
|
) {
|
|
1131
|
-
rayDirection.copy(cameraControls._target).sub(cameraPosition).normalize();
|
|
1226
|
+
rayDirection.copy(this.cameraControls._target).sub(cameraPosition).normalize();
|
|
1132
1227
|
} else {
|
|
1133
|
-
camera.getWorldDirection(rayDirection); // -Z 方向(世界坐标)
|
|
1228
|
+
this.camera.getWorldDirection(rayDirection); // -Z 方向(世界坐标)
|
|
1134
1229
|
}
|
|
1135
1230
|
|
|
1136
1231
|
const ray = new this.THREE.Ray(cameraPosition.clone(), rayDirection.clone());
|
|
1137
1232
|
|
|
1138
1233
|
// 准备/计算场景包围盒
|
|
1139
|
-
// if (!sceneBoundingBox) {
|
|
1234
|
+
// if (!this.sceneBoundingBox) {
|
|
1140
1235
|
// const box3 = new this.THREE.Box3();
|
|
1141
|
-
// if (typeof modelGroup !== 'undefined' && modelGroup) {
|
|
1142
|
-
// box3.expandByObject(modelGroup);
|
|
1143
|
-
// } else if (scene) {
|
|
1144
|
-
// box3.expandByObject(scene);
|
|
1236
|
+
// if (typeof this.modelGroup !== 'undefined' && this.modelGroup) {
|
|
1237
|
+
// box3.expandByObject(this.modelGroup);
|
|
1238
|
+
// } else if (this.scene) {
|
|
1239
|
+
// box3.expandByObject(this.scene);
|
|
1145
1240
|
// }
|
|
1146
|
-
// sceneBoundingBox = box3;
|
|
1241
|
+
// this.sceneBoundingBox = box3;
|
|
1147
1242
|
// }
|
|
1148
1243
|
|
|
1149
1244
|
// 与场景包围盒的交点(若无交点则进行回退)
|
|
@@ -1151,22 +1246,24 @@ export default {
|
|
|
1151
1246
|
let boxHitPoint = null;
|
|
1152
1247
|
// 若包围盒不存在或为空,兜底从模型组/场景计算一次
|
|
1153
1248
|
if (
|
|
1154
|
-
!sceneBoundingBox ||
|
|
1155
|
-
(sceneBoundingBox.isBox3 &&
|
|
1249
|
+
!this.sceneBoundingBox ||
|
|
1250
|
+
(this.sceneBoundingBox.isBox3 &&
|
|
1251
|
+
this.sceneBoundingBox.isEmpty &&
|
|
1252
|
+
this.sceneBoundingBox.isEmpty())
|
|
1156
1253
|
) {
|
|
1157
1254
|
const obj =
|
|
1158
|
-
typeof modelGroup !== 'undefined' &&
|
|
1159
|
-
modelGroup &&
|
|
1160
|
-
modelGroup.children &&
|
|
1161
|
-
modelGroup.children.length
|
|
1162
|
-
? modelGroup
|
|
1163
|
-
: scene;
|
|
1255
|
+
typeof this.modelGroup !== 'undefined' &&
|
|
1256
|
+
this.modelGroup &&
|
|
1257
|
+
this.modelGroup.children &&
|
|
1258
|
+
this.modelGroup.children.length
|
|
1259
|
+
? this.modelGroup
|
|
1260
|
+
: this.scene;
|
|
1164
1261
|
if (obj) {
|
|
1165
|
-
sceneBoundingBox = new this.THREE.Box3().setFromObject(obj);
|
|
1262
|
+
this.sceneBoundingBox = new this.THREE.Box3().setFromObject(obj);
|
|
1166
1263
|
}
|
|
1167
1264
|
}
|
|
1168
|
-
if (sceneBoundingBox && sceneBoundingBox.isBox3) {
|
|
1169
|
-
boxHitPoint = ray.intersectBox(sceneBoundingBox, new this.THREE.Vector3());
|
|
1265
|
+
if (this.sceneBoundingBox && this.sceneBoundingBox.isBox3) {
|
|
1266
|
+
boxHitPoint = ray.intersectBox(this.sceneBoundingBox, new this.THREE.Vector3());
|
|
1170
1267
|
}
|
|
1171
1268
|
|
|
1172
1269
|
// targetPoint 保留原平面回退逻辑(用于其他需要点位的场景)
|
|
@@ -1206,14 +1303,14 @@ export default {
|
|
|
1206
1303
|
* @returns {boolean} 是否在视椎体内
|
|
1207
1304
|
*/
|
|
1208
1305
|
isModelInFrustum(model, instanceId = null, frustum = null) {
|
|
1209
|
-
if (!model || !camera) return true;
|
|
1306
|
+
if (!model || !this.camera) return true;
|
|
1210
1307
|
|
|
1211
1308
|
// 优先使用传入的 frustum,避免重复创建
|
|
1212
1309
|
if (!frustum) {
|
|
1213
1310
|
frustum = new this.THREE.Frustum();
|
|
1214
1311
|
const matrix = new this.THREE.Matrix4().multiplyMatrices(
|
|
1215
|
-
camera.projectionMatrix,
|
|
1216
|
-
camera.matrixWorldInverse
|
|
1312
|
+
this.camera.projectionMatrix,
|
|
1313
|
+
this.camera.matrixWorldInverse
|
|
1217
1314
|
);
|
|
1218
1315
|
frustum.setFromProjectionMatrix(matrix);
|
|
1219
1316
|
}
|
|
@@ -1247,7 +1344,7 @@ export default {
|
|
|
1247
1344
|
* @returns {number} SSE值
|
|
1248
1345
|
*/
|
|
1249
1346
|
calculateSSE(model) {
|
|
1250
|
-
if (!model || !camera || !renderer) return 0;
|
|
1347
|
+
if (!model || !this.camera || !this.renderer) return 0;
|
|
1251
1348
|
|
|
1252
1349
|
// 获取模型的包围盒
|
|
1253
1350
|
const box = new this.THREE.Box3().setFromObject(model);
|
|
@@ -1261,7 +1358,7 @@ export default {
|
|
|
1261
1358
|
|
|
1262
1359
|
// 获取相机世界位置
|
|
1263
1360
|
const cameraPosition = new this.THREE.Vector3();
|
|
1264
|
-
camera.getWorldPosition(cameraPosition);
|
|
1361
|
+
this.camera.getWorldPosition(cameraPosition);
|
|
1265
1362
|
|
|
1266
1363
|
// 计算相机到物体包围盒中心的距离
|
|
1267
1364
|
const distance = cameraPosition.distanceTo(center);
|
|
@@ -1270,10 +1367,10 @@ export default {
|
|
|
1270
1367
|
if (distance === 0) return Infinity;
|
|
1271
1368
|
|
|
1272
1369
|
// 获取视口高度
|
|
1273
|
-
const viewportHeight = renderer.domElement.clientHeight;
|
|
1370
|
+
const viewportHeight = this.renderer.domElement.clientHeight;
|
|
1274
1371
|
|
|
1275
1372
|
// 计算tan(fov/2),fov是以度为单位
|
|
1276
|
-
const halfFovRad = this.THREE.MathUtils.degToRad(camera.fov / 2);
|
|
1373
|
+
const halfFovRad = this.THREE.MathUtils.degToRad(this.camera.fov / 2);
|
|
1277
1374
|
const tanHalfFov = Math.tan(halfFovRad);
|
|
1278
1375
|
|
|
1279
1376
|
// 计算SSE
|
|
@@ -1283,14 +1380,14 @@ export default {
|
|
|
1283
1380
|
},
|
|
1284
1381
|
// 针对已卸载实例的信息进行视锥体检测
|
|
1285
1382
|
isInstanceInfoInFrustum(instanceInfo) {
|
|
1286
|
-
if (!instanceInfo || !camera) return true;
|
|
1383
|
+
if (!instanceInfo || !this.camera) return true;
|
|
1287
1384
|
const { geometry, originalMatrix, parent } = instanceInfo;
|
|
1288
1385
|
if (!geometry || !originalMatrix) return false;
|
|
1289
1386
|
|
|
1290
1387
|
const frustum = new this.THREE.Frustum();
|
|
1291
1388
|
const vpMatrix = new this.THREE.Matrix4().multiplyMatrices(
|
|
1292
|
-
camera.projectionMatrix,
|
|
1293
|
-
camera.matrixWorldInverse
|
|
1389
|
+
this.camera.projectionMatrix,
|
|
1390
|
+
this.camera.matrixWorldInverse
|
|
1294
1391
|
);
|
|
1295
1392
|
frustum.setFromProjectionMatrix(vpMatrix);
|
|
1296
1393
|
|
|
@@ -1316,7 +1413,7 @@ export default {
|
|
|
1316
1413
|
const modelState = this.noObserver
|
|
1317
1414
|
? this.noObserver.modelStateManager
|
|
1318
1415
|
: this.modelStateManager;
|
|
1319
|
-
if (!this.modelStateManager.frustumCheckEnabled || !scene) return;
|
|
1416
|
+
if (!this.modelStateManager.frustumCheckEnabled || !this.scene) return;
|
|
1320
1417
|
const now = Date.now();
|
|
1321
1418
|
if (now - modelState.lastCullingTime < 100) {
|
|
1322
1419
|
return;
|
|
@@ -1329,8 +1426,8 @@ export default {
|
|
|
1329
1426
|
|
|
1330
1427
|
const globalFrustum = this._frustum;
|
|
1331
1428
|
const globalVpMatrix = this._vpMatrix.multiplyMatrices(
|
|
1332
|
-
camera.projectionMatrix,
|
|
1333
|
-
camera.matrixWorldInverse
|
|
1429
|
+
this.camera.projectionMatrix,
|
|
1430
|
+
this.camera.matrixWorldInverse
|
|
1334
1431
|
);
|
|
1335
1432
|
globalFrustum.setFromProjectionMatrix(globalVpMatrix);
|
|
1336
1433
|
|
|
@@ -1368,12 +1465,12 @@ export default {
|
|
|
1368
1465
|
if (occlusionEnabled) {
|
|
1369
1466
|
const state = occlusionState;
|
|
1370
1467
|
const w =
|
|
1371
|
-
renderer && renderer.domElement
|
|
1372
|
-
? renderer.domElement.clientWidth || renderer.domElement.width || 0
|
|
1468
|
+
this.renderer && this.renderer.domElement
|
|
1469
|
+
? this.renderer.domElement.clientWidth || this.renderer.domElement.width || 0
|
|
1373
1470
|
: 0;
|
|
1374
1471
|
const h =
|
|
1375
|
-
renderer && renderer.domElement
|
|
1376
|
-
? renderer.domElement.clientHeight || renderer.domElement.height || 0
|
|
1472
|
+
this.renderer && this.renderer.domElement
|
|
1473
|
+
? this.renderer.domElement.clientHeight || this.renderer.domElement.height || 0
|
|
1377
1474
|
: 0;
|
|
1378
1475
|
// bufferWidth/Height 仍从响应式对象读取以支持动态修改
|
|
1379
1476
|
// 性能优化:使用降采样缓冲区进行遮挡剔除,大幅减少 readPixels 耗时 (从全屏降至约 256px 宽)
|
|
@@ -1409,15 +1506,15 @@ export default {
|
|
|
1409
1506
|
if (!state._occScene) state._occScene = new this.THREE.Scene();
|
|
1410
1507
|
// if (!state._occPerfStats) state._occPerfStats = Object.create(null);
|
|
1411
1508
|
// const _occRecordPerf = (name, ms, meta) => {
|
|
1412
|
-
// const stats = state._occPerfStats;
|
|
1413
|
-
// const prev = stats[name];
|
|
1509
|
+
// const this.stats = state._occPerfStats;
|
|
1510
|
+
// const prev = this.stats[name];
|
|
1414
1511
|
// const next = prev || { count: 0, total: 0, max: 0, last: 0, meta: null };
|
|
1415
1512
|
// next.count++;
|
|
1416
1513
|
// next.total += ms;
|
|
1417
1514
|
// next.last = ms;
|
|
1418
1515
|
// if (ms > next.max) next.max = ms;
|
|
1419
1516
|
// if (meta) next.meta = meta;
|
|
1420
|
-
// stats[name] = next;
|
|
1517
|
+
// this.stats[name] = next;
|
|
1421
1518
|
// };
|
|
1422
1519
|
|
|
1423
1520
|
// 过滤掉透明物体
|
|
@@ -1543,8 +1640,8 @@ export default {
|
|
|
1543
1640
|
_tempScale.copy(halfSize).multiplyScalar(2);
|
|
1544
1641
|
_tempMatrix.copy(matrix);
|
|
1545
1642
|
_tempMatrix.scale(_tempScale);
|
|
1546
|
-
if (typeof bizToThreeMatrix !== 'undefined' && bizToThreeMatrix) {
|
|
1547
|
-
_tempMatrix.premultiply(bizToThreeMatrix);
|
|
1643
|
+
if (typeof this.bizToThreeMatrix !== 'undefined' && this.bizToThreeMatrix) {
|
|
1644
|
+
_tempMatrix.premultiply(this.bizToThreeMatrix);
|
|
1548
1645
|
}
|
|
1549
1646
|
|
|
1550
1647
|
boxes.mesh.setMatrixAt(i, _tempMatrix);
|
|
@@ -1648,7 +1745,7 @@ export default {
|
|
|
1648
1745
|
const vertexCount = (obbData.length / 3) | 0;
|
|
1649
1746
|
const needTransform =
|
|
1650
1747
|
(matrixArr && matrixArr.length >= 16) ||
|
|
1651
|
-
(typeof bizToThreeMatrix !== 'undefined' && bizToThreeMatrix);
|
|
1748
|
+
(typeof this.bizToThreeMatrix !== 'undefined' && this.bizToThreeMatrix);
|
|
1652
1749
|
|
|
1653
1750
|
if (needTransform) {
|
|
1654
1751
|
if (matrixArr && matrixArr.length >= 16) {
|
|
@@ -1656,8 +1753,8 @@ export default {
|
|
|
1656
1753
|
} else {
|
|
1657
1754
|
_tempMatA.identity();
|
|
1658
1755
|
}
|
|
1659
|
-
if (typeof bizToThreeMatrix !== 'undefined' && bizToThreeMatrix) {
|
|
1660
|
-
_tempMatA.premultiply(bizToThreeMatrix);
|
|
1756
|
+
if (typeof this.bizToThreeMatrix !== 'undefined' && this.bizToThreeMatrix) {
|
|
1757
|
+
_tempMatA.premultiply(this.bizToThreeMatrix);
|
|
1661
1758
|
}
|
|
1662
1759
|
}
|
|
1663
1760
|
|
|
@@ -1814,8 +1911,8 @@ export default {
|
|
|
1814
1911
|
tempMatrix.copy(matrix);
|
|
1815
1912
|
tempScale.copy(halfSize).multiplyScalar(2);
|
|
1816
1913
|
tempMatrix.scale(tempScale);
|
|
1817
|
-
if (typeof bizToThreeMatrix !== 'undefined' && bizToThreeMatrix) {
|
|
1818
|
-
tempMatrix.premultiply(bizToThreeMatrix);
|
|
1914
|
+
if (typeof this.bizToThreeMatrix !== 'undefined' && this.bizToThreeMatrix) {
|
|
1915
|
+
tempMatrix.premultiply(this.bizToThreeMatrix);
|
|
1819
1916
|
}
|
|
1820
1917
|
} else {
|
|
1821
1918
|
c.box.getSize(tempScale);
|
|
@@ -1842,23 +1939,23 @@ export default {
|
|
|
1842
1939
|
state._occTransparentMaxIdx = 0;
|
|
1843
1940
|
}
|
|
1844
1941
|
|
|
1845
|
-
// console.log('renderer', renderer)
|
|
1846
|
-
const prevToneMapping = renderer.toneMapping;
|
|
1847
|
-
const prevTarget = renderer.getRenderTarget ? renderer.getRenderTarget() : null;
|
|
1942
|
+
// console.log('this.renderer', this.renderer)
|
|
1943
|
+
const prevToneMapping = this.renderer.toneMapping;
|
|
1944
|
+
const prevTarget = this.renderer.getRenderTarget ? this.renderer.getRenderTarget() : null;
|
|
1848
1945
|
let prevClearColorHex = 0x000000;
|
|
1849
1946
|
let prevClearAlpha = 0;
|
|
1850
1947
|
try {
|
|
1851
|
-
const c = renderer.getClearColor ? renderer.getClearColor() : null;
|
|
1948
|
+
const c = this.renderer.getClearColor ? this.renderer.getClearColor() : null;
|
|
1852
1949
|
if (c && c.isColor) prevClearColorHex = c.getHex();
|
|
1853
1950
|
prevClearAlpha =
|
|
1854
|
-
typeof renderer.getClearAlpha === 'function' ? renderer.getClearAlpha() : 0;
|
|
1951
|
+
typeof this.renderer.getClearAlpha === 'function' ? this.renderer.getClearAlpha() : 0;
|
|
1855
1952
|
} catch (_) {}
|
|
1856
|
-
renderer.toneMapping = this.THREE.NoToneMapping;
|
|
1857
|
-
renderer.setRenderTarget(rt);
|
|
1858
|
-
renderer.setClearColor(new this.THREE.Color(0, 0, 0), 0);
|
|
1859
|
-
renderer.clear(true, true, false);
|
|
1860
|
-
camera.updateMatrixWorld(true);
|
|
1861
|
-
renderer.render(state._occScene, camera);
|
|
1953
|
+
this.renderer.toneMapping = this.THREE.NoToneMapping;
|
|
1954
|
+
this.renderer.setRenderTarget(rt);
|
|
1955
|
+
this.renderer.setClearColor(new this.THREE.Color(0, 0, 0), 0);
|
|
1956
|
+
this.renderer.clear(true, true, false);
|
|
1957
|
+
this.camera.updateMatrixWorld(true);
|
|
1958
|
+
this.renderer.render(state._occScene, this.camera);
|
|
1862
1959
|
this.updateGlobalSceneBoundingBox();
|
|
1863
1960
|
// const t1 = performance.now();
|
|
1864
1961
|
// 从响应式对象读取 previewEnabled
|
|
@@ -1883,11 +1980,11 @@ export default {
|
|
|
1883
1980
|
}
|
|
1884
1981
|
state._previewCanvas.width = sw;
|
|
1885
1982
|
state._previewCanvas.height = sh;
|
|
1886
|
-
const cssW = Math.min(renderer.domElement.width / 5);
|
|
1887
|
-
const cssH = Math.min(renderer.domElement.height / 5);
|
|
1983
|
+
const cssW = Math.min(this.renderer.domElement.width / 5);
|
|
1984
|
+
const cssH = Math.min(this.renderer.domElement.height / 5);
|
|
1888
1985
|
state._previewCanvas.style.width = cssW + 'px';
|
|
1889
1986
|
state._previewCanvas.style.height = cssH + 'px';
|
|
1890
|
-
renderer.readRenderTargetPixels(rt, 0, 0, sw, sh, state._previewBuffer);
|
|
1987
|
+
this.renderer.readRenderTargetPixels(rt, 0, 0, sw, sh, state._previewBuffer);
|
|
1891
1988
|
if (
|
|
1892
1989
|
!state._previewImageData ||
|
|
1893
1990
|
state._previewImageData.width !== sw ||
|
|
@@ -1915,7 +2012,7 @@ export default {
|
|
|
1915
2012
|
}
|
|
1916
2013
|
// const tPreview1 = performance.now();
|
|
1917
2014
|
// _occRecordPerf('occ_preview_ms', tPreview1 - tPreview0, { sw, sh });
|
|
1918
|
-
renderer.readRenderTargetPixels(rt, 0, 0, sw, sh, state._colorBuffer);
|
|
2015
|
+
this.renderer.readRenderTargetPixels(rt, 0, 0, sw, sh, state._colorBuffer);
|
|
1919
2016
|
|
|
1920
2017
|
const idIndexArr = activeIdIndexArr;
|
|
1921
2018
|
const maxIdx = typeof state._occMaxIdx === 'number' ? state._occMaxIdx : 0;
|
|
@@ -1956,10 +2053,10 @@ export default {
|
|
|
1956
2053
|
const transparentMaxIdx =
|
|
1957
2054
|
typeof state._occTransparentMaxIdx === 'number' ? state._occTransparentMaxIdx : 0;
|
|
1958
2055
|
if (transparentMaxIdx > 0 && transparentMesh && transparentMesh.visible) {
|
|
1959
|
-
renderer.setClearColor(new this.THREE.Color(0, 0, 0), 0);
|
|
1960
|
-
renderer.clear(true, false, false);
|
|
1961
|
-
renderer.render(state._occTransparentScene, camera);
|
|
1962
|
-
renderer.readRenderTargetPixels(rt, 0, 0, sw, sh, state._colorBuffer);
|
|
2056
|
+
this.renderer.setClearColor(new this.THREE.Color(0, 0, 0), 0);
|
|
2057
|
+
this.renderer.clear(true, false, false);
|
|
2058
|
+
this.renderer.render(state._occTransparentScene, this.camera);
|
|
2059
|
+
this.renderer.readRenderTargetPixels(rt, 0, 0, sw, sh, state._colorBuffer);
|
|
1963
2060
|
|
|
1964
2061
|
const tIdIndexArr = transparentIdIndexArr;
|
|
1965
2062
|
const tScanResult = await this.scanOcclusionIndices(
|
|
@@ -1982,9 +2079,9 @@ export default {
|
|
|
1982
2079
|
}
|
|
1983
2080
|
}
|
|
1984
2081
|
|
|
1985
|
-
renderer.setRenderTarget(prevTarget);
|
|
1986
|
-
renderer.setClearColor(prevClearColorHex, prevClearAlpha);
|
|
1987
|
-
renderer.toneMapping = prevToneMapping;
|
|
2082
|
+
this.renderer.setRenderTarget(prevTarget);
|
|
2083
|
+
this.renderer.setClearColor(prevClearColorHex, prevClearAlpha);
|
|
2084
|
+
this.renderer.toneMapping = prevToneMapping;
|
|
1988
2085
|
} catch (e) {
|
|
1989
2086
|
for (let i = 0; i < candidates.length; i++) {
|
|
1990
2087
|
visibleIdSet.add(candidates[i].modelId);
|
|
@@ -1999,7 +2096,7 @@ export default {
|
|
|
1999
2096
|
visibleIdSet.forEach(id => visibleIds.push(id));
|
|
2000
2097
|
const toLoadSet = new Set(visibleIdSet);
|
|
2001
2098
|
const parentsToCheck = new Set();
|
|
2002
|
-
scene.traverse(child => {
|
|
2099
|
+
this.scene.traverse(child => {
|
|
2003
2100
|
if (!child.isInstancedMesh) return;
|
|
2004
2101
|
// 如果复用数量等于大于2个,则跳过裁剪和剔除处理(始终保留)
|
|
2005
2102
|
if (child.count >= 2) {
|
|
@@ -2051,7 +2148,7 @@ export default {
|
|
|
2051
2148
|
}
|
|
2052
2149
|
|
|
2053
2150
|
// 仅当所有实例都不活跃时,才执行卸载
|
|
2054
|
-
if (!firstPerSign && !roaming && allInactive) {
|
|
2151
|
+
if (!this.firstPerSign && !this.roaming && allInactive) {
|
|
2055
2152
|
toUnload.push({ modelId, child });
|
|
2056
2153
|
}
|
|
2057
2154
|
}
|
|
@@ -2072,7 +2169,7 @@ export default {
|
|
|
2072
2169
|
if (modelInVisible) {
|
|
2073
2170
|
toLoadSet.delete(modelId);
|
|
2074
2171
|
}
|
|
2075
|
-
if (!firstPerSign && !roaming && (!inFrustum || !modelInVisible)) {
|
|
2172
|
+
if (!this.firstPerSign && !this.roaming && (!inFrustum || !modelInVisible)) {
|
|
2076
2173
|
toUnload.push({ modelId, child });
|
|
2077
2174
|
}
|
|
2078
2175
|
});
|
|
@@ -2080,7 +2177,7 @@ export default {
|
|
|
2080
2177
|
if (child && child.parent) parentsToCheck.add(child.parent);
|
|
2081
2178
|
this.unloadInstancedModel(modelId, child);
|
|
2082
2179
|
}
|
|
2083
|
-
if (scene) {
|
|
2180
|
+
if (this.scene) {
|
|
2084
2181
|
parentsToCheck.forEach(group => {
|
|
2085
2182
|
if (group && group.children && group.children.length === 0) {
|
|
2086
2183
|
group.removeFromParent();
|
|
@@ -2090,11 +2187,11 @@ export default {
|
|
|
2090
2187
|
this.modelStateManager.isloadedModelsIds = Object.freeze(Array.from(toLoadSet));
|
|
2091
2188
|
},
|
|
2092
2189
|
isBoxInFrustum(box) {
|
|
2093
|
-
if (!camera) return true;
|
|
2190
|
+
if (!this.camera) return true;
|
|
2094
2191
|
const frustum = new this.THREE.Frustum();
|
|
2095
2192
|
const vpMatrix = new this.THREE.Matrix4().multiplyMatrices(
|
|
2096
|
-
camera.projectionMatrix,
|
|
2097
|
-
camera.matrixWorldInverse
|
|
2193
|
+
this.camera.projectionMatrix,
|
|
2194
|
+
this.camera.matrixWorldInverse
|
|
2098
2195
|
);
|
|
2099
2196
|
frustum.setFromProjectionMatrix(vpMatrix);
|
|
2100
2197
|
return frustum.intersectsBox(box);
|
|
@@ -2192,6 +2289,7 @@ export default {
|
|
|
2192
2289
|
* @param {string} [config.projectId] - 项目ID
|
|
2193
2290
|
*/
|
|
2194
2291
|
init(config = {}) {
|
|
2292
|
+
console.log('init');
|
|
2195
2293
|
this.initStreamLoader(config.modelApi, config);
|
|
2196
2294
|
},
|
|
2197
2295
|
|
|
@@ -2209,7 +2307,10 @@ export default {
|
|
|
2209
2307
|
debug: isDebug,
|
|
2210
2308
|
renderModelData: this.renderModelData.bind(this),
|
|
2211
2309
|
ensureNotInteracting: async abortSignal => {
|
|
2212
|
-
if (
|
|
2310
|
+
if (
|
|
2311
|
+
this.userInteracting ||
|
|
2312
|
+
this.noObserver.batchLoadingState.interactionState.isInteracting
|
|
2313
|
+
) {
|
|
2213
2314
|
await new Promise(resolve => setTimeout(resolve, 0));
|
|
2214
2315
|
}
|
|
2215
2316
|
},
|
|
@@ -2318,17 +2419,17 @@ export default {
|
|
|
2318
2419
|
* 同步获取当前WebGL画面的截图数据,解决preserveDrawingBuffer为false时html2canvas截黑屏的问题
|
|
2319
2420
|
*/
|
|
2320
2421
|
getScreenshotDataURL() {
|
|
2321
|
-
if (!renderer || !scene || !camera) return null;
|
|
2422
|
+
if (!this.renderer || !this.scene || !this.camera) return null;
|
|
2322
2423
|
|
|
2323
2424
|
// 强制渲染一帧
|
|
2324
|
-
if (outlineComposer) {
|
|
2325
|
-
outlineComposer.render();
|
|
2425
|
+
if (this.outlineComposer) {
|
|
2426
|
+
this.outlineComposer.render();
|
|
2326
2427
|
} else {
|
|
2327
|
-
renderer.render(scene, camera);
|
|
2428
|
+
this.renderer.render(this.scene, this.camera);
|
|
2328
2429
|
}
|
|
2329
2430
|
|
|
2330
2431
|
// 立即同步提取像素数据
|
|
2331
|
-
return renderer.domElement.toDataURL('image/png', 1.0);
|
|
2432
|
+
return this.renderer.domElement.toDataURL('image/png', 1.0);
|
|
2332
2433
|
},
|
|
2333
2434
|
/**
|
|
2334
2435
|
* 内部渲染流式数据方法
|
|
@@ -2406,7 +2507,7 @@ export default {
|
|
|
2406
2507
|
},
|
|
2407
2508
|
computeFrustumAABB() {
|
|
2408
2509
|
// 确保相机矩阵最新
|
|
2409
|
-
camera.updateMatrixWorld(true);
|
|
2510
|
+
this.camera.updateMatrixWorld(true);
|
|
2410
2511
|
|
|
2411
2512
|
// NDC 八个角
|
|
2412
2513
|
const ndcCorners = {
|
|
@@ -2422,8 +2523,8 @@ export default {
|
|
|
2422
2523
|
|
|
2423
2524
|
for (let key in ndcCorners) {
|
|
2424
2525
|
const v = new this.THREE.Vector3(...ndcCorners[key]);
|
|
2425
|
-
v.unproject(camera); // NDC → world
|
|
2426
|
-
v.applyMatrix4(threeToBizMatrix); // world → biz
|
|
2526
|
+
v.unproject(this.camera); // NDC → world
|
|
2527
|
+
v.applyMatrix4(this.threeToBizMatrix); // world → biz
|
|
2427
2528
|
ndcCorners[key] = v;
|
|
2428
2529
|
}
|
|
2429
2530
|
|
|
@@ -2459,79 +2560,85 @@ export default {
|
|
|
2459
2560
|
};
|
|
2460
2561
|
},
|
|
2461
2562
|
initRender() {
|
|
2462
|
-
renderer = new this.THREE.WebGLRenderer({
|
|
2563
|
+
this.renderer = new this.THREE.WebGLRenderer({
|
|
2463
2564
|
antialias: true,
|
|
2464
2565
|
alpha: true,
|
|
2465
2566
|
logarithmicDepthBuffer: true,
|
|
2466
2567
|
powerPreference: 'high-performance',
|
|
2467
2568
|
preserveDrawingBuffer: false, //保留图形缓冲区 TODO 临时截图使用
|
|
2468
2569
|
});
|
|
2469
|
-
renderer.debug.checkShaderErrors = false;
|
|
2470
|
-
renderer.info.autoReset = false;
|
|
2471
|
-
renderer.setPixelRatio(window.devicePixelRatio);
|
|
2472
|
-
const rect = instructions.getBoundingClientRect();
|
|
2473
|
-
renderer.setSize(rect.width, rect.height);
|
|
2474
|
-
renderer.domElement.id = 'three-model';
|
|
2475
|
-
renderer.shadowMap.enabled = true;
|
|
2476
|
-
renderer.outputEncoding = this.THREE.sRGBEncoding;
|
|
2477
|
-
instructions.appendChild(renderer.domElement);
|
|
2478
|
-
renderer.setClearAlpha(0);
|
|
2570
|
+
this.renderer.debug.checkShaderErrors = false;
|
|
2571
|
+
this.renderer.info.autoReset = false;
|
|
2572
|
+
this.renderer.setPixelRatio(window.devicePixelRatio);
|
|
2573
|
+
const rect = this.instructions.getBoundingClientRect();
|
|
2574
|
+
this.renderer.setSize(rect.width, rect.height);
|
|
2575
|
+
this.renderer.domElement.id = 'three-model-' + this.containId;
|
|
2576
|
+
this.renderer.shadowMap.enabled = true;
|
|
2577
|
+
this.renderer.outputEncoding = this.THREE.sRGBEncoding;
|
|
2578
|
+
this.instructions.appendChild(this.renderer.domElement);
|
|
2579
|
+
this.renderer.setClearAlpha(0);
|
|
2479
2580
|
|
|
2480
2581
|
// 监听体系已重构至 initCameraChangeObserver,此处仅保留必要的初始化
|
|
2481
2582
|
// 原始的 wheel 监听逻辑已迁移
|
|
2482
|
-
// renderer.domElement.addEventListener('wheel', this._wheelHandler);
|
|
2583
|
+
// this.renderer.domElement.addEventListener('wheel', this._wheelHandler);
|
|
2483
2584
|
|
|
2484
2585
|
// 与校审截图功能冲突,暂时先注释掉
|
|
2485
2586
|
// -----------
|
|
2486
|
-
// renderer.autoClear = false;
|
|
2487
|
-
// renderer.autoClearColor = false;
|
|
2488
|
-
// renderer.autoClearDepth = false;
|
|
2489
|
-
// renderer.autoClearStencil = false;
|
|
2587
|
+
// this.renderer.autoClear = false;
|
|
2588
|
+
// this.renderer.autoClearColor = false;
|
|
2589
|
+
// this.renderer.autoClearDepth = false;
|
|
2590
|
+
// this.renderer.autoClearStencil = false;
|
|
2490
2591
|
// -----------
|
|
2491
2592
|
},
|
|
2492
2593
|
initPostProcessing() {
|
|
2493
|
-
outlineComposer = new EffectComposer(renderer, renderTarget);
|
|
2594
|
+
this.outlineComposer = new EffectComposer(this.renderer, this.renderTarget);
|
|
2595
|
+
|
|
2596
|
+
const renderPass = new RenderPass(this.scene, this.camera);
|
|
2597
|
+
this.outlineComposer.addPass(renderPass);
|
|
2494
2598
|
|
|
2495
|
-
const
|
|
2496
|
-
|
|
2599
|
+
const rect = this.instructions.getBoundingClientRect();
|
|
2600
|
+
this.outlinePass = new OutlinePass(
|
|
2601
|
+
new this.THREE.Vector2(rect.width, rect.height),
|
|
2602
|
+
this.scene,
|
|
2603
|
+
this.camera
|
|
2604
|
+
);
|
|
2497
2605
|
|
|
2498
|
-
|
|
2499
|
-
outlinePass =
|
|
2500
|
-
outlinePass.
|
|
2501
|
-
outlinePass.
|
|
2502
|
-
outlinePass.
|
|
2503
|
-
|
|
2504
|
-
outlinePass.hiddenEdgeColor.set('#ffffff');
|
|
2505
|
-
outlineComposer.addPass(outlinePass);
|
|
2606
|
+
this.outlinePass.edgeStrength = 3;
|
|
2607
|
+
this.outlinePass.edgeGlow = 0.5; // 边缘模糊度
|
|
2608
|
+
this.outlinePass.edgeThickness = 2; // 轮廓线宽度
|
|
2609
|
+
this.outlinePass.visibleEdgeColor.set('#ffffff'); // 默认白色,后续可动态调整
|
|
2610
|
+
this.outlinePass.hiddenEdgeColor.set('#ffffff');
|
|
2611
|
+
this.outlineComposer.addPass(this.outlinePass);
|
|
2506
2612
|
|
|
2507
2613
|
const outputPass = new OutputPass();
|
|
2508
|
-
outlineComposer.addPass(outputPass);
|
|
2614
|
+
this.outlineComposer.addPass(outputPass);
|
|
2509
2615
|
},
|
|
2510
2616
|
initScene() {
|
|
2511
|
-
modelGroup = new this.THREE.Group();
|
|
2512
|
-
scene = new this.THREE.Scene();
|
|
2617
|
+
this.modelGroup = new this.THREE.Group();
|
|
2618
|
+
this.scene = new this.THREE.Scene();
|
|
2513
2619
|
if (isDebug) {
|
|
2514
|
-
stats = new Stats();
|
|
2515
|
-
document.body.appendChild(stats.dom);
|
|
2620
|
+
this.stats = new Stats();
|
|
2621
|
+
document.body.appendChild(this.stats.dom);
|
|
2516
2622
|
}
|
|
2517
2623
|
},
|
|
2518
2624
|
initCamera() {
|
|
2519
|
-
const rect = instructions.getBoundingClientRect();
|
|
2520
|
-
camera = new this.THREE.PerspectiveCamera(45, rect.width / rect.height, 0.1, 1000000);
|
|
2625
|
+
const rect = this.instructions.getBoundingClientRect();
|
|
2626
|
+
this.camera = new this.THREE.PerspectiveCamera(45, rect.width / rect.height, 0.1, 1000000);
|
|
2521
2627
|
// camera.position.set(0, 100, 150);
|
|
2628
|
+
// this.camera.position.set(0, 100, 150);
|
|
2522
2629
|
},
|
|
2523
2630
|
initControl() {
|
|
2524
2631
|
// 初始化控件
|
|
2525
|
-
cameraControls = new CameraControls(camera, renderer.domElement);
|
|
2526
|
-
cameraControls.dollyToCursor = true;
|
|
2527
|
-
cameraControls.smoothTime = 0.1;
|
|
2528
|
-
cameraControls.draggingSmoothTime = 0.05;
|
|
2529
|
-
cameraControls.truckSpeed = 2.0;
|
|
2530
|
-
cameraControls.infinityDolly = true;
|
|
2531
|
-
cameraControls.minDistance = 10;
|
|
2632
|
+
this.cameraControls = new CameraControls(this.camera, this.renderer.domElement);
|
|
2633
|
+
this.cameraControls.dollyToCursor = true;
|
|
2634
|
+
this.cameraControls.smoothTime = 0.1;
|
|
2635
|
+
this.cameraControls.draggingSmoothTime = 0.05;
|
|
2636
|
+
this.cameraControls.truckSpeed = 2.0;
|
|
2637
|
+
this.cameraControls.infinityDolly = true;
|
|
2638
|
+
this.cameraControls.minDistance = 10;
|
|
2532
2639
|
// 若已存在场景包围盒,初始化时设置最大dolly距离为其对角线长度
|
|
2533
2640
|
|
|
2534
|
-
cameraControls.dollySpeed = 0.15; // 鼠标滚轮每次移动速度倍率
|
|
2641
|
+
this.cameraControls.dollySpeed = 0.15; // 鼠标滚轮每次移动速度倍率
|
|
2535
2642
|
},
|
|
2536
2643
|
|
|
2537
2644
|
setCameraObserverEnabled(enabled) {
|
|
@@ -2545,7 +2652,7 @@ export default {
|
|
|
2545
2652
|
initCameraChangeObserver() {
|
|
2546
2653
|
// 初始化 control 状态标志
|
|
2547
2654
|
this.noObserver.isControlActive = false;
|
|
2548
|
-
|
|
2655
|
+
let _this = this;
|
|
2549
2656
|
// 1. 创建统一的响应触发器 (Debounced)
|
|
2550
2657
|
this._cameraChangeObserver = this.debounce(
|
|
2551
2658
|
async source => {
|
|
@@ -2615,17 +2722,17 @@ export default {
|
|
|
2615
2722
|
const isZoomIn = deltaY < 0; // 靠近
|
|
2616
2723
|
|
|
2617
2724
|
// if (isZoomOut) {
|
|
2618
|
-
// cameraControls.infinityDolly = false; // 向外遵守 maxDistance
|
|
2725
|
+
// this.cameraControls.infinityDolly = false; // 向外遵守 maxDistance
|
|
2619
2726
|
// } else if (isZoomIn) {
|
|
2620
|
-
// cameraControls.infinityDolly = true; // 向前允许推进(超越 minDistance)
|
|
2727
|
+
// this.cameraControls.infinityDolly = true; // 向前允许推进(超越 minDistance)
|
|
2621
2728
|
// }
|
|
2622
2729
|
|
|
2623
2730
|
// dolly最大距离限制
|
|
2624
2731
|
try {
|
|
2625
|
-
if (sceneBoundingBox && isFinite(maxDollyDistance)) {
|
|
2732
|
+
if (this.sceneBoundingBox && isFinite(maxDollyDistance)) {
|
|
2626
2733
|
if (isZoomOut) {
|
|
2627
|
-
camera.updateMatrixWorld(true);
|
|
2628
|
-
const currentDistance = camera.position.distanceTo(cameraControls._target);
|
|
2734
|
+
this.camera.updateMatrixWorld(true);
|
|
2735
|
+
const currentDistance = this.camera.position.distanceTo(this.cameraControls._target);
|
|
2629
2736
|
if (currentDistance >= maxDollyDistance) {
|
|
2630
2737
|
event.preventDefault && event.preventDefault();
|
|
2631
2738
|
event.stopImmediatePropagation && event.stopImmediatePropagation();
|
|
@@ -2640,53 +2747,53 @@ export default {
|
|
|
2640
2747
|
// 触发观察者
|
|
2641
2748
|
this._cameraChangeObserver('wheel');
|
|
2642
2749
|
};
|
|
2643
|
-
renderer.domElement.addEventListener('wheel', this._wheelHandler);
|
|
2750
|
+
this.renderer.domElement.addEventListener('wheel', this._wheelHandler);
|
|
2644
2751
|
|
|
2645
2752
|
// 4. 监听器 - Controls (用户拖拽/操作)
|
|
2646
2753
|
this._onControlStart = res => {
|
|
2647
2754
|
this.noObserver.isControlActive = true;
|
|
2648
2755
|
|
|
2649
2756
|
// 统一交互开始处理(相机)
|
|
2650
|
-
this.beginInteraction('camera');
|
|
2757
|
+
this.beginInteraction('this.camera');
|
|
2651
2758
|
this.$emit('controlStart', res);
|
|
2652
2759
|
|
|
2653
2760
|
// 记录鼠标按下时的位置
|
|
2654
2761
|
const event = res.originalEvent || window.event;
|
|
2655
2762
|
if (event) {
|
|
2656
|
-
mouseDownPosition.x = event.clientX || 0;
|
|
2657
|
-
mouseDownPosition.y = event.clientY || 0;
|
|
2658
|
-
isDragging = false;
|
|
2763
|
+
_this.mouseDownPosition.x = event.clientX || 0;
|
|
2764
|
+
_this.mouseDownPosition.y = event.clientY || 0;
|
|
2765
|
+
_this.isDragging = false;
|
|
2659
2766
|
}
|
|
2660
2767
|
};
|
|
2661
2768
|
|
|
2662
2769
|
this._onControlEnd = res => {
|
|
2663
|
-
|
|
2770
|
+
_this.noObserver.isControlActive = false;
|
|
2664
2771
|
|
|
2665
2772
|
this.$emit('controlEnd', res);
|
|
2666
2773
|
|
|
2667
2774
|
// 统一交互结束处理(相机)
|
|
2668
|
-
this.endInteraction('camera', res, { immediateResume: false });
|
|
2775
|
+
this.endInteraction('this.camera', res, { immediateResume: false });
|
|
2669
2776
|
|
|
2670
2777
|
// 记录鼠标抬起时的位置并计算是否发生了拖拽
|
|
2671
2778
|
const event = res.originalEvent || window.event;
|
|
2672
2779
|
if (event) {
|
|
2673
|
-
mouseUpPosition.x = event.clientX || 0;
|
|
2674
|
-
mouseUpPosition.y = event.clientY || 0;
|
|
2675
|
-
const deltaX = Math.abs(mouseUpPosition.x - mouseDownPosition.x);
|
|
2676
|
-
const deltaY = Math.abs(mouseUpPosition.y - mouseDownPosition.y);
|
|
2780
|
+
_this.mouseUpPosition.x = event.clientX || 0;
|
|
2781
|
+
_this.mouseUpPosition.y = event.clientY || 0;
|
|
2782
|
+
const deltaX = Math.abs(_this.mouseUpPosition.x - _this.mouseDownPosition.x);
|
|
2783
|
+
const deltaY = Math.abs(_this.mouseUpPosition.y - _this.mouseDownPosition.y);
|
|
2677
2784
|
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
2678
|
-
isDragging = distance > dragThreshold;
|
|
2785
|
+
_this.isDragging = distance > dragThreshold;
|
|
2679
2786
|
}
|
|
2680
2787
|
|
|
2681
2788
|
// 只有在实际发生拖拽时才执行相关操作
|
|
2682
|
-
if (isDragging) {
|
|
2789
|
+
if (_this.isDragging) {
|
|
2683
2790
|
// 居中逻辑
|
|
2684
|
-
// if (needsCenteringAfterInteraction && !hasExecutedCentering) {
|
|
2791
|
+
// if (this.needsCenteringAfterInteraction && !this.hasExecutedCentering) {
|
|
2685
2792
|
// setTimeout(() => {
|
|
2686
|
-
// if (modelGroups.length > 0) {
|
|
2687
|
-
// this.setModelCenter(modelGroups[modelGroups.length - 1]);
|
|
2688
|
-
// hasExecutedCentering = true;
|
|
2689
|
-
// needsCenteringAfterInteraction = false;
|
|
2793
|
+
// if (this.modelGroups.length > 0) {
|
|
2794
|
+
// this.setModelCenter(this.modelGroups[this.modelGroups.length - 1]);
|
|
2795
|
+
// this.hasExecutedCentering = true;
|
|
2796
|
+
// this.needsCenteringAfterInteraction = false;
|
|
2690
2797
|
// }
|
|
2691
2798
|
// }, 300);
|
|
2692
2799
|
// }
|
|
@@ -2696,32 +2803,32 @@ export default {
|
|
|
2696
2803
|
}
|
|
2697
2804
|
};
|
|
2698
2805
|
|
|
2699
|
-
cameraControls.addEventListener('controlstart', this._onControlStart);
|
|
2700
|
-
cameraControls.addEventListener('controlend', this._onControlEnd);
|
|
2806
|
+
this.cameraControls.addEventListener('controlstart', this._onControlStart);
|
|
2807
|
+
this.cameraControls.addEventListener('controlend', this._onControlEnd);
|
|
2701
2808
|
|
|
2702
2809
|
// 5. 监听器 - Programmatic (程序化动画/过渡结束)
|
|
2703
|
-
// 监听 rest 事件,捕获 cameraControls.setLookAt(..., true) 等动画结束(以及阻尼停止)
|
|
2810
|
+
// 监听 rest 事件,捕获 this.cameraControls.setLookAt(..., true) 等动画结束(以及阻尼停止)
|
|
2704
2811
|
// 注意:rest 事件在用户交互完全静止时也会触发,与 controlEnd 有部分重叠,但 Observer 有防抖,影响不大
|
|
2705
2812
|
this._onRest = () => {
|
|
2706
2813
|
this._cameraChangeObserver('rest');
|
|
2707
2814
|
};
|
|
2708
|
-
cameraControls.addEventListener('rest', this._onRest);
|
|
2815
|
+
this.cameraControls.addEventListener('rest', this._onRest);
|
|
2709
2816
|
},
|
|
2710
2817
|
// 初始化光源
|
|
2711
2818
|
initLight() {
|
|
2712
|
-
const pmremGenerator = new this.THREE.PMREMGenerator(renderer);
|
|
2713
|
-
scene.environment = pmremGenerator.fromScene(new RoomEnvironment(), 0.04).texture;
|
|
2819
|
+
const pmremGenerator = new this.THREE.PMREMGenerator(this.renderer);
|
|
2820
|
+
this.scene.environment = pmremGenerator.fromScene(new RoomEnvironment(), 0.04).texture;
|
|
2714
2821
|
},
|
|
2715
2822
|
// 初始化文字画布
|
|
2716
2823
|
initLabelRender() {
|
|
2717
|
-
labelRenderer = new CSS2DRenderer();
|
|
2718
|
-
const rect = instructions.getBoundingClientRect();
|
|
2719
|
-
labelRenderer.setSize(rect.width, rect.height);
|
|
2720
|
-
labelRenderer.domElement.style.position = 'absolute';
|
|
2824
|
+
this.labelRenderer = new CSS2DRenderer();
|
|
2825
|
+
const rect = this.instructions.getBoundingClientRect();
|
|
2826
|
+
this.labelRenderer.setSize(rect.width, rect.height);
|
|
2827
|
+
this.labelRenderer.domElement.style.position = 'absolute';
|
|
2721
2828
|
|
|
2722
|
-
labelRenderer.domElement.style.top = '0';
|
|
2723
|
-
labelRenderer.domElement.style.pointerEvents = 'none';
|
|
2724
|
-
instructions.appendChild(labelRenderer.domElement);
|
|
2829
|
+
this.labelRenderer.domElement.style.top = '0';
|
|
2830
|
+
this.labelRenderer.domElement.style.pointerEvents = 'none';
|
|
2831
|
+
this.instructions.appendChild(this.labelRenderer.domElement);
|
|
2725
2832
|
},
|
|
2726
2833
|
// 根据模型数据绘制模型实体 业务平台可调用此方法加载模型
|
|
2727
2834
|
/*
|
|
@@ -2730,6 +2837,7 @@ export default {
|
|
|
2730
2837
|
meshNameConfig: {}
|
|
2731
2838
|
*/
|
|
2732
2839
|
drawModel(data, color = '', meshNameConfig = {}, options = {}) {
|
|
2840
|
+
console.log(data);
|
|
2733
2841
|
// data = require('./mock.json');
|
|
2734
2842
|
// 使用新的分帧加载方法,提供进度回调
|
|
2735
2843
|
return this.drawModelWithBatchLoading(
|
|
@@ -2739,7 +2847,7 @@ export default {
|
|
|
2739
2847
|
options,
|
|
2740
2848
|
progress => {
|
|
2741
2849
|
// 触发原有的进度事件
|
|
2742
|
-
this.$emit('loadProgress', progress);
|
|
2850
|
+
this.$emit('loadProgress', this.progress);
|
|
2743
2851
|
},
|
|
2744
2852
|
complete => {
|
|
2745
2853
|
options?.onComplete?.(complete);
|
|
@@ -2751,13 +2859,13 @@ export default {
|
|
|
2751
2859
|
},
|
|
2752
2860
|
// 动态设置视角滚轮的距离
|
|
2753
2861
|
setCameraConfig() {
|
|
2754
|
-
// let box3 = new this.THREE.Box3().setFromObject(sceneBoundingBox);
|
|
2862
|
+
// let box3 = new this.THREE.Box3().setFromObject(this.sceneBoundingBox);
|
|
2755
2863
|
let size = new this.THREE.Vector3();
|
|
2756
|
-
sceneBoundingBox.getSize(size);
|
|
2864
|
+
this.sceneBoundingBox.getSize(size);
|
|
2757
2865
|
const maxBorder = Math.max(size.x, size.y, size.z);
|
|
2758
|
-
// cameraControls.camera.far = maxBorder * 10; // 设置相机的远裁剪面
|
|
2759
|
-
cameraControls.minDistance = maxBorder * 0.2; // 动态设置视角滚轮的距离
|
|
2760
|
-
camera.updateProjectionMatrix();
|
|
2866
|
+
// this.cameraControls.this.camera.far = maxBorder * 10; // 设置相机的远裁剪面
|
|
2867
|
+
this.cameraControls.minDistance = maxBorder * 0.2; // 动态设置视角滚轮的距离
|
|
2868
|
+
this.camera.updateProjectionMatrix();
|
|
2761
2869
|
},
|
|
2762
2870
|
// 获取mesh的中心点
|
|
2763
2871
|
getMeshCenterAndVolume(mesh) {
|
|
@@ -2773,14 +2881,14 @@ export default {
|
|
|
2773
2881
|
},
|
|
2774
2882
|
mouseDown(event) {
|
|
2775
2883
|
// 在鼠标按下时启用渲染中断以提升响应性
|
|
2776
|
-
forceSkipRendering = true;
|
|
2777
|
-
skipNextRenderFrame = true;
|
|
2884
|
+
this.forceSkipRendering = true;
|
|
2885
|
+
this.skipNextRenderFrame = true;
|
|
2778
2886
|
|
|
2779
2887
|
const intersects = this.getRaycasterObjects(event);
|
|
2780
|
-
firstTime = new Date().getTime();
|
|
2888
|
+
this.firstTime = new Date().getTime();
|
|
2781
2889
|
let params = {
|
|
2782
2890
|
event,
|
|
2783
|
-
firstTime,
|
|
2891
|
+
firstTime: this.firstTime,
|
|
2784
2892
|
};
|
|
2785
2893
|
intersects.length &&
|
|
2786
2894
|
(params.v3Position = {
|
|
@@ -2792,18 +2900,20 @@ export default {
|
|
|
2792
2900
|
},
|
|
2793
2901
|
getRaycasterObjects(event) {
|
|
2794
2902
|
// 保护空值,避免在未初始化或销毁后触发错误
|
|
2795
|
-
if (!renderer || !renderer.domElement || !camera || !scene) return [];
|
|
2903
|
+
if (!this.renderer || !this.renderer.domElement || !this.camera || !this.scene) return [];
|
|
2796
2904
|
// 获取元素在页面中的偏移位置
|
|
2797
|
-
const rect = renderer.domElement.getBoundingClientRect();
|
|
2905
|
+
const rect = this.renderer.domElement.getBoundingClientRect();
|
|
2798
2906
|
const x = event.clientX - rect.left;
|
|
2799
2907
|
const y = event.clientY - rect.top;
|
|
2800
2908
|
|
|
2801
|
-
// mouse.x = (event.clientX / instructions.offsetWidth) * 2 - 1;
|
|
2802
|
-
// mouse.y = -(event.clientY / instructions.offsetHeight) * 2 + 1;
|
|
2803
|
-
mouse.x = (x / rect.width) * 2 - 1;
|
|
2804
|
-
mouse.y = -(y / rect.height) * 2 + 1;
|
|
2805
|
-
raycaster.setFromCamera(mouse, camera);
|
|
2806
|
-
return scene &&
|
|
2909
|
+
// this.mouse.x = (event.clientX / this.instructions.offsetWidth) * 2 - 1;
|
|
2910
|
+
// this.mouse.y = -(event.clientY / this.instructions.offsetHeight) * 2 + 1;
|
|
2911
|
+
this.mouse.x = (x / rect.width) * 2 - 1;
|
|
2912
|
+
this.mouse.y = -(y / rect.height) * 2 + 1;
|
|
2913
|
+
this.raycaster.setFromCamera(this.mouse, this.camera);
|
|
2914
|
+
return this.scene && this.scene.children
|
|
2915
|
+
? this.raycaster.intersectObjects(this.scene.children, true)
|
|
2916
|
+
: [];
|
|
2807
2917
|
},
|
|
2808
2918
|
getInstanceId(instancedMesh, instanceIndex, options) {
|
|
2809
2919
|
if (!instancedMesh || instanceIndex === undefined || instanceIndex === null) {
|
|
@@ -2819,28 +2929,28 @@ export default {
|
|
|
2819
2929
|
mouseClick(event) {
|
|
2820
2930
|
// 鼠标抬起时重置渲染中断标记
|
|
2821
2931
|
setTimeout(() => {
|
|
2822
|
-
forceSkipRendering = false;
|
|
2932
|
+
this.forceSkipRendering = false;
|
|
2823
2933
|
// interactionFrameCount = 0;
|
|
2824
2934
|
// 恢复批次加载操作
|
|
2825
2935
|
this.resumeBatchLoading();
|
|
2826
2936
|
}, 50); // 短暂延迟确保交互完成
|
|
2827
2937
|
|
|
2828
2938
|
// 在测量模式下,不进行事件暴露
|
|
2829
|
-
if (!measureFlag) {
|
|
2830
|
-
lastTime = new Date().getTime();
|
|
2831
|
-
if (lastTime - firstTime < 300) {
|
|
2939
|
+
if (!this.measureFlag) {
|
|
2940
|
+
this.lastTime = new Date().getTime();
|
|
2941
|
+
if (this.lastTime - this.firstTime < 300) {
|
|
2832
2942
|
const intersects = this.getRaycasterObjects(event);
|
|
2833
2943
|
let params = {};
|
|
2834
2944
|
let cameraData = {
|
|
2835
2945
|
position: {
|
|
2836
|
-
x: cameraControls.camera.position.x,
|
|
2837
|
-
y: cameraControls.camera.position.y,
|
|
2838
|
-
z: cameraControls.camera.position.z,
|
|
2946
|
+
x: this.cameraControls.camera.position.x,
|
|
2947
|
+
y: this.cameraControls.camera.position.y,
|
|
2948
|
+
z: this.cameraControls.camera.position.z,
|
|
2839
2949
|
},
|
|
2840
2950
|
lookAt: {
|
|
2841
|
-
heading: cameraControls._target.x,
|
|
2842
|
-
pitch: cameraControls._target.y,
|
|
2843
|
-
roll: cameraControls._target.z,
|
|
2951
|
+
heading: this.cameraControls._target.x,
|
|
2952
|
+
pitch: this.cameraControls._target.y,
|
|
2953
|
+
roll: this.cameraControls._target.z,
|
|
2844
2954
|
},
|
|
2845
2955
|
};
|
|
2846
2956
|
if (intersects.length > 0) {
|
|
@@ -2874,11 +2984,11 @@ export default {
|
|
|
2874
2984
|
if (event.button === 0) {
|
|
2875
2985
|
this.$emit('leftClick', params);
|
|
2876
2986
|
} else if (event.button === 1) {
|
|
2877
|
-
if (lastTime - lastMiddleClickTime < 2000) {
|
|
2987
|
+
if (this.lastTime - this.lastMiddleClickTime < 2000) {
|
|
2878
2988
|
this.$emit('middleDblClick', params);
|
|
2879
|
-
lastMiddleClickTime = 0;
|
|
2989
|
+
this.lastMiddleClickTime = 0;
|
|
2880
2990
|
} else {
|
|
2881
|
-
lastMiddleClickTime = lastTime;
|
|
2991
|
+
this.lastMiddleClickTime = this.lastTime;
|
|
2882
2992
|
}
|
|
2883
2993
|
}
|
|
2884
2994
|
}
|
|
@@ -2886,24 +2996,24 @@ export default {
|
|
|
2886
2996
|
},
|
|
2887
2997
|
// 窗口发生改变时, 更新渲染器与相机的大小
|
|
2888
2998
|
resize(width, height) {
|
|
2889
|
-
if (camera) {
|
|
2890
|
-
camera.aspect = width / height;
|
|
2891
|
-
camera.updateProjectionMatrix();
|
|
2892
|
-
renderer.setSize(width, height, true);
|
|
2893
|
-
if (renderTarget) {
|
|
2894
|
-
renderTarget.setSize(width, height);
|
|
2999
|
+
if (this.camera) {
|
|
3000
|
+
this.camera.aspect = width / height;
|
|
3001
|
+
this.camera.updateProjectionMatrix();
|
|
3002
|
+
this.renderer.setSize(width, height, true);
|
|
3003
|
+
if (this.renderTarget) {
|
|
3004
|
+
this.renderTarget.setSize(width, height);
|
|
2895
3005
|
}
|
|
2896
|
-
if (outlineComposer) {
|
|
2897
|
-
outlineComposer.setSize(width, height);
|
|
3006
|
+
if (this.outlineComposer) {
|
|
3007
|
+
this.outlineComposer.setSize(width, height);
|
|
2898
3008
|
}
|
|
2899
|
-
if (outlinePass) {
|
|
2900
|
-
outlinePass.setSize(width, height);
|
|
3009
|
+
if (this.outlinePass) {
|
|
3010
|
+
this.outlinePass.setSize(width, height);
|
|
2901
3011
|
}
|
|
2902
|
-
labelRenderer.setSize(width, height);
|
|
3012
|
+
this.labelRenderer.setSize(width, height);
|
|
2903
3013
|
// this.timeRender()
|
|
2904
3014
|
// 这里也要更新测量
|
|
2905
|
-
if (threeMeasure) {
|
|
2906
|
-
threeMeasure.updateParams(width, height);
|
|
3015
|
+
if (this.threeMeasure) {
|
|
3016
|
+
this.threeMeasure.updateParams(width, height);
|
|
2907
3017
|
}
|
|
2908
3018
|
}
|
|
2909
3019
|
},
|
|
@@ -2943,7 +3053,7 @@ export default {
|
|
|
2943
3053
|
roll: center.z,
|
|
2944
3054
|
enableTransition: options.enableTransition,
|
|
2945
3055
|
});
|
|
2946
|
-
// cameraControls.setLookAt(
|
|
3056
|
+
// this.cameraControls.setLookAt(
|
|
2947
3057
|
// center.x,
|
|
2948
3058
|
// center.y + size.y,
|
|
2949
3059
|
// center.z + size.z / 2,
|
|
@@ -2952,37 +3062,37 @@ export default {
|
|
|
2952
3062
|
// center.z,
|
|
2953
3063
|
// true
|
|
2954
3064
|
// );
|
|
2955
|
-
// cameraControls.update(0);
|
|
2956
|
-
// camera.updateProjectionMatrix();
|
|
2957
|
-
// cameraControls.saveState();
|
|
3065
|
+
// this.cameraControls.update(0);
|
|
3066
|
+
// this.camera.updateProjectionMatrix();
|
|
3067
|
+
// this.cameraControls.saveState();
|
|
2958
3068
|
},
|
|
2959
3069
|
// 带防抖和用户交互检测的智能居中方法
|
|
2960
3070
|
smartModelCenter(mesh, debounceDelay = 100) {
|
|
2961
|
-
// if (hasExecutedCentering) {
|
|
3071
|
+
// if (this.hasExecutedCentering) {
|
|
2962
3072
|
// return;
|
|
2963
3073
|
// }
|
|
2964
3074
|
|
|
2965
3075
|
// 如果用户正在交互,标记需要在交互结束后居中
|
|
2966
|
-
if (userInteracting) {
|
|
2967
|
-
needsCenteringAfterInteraction = true;
|
|
3076
|
+
if (this.userInteracting) {
|
|
3077
|
+
this.needsCenteringAfterInteraction = true;
|
|
2968
3078
|
return;
|
|
2969
3079
|
}
|
|
2970
3080
|
|
|
2971
3081
|
// 清除之前的防抖定时器
|
|
2972
|
-
if (centeringDebounceTimer) {
|
|
2973
|
-
clearTimeout(centeringDebounceTimer);
|
|
3082
|
+
if (this.centeringDebounceTimer) {
|
|
3083
|
+
clearTimeout(this.centeringDebounceTimer);
|
|
2974
3084
|
}
|
|
2975
3085
|
|
|
2976
3086
|
// 设置新的防抖定时器
|
|
2977
|
-
centeringDebounceTimer = setTimeout(() => {
|
|
3087
|
+
this.centeringDebounceTimer = setTimeout(() => {
|
|
2978
3088
|
// 如果已经执行过居中操作,则不再执行
|
|
2979
3089
|
if (
|
|
2980
|
-
!userInteracting &&
|
|
2981
|
-
!hasExecutedCentering &&
|
|
3090
|
+
!this.userInteracting &&
|
|
3091
|
+
!this.hasExecutedCentering &&
|
|
2982
3092
|
this.noObserver.documentModelIds.size > 0
|
|
2983
3093
|
) {
|
|
2984
3094
|
this.setModelCenter(mesh, { enableTransition: false });
|
|
2985
|
-
hasExecutedCentering = true;
|
|
3095
|
+
this.hasExecutedCentering = true;
|
|
2986
3096
|
// 触发场景更新
|
|
2987
3097
|
this.notifyCameraChange();
|
|
2988
3098
|
}
|
|
@@ -3004,9 +3114,10 @@ export default {
|
|
|
3004
3114
|
* '#ff0000'
|
|
3005
3115
|
* '#f00'
|
|
3006
3116
|
* 'red'
|
|
3117
|
+
* hasOutline 是否需要加上高亮边。默认为true
|
|
3007
3118
|
* }
|
|
3008
3119
|
*/
|
|
3009
|
-
updateProperty(list) {
|
|
3120
|
+
updateProperty(list, hasOutline = true) {
|
|
3010
3121
|
let isUpdate = false;
|
|
3011
3122
|
for (let index = 0; index < list.length; index++) {
|
|
3012
3123
|
let ele = list[index];
|
|
@@ -3025,12 +3136,14 @@ export default {
|
|
|
3025
3136
|
this.removeOutlineObject(children, instanceIndex);
|
|
3026
3137
|
return;
|
|
3027
3138
|
}
|
|
3028
|
-
if (
|
|
3029
|
-
if (
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
this.
|
|
3139
|
+
if (hasOutline) {
|
|
3140
|
+
if (this.outlinePass) {
|
|
3141
|
+
if (children.isInstancedMesh) {
|
|
3142
|
+
const proxy = this.ensureOutlineInstanceProxy(children, instanceIndex);
|
|
3143
|
+
this.pushOutlineTarget(proxy);
|
|
3144
|
+
} else if (!this.isSourceHiddenInstance(children, instanceId)) {
|
|
3145
|
+
this.pushOutlineTarget(children);
|
|
3146
|
+
}
|
|
3034
3147
|
}
|
|
3035
3148
|
}
|
|
3036
3149
|
}
|
|
@@ -3111,8 +3224,8 @@ export default {
|
|
|
3111
3224
|
});
|
|
3112
3225
|
}
|
|
3113
3226
|
|
|
3114
|
-
if (scene) {
|
|
3115
|
-
scene.traverse(child => {
|
|
3227
|
+
if (this.scene) {
|
|
3228
|
+
this.scene.traverse(child => {
|
|
3116
3229
|
if (!child || !child.isInstancedMesh) return;
|
|
3117
3230
|
const userData = child.userData || {};
|
|
3118
3231
|
if (!(userData.instancesMap instanceof Map) || userData.instancesMap.size === 0) return;
|
|
@@ -3159,7 +3272,7 @@ export default {
|
|
|
3159
3272
|
this.removeOutlineObject(children, instanceIndex);
|
|
3160
3273
|
return;
|
|
3161
3274
|
}
|
|
3162
|
-
if (outlinePass) {
|
|
3275
|
+
if (this.outlinePass) {
|
|
3163
3276
|
if (children.isInstancedMesh) {
|
|
3164
3277
|
const proxy = this.ensureOutlineInstanceProxy(children, instanceIndex);
|
|
3165
3278
|
this.pushOutlineTarget(proxy);
|
|
@@ -3182,8 +3295,8 @@ export default {
|
|
|
3182
3295
|
// 恢复模型原来的状态
|
|
3183
3296
|
updateWholeProperty() {
|
|
3184
3297
|
throw new Error('该方法已暂停使用,请使用restore方法。');
|
|
3185
|
-
// if (scene) {
|
|
3186
|
-
// scene.traverse(obj => {
|
|
3298
|
+
// if (this.scene) {
|
|
3299
|
+
// this.scene.traverse(obj => {
|
|
3187
3300
|
// if (obj instanceof this.THREE.Mesh) {
|
|
3188
3301
|
// // 恢复颜色
|
|
3189
3302
|
// obj.setColorAt(obj.userData.instanceIndex, obj.material.userData.nColor)
|
|
@@ -3253,12 +3366,12 @@ export default {
|
|
|
3253
3366
|
const { instanceIndex } = children.userData.instancesMap.get(instanceId);
|
|
3254
3367
|
children.setColorAt(instanceIndex, children.material.userData.nColor);
|
|
3255
3368
|
children.instanceColor.needsUpdate = true;
|
|
3256
|
-
if (outlinePass) {
|
|
3369
|
+
if (this.outlinePass) {
|
|
3257
3370
|
if (children.isInstancedMesh) {
|
|
3258
3371
|
this.removeOutlineInstanceProxy(children, instanceIndex);
|
|
3259
3372
|
} else {
|
|
3260
|
-
const idx = outlinePass.selectedObjects.indexOf(children);
|
|
3261
|
-
if (idx !== -1) outlinePass.selectedObjects.splice(idx, 1);
|
|
3373
|
+
const idx = this.outlinePass.selectedObjects.indexOf(children);
|
|
3374
|
+
if (idx !== -1) this.outlinePass.selectedObjects.splice(idx, 1);
|
|
3262
3375
|
}
|
|
3263
3376
|
}
|
|
3264
3377
|
}
|
|
@@ -3301,7 +3414,7 @@ export default {
|
|
|
3301
3414
|
// 定位到模型
|
|
3302
3415
|
// name 模型名称 可以是数组
|
|
3303
3416
|
locateModel(name) {
|
|
3304
|
-
if (!scene) return;
|
|
3417
|
+
if (!this.scene) return;
|
|
3305
3418
|
if (Array.isArray(name)) {
|
|
3306
3419
|
const box3 = new this.THREE.Box3();
|
|
3307
3420
|
name.forEach(n => {
|
|
@@ -3319,7 +3432,7 @@ export default {
|
|
|
3319
3432
|
}
|
|
3320
3433
|
let obj = this.getObjectByName(name)[0];
|
|
3321
3434
|
if (obj) {
|
|
3322
|
-
// cameraControls.fitToSphere(obj.parent, true); // TODO 待处理,先用 setModelCenter 进行定位
|
|
3435
|
+
// this.cameraControls.fitToSphere(obj.parent, true); // TODO 待处理,先用 setModelCenter 进行定位
|
|
3323
3436
|
if (obj.isGroup) {
|
|
3324
3437
|
this.setModelCenter(obj);
|
|
3325
3438
|
} else if (obj.isMesh) {
|
|
@@ -3343,8 +3456,8 @@ export default {
|
|
|
3343
3456
|
}
|
|
3344
3457
|
*/
|
|
3345
3458
|
updatePropertyByCustom(params) {
|
|
3346
|
-
if (!scene) return;
|
|
3347
|
-
scene.traverse(child => {
|
|
3459
|
+
if (!this.scene) return;
|
|
3460
|
+
this.scene.traverse(child => {
|
|
3348
3461
|
if (child.isMesh && child.userData[params.customName] === params.customValue) {
|
|
3349
3462
|
for (const key in params.attr) {
|
|
3350
3463
|
switch (key) {
|
|
@@ -3376,7 +3489,7 @@ export default {
|
|
|
3376
3489
|
*/
|
|
3377
3490
|
cameraLocation(params) {
|
|
3378
3491
|
const { enableTransition = true } = params;
|
|
3379
|
-
cameraControls.setLookAt(
|
|
3492
|
+
this.cameraControls.setLookAt(
|
|
3380
3493
|
params.x,
|
|
3381
3494
|
params.y,
|
|
3382
3495
|
params.z,
|
|
@@ -3385,7 +3498,7 @@ export default {
|
|
|
3385
3498
|
params.roll,
|
|
3386
3499
|
enableTransition
|
|
3387
3500
|
);
|
|
3388
|
-
cameraControls.update(0);
|
|
3501
|
+
this.cameraControls.update(0);
|
|
3389
3502
|
},
|
|
3390
3503
|
// 使用中心点和实体的长宽高进行定位
|
|
3391
3504
|
/*
|
|
@@ -3400,7 +3513,7 @@ export default {
|
|
|
3400
3513
|
|
|
3401
3514
|
let maxDim = Math.max(size.x, size.y, size.z);
|
|
3402
3515
|
let minDim = Math.min(size.x, size.y, size.z);
|
|
3403
|
-
let fov = camera.fov * (Math.PI / 180);
|
|
3516
|
+
let fov = this.camera.fov * (Math.PI / 180);
|
|
3404
3517
|
// let baseDistance = viewAll
|
|
3405
3518
|
// ? Math.abs((minDim * 1.0) / Math.sin(fov / 2))
|
|
3406
3519
|
// : Math.abs((maxDim * 1.0) / Math.sin(fov / 2));
|
|
@@ -3412,7 +3525,7 @@ export default {
|
|
|
3412
3525
|
let cameraCenter = viewAll
|
|
3413
3526
|
? new this.THREE.Vector3(p.x, p.y, p.z)
|
|
3414
3527
|
: new this.THREE.Vector3(p.x, p.y, p.z).addScalar(Math.max(size.x, size.y, size.z));
|
|
3415
|
-
cameraControls.setLookAt(
|
|
3528
|
+
this.cameraControls.setLookAt(
|
|
3416
3529
|
cameraCenter.x,
|
|
3417
3530
|
cameraCenter.y,
|
|
3418
3531
|
cameraCenter.z,
|
|
@@ -3432,11 +3545,11 @@ export default {
|
|
|
3432
3545
|
}
|
|
3433
3546
|
*/
|
|
3434
3547
|
billboard(data) {
|
|
3435
|
-
if (!scene) return null;
|
|
3548
|
+
if (!this.scene) return null;
|
|
3436
3549
|
const divLabel = new CSS2DObject(data.billboard);
|
|
3437
3550
|
divLabel.name = data.labelClass; // 这个是用来清除广告牌用的
|
|
3438
3551
|
divLabel.position.set(data.x, data.y, data.z);
|
|
3439
|
-
scene.add(divLabel);
|
|
3552
|
+
this.scene.add(divLabel);
|
|
3440
3553
|
return divLabel;
|
|
3441
3554
|
},
|
|
3442
3555
|
// 通过名字获取实体对象, 返回数组
|
|
@@ -3445,10 +3558,10 @@ export default {
|
|
|
3445
3558
|
passType: 要过滤的类型,默认是group,不返回group类型的实体
|
|
3446
3559
|
*/
|
|
3447
3560
|
getObjectByName(name, passType = 'group') {
|
|
3448
|
-
if (!scene) return [];
|
|
3561
|
+
if (!this.scene) return [];
|
|
3449
3562
|
let object = [];
|
|
3450
3563
|
const instancedMeshProps = instanceToInstancedMeshMap.get(name);
|
|
3451
|
-
scene.traverse(item => {
|
|
3564
|
+
this.scene.traverse(item => {
|
|
3452
3565
|
const tempName = instancedMeshProps ? instancedMeshProps.drawObjectId : name;
|
|
3453
3566
|
if (item.name == tempName && item.type.toLowerCase() != passType.toLowerCase()) {
|
|
3454
3567
|
object.push(item);
|
|
@@ -3458,8 +3571,8 @@ export default {
|
|
|
3458
3571
|
},
|
|
3459
3572
|
// 通过id获取实体对象, 返回查找到的对象
|
|
3460
3573
|
getObjectById(id) {
|
|
3461
|
-
if (!scene) return null;
|
|
3462
|
-
return scene.getObjectById(id);
|
|
3574
|
+
if (!this.scene) return null;
|
|
3575
|
+
return this.scene.getObjectById(id);
|
|
3463
3576
|
},
|
|
3464
3577
|
getColorConfig() {
|
|
3465
3578
|
const modelState = this.noObserver
|
|
@@ -3511,7 +3624,7 @@ export default {
|
|
|
3511
3624
|
},
|
|
3512
3625
|
// 通过id删除对象
|
|
3513
3626
|
removeObjectById(id) {
|
|
3514
|
-
if (!scene) return;
|
|
3627
|
+
if (!this.scene) return;
|
|
3515
3628
|
let array = this.getObjectByName(id);
|
|
3516
3629
|
array.forEach(item => {
|
|
3517
3630
|
if (item.name === id) {
|
|
@@ -3520,13 +3633,13 @@ export default {
|
|
|
3520
3633
|
if (item.isMesh) {
|
|
3521
3634
|
item.clear();
|
|
3522
3635
|
}
|
|
3523
|
-
scene.remove(item);
|
|
3636
|
+
this.scene.remove(item);
|
|
3524
3637
|
}
|
|
3525
3638
|
});
|
|
3526
3639
|
},
|
|
3527
3640
|
// 通过名称删除对象
|
|
3528
3641
|
removeObjectByName(name) {
|
|
3529
|
-
if (!scene) return;
|
|
3642
|
+
if (!this.scene) return;
|
|
3530
3643
|
let array = this.getObjectByName(name);
|
|
3531
3644
|
array.forEach(item => {
|
|
3532
3645
|
item.material && item.material.dispose();
|
|
@@ -3534,13 +3647,13 @@ export default {
|
|
|
3534
3647
|
if (item.isMesh) {
|
|
3535
3648
|
item.clear();
|
|
3536
3649
|
}
|
|
3537
|
-
if (scene) scene.remove(item);
|
|
3650
|
+
if (this.scene) this.scene.remove(item);
|
|
3538
3651
|
});
|
|
3539
3652
|
},
|
|
3540
3653
|
// 删除场景中所有的实体
|
|
3541
3654
|
removeAll() {
|
|
3542
3655
|
return new Promise(resolve => {
|
|
3543
|
-
if (scene) {
|
|
3656
|
+
if (this.scene) {
|
|
3544
3657
|
this.removeTraverse();
|
|
3545
3658
|
this.removeModelByDocumentId();
|
|
3546
3659
|
resolve();
|
|
@@ -3550,10 +3663,10 @@ export default {
|
|
|
3550
3663
|
});
|
|
3551
3664
|
},
|
|
3552
3665
|
removeTraverse() {
|
|
3553
|
-
if (!modelGroup) return;
|
|
3554
|
-
let length = modelGroup.children.length;
|
|
3666
|
+
if (!this.modelGroup) return;
|
|
3667
|
+
let length = this.modelGroup.children.length;
|
|
3555
3668
|
if (length > 0) {
|
|
3556
|
-
let list = modelGroup.children[0];
|
|
3669
|
+
let list = this.modelGroup.children[0];
|
|
3557
3670
|
if (!list) return;
|
|
3558
3671
|
list.traverse(item => {
|
|
3559
3672
|
if (item.isMesh) {
|
|
@@ -3562,32 +3675,32 @@ export default {
|
|
|
3562
3675
|
item.clear();
|
|
3563
3676
|
item.material = null;
|
|
3564
3677
|
item.geometry = null;
|
|
3565
|
-
modelGroup && modelGroup.remove(item);
|
|
3678
|
+
this.modelGroup && this.modelGroup.remove(item);
|
|
3566
3679
|
item = null;
|
|
3567
3680
|
}
|
|
3568
3681
|
});
|
|
3569
|
-
modelGroup && modelGroup.remove(list);
|
|
3682
|
+
this.modelGroup && this.modelGroup.remove(list);
|
|
3570
3683
|
this.removeTraverse();
|
|
3571
3684
|
} else {
|
|
3572
3685
|
// 在这里清除一些标记之类的
|
|
3573
|
-
modelGroup.clear();
|
|
3574
|
-
scene.remove(modelGroup);
|
|
3575
|
-
renderer.clear();
|
|
3576
|
-
modelGroup = null;
|
|
3577
|
-
modelGroup = new this.THREE.Group();
|
|
3686
|
+
this.modelGroup.clear();
|
|
3687
|
+
this.scene.remove(this.modelGroup);
|
|
3688
|
+
this.renderer.clear();
|
|
3689
|
+
this.modelGroup = null;
|
|
3690
|
+
this.modelGroup = new this.THREE.Group();
|
|
3578
3691
|
}
|
|
3579
3692
|
},
|
|
3580
3693
|
// 销毁场景 释放内存
|
|
3581
3694
|
destroyScene() {
|
|
3582
|
-
cancelAnimationFrame(animateId);
|
|
3695
|
+
cancelAnimationFrame(this.animateId);
|
|
3583
3696
|
|
|
3584
3697
|
if (this.noObserver && this.noObserver.outlineInstanceProxyMap) {
|
|
3585
3698
|
this.noObserver.outlineInstanceProxyMap.forEach(proxy => {
|
|
3586
|
-
if (outlinePass) {
|
|
3587
|
-
const idx = outlinePass.selectedObjects.indexOf(proxy);
|
|
3588
|
-
if (idx !== -1) outlinePass.selectedObjects.splice(idx, 1);
|
|
3699
|
+
if (this.outlinePass) {
|
|
3700
|
+
const idx = this.outlinePass.selectedObjects.indexOf(proxy);
|
|
3701
|
+
if (idx !== -1) this.outlinePass.selectedObjects.splice(idx, 1);
|
|
3589
3702
|
}
|
|
3590
|
-
if (scene) scene.remove(proxy);
|
|
3703
|
+
if (this.scene) this.scene.remove(proxy);
|
|
3591
3704
|
if (proxy && proxy.material && proxy.material.dispose) proxy.material.dispose();
|
|
3592
3705
|
});
|
|
3593
3706
|
this.noObserver.outlineInstanceProxyMap.clear();
|
|
@@ -3597,9 +3710,9 @@ export default {
|
|
|
3597
3710
|
? this.noObserver.batchLoadingState
|
|
3598
3711
|
: this.batchLoadingState;
|
|
3599
3712
|
// 清理防抖定时器和重置状态
|
|
3600
|
-
if (centeringDebounceTimer) {
|
|
3601
|
-
clearTimeout(centeringDebounceTimer);
|
|
3602
|
-
centeringDebounceTimer = null;
|
|
3713
|
+
if (this.centeringDebounceTimer) {
|
|
3714
|
+
clearTimeout(this.centeringDebounceTimer);
|
|
3715
|
+
this.centeringDebounceTimer = null;
|
|
3603
3716
|
}
|
|
3604
3717
|
|
|
3605
3718
|
// 清理渲染暂停/恢复相关的定时器
|
|
@@ -3617,9 +3730,9 @@ export default {
|
|
|
3617
3730
|
// 停止批量加载
|
|
3618
3731
|
this.stopBatchLoading();
|
|
3619
3732
|
|
|
3620
|
-
hasExecutedCentering = false;
|
|
3621
|
-
needsCenteringAfterInteraction = false;
|
|
3622
|
-
userInteracting = false;
|
|
3733
|
+
this.hasExecutedCentering = false;
|
|
3734
|
+
this.needsCenteringAfterInteraction = false;
|
|
3735
|
+
this.userInteracting = false;
|
|
3623
3736
|
|
|
3624
3737
|
// 关闭视椎体裁切并清理防抖定时器
|
|
3625
3738
|
this.modelStateManager.frustumCheckEnabled = false;
|
|
@@ -3629,36 +3742,36 @@ export default {
|
|
|
3629
3742
|
}
|
|
3630
3743
|
this.clearBypassCullingModelIds();
|
|
3631
3744
|
|
|
3632
|
-
if (scene) {
|
|
3745
|
+
if (this.scene) {
|
|
3633
3746
|
this.removeTraverse();
|
|
3634
|
-
scene.clear();
|
|
3635
|
-
scene = null;
|
|
3747
|
+
this.scene.clear();
|
|
3748
|
+
this.scene = null;
|
|
3636
3749
|
}
|
|
3637
3750
|
|
|
3638
3751
|
// 移除滚轮事件监听器
|
|
3639
|
-
if (renderer && renderer.domElement && this._wheelHandler) {
|
|
3640
|
-
renderer.domElement.removeEventListener('wheel', this._wheelHandler);
|
|
3752
|
+
if (this.renderer && this.renderer.domElement && this._wheelHandler) {
|
|
3753
|
+
this.renderer.domElement.removeEventListener('wheel', this._wheelHandler);
|
|
3641
3754
|
this._wheelHandler = null;
|
|
3642
3755
|
}
|
|
3643
3756
|
|
|
3644
3757
|
// 移除鼠标点击/按下事件监听器
|
|
3645
|
-
if (renderer && renderer.domElement) {
|
|
3646
|
-
renderer.domElement.removeEventListener('mouseup', this.mouseClick, false);
|
|
3647
|
-
renderer.domElement.removeEventListener('mousedown', this.mouseDown, false);
|
|
3648
|
-
renderer.domElement.removeEventListener('pointerup', this.mouseClick, false);
|
|
3649
|
-
renderer.domElement.removeEventListener('pointerdown', this.mouseDown, false);
|
|
3758
|
+
if (this.renderer && this.renderer.domElement) {
|
|
3759
|
+
this.renderer.domElement.removeEventListener('mouseup', this.mouseClick, false);
|
|
3760
|
+
this.renderer.domElement.removeEventListener('mousedown', this.mouseDown, false);
|
|
3761
|
+
this.renderer.domElement.removeEventListener('pointerup', this.mouseClick, false);
|
|
3762
|
+
this.renderer.domElement.removeEventListener('pointerdown', this.mouseDown, false);
|
|
3650
3763
|
}
|
|
3651
3764
|
|
|
3652
3765
|
// 取消 pointer lock 并移除相关键盘事件
|
|
3653
|
-
if (pointControls) {
|
|
3766
|
+
if (this.pointControls) {
|
|
3654
3767
|
if (this._onFirstPersonChange) {
|
|
3655
3768
|
try {
|
|
3656
|
-
pointControls.removeEventListener('change', this._onFirstPersonChange);
|
|
3769
|
+
this.pointControls.removeEventListener('change', this._onFirstPersonChange);
|
|
3657
3770
|
} catch (e) {}
|
|
3658
3771
|
this._onFirstPersonChange = null;
|
|
3659
3772
|
}
|
|
3660
3773
|
try {
|
|
3661
|
-
pointControls.unlock && pointControls.unlock();
|
|
3774
|
+
this.pointControls.unlock && this.pointControls.unlock();
|
|
3662
3775
|
} catch (e) {}
|
|
3663
3776
|
}
|
|
3664
3777
|
if (this.noObserver) {
|
|
@@ -3669,38 +3782,38 @@ export default {
|
|
|
3669
3782
|
document.removeEventListener('keydown', this.handleMeasureKeyDown, false);
|
|
3670
3783
|
|
|
3671
3784
|
// 关闭测量工具
|
|
3672
|
-
if (threeMeasure) {
|
|
3785
|
+
if (this.threeMeasure) {
|
|
3673
3786
|
try {
|
|
3674
|
-
threeMeasure.close && threeMeasure.close();
|
|
3787
|
+
this.threeMeasure.close && this.threeMeasure.close();
|
|
3675
3788
|
} catch (e) {}
|
|
3676
|
-
threeMeasure = null;
|
|
3789
|
+
this.threeMeasure = null;
|
|
3677
3790
|
}
|
|
3678
3791
|
|
|
3679
|
-
// 移除 cameraControls 事件监听
|
|
3680
|
-
if (cameraControls) {
|
|
3792
|
+
// 移除 this.cameraControls 事件监听
|
|
3793
|
+
if (this.cameraControls) {
|
|
3681
3794
|
if (this._onControlStart)
|
|
3682
|
-
cameraControls.removeEventListener('controlstart', this._onControlStart);
|
|
3795
|
+
this.cameraControls.removeEventListener('controlstart', this._onControlStart);
|
|
3683
3796
|
if (this._onControlEnd)
|
|
3684
|
-
cameraControls.removeEventListener('controlend', this._onControlEnd);
|
|
3797
|
+
this.cameraControls.removeEventListener('controlend', this._onControlEnd);
|
|
3685
3798
|
this._onControlStart = null;
|
|
3686
3799
|
this._onControlEnd = null;
|
|
3687
3800
|
}
|
|
3688
3801
|
|
|
3689
3802
|
// 清理 Label 渲染器 DOM
|
|
3690
|
-
if (labelRenderer && labelRenderer.domElement && instructions) {
|
|
3803
|
+
if (this.labelRenderer && this.labelRenderer.domElement && this.instructions) {
|
|
3691
3804
|
try {
|
|
3692
|
-
instructions.removeChild(labelRenderer.domElement);
|
|
3805
|
+
this.instructions.removeChild(this.labelRenderer.domElement);
|
|
3693
3806
|
} catch (e) {}
|
|
3694
3807
|
}
|
|
3695
|
-
labelRenderer = null;
|
|
3808
|
+
this.labelRenderer = null;
|
|
3696
3809
|
|
|
3697
|
-
renderer.forceContextLoss();
|
|
3698
|
-
renderer.dispose();
|
|
3699
|
-
camera = null;
|
|
3700
|
-
cameraControls = null;
|
|
3701
|
-
pointControls = null;
|
|
3702
|
-
renderer.domElement = null;
|
|
3703
|
-
renderer = null;
|
|
3810
|
+
this.renderer.forceContextLoss();
|
|
3811
|
+
this.renderer.dispose();
|
|
3812
|
+
this.camera = null;
|
|
3813
|
+
this.cameraControls = null;
|
|
3814
|
+
this.pointControls = null;
|
|
3815
|
+
this.renderer.domElement = null;
|
|
3816
|
+
this.renderer = null;
|
|
3704
3817
|
},
|
|
3705
3818
|
// 绘制曲线
|
|
3706
3819
|
/*
|
|
@@ -3718,8 +3831,10 @@ export default {
|
|
|
3718
3831
|
route.push(new this.THREE.Vector3(element.x, element.y, element.z));
|
|
3719
3832
|
});
|
|
3720
3833
|
if (route.length > 1) {
|
|
3721
|
-
curve = new this.THREE.CatmullRomCurve3(route);
|
|
3722
|
-
const geometryLine = new this.THREE.BufferGeometry().setFromPoints(
|
|
3834
|
+
this.curve = new this.THREE.CatmullRomCurve3(route);
|
|
3835
|
+
const geometryLine = new this.THREE.BufferGeometry().setFromPoints(
|
|
3836
|
+
this.curve.getPoints(5000)
|
|
3837
|
+
);
|
|
3723
3838
|
const materialLine = new this.THREE.LineBasicMaterial({
|
|
3724
3839
|
color: params.color,
|
|
3725
3840
|
depthTest: false,
|
|
@@ -3727,7 +3842,7 @@ export default {
|
|
|
3727
3842
|
});
|
|
3728
3843
|
let line = new this.THREE.Line(geometryLine, materialLine);
|
|
3729
3844
|
line.name = params.name;
|
|
3730
|
-
if (scene) scene.add(line);
|
|
3845
|
+
if (this.scene) this.scene.add(line);
|
|
3731
3846
|
}
|
|
3732
3847
|
},
|
|
3733
3848
|
// 绘制贴图曲线
|
|
@@ -3747,24 +3862,24 @@ export default {
|
|
|
3747
3862
|
// 画曲线
|
|
3748
3863
|
if (route.length > 1) {
|
|
3749
3864
|
// 曲线 作为路径
|
|
3750
|
-
curve = new this.THREE.CatmullRomCurve3(route, false, 'catmullrom', 0);
|
|
3751
|
-
const geometry = new this.THREE.TubeGeometry(curve, 5000, 0.5, 4);
|
|
3865
|
+
this.curve = new this.THREE.CatmullRomCurve3(route, false, 'catmullrom', 0);
|
|
3866
|
+
const geometry = new this.THREE.TubeGeometry(this.curve, 5000, 0.5, 4);
|
|
3752
3867
|
//加载纹理
|
|
3753
|
-
lineTexture = new this.THREE.TextureLoader().load('/static/arrow/arrow-right.png');
|
|
3754
|
-
lineTexture.wrapS = this.THREE.RepeatWrapping;
|
|
3755
|
-
lineTexture.wrapT = this.THREE.RepeatWrapping;
|
|
3756
|
-
lineTexture.repeat.set(20, 1); //水平重复20次
|
|
3757
|
-
lineTexture.needsUpdate = true;
|
|
3758
|
-
lineTexture.offset.y = 0.5;
|
|
3868
|
+
this.lineTexture = new this.THREE.TextureLoader().load('/static/arrow/arrow-right.png');
|
|
3869
|
+
this.lineTexture.wrapS = this.THREE.RepeatWrapping;
|
|
3870
|
+
this.lineTexture.wrapT = this.THREE.RepeatWrapping;
|
|
3871
|
+
this.lineTexture.repeat.set(20, 1); //水平重复20次
|
|
3872
|
+
this.lineTexture.needsUpdate = true;
|
|
3873
|
+
this.lineTexture.offset.y = 0.5;
|
|
3759
3874
|
const material = new this.THREE.MeshBasicMaterial({
|
|
3760
|
-
map: lineTexture,
|
|
3875
|
+
map: this.lineTexture,
|
|
3761
3876
|
side: this.THREE.BackSide, //显示背面
|
|
3762
3877
|
transparent: true,
|
|
3763
3878
|
});
|
|
3764
3879
|
let line = new this.THREE.Line(geometry, material);
|
|
3765
3880
|
line.name = params.name;
|
|
3766
|
-
if (scene) scene.add(line);
|
|
3767
|
-
clock = new this.THREE.Clock();
|
|
3881
|
+
if (this.scene) this.scene.add(line);
|
|
3882
|
+
this.clock = new this.THREE.Clock();
|
|
3768
3883
|
}
|
|
3769
3884
|
},
|
|
3770
3885
|
//
|
|
@@ -3777,8 +3892,8 @@ export default {
|
|
|
3777
3892
|
name: '', 路径的名称,用来清除用的
|
|
3778
3893
|
*/
|
|
3779
3894
|
startRoam(params) {
|
|
3780
|
-
progress = 0;
|
|
3781
|
-
roamConfig = {
|
|
3895
|
+
this.progress = 0;
|
|
3896
|
+
this.roamConfig = {
|
|
3782
3897
|
loop: params.loop,
|
|
3783
3898
|
speed: params.speed,
|
|
3784
3899
|
};
|
|
@@ -3786,7 +3901,7 @@ export default {
|
|
|
3786
3901
|
name: params.name,
|
|
3787
3902
|
path: params.path,
|
|
3788
3903
|
});
|
|
3789
|
-
roaming = true;
|
|
3904
|
+
this.roaming = true;
|
|
3790
3905
|
},
|
|
3791
3906
|
// 更新漫游的配置
|
|
3792
3907
|
/*
|
|
@@ -3794,52 +3909,52 @@ export default {
|
|
|
3794
3909
|
*/
|
|
3795
3910
|
updateRoamConfig(params) {
|
|
3796
3911
|
for (let key in params) {
|
|
3797
|
-
roamConfig[key] = params[key];
|
|
3912
|
+
this.roamConfig[key] = params[key];
|
|
3798
3913
|
}
|
|
3799
3914
|
},
|
|
3800
3915
|
// 结束/退出漫游
|
|
3801
3916
|
endRoam() {
|
|
3802
|
-
roaming = false;
|
|
3803
|
-
progress = 0;
|
|
3804
|
-
this.removeObjectByName(roamConfig.name);
|
|
3805
|
-
roamConfig = {
|
|
3917
|
+
this.roaming = false;
|
|
3918
|
+
this.progress = 0;
|
|
3919
|
+
this.removeObjectByName(this.roamConfig.name);
|
|
3920
|
+
this.roamConfig = {
|
|
3806
3921
|
loop: false,
|
|
3807
3922
|
speed: 0,
|
|
3808
3923
|
name: '',
|
|
3809
3924
|
};
|
|
3810
|
-
roaming = false;
|
|
3811
|
-
lineTexture = null;
|
|
3925
|
+
this.roaming = false;
|
|
3926
|
+
this.lineTexture = null;
|
|
3812
3927
|
},
|
|
3813
3928
|
// 相机跟随轨道
|
|
3814
3929
|
cameraTrack() {
|
|
3815
|
-
if (roaming) {
|
|
3930
|
+
if (this.roaming) {
|
|
3816
3931
|
// renderEnabled = true
|
|
3817
|
-
lineTexture.offset.x -= 0.05;
|
|
3932
|
+
this.lineTexture.offset.x -= 0.05;
|
|
3818
3933
|
// 相机和控制器的偏移
|
|
3819
|
-
let offset = 10 / curve.getLength();
|
|
3820
|
-
// progress 取值范围为0~1。getPoint(0)表示曲线起点,getPoint(1)表示曲线终点
|
|
3821
|
-
if (progress <= 1 - offset) {
|
|
3934
|
+
let offset = 10 / this.curve.getLength();
|
|
3935
|
+
// this.progress 取值范围为0~1。getPoint(0)表示曲线起点,getPoint(1)表示曲线终点
|
|
3936
|
+
if (this.progress <= 1 - offset) {
|
|
3822
3937
|
// this.timeRender()
|
|
3823
|
-
const point = curve.getPointAt(progress);
|
|
3824
|
-
const pointBox = curve.getPointAt(progress + offset);
|
|
3825
|
-
camera.position.set(point.x, point.y + 5, point.z);
|
|
3826
|
-
camera.lookAt(pointBox.x, pointBox.y + 5, pointBox.z);
|
|
3827
|
-
cameraControls.setPosition(point.x, point.y + 5, point.z, false);
|
|
3828
|
-
cameraControls.setTarget(pointBox.x, pointBox.y + 5, pointBox.z, false);
|
|
3829
|
-
progress += roamConfig.speed / 300;
|
|
3938
|
+
const point = this.curve.getPointAt(this.progress);
|
|
3939
|
+
const pointBox = this.curve.getPointAt(this.progress + offset);
|
|
3940
|
+
this.camera.position.set(point.x, point.y + 5, point.z);
|
|
3941
|
+
this.camera.lookAt(pointBox.x, pointBox.y + 5, pointBox.z);
|
|
3942
|
+
this.cameraControls.setPosition(point.x, point.y + 5, point.z, false);
|
|
3943
|
+
this.cameraControls.setTarget(pointBox.x, pointBox.y + 5, pointBox.z, false);
|
|
3944
|
+
this.progress += this.roamConfig.speed / 300;
|
|
3830
3945
|
|
|
3831
3946
|
if (typeof this._cameraChangeObserver === 'function') {
|
|
3832
3947
|
this._cameraChangeObserver('roam');
|
|
3833
3948
|
}
|
|
3834
3949
|
} else {
|
|
3835
3950
|
// 循环漫游
|
|
3836
|
-
if (roamConfig.loop) {
|
|
3837
|
-
progress = 0;
|
|
3951
|
+
if (this.roamConfig.loop) {
|
|
3952
|
+
this.progress = 0;
|
|
3838
3953
|
}
|
|
3839
3954
|
}
|
|
3840
3955
|
} else {
|
|
3841
|
-
lineTexture = null;
|
|
3842
|
-
progress = 0;
|
|
3956
|
+
this.lineTexture = null;
|
|
3957
|
+
this.progress = 0;
|
|
3843
3958
|
}
|
|
3844
3959
|
},
|
|
3845
3960
|
// 全局整体炸开
|
|
@@ -3847,10 +3962,10 @@ export default {
|
|
|
3847
3962
|
* 参数val: 爆炸的值
|
|
3848
3963
|
*/
|
|
3849
3964
|
globalBomb(val) {
|
|
3850
|
-
if (scene.children.length === 0) return;
|
|
3851
|
-
for (let i = 0; i < scene.children.length; i++) {
|
|
3852
|
-
console.log('scene', scene);
|
|
3853
|
-
scene.children[i].traverse(item => {
|
|
3965
|
+
if (this.scene.children.length === 0) return;
|
|
3966
|
+
for (let i = 0; i < this.scene.children.length; i++) {
|
|
3967
|
+
console.log('this.scene', this.scene);
|
|
3968
|
+
this.scene.children[i].traverse(item => {
|
|
3854
3969
|
if (!item.isMesh || !item.worldDir) return;
|
|
3855
3970
|
// 爆炸公式
|
|
3856
3971
|
this.computedBomb(item, val);
|
|
@@ -3882,7 +3997,7 @@ export default {
|
|
|
3882
3997
|
},
|
|
3883
3998
|
getClippingPlanes() {
|
|
3884
3999
|
let clippingPlanesConstant = [];
|
|
3885
|
-
renderer.clippingPlanes.forEach(item => {
|
|
4000
|
+
this.renderer.clippingPlanes.forEach(item => {
|
|
3886
4001
|
clippingPlanesConstant.push(item.constant);
|
|
3887
4002
|
});
|
|
3888
4003
|
return clippingPlanesConstant;
|
|
@@ -3893,7 +4008,7 @@ export default {
|
|
|
3893
4008
|
剖切值变换时, 使用
|
|
3894
4009
|
*/
|
|
3895
4010
|
setGlobalClipping(flag = true) {
|
|
3896
|
-
const box3 = new this.THREE.Box3().setFromObject(scene.children[0]);
|
|
4011
|
+
const box3 = new this.THREE.Box3().setFromObject(this.scene.children[0]);
|
|
3897
4012
|
let max = box3.max;
|
|
3898
4013
|
let min = box3.min;
|
|
3899
4014
|
const clippingPlanes = [
|
|
@@ -3923,10 +4038,10 @@ export default {
|
|
|
3923
4038
|
),
|
|
3924
4039
|
];
|
|
3925
4040
|
|
|
3926
|
-
renderer.clippingPlanes = clippingPlanes;
|
|
4041
|
+
this.renderer.clippingPlanes = clippingPlanes;
|
|
3927
4042
|
if (flag) {
|
|
3928
4043
|
// 全局剖切的初始值
|
|
3929
|
-
guiParams = {
|
|
4044
|
+
this.guiParams = {
|
|
3930
4045
|
x轴: Math.ceil(clippingPlanes[0].constant),
|
|
3931
4046
|
y轴: Math.ceil(clippingPlanes[2].constant),
|
|
3932
4047
|
z轴: Math.ceil(clippingPlanes[1].constant),
|
|
@@ -3968,13 +4083,13 @@ export default {
|
|
|
3968
4083
|
z: 2,
|
|
3969
4084
|
};
|
|
3970
4085
|
for (const key in params) {
|
|
3971
|
-
renderer.clippingPlanes[axis[key]].constant = params[key];
|
|
4086
|
+
this.renderer.clippingPlanes[axis[key]].constant = params[key];
|
|
3972
4087
|
}
|
|
3973
4088
|
// this.timeRender()
|
|
3974
4089
|
},
|
|
3975
4090
|
// 取消全局剖切
|
|
3976
4091
|
cancelGlobalClipping() {
|
|
3977
|
-
guiParams = {
|
|
4092
|
+
this.guiParams = {
|
|
3978
4093
|
x轴: 0,
|
|
3979
4094
|
y轴: 0,
|
|
3980
4095
|
z轴: 0,
|
|
@@ -3983,14 +4098,14 @@ export default {
|
|
|
3983
4098
|
'-z轴': 0,
|
|
3984
4099
|
};
|
|
3985
4100
|
this.clippingPlanesConstants = null;
|
|
3986
|
-
renderer.clippingPlanes = Object.freeze([]);
|
|
3987
|
-
gui && gui.destroy();
|
|
4101
|
+
this.renderer.clippingPlanes = Object.freeze([]);
|
|
4102
|
+
this.gui && this.gui.destroy();
|
|
3988
4103
|
},
|
|
3989
4104
|
// 单个实体的剖切/ 局部剖切 obj 实体对象 flag 代表是否使用图形组件自带的剖切面板 默认为true
|
|
3990
4105
|
setLocalClipping(obj, flag = true) {
|
|
3991
|
-
clippingMesh.splice(0);
|
|
3992
|
-
clippingMesh.push(obj);
|
|
3993
|
-
renderer.localClippingEnabled = true;
|
|
4106
|
+
this.clippingMesh.splice(0);
|
|
4107
|
+
this.clippingMesh.push(obj);
|
|
4108
|
+
this.renderer.localClippingEnabled = true;
|
|
3994
4109
|
// mesh的boundingBox 可以获取到该对象位置的最大最小值 但是在这里我们需要把y、z轴互换
|
|
3995
4110
|
const boundingBox = new this.THREE.Box3().copy(obj.boundingBox);
|
|
3996
4111
|
boundingBox.applyMatrix4(obj.matrixWorld);
|
|
@@ -4006,7 +4121,7 @@ export default {
|
|
|
4006
4121
|
obj.material.needsUpdate = true;
|
|
4007
4122
|
// 将局部剖切的对象记录下来
|
|
4008
4123
|
if (flag) {
|
|
4009
|
-
guiParams = {
|
|
4124
|
+
this.guiParams = {
|
|
4010
4125
|
x轴: clippingPlanes[0].constant,
|
|
4011
4126
|
y轴: clippingPlanes[2].constant,
|
|
4012
4127
|
z轴: clippingPlanes[1].constant,
|
|
@@ -4041,7 +4156,7 @@ export default {
|
|
|
4041
4156
|
y: 1,
|
|
4042
4157
|
z: 2,
|
|
4043
4158
|
};
|
|
4044
|
-
let obj = clippingMesh[clippingMesh.length - 1];
|
|
4159
|
+
let obj = this.clippingMesh[this.clippingMesh.length - 1];
|
|
4045
4160
|
for (const key in params) {
|
|
4046
4161
|
obj.material.clippingPlanes[axis[key]].constant = params[key];
|
|
4047
4162
|
obj.material.needsUpdate = true;
|
|
@@ -4050,7 +4165,7 @@ export default {
|
|
|
4050
4165
|
},
|
|
4051
4166
|
// 取消局部/单个实体的剖切
|
|
4052
4167
|
cancelLocalClipping() {
|
|
4053
|
-
guiParams = {
|
|
4168
|
+
this.guiParams = {
|
|
4054
4169
|
x轴: 0,
|
|
4055
4170
|
y轴: 0,
|
|
4056
4171
|
z轴: 0,
|
|
@@ -4058,20 +4173,20 @@ export default {
|
|
|
4058
4173
|
'-y轴': 0,
|
|
4059
4174
|
'-z轴': 0,
|
|
4060
4175
|
};
|
|
4061
|
-
gui && gui.destroy();
|
|
4062
|
-
clippingMesh.forEach(item => {
|
|
4176
|
+
this.gui && this.gui.destroy();
|
|
4177
|
+
this.clippingMesh.forEach(item => {
|
|
4063
4178
|
item.material.clippingPlanes = Object.freeze([]);
|
|
4064
4179
|
item.material.needsUpdate = true;
|
|
4065
4180
|
});
|
|
4066
|
-
clippingMesh.splice(0);
|
|
4181
|
+
this.clippingMesh.splice(0);
|
|
4067
4182
|
},
|
|
4068
4183
|
// 添加剖切轴工具
|
|
4069
4184
|
addClippingGui(title, boudingValue, objClipp1, objClipp2) {
|
|
4070
|
-
gui = new GUI({
|
|
4185
|
+
this.gui = new GUI({
|
|
4071
4186
|
title: title,
|
|
4072
4187
|
});
|
|
4073
|
-
gui
|
|
4074
|
-
.add(guiParams, 'x轴')
|
|
4188
|
+
this.gui
|
|
4189
|
+
.add(this.guiParams, 'x轴')
|
|
4075
4190
|
.step(0.001)
|
|
4076
4191
|
.min(boudingValue.min.x)
|
|
4077
4192
|
.max(boudingValue.max.x)
|
|
@@ -4079,8 +4194,8 @@ export default {
|
|
|
4079
4194
|
objClipp1[0].constant = d;
|
|
4080
4195
|
objClipp2 && (objClipp2[0].constant = d);
|
|
4081
4196
|
});
|
|
4082
|
-
gui
|
|
4083
|
-
.add(guiParams, '-x轴')
|
|
4197
|
+
this.gui
|
|
4198
|
+
.add(this.guiParams, '-x轴')
|
|
4084
4199
|
.step(0.001)
|
|
4085
4200
|
.min(boudingValue.min.x)
|
|
4086
4201
|
.max(boudingValue.max.x)
|
|
@@ -4088,8 +4203,8 @@ export default {
|
|
|
4088
4203
|
objClipp1[3].constant = -d;
|
|
4089
4204
|
objClipp2 && (objClipp2[3].constant = -d);
|
|
4090
4205
|
});
|
|
4091
|
-
gui
|
|
4092
|
-
.add(guiParams, 'y轴')
|
|
4206
|
+
this.gui
|
|
4207
|
+
.add(this.guiParams, 'y轴')
|
|
4093
4208
|
.step(0.001)
|
|
4094
4209
|
.min(boudingValue.min.y)
|
|
4095
4210
|
.max(boudingValue.max.y)
|
|
@@ -4097,8 +4212,8 @@ export default {
|
|
|
4097
4212
|
objClipp1[2].constant = d;
|
|
4098
4213
|
objClipp2 && (objClipp2[2].constant = d);
|
|
4099
4214
|
});
|
|
4100
|
-
gui
|
|
4101
|
-
.add(guiParams, '-y轴')
|
|
4215
|
+
this.gui
|
|
4216
|
+
.add(this.guiParams, '-y轴')
|
|
4102
4217
|
.step(0.001)
|
|
4103
4218
|
.min(boudingValue.min.y)
|
|
4104
4219
|
.max(boudingValue.max.y)
|
|
@@ -4106,8 +4221,8 @@ export default {
|
|
|
4106
4221
|
objClipp1[5].constant = -d;
|
|
4107
4222
|
objClipp2 && (objClipp2[5].constant = -d);
|
|
4108
4223
|
});
|
|
4109
|
-
gui
|
|
4110
|
-
.add(guiParams, 'z轴')
|
|
4224
|
+
this.gui
|
|
4225
|
+
.add(this.guiParams, 'z轴')
|
|
4111
4226
|
.step(0.001)
|
|
4112
4227
|
.min(boudingValue.min.z)
|
|
4113
4228
|
.max(boudingValue.max.z)
|
|
@@ -4115,8 +4230,8 @@ export default {
|
|
|
4115
4230
|
objClipp1[1].constant = d;
|
|
4116
4231
|
objClipp2 && (objClipp2[1].constant = d);
|
|
4117
4232
|
});
|
|
4118
|
-
gui
|
|
4119
|
-
.add(guiParams, '-z轴')
|
|
4233
|
+
this.gui
|
|
4234
|
+
.add(this.guiParams, '-z轴')
|
|
4120
4235
|
.step(0.001)
|
|
4121
4236
|
.min(boudingValue.min.z)
|
|
4122
4237
|
.max(boudingValue.max.z)
|
|
@@ -4128,19 +4243,19 @@ export default {
|
|
|
4128
4243
|
// 开启第一视角
|
|
4129
4244
|
startFirstPer(options) {
|
|
4130
4245
|
let { moveSpeed = 200, jumpSpeed = 200 } = options || {};
|
|
4131
|
-
removeSpeed = moveSpeed;
|
|
4132
|
-
upSpeed = jumpSpeed;
|
|
4246
|
+
this.removeSpeed = moveSpeed;
|
|
4247
|
+
this.upSpeed = jumpSpeed;
|
|
4133
4248
|
|
|
4134
|
-
clock = new this.THREE.Clock();
|
|
4135
|
-
downRaycaster = new this.THREE.Raycaster(
|
|
4249
|
+
this.clock = new this.THREE.Clock();
|
|
4250
|
+
this.downRaycaster = new this.THREE.Raycaster(
|
|
4136
4251
|
new this.THREE.Vector3(),
|
|
4137
4252
|
new this.THREE.Vector3(0, -1, 0),
|
|
4138
4253
|
0,
|
|
4139
4254
|
10
|
|
4140
4255
|
);
|
|
4141
|
-
velocity = new this.THREE.Vector3(); //移动速度变量
|
|
4142
|
-
direction = new this.THREE.Vector3(); //移动的方向变量
|
|
4143
|
-
firstPerSign = true;
|
|
4256
|
+
this.velocity = new this.THREE.Vector3(); //移动速度变量
|
|
4257
|
+
this.direction = new this.THREE.Vector3(); //移动的方向变量
|
|
4258
|
+
this.firstPerSign = true;
|
|
4144
4259
|
this.initPointerLock();
|
|
4145
4260
|
},
|
|
4146
4261
|
// 页面是否锁定
|
|
@@ -4148,11 +4263,11 @@ export default {
|
|
|
4148
4263
|
this.home();
|
|
4149
4264
|
setTimeout(() => {
|
|
4150
4265
|
// 开启第一视角时,将相机与水平面保持水平
|
|
4151
|
-
camera.rotation.x = 0;
|
|
4152
|
-
camera.rotation.z = 0;
|
|
4266
|
+
this.camera.rotation.x = 0;
|
|
4267
|
+
this.camera.rotation.z = 0;
|
|
4153
4268
|
|
|
4154
|
-
pointControls = new PointerLockControls(camera, renderer.domElement);
|
|
4155
|
-
pointControls.lock();
|
|
4269
|
+
this.pointControls = new PointerLockControls(this.camera, this.renderer.domElement);
|
|
4270
|
+
this.pointControls.lock();
|
|
4156
4271
|
if (!this._onFirstPersonChange) {
|
|
4157
4272
|
this._onFirstPersonChange = () => {
|
|
4158
4273
|
if (typeof this._cameraChangeObserver === 'function') {
|
|
@@ -4161,28 +4276,28 @@ export default {
|
|
|
4161
4276
|
};
|
|
4162
4277
|
}
|
|
4163
4278
|
try {
|
|
4164
|
-
pointControls.addEventListener('change', this._onFirstPersonChange);
|
|
4279
|
+
this.pointControls.addEventListener('change', this._onFirstPersonChange);
|
|
4165
4280
|
} catch (e) {}
|
|
4166
4281
|
// 锁定
|
|
4167
|
-
pointControls.addEventListener('lock', () => {
|
|
4168
|
-
cameraControls.enabled = false;
|
|
4282
|
+
this.pointControls.addEventListener('lock', () => {
|
|
4283
|
+
this.cameraControls.enabled = false;
|
|
4169
4284
|
window.addEventListener('keydown', this.onKeyDown, false);
|
|
4170
4285
|
window.addEventListener('keyup', this.onKeyUp, false);
|
|
4171
|
-
renderer.domElement.removeEventListener('mouseup', this.mouseClick, false);
|
|
4172
|
-
renderer.domElement.removeEventListener('mousedown', this.mouseDown, false);
|
|
4286
|
+
this.renderer.domElement.removeEventListener('mouseup', this.mouseClick, false);
|
|
4287
|
+
this.renderer.domElement.removeEventListener('mousedown', this.mouseDown, false);
|
|
4173
4288
|
if (typeof this._cameraChangeObserver === 'function') {
|
|
4174
4289
|
this._cameraChangeObserver('firstPersonLock');
|
|
4175
4290
|
}
|
|
4176
4291
|
});
|
|
4177
4292
|
// 解锁
|
|
4178
|
-
pointControls.addEventListener('unlock', () => {
|
|
4179
|
-
firstPerSign = false;
|
|
4180
|
-
cameraControls.enabled = true;
|
|
4293
|
+
this.pointControls.addEventListener('unlock', () => {
|
|
4294
|
+
this.firstPerSign = false;
|
|
4295
|
+
this.cameraControls.enabled = true;
|
|
4181
4296
|
// 返回初始视角
|
|
4182
4297
|
this.home();
|
|
4183
4298
|
try {
|
|
4184
|
-
if (this._onFirstPersonChange && pointControls) {
|
|
4185
|
-
pointControls.removeEventListener('change', this._onFirstPersonChange);
|
|
4299
|
+
if (this._onFirstPersonChange && this.pointControls) {
|
|
4300
|
+
this.pointControls.removeEventListener('change', this._onFirstPersonChange);
|
|
4186
4301
|
}
|
|
4187
4302
|
} catch (e) {}
|
|
4188
4303
|
if (this.noObserver) {
|
|
@@ -4191,57 +4306,61 @@ export default {
|
|
|
4191
4306
|
setTimeout(() => {
|
|
4192
4307
|
window.removeEventListener('keydown', this.onKeyDown);
|
|
4193
4308
|
window.removeEventListener('keyup', this.onKeyUp);
|
|
4194
|
-
renderer.domElement.addEventListener('mouseup', this.mouseClick, false);
|
|
4195
|
-
renderer.domElement.addEventListener('mousedown', this.mouseDown, false);
|
|
4309
|
+
this.renderer.domElement.addEventListener('mouseup', this.mouseClick, false);
|
|
4310
|
+
this.renderer.domElement.addEventListener('mousedown', this.mouseDown, false);
|
|
4196
4311
|
// this.timeRender()
|
|
4197
4312
|
}, 0);
|
|
4198
4313
|
if (typeof this._cameraChangeObserver === 'function') {
|
|
4199
4314
|
this._cameraChangeObserver('firstPersonUnlock');
|
|
4200
4315
|
}
|
|
4201
4316
|
});
|
|
4202
|
-
if (scene) scene.add(pointControls.object);
|
|
4317
|
+
if (this.scene) this.scene.add(this.pointControls.object);
|
|
4203
4318
|
}, 10);
|
|
4204
4319
|
},
|
|
4205
4320
|
// 第一视角运动
|
|
4206
4321
|
firstPerspective() {
|
|
4207
|
-
if (!cameraControls.enabled && firstPerSign) {
|
|
4322
|
+
if (!this.cameraControls.enabled && this.firstPerSign) {
|
|
4208
4323
|
// 获取到控制器对象
|
|
4209
|
-
let control = pointControls.object;
|
|
4324
|
+
let control = this.pointControls.object;
|
|
4210
4325
|
// 获取刷新时间
|
|
4211
|
-
let delta = clock.getDelta();
|
|
4326
|
+
let delta = this.clock.getDelta();
|
|
4212
4327
|
// velocity每次的速度,为了保证有过渡
|
|
4213
|
-
velocity.x -= velocity.x * 10.0 * delta;
|
|
4214
|
-
velocity.z -= velocity.z * 10.0 * delta;
|
|
4215
|
-
velocity.y -= 9.8 * 100.0 * delta; // 默认下降的速度
|
|
4328
|
+
this.velocity.x -= this.velocity.x * 10.0 * delta;
|
|
4329
|
+
this.velocity.z -= this.velocity.z * 10.0 * delta;
|
|
4330
|
+
this.velocity.y -= 9.8 * 100.0 * delta; // 默认下降的速度
|
|
4216
4331
|
// 获取当前按键的方向并获取朝哪个方向移动
|
|
4217
|
-
direction.z = Number(moveForward) - Number(moveBackward);
|
|
4218
|
-
direction.x = Number(moveRight) - Number(moveLeft);
|
|
4332
|
+
this.direction.z = Number(this.moveForward) - Number(this.moveBackward);
|
|
4333
|
+
this.direction.x = Number(this.moveRight) - Number(this.moveLeft);
|
|
4219
4334
|
// 将法向量的值归一化
|
|
4220
|
-
direction.normalize();
|
|
4221
|
-
if (moveForward || moveBackward)
|
|
4222
|
-
|
|
4335
|
+
this.direction.normalize();
|
|
4336
|
+
if (this.moveForward || this.moveBackward)
|
|
4337
|
+
this.velocity.z -= this.direction.z * this.removeSpeed * delta;
|
|
4338
|
+
if (this.moveLeft || this.moveRight)
|
|
4339
|
+
this.velocity.x -= this.direction.x * this.removeSpeed * delta;
|
|
4223
4340
|
// }
|
|
4224
4341
|
// 复制相机的位置
|
|
4225
|
-
downRaycaster.ray.origin.copy(control.position);
|
|
4342
|
+
this.downRaycaster.ray.origin.copy(control.position);
|
|
4226
4343
|
// 获取相机靠下5的位置
|
|
4227
|
-
downRaycaster.ray.origin.y += 5;
|
|
4344
|
+
this.downRaycaster.ray.origin.y += 5;
|
|
4228
4345
|
// 判断是否停留在了立方体上面
|
|
4229
4346
|
let intersections =
|
|
4230
|
-
scene &&
|
|
4347
|
+
this.scene && this.scene.children
|
|
4348
|
+
? this.downRaycaster.intersectObjects(this.scene.children, true)
|
|
4349
|
+
: [];
|
|
4231
4350
|
var onObject = intersections.length > 0;
|
|
4232
4351
|
if (onObject === true) {
|
|
4233
|
-
velocity.y = Math.max(0, velocity.y);
|
|
4234
|
-
canJump = true;
|
|
4352
|
+
this.velocity.y = Math.max(0, this.velocity.y);
|
|
4353
|
+
this.canJump = true;
|
|
4235
4354
|
}
|
|
4236
4355
|
// 根据速度值移动控制器
|
|
4237
|
-
pointControls.moveRight(-velocity.x * delta);
|
|
4238
|
-
pointControls.moveForward(-velocity.z * delta);
|
|
4239
|
-
control.position.y += velocity.y * delta;
|
|
4356
|
+
this.pointControls.this.moveRight(-this.velocity.x * delta);
|
|
4357
|
+
this.pointControls.this.moveForward(-this.velocity.z * delta);
|
|
4358
|
+
control.position.y += this.velocity.y * delta;
|
|
4240
4359
|
// 保证控制器的y轴在平面上
|
|
4241
4360
|
if (control.position.y < 3 - 0 / 10) {
|
|
4242
|
-
velocity.y = -0 / 10;
|
|
4361
|
+
this.velocity.y = -0 / 10;
|
|
4243
4362
|
control.position.y = 3 - 0 / 10;
|
|
4244
|
-
canJump = true;
|
|
4363
|
+
this.canJump = true;
|
|
4245
4364
|
}
|
|
4246
4365
|
if (this.noObserver) {
|
|
4247
4366
|
if (!this.noObserver._firstPersonLastPos) {
|
|
@@ -4267,27 +4386,27 @@ export default {
|
|
|
4267
4386
|
// 前进
|
|
4268
4387
|
case 38:
|
|
4269
4388
|
case 87:
|
|
4270
|
-
moveForward = true;
|
|
4389
|
+
this.moveForward = true;
|
|
4271
4390
|
break;
|
|
4272
4391
|
// 向左
|
|
4273
4392
|
case 37:
|
|
4274
4393
|
case 65:
|
|
4275
|
-
moveLeft = true;
|
|
4394
|
+
this.moveLeft = true;
|
|
4276
4395
|
break;
|
|
4277
4396
|
// 后退
|
|
4278
4397
|
case 40:
|
|
4279
4398
|
case 83:
|
|
4280
|
-
moveBackward = true;
|
|
4399
|
+
this.moveBackward = true;
|
|
4281
4400
|
break;
|
|
4282
4401
|
// 向右
|
|
4283
4402
|
case 39:
|
|
4284
4403
|
case 68:
|
|
4285
|
-
moveRight = true;
|
|
4404
|
+
this.moveRight = true;
|
|
4286
4405
|
break;
|
|
4287
4406
|
// 跳跃
|
|
4288
4407
|
case 32:
|
|
4289
|
-
if (canJump && spaceUp) velocity.y += upSpeed;
|
|
4290
|
-
canJump = false;
|
|
4408
|
+
if (this.canJump && spaceUp) this.velocity.y += this.upSpeed;
|
|
4409
|
+
this.canJump = false;
|
|
4291
4410
|
spaceUp = false;
|
|
4292
4411
|
break;
|
|
4293
4412
|
}
|
|
@@ -4299,22 +4418,22 @@ export default {
|
|
|
4299
4418
|
// 前进
|
|
4300
4419
|
case 38:
|
|
4301
4420
|
case 87:
|
|
4302
|
-
moveForward = false;
|
|
4421
|
+
this.moveForward = false;
|
|
4303
4422
|
break;
|
|
4304
4423
|
// 向左
|
|
4305
4424
|
case 37:
|
|
4306
4425
|
case 65:
|
|
4307
|
-
moveLeft = false;
|
|
4426
|
+
this.moveLeft = false;
|
|
4308
4427
|
break;
|
|
4309
4428
|
// 后退
|
|
4310
4429
|
case 40:
|
|
4311
4430
|
case 83:
|
|
4312
|
-
moveBackward = false;
|
|
4431
|
+
this.moveBackward = false;
|
|
4313
4432
|
break;
|
|
4314
4433
|
// 向右
|
|
4315
4434
|
case 39:
|
|
4316
4435
|
case 68:
|
|
4317
|
-
moveRight = false;
|
|
4436
|
+
this.moveRight = false;
|
|
4318
4437
|
break;
|
|
4319
4438
|
// 跳跃
|
|
4320
4439
|
case 32:
|
|
@@ -4324,14 +4443,14 @@ export default {
|
|
|
4324
4443
|
},
|
|
4325
4444
|
// 返回主视角/恢复相机初始状态
|
|
4326
4445
|
home() {
|
|
4327
|
-
hasExecutedCentering = true;
|
|
4446
|
+
this.hasExecutedCentering = true;
|
|
4328
4447
|
|
|
4329
|
-
if (roaming) {
|
|
4448
|
+
if (this.roaming) {
|
|
4330
4449
|
this.endRoam();
|
|
4331
4450
|
}
|
|
4332
4451
|
|
|
4333
|
-
const center = sceneBoundingBox.getCenter(new this.THREE.Vector3());
|
|
4334
|
-
const size = sceneBoundingBox.getSize(new this.THREE.Vector3());
|
|
4452
|
+
const center = this.sceneBoundingBox.getCenter(new this.THREE.Vector3());
|
|
4453
|
+
const size = this.sceneBoundingBox.getSize(new this.THREE.Vector3());
|
|
4335
4454
|
const maxDim = Math.max(size.x, size.y, size.z);
|
|
4336
4455
|
|
|
4337
4456
|
this.cameraLocation({
|
|
@@ -4343,8 +4462,8 @@ export default {
|
|
|
4343
4462
|
roll: center.z,
|
|
4344
4463
|
});
|
|
4345
4464
|
this.setCameraConfig();
|
|
4346
|
-
// cameraControls.reset(true);
|
|
4347
|
-
// cameraControls.update(0);
|
|
4465
|
+
// this.cameraControls.reset(true);
|
|
4466
|
+
// this.cameraControls.update(0);
|
|
4348
4467
|
// this.timeRender()
|
|
4349
4468
|
},
|
|
4350
4469
|
// 测量
|
|
@@ -4352,63 +4471,63 @@ export default {
|
|
|
4352
4471
|
参数: type: '', distance、area、angle、height, 暂时只提供距离、面积、角度、高度这四种方式
|
|
4353
4472
|
*/
|
|
4354
4473
|
openMeasure(type) {
|
|
4355
|
-
if (threeMeasure) {
|
|
4356
|
-
threeMeasure.close();
|
|
4357
|
-
threeMeasure = null;
|
|
4474
|
+
if (this.threeMeasure) {
|
|
4475
|
+
this.threeMeasure.close(false);
|
|
4476
|
+
this.threeMeasure = null;
|
|
4358
4477
|
}
|
|
4359
|
-
measureFlag = true;
|
|
4478
|
+
this.measureFlag = true;
|
|
4360
4479
|
// renderEnabled = true
|
|
4361
4480
|
switch (type) {
|
|
4362
4481
|
case 'distance':
|
|
4363
|
-
threeMeasure = new MeasureDistance.MeasureDistance(
|
|
4364
|
-
renderer,
|
|
4365
|
-
scene,
|
|
4366
|
-
camera,
|
|
4367
|
-
instructions.offsetWidth,
|
|
4368
|
-
instructions.offsetHeight
|
|
4482
|
+
this.threeMeasure = new MeasureDistance.MeasureDistance(
|
|
4483
|
+
this.renderer,
|
|
4484
|
+
this.scene,
|
|
4485
|
+
this.camera,
|
|
4486
|
+
this.instructions.offsetWidth,
|
|
4487
|
+
this.instructions.offsetHeight
|
|
4369
4488
|
);
|
|
4370
|
-
threeMeasure.start();
|
|
4489
|
+
this.threeMeasure.start();
|
|
4371
4490
|
break;
|
|
4372
4491
|
case 'area':
|
|
4373
|
-
threeMeasure = new MeasureArea.MeasureArea(
|
|
4374
|
-
renderer,
|
|
4375
|
-
scene,
|
|
4376
|
-
camera,
|
|
4377
|
-
instructions.offsetWidth,
|
|
4378
|
-
instructions.offsetHeight
|
|
4492
|
+
this.threeMeasure = new MeasureArea.MeasureArea(
|
|
4493
|
+
this.renderer,
|
|
4494
|
+
this.scene,
|
|
4495
|
+
this.camera,
|
|
4496
|
+
this.instructions.offsetWidth,
|
|
4497
|
+
this.instructions.offsetHeight
|
|
4379
4498
|
);
|
|
4380
|
-
threeMeasure.start();
|
|
4499
|
+
this.threeMeasure.start();
|
|
4381
4500
|
break;
|
|
4382
4501
|
case 'angle':
|
|
4383
|
-
threeMeasure = new MeasureAngle.MeasureAngle(
|
|
4384
|
-
renderer,
|
|
4385
|
-
scene,
|
|
4386
|
-
camera,
|
|
4387
|
-
instructions.offsetWidth,
|
|
4388
|
-
instructions.offsetHeight
|
|
4502
|
+
this.threeMeasure = new MeasureAngle.MeasureAngle(
|
|
4503
|
+
this.renderer,
|
|
4504
|
+
this.scene,
|
|
4505
|
+
this.camera,
|
|
4506
|
+
this.instructions.offsetWidth,
|
|
4507
|
+
this.instructions.offsetHeight
|
|
4389
4508
|
);
|
|
4390
|
-
threeMeasure.start();
|
|
4509
|
+
this.threeMeasure.start();
|
|
4391
4510
|
break;
|
|
4392
4511
|
case 'height':
|
|
4393
|
-
threeMeasure = new MeasureHeight.MeasureHeight(
|
|
4394
|
-
renderer,
|
|
4395
|
-
scene,
|
|
4396
|
-
camera,
|
|
4397
|
-
instructions.offsetWidth,
|
|
4398
|
-
instructions.offsetHeight
|
|
4512
|
+
this.threeMeasure = new MeasureHeight.MeasureHeight(
|
|
4513
|
+
this.renderer,
|
|
4514
|
+
this.scene,
|
|
4515
|
+
this.camera,
|
|
4516
|
+
this.instructions.offsetWidth,
|
|
4517
|
+
this.instructions.offsetHeight
|
|
4399
4518
|
);
|
|
4400
|
-
threeMeasure.start();
|
|
4519
|
+
this.threeMeasure.start();
|
|
4401
4520
|
break;
|
|
4402
4521
|
}
|
|
4403
4522
|
// 添加键盘事件监听器
|
|
4404
4523
|
document.addEventListener('keydown', this.handleMeasureKeyDown, false);
|
|
4405
4524
|
},
|
|
4406
|
-
// 关闭测量
|
|
4407
|
-
closeMeasure() {
|
|
4408
|
-
measureFlag = false;
|
|
4409
|
-
if (threeMeasure) {
|
|
4410
|
-
threeMeasure.close();
|
|
4411
|
-
threeMeasure = null;
|
|
4525
|
+
// 关闭测量 isClear代表是否清除测量结果
|
|
4526
|
+
closeMeasure(isClear) {
|
|
4527
|
+
this.measureFlag = false;
|
|
4528
|
+
if (this.threeMeasure) {
|
|
4529
|
+
this.threeMeasure.close(isClear);
|
|
4530
|
+
!isClear && (this.threeMeasure = null);
|
|
4412
4531
|
// this.timeRender()
|
|
4413
4532
|
}
|
|
4414
4533
|
// 移除键盘事件监听器
|
|
@@ -4482,9 +4601,9 @@ export default {
|
|
|
4482
4601
|
参数: object, 目标实体,
|
|
4483
4602
|
*/
|
|
4484
4603
|
isolate(object) {
|
|
4485
|
-
if (!scene) return;
|
|
4604
|
+
if (!this.scene) return;
|
|
4486
4605
|
// 隔离 将目标实体以外的实体隐藏掉
|
|
4487
|
-
scene.traverse(item => {
|
|
4606
|
+
this.scene.traverse(item => {
|
|
4488
4607
|
if (item.isMesh && item.name !== object.name) {
|
|
4489
4608
|
const offsetMatrix = new this.THREE.Matrix4()
|
|
4490
4609
|
.copy(item.userData.copyMatrix)
|
|
@@ -4496,8 +4615,8 @@ export default {
|
|
|
4496
4615
|
},
|
|
4497
4616
|
// 还原操作 将修改过的实体进行恢复
|
|
4498
4617
|
restore() {
|
|
4499
|
-
if (!scene) return;
|
|
4500
|
-
scene.traverse(item => {
|
|
4618
|
+
if (!this.scene) return;
|
|
4619
|
+
this.scene.traverse(item => {
|
|
4501
4620
|
if (item.isMesh) {
|
|
4502
4621
|
const instanceId = item.userData ? item.userData.instanceId : null;
|
|
4503
4622
|
item.setColorAt(item.userData.instanceIndex, item.material.userData.nColor);
|
|
@@ -4542,24 +4661,24 @@ export default {
|
|
|
4542
4661
|
const loader = new GLTFLoader();
|
|
4543
4662
|
let locationModel = null;
|
|
4544
4663
|
loader.load(url, gltf => {
|
|
4545
|
-
locationModel = gltf.scene;
|
|
4664
|
+
locationModel = gltf.this.scene;
|
|
4546
4665
|
locationModel.scale.set(scale, scale, scale);
|
|
4547
4666
|
locationModel.updateMatrixWorld();
|
|
4548
4667
|
if (immediately) {
|
|
4549
|
-
cameraControls.fitToSphere(gltf.scene, true);
|
|
4668
|
+
this.cameraControls.fitToSphere(gltf.this.scene, true);
|
|
4550
4669
|
}
|
|
4551
4670
|
// 动画混合器
|
|
4552
4671
|
// 不参与裁剪
|
|
4553
4672
|
locationModel.userData.cull = false;
|
|
4554
4673
|
locationModel.name = name;
|
|
4555
|
-
if (scene) scene.add(locationModel);
|
|
4674
|
+
if (this.scene) this.scene.add(locationModel);
|
|
4556
4675
|
locationModel.position.copy(new this.THREE.Vector3(position.x, position.y, position.z));
|
|
4557
4676
|
if (gltf.animations.length > 0) {
|
|
4558
|
-
let actionMixer = new this.THREE.AnimationMixer(gltf.scene);
|
|
4677
|
+
let actionMixer = new this.THREE.AnimationMixer(gltf.this.scene);
|
|
4559
4678
|
const walkActive = actionMixer.clipAction(gltf.animations[0]);
|
|
4560
4679
|
walkActive.play();
|
|
4561
|
-
modelActive.push(walkActive);
|
|
4562
|
-
modelActions.push(actionMixer);
|
|
4680
|
+
this.modelActive.push(walkActive);
|
|
4681
|
+
this.modelActions.push(actionMixer);
|
|
4563
4682
|
}
|
|
4564
4683
|
callback && callback();
|
|
4565
4684
|
});
|
|
@@ -4570,8 +4689,8 @@ export default {
|
|
|
4570
4689
|
obj.forEach((item, index) => {
|
|
4571
4690
|
if (item.animations > 0) {
|
|
4572
4691
|
item.removeFromParent();
|
|
4573
|
-
modelActions[index].uncacheRoot(item);
|
|
4574
|
-
modelActions[index].uncacheRoot(modelActive[index]);
|
|
4692
|
+
this.modelActions[index].uncacheRoot(item);
|
|
4693
|
+
this.modelActions[index].uncacheRoot(this.modelActive[index]);
|
|
4575
4694
|
}
|
|
4576
4695
|
item.traverse(child => {
|
|
4577
4696
|
if (child instanceof this.THREE.Mesh) {
|
|
@@ -4579,47 +4698,47 @@ export default {
|
|
|
4579
4698
|
child.material.dispose();
|
|
4580
4699
|
}
|
|
4581
4700
|
});
|
|
4582
|
-
if (scene) scene.remove(item);
|
|
4701
|
+
if (this.scene) this.scene.remove(item);
|
|
4583
4702
|
});
|
|
4584
|
-
modelActions.splice(0);
|
|
4585
|
-
modelActive.splice(0);
|
|
4703
|
+
this.modelActions.splice(0);
|
|
4704
|
+
this.modelActive.splice(0);
|
|
4586
4705
|
},
|
|
4587
4706
|
// 修改天空背景
|
|
4588
4707
|
skyBoxScene(url) {
|
|
4589
4708
|
const textureCube = new this.THREE.CubeTextureLoader().load(url);
|
|
4590
|
-
scene.background = textureCube;
|
|
4709
|
+
this.scene.background = textureCube;
|
|
4591
4710
|
},
|
|
4592
4711
|
// 清除天空背景
|
|
4593
4712
|
clearSkyBoxScene() {
|
|
4594
|
-
scene.background = null;
|
|
4713
|
+
this.scene.background = null;
|
|
4595
4714
|
},
|
|
4596
4715
|
// 下雨模拟
|
|
4597
4716
|
sceneSimu(type) {
|
|
4598
|
-
if (!outlineComposer) {
|
|
4599
|
-
outlineComposer = new EffectComposer(renderer, renderTarget);
|
|
4600
|
-
outlineComposer.addPass(new RenderPass(scene, camera));
|
|
4717
|
+
if (!this.outlineComposer) {
|
|
4718
|
+
this.outlineComposer = new EffectComposer(this.renderer, this.renderTarget);
|
|
4719
|
+
this.outlineComposer.addPass(new RenderPass(this.scene, this.camera));
|
|
4601
4720
|
}
|
|
4602
4721
|
if (type === 'rain') {
|
|
4603
|
-
scenePass = new ShaderPass(RainShader);
|
|
4604
|
-
scenePass.uniforms['iResolution'].value = new this.THREE.Vector2(
|
|
4722
|
+
this.scenePass = new ShaderPass(RainShader);
|
|
4723
|
+
this.scenePass.uniforms['iResolution'].value = new this.THREE.Vector2(
|
|
4605
4724
|
window.innerWidth,
|
|
4606
4725
|
window.innerHeight
|
|
4607
4726
|
);
|
|
4608
|
-
outlineComposer.addPass(scenePass);
|
|
4727
|
+
this.outlineComposer.addPass(this.scenePass);
|
|
4609
4728
|
} else if (type === 'snow') {
|
|
4610
|
-
scenePass = new ShaderPass(SnowShader);
|
|
4611
|
-
scenePass.uniforms['iResolution'].value = new this.THREE.Vector2(
|
|
4729
|
+
this.scenePass = new ShaderPass(SnowShader);
|
|
4730
|
+
this.scenePass.uniforms['iResolution'].value = new this.THREE.Vector2(
|
|
4612
4731
|
window.innerWidth,
|
|
4613
4732
|
window.innerHeight
|
|
4614
4733
|
);
|
|
4615
|
-
outlineComposer.addPass(scenePass);
|
|
4734
|
+
this.outlineComposer.addPass(this.scenePass);
|
|
4616
4735
|
}
|
|
4617
4736
|
},
|
|
4618
4737
|
clearSceneSim() {
|
|
4619
|
-
if (scenePass && outlineComposer) {
|
|
4620
|
-
outlineComposer.removePass(scenePass);
|
|
4738
|
+
if (this.scenePass && this.outlineComposer) {
|
|
4739
|
+
this.outlineComposer.removePass(this.scenePass);
|
|
4621
4740
|
}
|
|
4622
|
-
scenePass = null;
|
|
4741
|
+
this.scenePass = null;
|
|
4623
4742
|
},
|
|
4624
4743
|
// 获取中心点
|
|
4625
4744
|
getCenter(obj, isBox3Info) {
|
|
@@ -4633,7 +4752,7 @@ export default {
|
|
|
4633
4752
|
let center = new this.THREE.Vector3();
|
|
4634
4753
|
(box3 && box3.getCenter(center)) || obj.boundingBox.getCenter(center);
|
|
4635
4754
|
if (isBox3Info || obj.userData.is3D) {
|
|
4636
|
-
center.applyMatrix4(bizToThreeMatrix);
|
|
4755
|
+
center.applyMatrix4(this.bizToThreeMatrix);
|
|
4637
4756
|
}
|
|
4638
4757
|
return center;
|
|
4639
4758
|
},
|
|
@@ -4648,37 +4767,37 @@ export default {
|
|
|
4648
4767
|
let size = new this.THREE.Vector3();
|
|
4649
4768
|
(box3 && box3.getSize(size)) || obj.boundingBox.getSize(size);
|
|
4650
4769
|
if (isBox3Info || obj.userData.is3D) {
|
|
4651
|
-
size.applyMatrix4(bizToThreeMatrix);
|
|
4770
|
+
size.applyMatrix4(this.bizToThreeMatrix);
|
|
4652
4771
|
}
|
|
4653
4772
|
return size;
|
|
4654
4773
|
},
|
|
4655
4774
|
animate() {
|
|
4656
4775
|
if (isDebug) {
|
|
4657
|
-
stats && stats.begin(); // 开始帧率统计
|
|
4776
|
+
this.stats && this.stats.begin(); // 开始帧率统计
|
|
4658
4777
|
}
|
|
4659
4778
|
|
|
4660
|
-
const delta = fpsClock.getDelta();
|
|
4661
|
-
timeStamp += delta;
|
|
4662
|
-
animateId = requestAnimationFrame(this.animate);
|
|
4779
|
+
const delta = this.fpsClock.getDelta();
|
|
4780
|
+
this.timeStamp += delta;
|
|
4781
|
+
this.animateId = requestAnimationFrame(this.animate);
|
|
4663
4782
|
|
|
4664
4783
|
// 1. 先重置计数器(关键!)
|
|
4665
|
-
renderer.info.reset(); // 重置上一帧的统计数据
|
|
4784
|
+
this.renderer.info.reset(); // 重置上一帧的统计数据
|
|
4666
4785
|
|
|
4667
|
-
if (timeStamp > singleFrameTime) {
|
|
4668
|
-
if (modelActions.length > 0) {
|
|
4669
|
-
modelActions.forEach(item => {
|
|
4670
|
-
item.update(timeStamp);
|
|
4786
|
+
if (this.timeStamp > singleFrameTime) {
|
|
4787
|
+
if (this.modelActions.length > 0) {
|
|
4788
|
+
this.modelActions.forEach(item => {
|
|
4789
|
+
item.update(this.timeStamp);
|
|
4671
4790
|
});
|
|
4672
4791
|
}
|
|
4673
|
-
cameraControls.enabled && cameraControls.update(timeStamp);
|
|
4792
|
+
this.cameraControls.enabled && this.cameraControls.update(this.timeStamp);
|
|
4674
4793
|
// 计算相机近裁面到包围盒当前面的距离
|
|
4675
4794
|
this.cameraTrack();
|
|
4676
4795
|
this.firstPerspective();
|
|
4677
|
-
if (scenePass) {
|
|
4678
|
-
let d = sceneClock.getDelta();
|
|
4679
|
-
scenePass.uniforms['iTime'].value += d;
|
|
4796
|
+
if (this.scenePass) {
|
|
4797
|
+
let d = this.sceneClock.getDelta();
|
|
4798
|
+
this.scenePass.uniforms['iTime'].value += d;
|
|
4680
4799
|
}
|
|
4681
|
-
labelRenderer.render(scene, camera);
|
|
4800
|
+
this.labelRenderer.render(this.scene, this.camera);
|
|
4682
4801
|
renderedThisFrame.clear();
|
|
4683
4802
|
|
|
4684
4803
|
// 增强的渲染中断逻辑:在用户交互期间强制跳过渲染
|
|
@@ -4686,31 +4805,33 @@ export default {
|
|
|
4686
4805
|
? this.noObserver.batchLoadingState
|
|
4687
4806
|
: this.batchLoadingState;
|
|
4688
4807
|
const shouldSkipRendering =
|
|
4689
|
-
skipNextRenderFrame ||
|
|
4808
|
+
this.skipNextRenderFrame ||
|
|
4809
|
+
this.forceSkipRendering ||
|
|
4810
|
+
loadingState.interactionState.isInteracting;
|
|
4690
4811
|
|
|
4691
4812
|
if (shouldSkipRendering) {
|
|
4692
4813
|
// 重置单次跳过标记
|
|
4693
|
-
if (skipNextRenderFrame) {
|
|
4694
|
-
skipNextRenderFrame = false;
|
|
4814
|
+
if (this.skipNextRenderFrame) {
|
|
4815
|
+
this.skipNextRenderFrame = false;
|
|
4695
4816
|
}
|
|
4696
4817
|
|
|
4697
4818
|
// 统计跳过的帧数
|
|
4698
4819
|
// interactionFrameCount++;
|
|
4699
4820
|
// 在交互期间,每隔几帧强制渲染一次以保持基本的视觉反馈
|
|
4700
4821
|
// if (interactionFrameCount % 2 === 0 && this.batchLoadingState.interactionState.isInteracting) {
|
|
4701
|
-
renderer.clear(true, true, true);
|
|
4702
|
-
renderer.render(scene, camera);
|
|
4822
|
+
this.renderer.clear(true, true, true);
|
|
4823
|
+
this.renderer.render(this.scene, this.camera);
|
|
4703
4824
|
// }
|
|
4704
4825
|
// 可选:添加调试信息(生产环境可注释掉)
|
|
4705
4826
|
// console.log(`跳过渲染帧 #${interactionFrameCount}, 交互类型: ${this.batchLoadingState.interactionState.interactionType}`);
|
|
4706
4827
|
} else {
|
|
4707
4828
|
// 正常渲染
|
|
4708
|
-
if (outlineComposer) {
|
|
4829
|
+
if (this.outlineComposer) {
|
|
4709
4830
|
// 使用后处理管线渲染,避免重复渲染
|
|
4710
|
-
outlineComposer.render();
|
|
4831
|
+
this.outlineComposer.render();
|
|
4711
4832
|
} else {
|
|
4712
|
-
renderer.clear(true, true, true);
|
|
4713
|
-
renderer.render(scene, camera);
|
|
4833
|
+
this.renderer.clear(true, true, true);
|
|
4834
|
+
this.renderer.render(this.scene, this.camera);
|
|
4714
4835
|
}
|
|
4715
4836
|
// 重置交互帧计数
|
|
4716
4837
|
// if (interactionFrameCount > 0) {
|
|
@@ -4727,15 +4848,15 @@ export default {
|
|
|
4727
4848
|
// try {
|
|
4728
4849
|
// const frustum = new this.THREE.Frustum();
|
|
4729
4850
|
// const vpMatrix = new this.THREE.Matrix4().multiplyMatrices(
|
|
4730
|
-
// camera.projectionMatrix,
|
|
4731
|
-
// camera.matrixWorldInverse
|
|
4851
|
+
// this.camera.projectionMatrix,
|
|
4852
|
+
// this.camera.matrixWorldInverse
|
|
4732
4853
|
// );
|
|
4733
4854
|
// frustum.setFromProjectionMatrix(vpMatrix);
|
|
4734
4855
|
|
|
4735
|
-
// // 优先使用 modelGroup 的子节点作为“模型”统计单位;否则回退到 scene.children
|
|
4736
|
-
// const children = (typeof modelGroup !== 'undefined' && modelGroup && modelGroup.children && modelGroup.children.length)
|
|
4737
|
-
// ? modelGroup.children
|
|
4738
|
-
// : scene.children;
|
|
4856
|
+
// // 优先使用 this.modelGroup 的子节点作为“模型”统计单位;否则回退到 this.scene.children
|
|
4857
|
+
// const children = (typeof this.modelGroup !== 'undefined' && this.modelGroup && this.modelGroup.children && this.modelGroup.children.length)
|
|
4858
|
+
// ? this.modelGroup.children
|
|
4859
|
+
// : this.scene.children;
|
|
4739
4860
|
|
|
4740
4861
|
// for (let i = 0; i < children.length; i++) {
|
|
4741
4862
|
// const obj = children[i];
|
|
@@ -4762,29 +4883,29 @@ export default {
|
|
|
4762
4883
|
// if ((perfLogFrameCount++ % 120 === 0) || (Date.now() - lastPerfLogTime >= 3000)) {
|
|
4763
4884
|
// lastPerfLogTime = Date.now();
|
|
4764
4885
|
// console.log(`frame info`, {
|
|
4765
|
-
// drawCalls: renderer.info.render.calls,
|
|
4766
|
-
// triangles: renderer.info.render.triangles,
|
|
4767
|
-
// textures: renderer.info.memory.textures,
|
|
4886
|
+
// drawCalls: this.renderer.info.render.calls,
|
|
4887
|
+
// triangles: this.renderer.info.render.triangles,
|
|
4888
|
+
// textures: this.renderer.info.memory.textures,
|
|
4768
4889
|
// });
|
|
4769
4890
|
// }
|
|
4770
4891
|
// }
|
|
4771
4892
|
|
|
4772
|
-
// renderer.setRenderTarget(null)
|
|
4773
|
-
timeStamp = timeStamp % singleFrameTime;
|
|
4893
|
+
// this.renderer.setRenderTarget(null)
|
|
4894
|
+
this.timeStamp = this.timeStamp % singleFrameTime;
|
|
4774
4895
|
}
|
|
4775
4896
|
|
|
4776
4897
|
if (isDebug) {
|
|
4777
|
-
stats && stats.end(); // 结束帧率统计
|
|
4898
|
+
this.stats && this.stats.end(); // 结束帧率统计
|
|
4778
4899
|
}
|
|
4779
4900
|
},
|
|
4780
4901
|
// 暴露个别参数让业务自己做特殊业务。
|
|
4781
4902
|
// 后续若多个业务有相同使用场景,再抽象至公共组件中。
|
|
4782
4903
|
exportParmas() {
|
|
4783
4904
|
return {
|
|
4784
|
-
renderer,
|
|
4785
|
-
camera,
|
|
4786
|
-
cameraControls,
|
|
4787
|
-
scene,
|
|
4905
|
+
renderer: this.renderer,
|
|
4906
|
+
camera: this.camera,
|
|
4907
|
+
cameraControls: this.cameraControls,
|
|
4908
|
+
scene: this.scene,
|
|
4788
4909
|
};
|
|
4789
4910
|
},
|
|
4790
4911
|
isSourceVisible(instanceId, object) {
|
|
@@ -4828,14 +4949,14 @@ export default {
|
|
|
4828
4949
|
return true;
|
|
4829
4950
|
},
|
|
4830
4951
|
removeOutlineObject(object, instanceIndex) {
|
|
4831
|
-
if (!outlinePass || !object) return;
|
|
4952
|
+
if (!this.outlinePass || !object) return;
|
|
4832
4953
|
if (object.isInstancedMesh) {
|
|
4833
4954
|
this.removeOutlineInstanceProxy(object, instanceIndex);
|
|
4834
4955
|
return;
|
|
4835
4956
|
}
|
|
4836
4957
|
|
|
4837
|
-
const idx = outlinePass.selectedObjects.indexOf(object);
|
|
4838
|
-
if (idx !== -1) outlinePass.selectedObjects.splice(idx, 1);
|
|
4958
|
+
const idx = this.outlinePass.selectedObjects.indexOf(object);
|
|
4959
|
+
if (idx !== -1) this.outlinePass.selectedObjects.splice(idx, 1);
|
|
4839
4960
|
},
|
|
4840
4961
|
|
|
4841
4962
|
/**
|
|
@@ -4853,9 +4974,9 @@ export default {
|
|
|
4853
4974
|
};
|
|
4854
4975
|
const { left, right, middle } = btn;
|
|
4855
4976
|
|
|
4856
|
-
left && (cameraControls.mouseButtons.left = ACTION_ENUM[left]);
|
|
4857
|
-
right && (cameraControls.mouseButtons.right = ACTION_ENUM[right]);
|
|
4858
|
-
middle && (cameraControls.mouseButtons.middle = ACTION_ENUM[middle]);
|
|
4977
|
+
left && (this.cameraControls.mouseButtons.left = ACTION_ENUM[left]);
|
|
4978
|
+
right && (this.cameraControls.mouseButtons.right = ACTION_ENUM[right]);
|
|
4979
|
+
middle && (this.cameraControls.mouseButtons.middle = ACTION_ENUM[middle]);
|
|
4859
4980
|
},
|
|
4860
4981
|
|
|
4861
4982
|
// 分帧加载相关方法
|
|
@@ -4899,8 +5020,8 @@ export default {
|
|
|
4899
5020
|
|
|
4900
5021
|
// 去重处理
|
|
4901
5022
|
// const existingDrawObjectIds = new Set();
|
|
4902
|
-
// if (modelGroup && modelGroup.children && modelGroup.children.length) {
|
|
4903
|
-
// modelGroup.children.forEach(child => {
|
|
5023
|
+
// if (this.modelGroup && this.modelGroup.children && this.modelGroup.children.length) {
|
|
5024
|
+
// this.modelGroup.children.forEach(child => {
|
|
4904
5025
|
// if (child && child.userData && child.userData.isInstancedMeshGroup && child.name) {
|
|
4905
5026
|
// existingDrawObjectIds.add(child.name);
|
|
4906
5027
|
// }
|
|
@@ -5107,11 +5228,11 @@ export default {
|
|
|
5107
5228
|
|
|
5108
5229
|
isDebug && performance.mark('handleInstancedMeshModel-start');
|
|
5109
5230
|
await handleInstancedMeshModel(
|
|
5110
|
-
modelGroup,
|
|
5231
|
+
this.modelGroup,
|
|
5111
5232
|
batch.instances,
|
|
5112
5233
|
batch.drawObjs,
|
|
5113
5234
|
'',
|
|
5114
|
-
scene,
|
|
5235
|
+
this.scene,
|
|
5115
5236
|
loadingState.color,
|
|
5116
5237
|
loadingState.meshNameConfig,
|
|
5117
5238
|
'',
|
|
@@ -5135,31 +5256,31 @@ export default {
|
|
|
5135
5256
|
: this.batchLoadingState;
|
|
5136
5257
|
if (!loadingState.isLoading) return;
|
|
5137
5258
|
|
|
5138
|
-
// if (modelGroup) {
|
|
5259
|
+
// if (this.modelGroup) {
|
|
5139
5260
|
// if (firstDraw) {
|
|
5140
|
-
// if (scene) scene.add(modelGroup);
|
|
5261
|
+
// if (this.scene) this.scene.add(this.modelGroup);
|
|
5141
5262
|
// firstDraw = false;
|
|
5142
5263
|
// }
|
|
5143
5264
|
// if (!rotatedSceneFlag) {
|
|
5144
5265
|
// rotatedSceneFlag = true;
|
|
5145
5266
|
// }
|
|
5146
|
-
if (modelGroup) {
|
|
5147
|
-
if (!modelGroup.userData.initDone) {
|
|
5148
|
-
scene.add(modelGroup);
|
|
5149
|
-
modelGroup.applyMatrix4(bizToThreeMatrix);
|
|
5150
|
-
modelGroup.updateMatrixWorld();
|
|
5151
|
-
this.smartModelCenter(sceneBoundingBox);
|
|
5267
|
+
if (this.modelGroup) {
|
|
5268
|
+
if (!this.modelGroup.userData.initDone) {
|
|
5269
|
+
this.scene.add(this.modelGroup);
|
|
5270
|
+
this.modelGroup.applyMatrix4(this.bizToThreeMatrix);
|
|
5271
|
+
this.modelGroup.updateMatrixWorld();
|
|
5272
|
+
this.smartModelCenter(this.sceneBoundingBox);
|
|
5152
5273
|
this.setCameraConfig();
|
|
5153
|
-
modelGroup.userData.initDone = true;
|
|
5274
|
+
this.modelGroup.userData.initDone = true;
|
|
5154
5275
|
}
|
|
5155
|
-
modelGroup.updateMatrixWorld();
|
|
5276
|
+
this.modelGroup.updateMatrixWorld();
|
|
5156
5277
|
let modelBox3 = new this.THREE.Box3();
|
|
5157
|
-
modelBox3.expandByObject(modelGroup);
|
|
5278
|
+
modelBox3.expandByObject(this.modelGroup);
|
|
5158
5279
|
let modelWorldPs = new this.THREE.Vector3()
|
|
5159
5280
|
.addVectors(modelBox3.max, modelBox3.min)
|
|
5160
5281
|
.multiplyScalar(0.5);
|
|
5161
|
-
modelGroup.userData.modelWorldPs = modelWorldPs;
|
|
5162
|
-
modelGroup.traverse(child => {
|
|
5282
|
+
this.modelGroup.userData.modelWorldPs = modelWorldPs;
|
|
5283
|
+
this.modelGroup.traverse(child => {
|
|
5163
5284
|
if (child.isMesh && !child.userData.batchInitDone) {
|
|
5164
5285
|
markRendered(child);
|
|
5165
5286
|
const json = this.getMeshCenterAndVolume(child);
|
|
@@ -5204,7 +5325,7 @@ export default {
|
|
|
5204
5325
|
|
|
5205
5326
|
if (isDebug) {
|
|
5206
5327
|
var axesHelper = new this.THREE.AxesHelper(10000);
|
|
5207
|
-
scene.add(axesHelper);
|
|
5328
|
+
this.scene.add(axesHelper);
|
|
5208
5329
|
}
|
|
5209
5330
|
// this.showSceneBoundingBox();
|
|
5210
5331
|
}
|
|
@@ -5245,8 +5366,8 @@ export default {
|
|
|
5245
5366
|
}
|
|
5246
5367
|
|
|
5247
5368
|
// 如果是第一次调用drawModel且用户正在交互,标记需要在交互结束后居中
|
|
5248
|
-
if (modelGroups.length === 0 && userInteracting) {
|
|
5249
|
-
needsCenteringAfterInteraction = true;
|
|
5369
|
+
if (this.modelGroups.length === 0 && this.userInteracting) {
|
|
5370
|
+
this.needsCenteringAfterInteraction = true;
|
|
5250
5371
|
}
|
|
5251
5372
|
|
|
5252
5373
|
// 启动分帧加载
|
|
@@ -5256,7 +5377,7 @@ export default {
|
|
|
5256
5377
|
/**
|
|
5257
5378
|
* 统一的中断控制中心 - 设置中断状态
|
|
5258
5379
|
* @param {boolean} active - 是否激活中断
|
|
5259
|
-
* @param {string} reason - 中断原因 ('wheel', 'camera', 'user_interaction' 等)
|
|
5380
|
+
* @param {string} reason - 中断原因 ('wheel', 'this.camera', 'user_interaction' 等)
|
|
5260
5381
|
* @param {Object} options - 配置项 { immediate: boolean }
|
|
5261
5382
|
*/
|
|
5262
5383
|
setSystemInterruption(active, reason = 'user_interaction', options = {}) {
|
|
@@ -5269,8 +5390,8 @@ export default {
|
|
|
5269
5390
|
|
|
5270
5391
|
// 1. 更新交互状态标记
|
|
5271
5392
|
// 如果是相机操作,更新全局标记
|
|
5272
|
-
if (reason === 'camera') {
|
|
5273
|
-
userInteracting = true;
|
|
5393
|
+
if (reason === 'this.camera') {
|
|
5394
|
+
this.userInteracting = true;
|
|
5274
5395
|
}
|
|
5275
5396
|
|
|
5276
5397
|
// 更新 batchLoadingState 中的交互状态
|
|
@@ -5287,8 +5408,8 @@ export default {
|
|
|
5287
5408
|
loadingState.pauseReason = reason;
|
|
5288
5409
|
|
|
5289
5410
|
// 交互期间强制跳过渲染帧,提升响应速度
|
|
5290
|
-
forceSkipRendering = true;
|
|
5291
|
-
skipNextRenderFrame = true;
|
|
5411
|
+
this.forceSkipRendering = true;
|
|
5412
|
+
this.skipNextRenderFrame = true;
|
|
5292
5413
|
|
|
5293
5414
|
// 3. 清理之前的恢复定时器(防止在交互中途意外恢复)
|
|
5294
5415
|
if (loadingState.resumeTimer) {
|
|
@@ -5314,8 +5435,8 @@ export default {
|
|
|
5314
5435
|
|
|
5315
5436
|
// 关键修复:立即更新交互状态,不依赖 doResume 的执行时机
|
|
5316
5437
|
// 这样可以避免当一种交互(如 camera)结束但另一种(如 wheel)仍活跃时,状态无法正确复位的问题
|
|
5317
|
-
if (reason === 'camera') {
|
|
5318
|
-
userInteracting = false;
|
|
5438
|
+
if (reason === 'this.camera') {
|
|
5439
|
+
this.userInteracting = false;
|
|
5319
5440
|
}
|
|
5320
5441
|
|
|
5321
5442
|
// 定义恢复执行逻辑
|
|
@@ -5324,11 +5445,11 @@ export default {
|
|
|
5324
5445
|
// 1. 如果有滚轮定时器未结束,说明还在连续滚动中,不恢复
|
|
5325
5446
|
if (loadingState.interactionState.wheelTimeout) return;
|
|
5326
5447
|
|
|
5327
|
-
// 2. 如果是 wheel 结束,但 userInteracting (camera) 还在进行,则不恢复
|
|
5328
|
-
if (reason === 'wheel' && userInteracting) return;
|
|
5448
|
+
// 2. 如果是 wheel 结束,但 this.userInteracting (this.camera) 还在进行,则不恢复
|
|
5449
|
+
if (reason === 'wheel' && this.userInteracting) return;
|
|
5329
5450
|
|
|
5330
5451
|
// 3. 检查是否有强制跳过标记 (可能由其他逻辑触发)
|
|
5331
|
-
// if (forceSkipRendering && reason !== 'user_interaction') return; // 视情况而定
|
|
5452
|
+
// if (this.forceSkipRendering && reason !== 'user_interaction') return; // 视情况而定
|
|
5332
5453
|
|
|
5333
5454
|
// --- 执行恢复 ---
|
|
5334
5455
|
|
|
@@ -5338,7 +5459,7 @@ export default {
|
|
|
5338
5459
|
loadingState.interactionState.isInteracting = false;
|
|
5339
5460
|
loadingState.interactionState.interactionType = '';
|
|
5340
5461
|
|
|
5341
|
-
forceSkipRendering = false;
|
|
5462
|
+
this.forceSkipRendering = false;
|
|
5342
5463
|
|
|
5343
5464
|
// 恢复本地批量加载 (如果未完成)
|
|
5344
5465
|
if (loadingState.isLoading && loadingState.currentBatch < loadingState.totalBatches) {
|
|
@@ -5383,7 +5504,8 @@ export default {
|
|
|
5383
5504
|
* 交互开始
|
|
5384
5505
|
*/
|
|
5385
5506
|
beginInteraction(type = 'user') {
|
|
5386
|
-
const reason =
|
|
5507
|
+
const reason =
|
|
5508
|
+
type === 'wheel' ? 'wheel' : type === 'this.camera' ? 'this.camera' : 'user_interaction';
|
|
5387
5509
|
this.setSystemInterruption(true, reason);
|
|
5388
5510
|
},
|
|
5389
5511
|
|
|
@@ -5440,10 +5562,10 @@ export default {
|
|
|
5440
5562
|
* 隐藏场景包围盒
|
|
5441
5563
|
*/
|
|
5442
5564
|
hideSceneBoundingBox() {
|
|
5443
|
-
if (sceneBoundingBoxHelper && scene) {
|
|
5444
|
-
scene.remove(sceneBoundingBoxHelper);
|
|
5445
|
-
sceneBoundingBoxHelper = null;
|
|
5446
|
-
boundingBoxVisible = false;
|
|
5565
|
+
if (this.sceneBoundingBoxHelper && this.scene) {
|
|
5566
|
+
this.scene.remove(this.sceneBoundingBoxHelper);
|
|
5567
|
+
this.sceneBoundingBoxHelper = null;
|
|
5568
|
+
this.boundingBoxVisible = false;
|
|
5447
5569
|
console.log('场景包围盒已隐藏');
|
|
5448
5570
|
}
|
|
5449
5571
|
},
|
|
@@ -5452,7 +5574,7 @@ export default {
|
|
|
5452
5574
|
* 切换场景包围盒显示状态
|
|
5453
5575
|
*/
|
|
5454
5576
|
toggleSceneBoundingBox() {
|
|
5455
|
-
if (boundingBoxVisible) {
|
|
5577
|
+
if (this.boundingBoxVisible) {
|
|
5456
5578
|
this.hideSceneBoundingBox();
|
|
5457
5579
|
} else {
|
|
5458
5580
|
this.showSceneBoundingBox();
|
|
@@ -5462,7 +5584,12 @@ export default {
|
|
|
5462
5584
|
};
|
|
5463
5585
|
</script>
|
|
5464
5586
|
<style lang="scss" scoped>
|
|
5465
|
-
#fl-model {
|
|
5587
|
+
// #fl-model {
|
|
5588
|
+
// width: 100%;
|
|
5589
|
+
// height: 100%;
|
|
5590
|
+
// cursor: pointer;
|
|
5591
|
+
// }
|
|
5592
|
+
.fl-model-containor {
|
|
5466
5593
|
width: 100%;
|
|
5467
5594
|
height: 100%;
|
|
5468
5595
|
cursor: pointer;
|
|
@@ -5564,7 +5691,7 @@ export default {
|
|
|
5564
5691
|
margin-bottom: 20px;
|
|
5565
5692
|
}
|
|
5566
5693
|
|
|
5567
|
-
.loading-progress-bar {
|
|
5694
|
+
.loading-this.progress-bar {
|
|
5568
5695
|
width: 100%;
|
|
5569
5696
|
height: 8px;
|
|
5570
5697
|
background-color: #f0f0f0;
|
|
@@ -5573,7 +5700,7 @@ export default {
|
|
|
5573
5700
|
margin-bottom: 15px;
|
|
5574
5701
|
}
|
|
5575
5702
|
|
|
5576
|
-
.loading-progress-fill {
|
|
5703
|
+
.loading-this.progress-fill {
|
|
5577
5704
|
height: 100%;
|
|
5578
5705
|
background: linear-gradient(90deg, #409eff 0%, #67c23a 100%);
|
|
5579
5706
|
border-radius: 4px;
|
|
@@ -5588,7 +5715,7 @@ export default {
|
|
|
5588
5715
|
</style>
|
|
5589
5716
|
<style>
|
|
5590
5717
|
/* 自定义lil-gui样式 - 浅色主题 */
|
|
5591
|
-
.lil-gui {
|
|
5718
|
+
.lil-this.gui {
|
|
5592
5719
|
background: rgba(255, 255, 255, 0.95) !important;
|
|
5593
5720
|
border: 1px solid #e0e0e0 !important;
|
|
5594
5721
|
border-radius: 8px !important;
|
|
@@ -5597,7 +5724,7 @@ export default {
|
|
|
5597
5724
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
|
|
5598
5725
|
}
|
|
5599
5726
|
|
|
5600
|
-
.lil-gui .title {
|
|
5727
|
+
.lil-this.gui .title {
|
|
5601
5728
|
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%) !important;
|
|
5602
5729
|
color: #495057 !important;
|
|
5603
5730
|
border-bottom: 1px solid #dee2e6 !important;
|
|
@@ -5606,50 +5733,50 @@ export default {
|
|
|
5606
5733
|
border-radius: 8px 8px 0 0 !important;
|
|
5607
5734
|
}
|
|
5608
5735
|
|
|
5609
|
-
.lil-gui .controller {
|
|
5736
|
+
.lil-this.gui .controller {
|
|
5610
5737
|
border-bottom: 1px solid #f1f3f4 !important;
|
|
5611
5738
|
background: transparent !important;
|
|
5612
5739
|
}
|
|
5613
5740
|
|
|
5614
|
-
.lil-gui .controller:last-child {
|
|
5741
|
+
.lil-this.gui .controller:last-child {
|
|
5615
5742
|
border-bottom: none !important;
|
|
5616
5743
|
}
|
|
5617
5744
|
|
|
5618
|
-
.lil-gui .controller .name {
|
|
5745
|
+
.lil-this.gui .controller .name {
|
|
5619
5746
|
color: #495057 !important;
|
|
5620
5747
|
font-weight: 500 !important;
|
|
5621
5748
|
font-size: 12px !important;
|
|
5622
5749
|
}
|
|
5623
5750
|
|
|
5624
|
-
.lil-gui .controller .widget {
|
|
5751
|
+
.lil-this.gui .controller .widget {
|
|
5625
5752
|
background: #f8f9fa !important;
|
|
5626
5753
|
border: 1px solid #ced4da !important;
|
|
5627
5754
|
border-radius: 4px !important;
|
|
5628
5755
|
color: #495057 !important;
|
|
5629
5756
|
}
|
|
5630
5757
|
|
|
5631
|
-
.lil-gui .controller .widget:hover {
|
|
5758
|
+
.lil-this.gui .controller .widget:hover {
|
|
5632
5759
|
border-color: #80bdff !important;
|
|
5633
5760
|
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25) !important;
|
|
5634
5761
|
}
|
|
5635
5762
|
|
|
5636
|
-
.lil-gui .controller .widget:focus {
|
|
5763
|
+
.lil-this.gui .controller .widget:focus {
|
|
5637
5764
|
border-color: #80bdff !important;
|
|
5638
5765
|
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25) !important;
|
|
5639
5766
|
outline: none !important;
|
|
5640
5767
|
}
|
|
5641
5768
|
|
|
5642
|
-
.lil-gui .controller input[type='range'] {
|
|
5769
|
+
.lil-this.gui .controller input[type='range'] {
|
|
5643
5770
|
background: #e9ecef !important;
|
|
5644
5771
|
height: 4px !important;
|
|
5645
5772
|
-webkit-appearance: none !important;
|
|
5646
5773
|
appearance: none !important;
|
|
5647
5774
|
border-radius: 2px !important;
|
|
5648
5775
|
}
|
|
5649
|
-
.lil-gui .controller.number .fill {
|
|
5776
|
+
.lil-this.gui .controller.number .fill {
|
|
5650
5777
|
border-right: solid #008de9;
|
|
5651
5778
|
}
|
|
5652
|
-
.lil-gui .controller input[type='range']::-webkit-slider-thumb {
|
|
5779
|
+
.lil-this.gui .controller input[type='range']::-webkit-slider-thumb {
|
|
5653
5780
|
background: #007bff !important;
|
|
5654
5781
|
border: 2px solid #ffffff !important;
|
|
5655
5782
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2) !important;
|
|
@@ -5661,7 +5788,7 @@ export default {
|
|
|
5661
5788
|
cursor: pointer !important;
|
|
5662
5789
|
}
|
|
5663
5790
|
|
|
5664
|
-
.lil-gui .controller input[type='range']::-moz-range-thumb {
|
|
5791
|
+
.lil-this.gui .controller input[type='range']::-moz-range-thumb {
|
|
5665
5792
|
background: #007bff !important;
|
|
5666
5793
|
border: 2px solid #ffffff !important;
|
|
5667
5794
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2) !important;
|
|
@@ -5671,23 +5798,23 @@ export default {
|
|
|
5671
5798
|
cursor: pointer !important;
|
|
5672
5799
|
}
|
|
5673
5800
|
|
|
5674
|
-
.lil-gui .controller .option {
|
|
5801
|
+
.lil-this.gui .controller .option {
|
|
5675
5802
|
background: #ffffff !important;
|
|
5676
5803
|
color: #495057 !important;
|
|
5677
5804
|
border-bottom: 1px solid #f1f3f4 !important;
|
|
5678
5805
|
}
|
|
5679
5806
|
|
|
5680
|
-
.lil-gui .controller .option:hover {
|
|
5807
|
+
.lil-this.gui .controller .option:hover {
|
|
5681
5808
|
background: #f8f9fa !important;
|
|
5682
5809
|
}
|
|
5683
5810
|
|
|
5684
|
-
.lil-gui .controller .option:last-child {
|
|
5811
|
+
.lil-this.gui .controller .option:last-child {
|
|
5685
5812
|
border-bottom: none !important;
|
|
5686
5813
|
}
|
|
5687
|
-
.lil-gui input:active {
|
|
5814
|
+
.lil-this.gui input:active {
|
|
5688
5815
|
background: #e6eff4;
|
|
5689
5816
|
}
|
|
5690
|
-
.lil-gui .controller button {
|
|
5817
|
+
.lil-this.gui .controller button {
|
|
5691
5818
|
background: linear-gradient(135deg, #007bff 0%, #0056b3 100%) !important;
|
|
5692
5819
|
color: #ffffff !important;
|
|
5693
5820
|
border: none !important;
|
|
@@ -5696,51 +5823,51 @@ export default {
|
|
|
5696
5823
|
transition: all 0.2s ease !important;
|
|
5697
5824
|
}
|
|
5698
5825
|
|
|
5699
|
-
.lil-gui .controller button:hover {
|
|
5826
|
+
.lil-this.gui .controller button:hover {
|
|
5700
5827
|
background: linear-gradient(135deg, #0056b3 0%, #004085 100%) !important;
|
|
5701
5828
|
transform: translateY(-1px) !important;
|
|
5702
5829
|
box-shadow: 0 4px 8px rgba(0, 123, 255, 0.3) !important;
|
|
5703
5830
|
}
|
|
5704
5831
|
|
|
5705
|
-
.lil-gui .controller .color {
|
|
5832
|
+
.lil-this.gui .controller .color {
|
|
5706
5833
|
border: 2px solid #ffffff !important;
|
|
5707
5834
|
border-radius: 4px !important;
|
|
5708
5835
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important;
|
|
5709
5836
|
}
|
|
5710
|
-
.lil-gui .controller.number .slider {
|
|
5837
|
+
.lil-this.gui .controller.number .slider {
|
|
5711
5838
|
background-color: #e6eff4;
|
|
5712
5839
|
}
|
|
5713
|
-
.lil-gui .controller.number .slider:hover {
|
|
5840
|
+
.lil-this.gui .controller.number .slider:hover {
|
|
5714
5841
|
background-color: #e6eff4;
|
|
5715
5842
|
}
|
|
5716
|
-
.lil-gui input:hover {
|
|
5843
|
+
.lil-this.gui input:hover {
|
|
5717
5844
|
background: #e6eff4;
|
|
5718
5845
|
}
|
|
5719
|
-
.lil-gui input[type='number']:focus,
|
|
5720
|
-
.lil-gui input[type='text']:focus,
|
|
5721
|
-
.lil-gui input {
|
|
5846
|
+
.lil-this.gui input[type='number']:focus,
|
|
5847
|
+
.lil-this.gui input[type='text']:focus,
|
|
5848
|
+
.lil-this.gui input {
|
|
5722
5849
|
background: #e6eff4;
|
|
5723
5850
|
}
|
|
5724
|
-
.lil-gui .controller > .name {
|
|
5851
|
+
.lil-this.gui .controller > .name {
|
|
5725
5852
|
min-width: 25px;
|
|
5726
5853
|
}
|
|
5727
|
-
.lil-gui .controller.number input {
|
|
5854
|
+
.lil-this.gui .controller.number input {
|
|
5728
5855
|
color: #2e3136;
|
|
5729
5856
|
}
|
|
5730
|
-
.lil-gui .controller.number .slider:active {
|
|
5857
|
+
.lil-this.gui .controller.number .slider:active {
|
|
5731
5858
|
background-color: #e6eff4;
|
|
5732
5859
|
}
|
|
5733
|
-
.lil-gui .folder > .title {
|
|
5860
|
+
.lil-this.gui .folder > .title {
|
|
5734
5861
|
background: linear-gradient(135deg, #f1f3f4 0%, #e9ecef 100%) !important;
|
|
5735
5862
|
color: #495057 !important;
|
|
5736
5863
|
border-bottom: 1px solid #dee2e6 !important;
|
|
5737
5864
|
}
|
|
5738
5865
|
|
|
5739
|
-
.lil-gui .folder > .title:before {
|
|
5866
|
+
.lil-this.gui .folder > .title:before {
|
|
5740
5867
|
color: #6c757d !important;
|
|
5741
5868
|
}
|
|
5742
5869
|
|
|
5743
|
-
.lil-gui .folder.closed > .children {
|
|
5870
|
+
.lil-this.gui .folder.closed > .children {
|
|
5744
5871
|
display: none !important;
|
|
5745
5872
|
}
|
|
5746
5873
|
</style>
|