fl-web-component 1.1.9 → 1.1.11
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 +4 -0
- package/dist/fl-web-component.common.js +103 -59
- package/dist/fl-web-component.css +1 -1
- package/package.json +1 -1
- package/packages/components/com-graphics/index.vue +225 -152
- package/src/utils/flgltf-parser.js +2 -2
- package/src/utils/instance-parser.js +81 -18
- package/src/utils/mock.js +9813 -10
|
@@ -21,7 +21,11 @@
|
|
|
21
21
|
threeMeasure,
|
|
22
22
|
modelGroup,
|
|
23
23
|
gui,
|
|
24
|
-
animateId,
|
|
24
|
+
animateId,
|
|
25
|
+
scenePass,
|
|
26
|
+
outlineComposer,
|
|
27
|
+
renderTarget,
|
|
28
|
+
sceneClock,
|
|
25
29
|
] = (function* (v) {
|
|
26
30
|
while (true) yield v;
|
|
27
31
|
})(null);
|
|
@@ -48,19 +52,21 @@
|
|
|
48
52
|
while (true) yield v;
|
|
49
53
|
})(true);
|
|
50
54
|
|
|
51
|
-
var clippingMesh = [],
|
|
55
|
+
var clippingMesh = [],
|
|
56
|
+
modelActive = [],
|
|
57
|
+
modelActions = [];
|
|
52
58
|
var removeSpeed = 200,
|
|
53
59
|
upSpeed = 200; //控制器移动速度 , //控制跳起时的速度
|
|
54
60
|
var roamConfig = {
|
|
55
61
|
loop: false,
|
|
56
62
|
speed: 0, // 最大值为3
|
|
57
|
-
name: ''
|
|
58
|
-
}
|
|
63
|
+
name: '',
|
|
64
|
+
};
|
|
59
65
|
var guiParams = {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
66
|
+
x轴: 0,
|
|
67
|
+
y轴: 0,
|
|
68
|
+
z轴: 0,
|
|
69
|
+
};
|
|
64
70
|
// 绘制对象映射实例表
|
|
65
71
|
import CameraControls from 'camera-controls';
|
|
66
72
|
import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment.js';
|
|
@@ -68,7 +74,7 @@
|
|
|
68
74
|
import { CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer';
|
|
69
75
|
import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls.js';
|
|
70
76
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
|
71
|
-
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'
|
|
77
|
+
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';
|
|
72
78
|
import MeasureDistance from '@/utils/threejs/measure-distance.js';
|
|
73
79
|
import MeasureArea from '@/utils/threejs/measure-area.js';
|
|
74
80
|
import MeasureAngle from '@/utils/threejs/measure-angle.js';
|
|
@@ -90,8 +96,7 @@
|
|
|
90
96
|
},
|
|
91
97
|
},
|
|
92
98
|
data() {
|
|
93
|
-
return {
|
|
94
|
-
};
|
|
99
|
+
return {};
|
|
95
100
|
},
|
|
96
101
|
created() {
|
|
97
102
|
CameraControls.install({ THREE: this.THREE });
|
|
@@ -103,8 +108,8 @@
|
|
|
103
108
|
minFilter: this.THREE.LinearFilter,
|
|
104
109
|
magFilter: this.THREE.LinearFilter,
|
|
105
110
|
format: this.THREE.RGBAFormat,
|
|
106
|
-
stencilBuffer: true
|
|
107
|
-
})
|
|
111
|
+
stencilBuffer: true,
|
|
112
|
+
});
|
|
108
113
|
},
|
|
109
114
|
mounted() {
|
|
110
115
|
instructions = document.getElementById('fl-model');
|
|
@@ -147,7 +152,7 @@
|
|
|
147
152
|
45,
|
|
148
153
|
window.innerWidth / window.innerHeight,
|
|
149
154
|
0.1,
|
|
150
|
-
|
|
155
|
+
100000
|
|
151
156
|
);
|
|
152
157
|
camera.position.set(0, 100, 150);
|
|
153
158
|
},
|
|
@@ -187,10 +192,19 @@
|
|
|
187
192
|
}
|
|
188
193
|
const { instances, drawObjs } = parseData(data);
|
|
189
194
|
if (instances.length > 0) {
|
|
190
|
-
modelGroup = handleInstancedMeshModel(
|
|
195
|
+
modelGroup = handleInstancedMeshModel(
|
|
196
|
+
instances,
|
|
197
|
+
drawObjs,
|
|
198
|
+
'',
|
|
199
|
+
scene,
|
|
200
|
+
color,
|
|
201
|
+
meshNameConfig
|
|
202
|
+
);
|
|
191
203
|
let modelBox3 = new this.THREE.Box3();
|
|
192
204
|
modelBox3.expandByObject(modelGroup);
|
|
193
|
-
let modelWorldPs = new this.THREE.Vector3()
|
|
205
|
+
let modelWorldPs = new this.THREE.Vector3()
|
|
206
|
+
.addVectors(modelBox3.max, modelBox3.min)
|
|
207
|
+
.multiplyScalar(0.5);
|
|
194
208
|
scene.add(modelGroup);
|
|
195
209
|
// 适配客户端的坐标系,threejs坐标需绕x轴旋转90度
|
|
196
210
|
const mat4 = new this.THREE.Matrix4();
|
|
@@ -198,33 +212,37 @@
|
|
|
198
212
|
modelGroup.applyMatrix4(mat4);
|
|
199
213
|
modelGroup.traverse(child => {
|
|
200
214
|
if (child.isMesh) {
|
|
201
|
-
const json = this.getMeshCenterAndVolume(child)
|
|
215
|
+
const json = this.getMeshCenterAndVolume(child);
|
|
202
216
|
let meshBox3 = new this.THREE.Box3();
|
|
203
217
|
meshBox3.setFromObject(child);
|
|
204
218
|
// 获取每个mesh的中心点,爆炸方向为爆炸中心点指向mesh中心点
|
|
205
|
-
let worldPs = new this.THREE.Vector3()
|
|
206
|
-
|
|
219
|
+
let worldPs = new this.THREE.Vector3()
|
|
220
|
+
.addVectors(meshBox3.max, meshBox3.min)
|
|
221
|
+
.multiplyScalar(0.5);
|
|
222
|
+
if (isNaN(worldPs.x)) return;
|
|
207
223
|
// 计算爆炸方向
|
|
208
|
-
child.worldDir = new this.THREE.Vector3()
|
|
224
|
+
child.worldDir = new this.THREE.Vector3()
|
|
225
|
+
.subVectors(worldPs, modelWorldPs)
|
|
226
|
+
.normalize();
|
|
209
227
|
// 保存初始坐标
|
|
210
|
-
child.userData.center = json.center
|
|
211
|
-
child.userData.worldPs = worldPs
|
|
212
|
-
child.userData.oldPs = child.getWorldPosition(new this.THREE.Vector3())
|
|
213
|
-
child.userData.box = json.box
|
|
214
|
-
child.userData.position = new this.THREE.Vector3().copy(child.position)
|
|
228
|
+
child.userData.center = json.center;
|
|
229
|
+
child.userData.worldPs = worldPs;
|
|
230
|
+
child.userData.oldPs = child.getWorldPosition(new this.THREE.Vector3());
|
|
231
|
+
child.userData.box = json.box;
|
|
232
|
+
child.userData.position = new this.THREE.Vector3().copy(child.position);
|
|
215
233
|
child.userData.translate = {
|
|
216
234
|
x: 0,
|
|
217
235
|
y: 0,
|
|
218
|
-
z: 0
|
|
219
|
-
}
|
|
236
|
+
z: 0,
|
|
237
|
+
};
|
|
220
238
|
child.userData.rotate = {
|
|
221
239
|
x: 0,
|
|
222
240
|
y: 0,
|
|
223
|
-
z: 0
|
|
224
|
-
}
|
|
225
|
-
child.userData.modelWorldPs = modelWorldPs
|
|
241
|
+
z: 0,
|
|
242
|
+
};
|
|
243
|
+
child.userData.modelWorldPs = modelWorldPs;
|
|
226
244
|
}
|
|
227
|
-
})
|
|
245
|
+
});
|
|
228
246
|
// this.compileShader();
|
|
229
247
|
// cameraControls.fitToSphere(scene, true); // TODO 待处理,先用 setModelCenter 进行定位
|
|
230
248
|
this.setModelCenter(modelGroup);
|
|
@@ -233,15 +251,15 @@
|
|
|
233
251
|
},
|
|
234
252
|
// 获取mesh的中心点
|
|
235
253
|
getMeshCenterAndVolume(mesh) {
|
|
236
|
-
const box = new this.THREE.Box3().setFromObject(mesh)
|
|
237
|
-
const volume = box.getSize(new this.THREE.Vector3())
|
|
238
|
-
const geometry = mesh.geometry
|
|
239
|
-
geometry.computeBoundingBox()
|
|
240
|
-
const center = geometry.boundingBox.getCenter(new this.THREE.Vector3())
|
|
254
|
+
const box = new this.THREE.Box3().setFromObject(mesh);
|
|
255
|
+
const volume = box.getSize(new this.THREE.Vector3());
|
|
256
|
+
const geometry = mesh.geometry;
|
|
257
|
+
geometry.computeBoundingBox();
|
|
258
|
+
const center = geometry.boundingBox.getCenter(new this.THREE.Vector3());
|
|
241
259
|
return {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
}
|
|
260
|
+
center: center,
|
|
261
|
+
box: volume,
|
|
262
|
+
};
|
|
245
263
|
},
|
|
246
264
|
compileShader() {
|
|
247
265
|
scene.traverse(child => {
|
|
@@ -411,23 +429,34 @@
|
|
|
411
429
|
targetObj.forEach(children => {
|
|
412
430
|
const index = children.userData.instanceIndex;
|
|
413
431
|
if (ele.attr[key]) {
|
|
414
|
-
const restoreMatrix = new this.THREE.Matrix4().copy(
|
|
432
|
+
const restoreMatrix = new this.THREE.Matrix4().copy(
|
|
433
|
+
children.userData.copyMatrix
|
|
434
|
+
);
|
|
415
435
|
children.setMatrixAt(index, restoreMatrix);
|
|
416
436
|
} else {
|
|
417
|
-
const offsetMatrix = new this.THREE.Matrix4()
|
|
437
|
+
const offsetMatrix = new this.THREE.Matrix4()
|
|
438
|
+
.copy(children.userData.copyMatrix)
|
|
439
|
+
.makeTranslation(9999999, 9999999, 9999999);
|
|
418
440
|
children.setMatrixAt(index, offsetMatrix);
|
|
419
441
|
}
|
|
420
442
|
children.instanceMatrix.needsUpdate = true;
|
|
421
443
|
});
|
|
422
444
|
break;
|
|
423
445
|
case 'opacity':
|
|
424
|
-
obj.material.opacity = ele.attr[key];
|
|
425
|
-
obj.material.transparent = true;
|
|
446
|
+
// obj.material.opacity = ele.attr[key];
|
|
447
|
+
// obj.material.transparent = true;
|
|
448
|
+
targetObj.forEach(children => {
|
|
449
|
+
if (children.isMesh) {
|
|
450
|
+
const opacity = children.geometry.attributes.opacity.array;
|
|
451
|
+
opacity[children.userData.instanceIndex] = ele.attr[key];
|
|
452
|
+
children.geometry.attributes.opacity.needsUpdate = true;
|
|
453
|
+
}
|
|
454
|
+
});
|
|
426
455
|
break;
|
|
427
|
-
case 'position':
|
|
456
|
+
case 'position':
|
|
428
457
|
targetObj.forEach(children => {
|
|
429
|
-
children.position.set(ele.attr[key].x, ele.attr[key].y, ele.attr[key].z)
|
|
430
|
-
})
|
|
458
|
+
children.position.set(ele.attr[key].x, ele.attr[key].y, ele.attr[key].z);
|
|
459
|
+
});
|
|
431
460
|
break;
|
|
432
461
|
}
|
|
433
462
|
}
|
|
@@ -436,7 +465,7 @@
|
|
|
436
465
|
},
|
|
437
466
|
// 恢复模型原来的状态
|
|
438
467
|
updateWholeProperty() {
|
|
439
|
-
throw
|
|
468
|
+
throw new Error('该方法已暂停使用,请使用restore方法。');
|
|
440
469
|
// if (scene) {
|
|
441
470
|
// scene.traverse(obj => {
|
|
442
471
|
// if (obj instanceof this.THREE.Mesh) {
|
|
@@ -470,14 +499,25 @@
|
|
|
470
499
|
}
|
|
471
500
|
});
|
|
472
501
|
break;
|
|
473
|
-
case 'visible':
|
|
502
|
+
case 'visible':
|
|
474
503
|
obj.forEach(children => {
|
|
475
504
|
const index = children.userData.instanceIndex;
|
|
476
|
-
const restoreMatrix = new this.THREE.Matrix4().copy(
|
|
505
|
+
const restoreMatrix = new this.THREE.Matrix4().copy(
|
|
506
|
+
children.userData.copyMatrix
|
|
507
|
+
);
|
|
477
508
|
children.setMatrixAt(index, restoreMatrix);
|
|
478
|
-
children.instanceMatrix.needsUpdate = true
|
|
509
|
+
children.instanceMatrix.needsUpdate = true;
|
|
479
510
|
});
|
|
480
511
|
break;
|
|
512
|
+
case 'opacity':
|
|
513
|
+
obj.forEach(children => {
|
|
514
|
+
if (children.isMesh) {
|
|
515
|
+
const opacity = children.geometry.attributes.opacity.array;
|
|
516
|
+
opacity[children.userData.instanceIndex] =
|
|
517
|
+
children.material.userData.nOpacity;
|
|
518
|
+
children.geometry.attributes.opacity.needsUpdate = true;
|
|
519
|
+
}
|
|
520
|
+
});
|
|
481
521
|
}
|
|
482
522
|
}
|
|
483
523
|
}
|
|
@@ -515,7 +555,10 @@
|
|
|
515
555
|
for (const key in params.attr) {
|
|
516
556
|
switch (key) {
|
|
517
557
|
case 'color':
|
|
518
|
-
child.setColorAt(
|
|
558
|
+
child.setColorAt(
|
|
559
|
+
obj.userData.instanceIndex,
|
|
560
|
+
new this.THREE.Color(params.attr[key])
|
|
561
|
+
);
|
|
519
562
|
child.instanceColor.needsUpdate = true;
|
|
520
563
|
break;
|
|
521
564
|
case 'visible':
|
|
@@ -529,7 +572,7 @@
|
|
|
529
572
|
child.material.needsUpdate = true;
|
|
530
573
|
}
|
|
531
574
|
}
|
|
532
|
-
})
|
|
575
|
+
});
|
|
533
576
|
},
|
|
534
577
|
// 相机定位
|
|
535
578
|
/*
|
|
@@ -555,7 +598,9 @@
|
|
|
555
598
|
box: {x: 0, y: 0, z: 0}
|
|
556
599
|
*/
|
|
557
600
|
locateByCenterBox(center, box) {
|
|
558
|
-
let cameraCenter = new this.THREE.Vector3(center.x, center.y, center.z).addScalar(
|
|
601
|
+
let cameraCenter = new this.THREE.Vector3(center.x, center.y, center.z).addScalar(
|
|
602
|
+
Math.max(box.x, box.y, box.z)
|
|
603
|
+
);
|
|
559
604
|
cameraControls.setLookAt(
|
|
560
605
|
cameraCenter.x,
|
|
561
606
|
cameraCenter.y,
|
|
@@ -564,7 +609,7 @@
|
|
|
564
609
|
center.y,
|
|
565
610
|
center.z,
|
|
566
611
|
true
|
|
567
|
-
)
|
|
612
|
+
);
|
|
568
613
|
},
|
|
569
614
|
// 添加广告牌
|
|
570
615
|
/*
|
|
@@ -636,28 +681,28 @@
|
|
|
636
681
|
item.clear();
|
|
637
682
|
}
|
|
638
683
|
scene.remove(item);
|
|
639
|
-
})
|
|
640
|
-
scene.clear()
|
|
684
|
+
});
|
|
685
|
+
scene.clear();
|
|
641
686
|
}
|
|
642
687
|
},
|
|
643
688
|
// 销毁场景 释放内存
|
|
644
689
|
destroyScene() {
|
|
645
|
-
cancelAnimationFrame(animateId)
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
690
|
+
cancelAnimationFrame(animateId);
|
|
691
|
+
if (scene) {
|
|
692
|
+
scene.traverse(child => {
|
|
693
|
+
child.material && child.material.dispose();
|
|
694
|
+
child.geometry && child.geometry.dispose();
|
|
695
|
+
child = null;
|
|
696
|
+
});
|
|
697
|
+
scene.clear();
|
|
698
|
+
scene = null;
|
|
699
|
+
}
|
|
700
|
+
renderer.forceContextLoss();
|
|
701
|
+
renderer.dispose();
|
|
702
|
+
camera = null;
|
|
703
|
+
cameraControls = null;
|
|
704
|
+
renderer.domElement = null;
|
|
705
|
+
renderer = null;
|
|
661
706
|
},
|
|
662
707
|
// 绘制曲线
|
|
663
708
|
/*
|
|
@@ -724,7 +769,7 @@
|
|
|
724
769
|
clock = new this.THREE.Clock();
|
|
725
770
|
}
|
|
726
771
|
},
|
|
727
|
-
//
|
|
772
|
+
//
|
|
728
773
|
// 开启漫游
|
|
729
774
|
/*
|
|
730
775
|
参数为Object
|
|
@@ -738,12 +783,12 @@
|
|
|
738
783
|
roamConfig = {
|
|
739
784
|
loop: params.loop,
|
|
740
785
|
speed: params.speed,
|
|
741
|
-
|
|
786
|
+
};
|
|
742
787
|
this.drawTextureCurve({
|
|
743
788
|
name: params.name,
|
|
744
789
|
path: params.path,
|
|
745
790
|
});
|
|
746
|
-
roaming = true
|
|
791
|
+
roaming = true;
|
|
747
792
|
},
|
|
748
793
|
// 更新漫游的配置
|
|
749
794
|
/*
|
|
@@ -751,7 +796,7 @@
|
|
|
751
796
|
*/
|
|
752
797
|
updateRoamConfig(params) {
|
|
753
798
|
for (let key in params) {
|
|
754
|
-
roamConfig[key] = params[key]
|
|
799
|
+
roamConfig[key] = params[key];
|
|
755
800
|
}
|
|
756
801
|
},
|
|
757
802
|
// 结束/退出漫游
|
|
@@ -763,9 +808,9 @@
|
|
|
763
808
|
loop: false,
|
|
764
809
|
speed: 0,
|
|
765
810
|
name: '',
|
|
766
|
-
}
|
|
767
|
-
roaming = false
|
|
768
|
-
lineTexture = null
|
|
811
|
+
};
|
|
812
|
+
roaming = false;
|
|
813
|
+
lineTexture = null;
|
|
769
814
|
},
|
|
770
815
|
// 相机跟随轨道
|
|
771
816
|
cameraTrack() {
|
|
@@ -846,15 +891,19 @@
|
|
|
846
891
|
renderer.clippingPlanes = clippingPlanes;
|
|
847
892
|
if (flag) {
|
|
848
893
|
guiParams = {
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
}
|
|
853
|
-
this.addClippingGui(
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
894
|
+
x轴: clippingPlanes[0].constant,
|
|
895
|
+
y轴: clippingPlanes[2].constant,
|
|
896
|
+
z轴: clippingPlanes[1].constant,
|
|
897
|
+
};
|
|
898
|
+
this.addClippingGui(
|
|
899
|
+
'全局剖切',
|
|
900
|
+
{
|
|
901
|
+
x: min.x,
|
|
902
|
+
y: min.z,
|
|
903
|
+
z: min.y,
|
|
904
|
+
},
|
|
905
|
+
clippingPlanes
|
|
906
|
+
);
|
|
858
907
|
}
|
|
859
908
|
return {
|
|
860
909
|
min: min,
|
|
@@ -880,17 +929,17 @@
|
|
|
880
929
|
// 取消全局剖切
|
|
881
930
|
cancelGlobalClipping() {
|
|
882
931
|
guiParams = {
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
932
|
+
x轴: 0,
|
|
933
|
+
y轴: 0,
|
|
934
|
+
z轴: 0,
|
|
886
935
|
};
|
|
887
936
|
renderer.clippingPlanes = Object.freeze([]);
|
|
888
937
|
gui && gui.destroy();
|
|
889
938
|
},
|
|
890
939
|
// 单个实体的剖切/ 局部剖切 obj 实体对象 flag 代表是否使用图形组件自带的剖切面板 默认为true
|
|
891
940
|
setLocalClipping(obj, flag = true) {
|
|
892
|
-
clippingMesh.splice(0)
|
|
893
|
-
clippingMesh.push(obj)
|
|
941
|
+
clippingMesh.splice(0);
|
|
942
|
+
clippingMesh.push(obj);
|
|
894
943
|
renderer.localClippingEnabled = true;
|
|
895
944
|
// mesh的boundingBox 可以获取到该对象位置的最大最小值 但是在这里我们需要把y、z轴互换
|
|
896
945
|
const boundingBox = new this.THREE.Box3().copy(obj.boundingBox);
|
|
@@ -905,21 +954,25 @@
|
|
|
905
954
|
// 将局部剖切的对象记录下来
|
|
906
955
|
if (flag) {
|
|
907
956
|
guiParams = {
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
}
|
|
912
|
-
this.addClippingGui(
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
957
|
+
x轴: clippingPlanes[0].constant,
|
|
958
|
+
y轴: clippingPlanes[2].constant,
|
|
959
|
+
z轴: clippingPlanes[1].constant,
|
|
960
|
+
};
|
|
961
|
+
this.addClippingGui(
|
|
962
|
+
'局部剖切',
|
|
963
|
+
{
|
|
964
|
+
x: Math.floor(boundingBox.min.x),
|
|
965
|
+
y: Math.floor(boundingBox.min.z),
|
|
966
|
+
z: Math.floor(boundingBox.min.y),
|
|
967
|
+
},
|
|
968
|
+
obj.material.clippingPlanes
|
|
969
|
+
);
|
|
917
970
|
// cube.material.clippingPlanes
|
|
918
|
-
}
|
|
971
|
+
}
|
|
919
972
|
return {
|
|
920
973
|
min: boundingBox.min,
|
|
921
974
|
max: boundingBox.max,
|
|
922
|
-
}
|
|
975
|
+
};
|
|
923
976
|
},
|
|
924
977
|
// 更新局部剖切的值
|
|
925
978
|
/*
|
|
@@ -932,7 +985,7 @@
|
|
|
932
985
|
y: 1,
|
|
933
986
|
z: 2,
|
|
934
987
|
};
|
|
935
|
-
let obj = clippingMesh[clippingMesh.length - 1]
|
|
988
|
+
let obj = clippingMesh[clippingMesh.length - 1];
|
|
936
989
|
for (const key in params) {
|
|
937
990
|
obj.material.clippingPlanes[axis[key]].constant = params[key];
|
|
938
991
|
obj.material.needsUpdate = true;
|
|
@@ -942,33 +995,45 @@
|
|
|
942
995
|
// 取消局部/单个实体的剖切
|
|
943
996
|
cancelLocalClipping() {
|
|
944
997
|
guiParams = {
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
998
|
+
x轴: 0,
|
|
999
|
+
y轴: 0,
|
|
1000
|
+
z轴: 0,
|
|
948
1001
|
};
|
|
949
1002
|
gui && gui.destroy();
|
|
950
1003
|
clippingMesh.forEach(item => {
|
|
951
|
-
item.material.clippingPlanes = Object.freeze([])
|
|
952
|
-
item.material.needsUpdate = true
|
|
953
|
-
})
|
|
954
|
-
clippingMesh.splice(0)
|
|
1004
|
+
item.material.clippingPlanes = Object.freeze([]);
|
|
1005
|
+
item.material.needsUpdate = true;
|
|
1006
|
+
});
|
|
1007
|
+
clippingMesh.splice(0);
|
|
955
1008
|
},
|
|
956
1009
|
// 添加剖切轴工具
|
|
957
1010
|
addClippingGui(title, minValue, objClipp1, objClipp2) {
|
|
958
1011
|
gui = new GUI({
|
|
959
|
-
title: title
|
|
960
|
-
})
|
|
961
|
-
gui
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
gui
|
|
970
|
-
|
|
971
|
-
|
|
1012
|
+
title: title,
|
|
1013
|
+
});
|
|
1014
|
+
gui
|
|
1015
|
+
.add(guiParams, 'x轴')
|
|
1016
|
+
.min(minValue.x)
|
|
1017
|
+
.max(Math.abs(guiParams['x轴']))
|
|
1018
|
+
.onChange(d => {
|
|
1019
|
+
objClipp1[0].constant = d;
|
|
1020
|
+
objClipp2 && (objClipp2[0].constant = d);
|
|
1021
|
+
});
|
|
1022
|
+
gui
|
|
1023
|
+
.add(guiParams, 'y轴')
|
|
1024
|
+
.min(minValue.y)
|
|
1025
|
+
.max(Math.abs(guiParams['y轴']))
|
|
1026
|
+
.onChange(d => {
|
|
1027
|
+
objClipp1[2].constant = d;
|
|
1028
|
+
objClipp2 && (objClipp2[2].constant = d);
|
|
1029
|
+
});
|
|
1030
|
+
gui
|
|
1031
|
+
.add(guiParams, 'z轴')
|
|
1032
|
+
.min(minValue.z)
|
|
1033
|
+
.max(Math.abs(guiParams['z轴']))
|
|
1034
|
+
.onChange(d => {
|
|
1035
|
+
objClipp1[1].constant = d;
|
|
1036
|
+
});
|
|
972
1037
|
},
|
|
973
1038
|
// 开启第一视角
|
|
974
1039
|
startFirstPer() {
|
|
@@ -1123,7 +1188,7 @@
|
|
|
1123
1188
|
// 返回主视角/恢复相机初始状态
|
|
1124
1189
|
home() {
|
|
1125
1190
|
if (roaming) {
|
|
1126
|
-
this.endRoam()
|
|
1191
|
+
this.endRoam();
|
|
1127
1192
|
}
|
|
1128
1193
|
cameraControls.reset(true);
|
|
1129
1194
|
cameraControls.update(0);
|
|
@@ -1240,7 +1305,9 @@
|
|
|
1240
1305
|
// 隔离 将目标实体以外的实体隐藏掉
|
|
1241
1306
|
scene.traverse(item => {
|
|
1242
1307
|
if (item.isMesh && item.name !== object.name) {
|
|
1243
|
-
const offsetMatrix = new this.THREE.Matrix4()
|
|
1308
|
+
const offsetMatrix = new this.THREE.Matrix4()
|
|
1309
|
+
.copy(item.userData.copyMatrix)
|
|
1310
|
+
.makeTranslation(9999999, 9999999, 9999999);
|
|
1244
1311
|
item.setMatrixAt(item.userData.instanceIndex, offsetMatrix);
|
|
1245
1312
|
item.instanceMatrix.needsUpdate = true;
|
|
1246
1313
|
}
|
|
@@ -1282,30 +1349,30 @@
|
|
|
1282
1349
|
},
|
|
1283
1350
|
// 添加自定义模型, 暂时只支持glb、gltf格式
|
|
1284
1351
|
addCustomModel(name, position, url, scale = 1, immediately = false, callback) {
|
|
1285
|
-
const loader = new GLTFLoader()
|
|
1352
|
+
const loader = new GLTFLoader();
|
|
1286
1353
|
let locationModel = null;
|
|
1287
|
-
loader.load(url,
|
|
1288
|
-
locationModel = gltf.scene
|
|
1289
|
-
locationModel.scale.set(scale, scale, scale)
|
|
1290
|
-
locationModel.updateMatrixWorld()
|
|
1354
|
+
loader.load(url, gltf => {
|
|
1355
|
+
locationModel = gltf.scene;
|
|
1356
|
+
locationModel.scale.set(scale, scale, scale);
|
|
1357
|
+
locationModel.updateMatrixWorld();
|
|
1291
1358
|
if (immediately) {
|
|
1292
|
-
cameraControls.fitToSphere(gltf.scene, true)
|
|
1359
|
+
cameraControls.fitToSphere(gltf.scene, true);
|
|
1293
1360
|
}
|
|
1294
1361
|
// 动画混合器
|
|
1295
1362
|
// 不参与裁剪
|
|
1296
1363
|
locationModel.userData.cull = false;
|
|
1297
1364
|
locationModel.name = name;
|
|
1298
|
-
scene.add(locationModel)
|
|
1299
|
-
locationModel.position.copy(new this.THREE.Vector3(position.x, position.y, position.z))
|
|
1365
|
+
scene.add(locationModel);
|
|
1366
|
+
locationModel.position.copy(new this.THREE.Vector3(position.x, position.y, position.z));
|
|
1300
1367
|
if (gltf.animations.length > 0) {
|
|
1301
1368
|
let actionMixer = new this.THREE.AnimationMixer(gltf.scene);
|
|
1302
|
-
const walkActive = actionMixer.clipAction(gltf.animations[0])
|
|
1303
|
-
walkActive.play()
|
|
1369
|
+
const walkActive = actionMixer.clipAction(gltf.animations[0]);
|
|
1370
|
+
walkActive.play();
|
|
1304
1371
|
modelActive.push(walkActive);
|
|
1305
1372
|
modelActions.push(actionMixer);
|
|
1306
1373
|
}
|
|
1307
|
-
callback && callback()
|
|
1308
|
-
})
|
|
1374
|
+
callback && callback();
|
|
1375
|
+
});
|
|
1309
1376
|
},
|
|
1310
1377
|
// 删除添加的自定义模型
|
|
1311
1378
|
removeCustomModel(name) {
|
|
@@ -1316,25 +1383,25 @@
|
|
|
1316
1383
|
modelActions[index].uncacheRoot(item);
|
|
1317
1384
|
modelActions[index].uncacheRoot(modelActive[index]);
|
|
1318
1385
|
}
|
|
1319
|
-
item.traverse(
|
|
1386
|
+
item.traverse(child => {
|
|
1320
1387
|
if (child instanceof this.THREE.Mesh) {
|
|
1321
|
-
child.geometry.dispose()
|
|
1322
|
-
child.material.dispose()
|
|
1388
|
+
child.geometry.dispose();
|
|
1389
|
+
child.material.dispose();
|
|
1323
1390
|
}
|
|
1324
|
-
})
|
|
1391
|
+
});
|
|
1325
1392
|
scene.remove(item);
|
|
1326
|
-
})
|
|
1393
|
+
});
|
|
1327
1394
|
modelActions.splice(0);
|
|
1328
1395
|
modelActive.splice(0);
|
|
1329
1396
|
},
|
|
1330
1397
|
// 修改天空背景
|
|
1331
1398
|
skyBoxScene(url) {
|
|
1332
|
-
const textureCube = new this.THREE.CubeTextureLoader().load(url)
|
|
1333
|
-
scene.background = textureCube
|
|
1399
|
+
const textureCube = new this.THREE.CubeTextureLoader().load(url);
|
|
1400
|
+
scene.background = textureCube;
|
|
1334
1401
|
},
|
|
1335
1402
|
// 清除天空背景
|
|
1336
1403
|
clearSkyBoxScene() {
|
|
1337
|
-
scene.background = null
|
|
1404
|
+
scene.background = null;
|
|
1338
1405
|
},
|
|
1339
1406
|
// 下雨模拟
|
|
1340
1407
|
sceneSimu(type) {
|
|
@@ -1342,13 +1409,19 @@
|
|
|
1342
1409
|
outlineComposer = new EffectComposer(renderer, renderTarget);
|
|
1343
1410
|
outlineComposer.addPass(new RenderPass(scene, camera));
|
|
1344
1411
|
}
|
|
1345
|
-
if(type === 'rain') {
|
|
1412
|
+
if (type === 'rain') {
|
|
1346
1413
|
scenePass = new ShaderPass(RainShader);
|
|
1347
|
-
scenePass.uniforms['iResolution'].value = new this.THREE.Vector2(
|
|
1414
|
+
scenePass.uniforms['iResolution'].value = new this.THREE.Vector2(
|
|
1415
|
+
window.innerWidth,
|
|
1416
|
+
window.innerHeight
|
|
1417
|
+
);
|
|
1348
1418
|
outlineComposer.addPass(scenePass);
|
|
1349
1419
|
} else if (type === 'snow') {
|
|
1350
1420
|
scenePass = new ShaderPass(SnowShader);
|
|
1351
|
-
scenePass.uniforms['iResolution'].value = new this.THREE.Vector2(
|
|
1421
|
+
scenePass.uniforms['iResolution'].value = new this.THREE.Vector2(
|
|
1422
|
+
window.innerWidth,
|
|
1423
|
+
window.innerHeight
|
|
1424
|
+
);
|
|
1352
1425
|
outlineComposer.addPass(scenePass);
|
|
1353
1426
|
}
|
|
1354
1427
|
},
|
|
@@ -1366,13 +1439,13 @@
|
|
|
1366
1439
|
if (modelActions.length > 0) {
|
|
1367
1440
|
modelActions.forEach(item => {
|
|
1368
1441
|
item.update(timeStamp);
|
|
1369
|
-
})
|
|
1442
|
+
});
|
|
1370
1443
|
}
|
|
1371
1444
|
cameraControls.enabled && cameraControls.update(timeStamp);
|
|
1372
1445
|
this.cameraTrack();
|
|
1373
1446
|
this.firstPerspective();
|
|
1374
1447
|
if (scenePass) {
|
|
1375
|
-
let d = sceneClock.getDelta()
|
|
1448
|
+
let d = sceneClock.getDelta();
|
|
1376
1449
|
scenePass.uniforms['iTime'].value += d;
|
|
1377
1450
|
}
|
|
1378
1451
|
labelRenderer.render(scene, camera);
|