fl-web-component 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fl-web-component.common.js +50 -53
- package/dist/fl-web-component.css +1 -1
- package/dist/fl-web-component.umd.js +50 -53
- package/dist/fl-web-component.umd.min.js +4 -4
- package/package.json +1 -1
- package/packages/components/com-graphics/index.vue +112 -61
- package/src/utils/flgltf-parser.js +4 -2
- package/src/utils/instance-parser.js +9 -3
- package/src/utils/mock.js +84499 -84499
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div id="
|
|
2
|
+
<div id="fl-model"></div>
|
|
3
3
|
</template>
|
|
4
4
|
<script>
|
|
5
5
|
var [
|
|
@@ -49,7 +49,11 @@
|
|
|
49
49
|
var removeSpeed = 200,
|
|
50
50
|
upSpeed = 200; //控制器移动速度 , //控制跳起时的速度
|
|
51
51
|
var modelGroup;
|
|
52
|
-
|
|
52
|
+
var roamConfig = {
|
|
53
|
+
loop: false,
|
|
54
|
+
speed: 0, // 最大值为3
|
|
55
|
+
name: ''
|
|
56
|
+
}
|
|
53
57
|
// 绘制对象映射实例表
|
|
54
58
|
let drawObjMapInstance = {};
|
|
55
59
|
import CameraControls from 'camera-controls';
|
|
@@ -75,10 +79,6 @@
|
|
|
75
79
|
},
|
|
76
80
|
data() {
|
|
77
81
|
return {
|
|
78
|
-
roamConfig: {
|
|
79
|
-
loop: false,
|
|
80
|
-
speed: 0, // 最大值为3
|
|
81
|
-
},
|
|
82
82
|
};
|
|
83
83
|
},
|
|
84
84
|
created() {
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
mouse = new this.THREE.Vector2();
|
|
89
89
|
},
|
|
90
90
|
mounted() {
|
|
91
|
-
instructions = document.getElementById('
|
|
91
|
+
instructions = document.getElementById('fl-model');
|
|
92
92
|
this.initRender();
|
|
93
93
|
this.initScene();
|
|
94
94
|
this.initCamera();
|
|
@@ -165,18 +165,20 @@
|
|
|
165
165
|
/*
|
|
166
166
|
参数:data 模型数据
|
|
167
167
|
color: '' 初始化模型的颜色 在业务方 有这个需求
|
|
168
|
+
meshNameConfig: {}
|
|
168
169
|
*/
|
|
169
|
-
drawModel(data, color = '') {
|
|
170
|
+
drawModel(data, color = '', meshNameConfig) {
|
|
170
171
|
if (Object.keys(data).length === 0) {
|
|
171
172
|
return;
|
|
172
173
|
}
|
|
173
174
|
const { instances, drawObjs } = parseData(data);
|
|
174
175
|
if (instances.length > 0) {
|
|
175
|
-
modelGroup = handleInstancedMeshModel(instances, drawObjs, '', scene, color);
|
|
176
|
+
modelGroup = handleInstancedMeshModel(instances, drawObjs, '', scene, color, meshNameConfig);
|
|
176
177
|
scene.add(modelGroup);
|
|
177
178
|
// this.compileShader();
|
|
178
|
-
cameraControls.fitToSphere(
|
|
179
|
-
|
|
179
|
+
// cameraControls.fitToSphere(scene, true); // TODO 待处理,先用 setModelCenter 进行定位
|
|
180
|
+
this.setModelCenter(modelGroup);
|
|
181
|
+
// cameraControls.saveState();
|
|
180
182
|
}
|
|
181
183
|
},
|
|
182
184
|
compileShader() {
|
|
@@ -229,7 +231,7 @@
|
|
|
229
231
|
mouse.y = -(event.clientY / instructions.offsetHeight) * 2 + 1;
|
|
230
232
|
raycaster.setFromCamera(mouse, camera);
|
|
231
233
|
const intersects = raycaster.intersectObjects(scene.children, true);
|
|
232
|
-
let params = {}
|
|
234
|
+
let params = {};
|
|
233
235
|
let cameraData = {
|
|
234
236
|
position: {
|
|
235
237
|
x: cameraControls.camera.position.x,
|
|
@@ -251,8 +253,8 @@
|
|
|
251
253
|
x: intersects[0].point.x,
|
|
252
254
|
y: intersects[0].point.y,
|
|
253
255
|
z: intersects[0].point.z,
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
+
},
|
|
257
|
+
};
|
|
256
258
|
} else {
|
|
257
259
|
params = {
|
|
258
260
|
objects: [],
|
|
@@ -262,8 +264,8 @@
|
|
|
262
264
|
x: -1,
|
|
263
265
|
y: -1,
|
|
264
266
|
z: -1,
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
+
},
|
|
268
|
+
};
|
|
267
269
|
}
|
|
268
270
|
if (event.button === 0) {
|
|
269
271
|
this.$emit('leftClick', params);
|
|
@@ -287,26 +289,26 @@
|
|
|
287
289
|
}
|
|
288
290
|
}
|
|
289
291
|
},
|
|
290
|
-
setModelCenter() {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
292
|
+
setModelCenter(mesh) {
|
|
293
|
+
const box3 = new this.THREE.Box3();
|
|
294
|
+
box3.setFromObject(mesh);
|
|
295
|
+
const center = new this.THREE.Vector3();
|
|
296
|
+
box3.getCenter(center);
|
|
297
|
+
const size = box3.getSize(new this.THREE.Vector3());
|
|
298
|
+
camera.position.set(center.x, center.y + size.y, center.z + size.z / 2);
|
|
299
|
+
camera.lookAt(new this.THREE.Vector3(center.x, center.y, center.z));
|
|
300
|
+
cameraControls.setLookAt(
|
|
301
|
+
center.x,
|
|
302
|
+
center.y + size.y,
|
|
303
|
+
center.z + size.z / 2,
|
|
304
|
+
center.x,
|
|
305
|
+
center.y,
|
|
306
|
+
center.z,
|
|
307
|
+
true
|
|
308
|
+
);
|
|
309
|
+
cameraControls.update(0);
|
|
310
|
+
camera.updateProjectionMatrix();
|
|
311
|
+
cameraControls.saveState();
|
|
310
312
|
},
|
|
311
313
|
// 修改指定模型实体属性
|
|
312
314
|
/**
|
|
@@ -354,6 +356,11 @@
|
|
|
354
356
|
obj.material.opacity = ele.attr[key];
|
|
355
357
|
obj.material.transparent = true;
|
|
356
358
|
break;
|
|
359
|
+
case 'position':
|
|
360
|
+
targetObj.forEach(children => {
|
|
361
|
+
children.position.set(ele.attr[key].x, ele.attr[key].y, ele.attr[key].z)
|
|
362
|
+
})
|
|
363
|
+
break;
|
|
357
364
|
}
|
|
358
365
|
}
|
|
359
366
|
// obj.material.needsUpdate = true;
|
|
@@ -415,7 +422,8 @@
|
|
|
415
422
|
locateModel(id) {
|
|
416
423
|
let obj = scene.getObjectByName(id);
|
|
417
424
|
if (obj) {
|
|
418
|
-
cameraControls.fitToSphere(obj.parent, true);
|
|
425
|
+
// cameraControls.fitToSphere(obj.parent, true); // TODO 待处理,先用 setModelCenter 进行定位
|
|
426
|
+
this.setModelCenter(obj.parent);
|
|
419
427
|
// cameraControls.fitToBox( obj, true);
|
|
420
428
|
}
|
|
421
429
|
},
|
|
@@ -495,6 +503,39 @@
|
|
|
495
503
|
}
|
|
496
504
|
});
|
|
497
505
|
},
|
|
506
|
+
// 删除场景中所有的实体
|
|
507
|
+
removeAll() {
|
|
508
|
+
if (scene) {
|
|
509
|
+
scene.traverse(item => {
|
|
510
|
+
item.material && item.material.dispose();
|
|
511
|
+
item.geometry && item.geometry.dispose();
|
|
512
|
+
if (item instanceof this.THREE.Mesh) {
|
|
513
|
+
item.clear();
|
|
514
|
+
}
|
|
515
|
+
scene.remove(item);
|
|
516
|
+
})
|
|
517
|
+
scene.clear()
|
|
518
|
+
}
|
|
519
|
+
},
|
|
520
|
+
// 销毁场景 释放内存
|
|
521
|
+
destroyScene() {
|
|
522
|
+
cancelAnimationFrame(animateId)
|
|
523
|
+
if (scene) {
|
|
524
|
+
scene.traverse(child => {
|
|
525
|
+
child.material && child.material.dispose()
|
|
526
|
+
child.geometry && child.geometry.dispose()
|
|
527
|
+
child = null
|
|
528
|
+
})
|
|
529
|
+
scene.clear()
|
|
530
|
+
scene = null
|
|
531
|
+
}
|
|
532
|
+
renderer.forceContextLoss()
|
|
533
|
+
renderer.dispose()
|
|
534
|
+
camera = null
|
|
535
|
+
cameraControls = null
|
|
536
|
+
renderer.domElement = null
|
|
537
|
+
renderer = null
|
|
538
|
+
},
|
|
498
539
|
// 绘制曲线
|
|
499
540
|
/*
|
|
500
541
|
参数声明:Object
|
|
@@ -524,6 +565,13 @@
|
|
|
524
565
|
}
|
|
525
566
|
},
|
|
526
567
|
// 绘制贴图曲线
|
|
568
|
+
/*
|
|
569
|
+
参数声明:Object
|
|
570
|
+
{
|
|
571
|
+
path: [{x:0, y: 0, z: 0}], 坐标点信息
|
|
572
|
+
name: '', // 线条的名字, 用来清除时使用的
|
|
573
|
+
}
|
|
574
|
+
*/
|
|
527
575
|
drawTextureCurve(params) {
|
|
528
576
|
this.removeObjectByName(params.name);
|
|
529
577
|
const route = [];
|
|
@@ -550,8 +598,10 @@
|
|
|
550
598
|
let line = new this.THREE.Line(geometry, material);
|
|
551
599
|
line.name = params.name;
|
|
552
600
|
scene.add(line);
|
|
601
|
+
clock = new this.THREE.Clock();
|
|
553
602
|
}
|
|
554
603
|
},
|
|
604
|
+
//
|
|
555
605
|
// 开启漫游
|
|
556
606
|
/*
|
|
557
607
|
参数为Object
|
|
@@ -562,37 +612,38 @@
|
|
|
562
612
|
*/
|
|
563
613
|
startRoam(params) {
|
|
564
614
|
progress = 0;
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
speed: params.speed,
|
|
570
|
-
roamName: params.name,
|
|
571
|
-
}
|
|
572
|
-
);
|
|
615
|
+
roamConfig = {
|
|
616
|
+
loop: params.loop,
|
|
617
|
+
speed: params.speed,
|
|
618
|
+
}
|
|
573
619
|
this.drawTextureCurve({
|
|
574
620
|
name: params.name,
|
|
575
621
|
path: params.path,
|
|
576
622
|
});
|
|
623
|
+
roaming = true
|
|
577
624
|
clock = new this.THREE.Clock();
|
|
578
625
|
},
|
|
579
|
-
//
|
|
580
|
-
|
|
581
|
-
|
|
626
|
+
// 更新漫游的配置
|
|
627
|
+
/*
|
|
628
|
+
参数为Object
|
|
629
|
+
*/
|
|
630
|
+
updateRoamConfig(params) {
|
|
631
|
+
for (let key in params) {
|
|
632
|
+
roamConfig[key] = key === 'speed' ? params[key] / 300 : params[key]
|
|
633
|
+
}
|
|
582
634
|
},
|
|
583
635
|
// 结束/退出漫游
|
|
584
636
|
endRoam() {
|
|
585
637
|
roaming = false;
|
|
586
638
|
progress = 0;
|
|
587
|
-
this.removeObjectByName(this.roamConfig.
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
);
|
|
639
|
+
this.removeObjectByName(this.roamConfig.name);
|
|
640
|
+
roamConfig = {
|
|
641
|
+
loop: false,
|
|
642
|
+
speed: 0,
|
|
643
|
+
name: '',
|
|
644
|
+
}
|
|
645
|
+
roaming = false
|
|
646
|
+
lineTexture = null
|
|
596
647
|
},
|
|
597
648
|
// 相机跟随轨道
|
|
598
649
|
cameraTrack() {
|
|
@@ -609,16 +660,16 @@
|
|
|
609
660
|
camera.lookAt(pointBox.x, pointBox.y + 5, pointBox.z);
|
|
610
661
|
cameraControls.setPosition(point.x, point.y + 5, point.z, false);
|
|
611
662
|
cameraControls.setTarget(pointBox.x, pointBox.y + 5, pointBox.z, false);
|
|
612
|
-
progress +=
|
|
663
|
+
progress += roamConfig.speed / 300;
|
|
613
664
|
} else {
|
|
614
665
|
// 循环漫游
|
|
615
|
-
if (
|
|
666
|
+
if (roamConfig.loop) {
|
|
616
667
|
progress = 0;
|
|
617
668
|
}
|
|
618
669
|
}
|
|
619
670
|
} else {
|
|
620
671
|
lineTexture = null;
|
|
621
|
-
|
|
672
|
+
progress = 0;
|
|
622
673
|
}
|
|
623
674
|
},
|
|
624
675
|
// 全局整体炸开
|
|
@@ -1063,7 +1114,7 @@
|
|
|
1063
1114
|
};
|
|
1064
1115
|
</script>
|
|
1065
1116
|
<style lang="scss" scoped>
|
|
1066
|
-
#
|
|
1117
|
+
#fl-model {
|
|
1067
1118
|
width: 100%;
|
|
1068
1119
|
height: 100%;
|
|
1069
1120
|
cursor: pointer;
|
|
@@ -132,10 +132,12 @@ function parseData(input) {
|
|
|
132
132
|
const formatInstances = [];
|
|
133
133
|
flattenAndComputeWorldMatrices(rootInstances, formatInstances);
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
const map = {
|
|
136
136
|
drawObjs: Array.from(drawObjMap.values()),
|
|
137
137
|
instances: formatInstances,
|
|
138
|
-
}
|
|
138
|
+
}
|
|
139
|
+
console.log('parseData', map)
|
|
140
|
+
return map;
|
|
139
141
|
}
|
|
140
142
|
|
|
141
143
|
export { parseData };
|
|
@@ -25,13 +25,13 @@ let drawObjMapInstance = {};
|
|
|
25
25
|
* @param {Object} instance - 实例对象,包含绘制对象ID和实例ID等数据
|
|
26
26
|
* @param {Array} drawObjs - 绘制对象数组,包含几何数据
|
|
27
27
|
*/
|
|
28
|
-
function handleInstancedMeshModel(instances, drawObjs, type, scene, customColor) {
|
|
28
|
+
function handleInstancedMeshModel(instances, drawObjs, type, scene, customColor, meshNameConfig) {
|
|
29
29
|
// 第一阶段:构建实例映射表
|
|
30
30
|
let modelGroup = new THREE.Group();
|
|
31
31
|
for (let i = 0; i < instances.length; i++) {
|
|
32
32
|
formatInstancedMap(instances[i], drawObjs);
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
console.log('drawObjMapInstance', drawObjMapInstance)
|
|
35
35
|
// 第二阶段:遍历所有实例进行处理
|
|
36
36
|
for (let i = 0; i < instances.length; i++) {
|
|
37
37
|
let targetGroup, instancedMeshIndex, drawObjectName;
|
|
@@ -68,10 +68,15 @@ function handleInstancedMeshModel(instances, drawObjs, type, scene, customColor)
|
|
|
68
68
|
if (!model) {
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
|
+
let meshName = ''
|
|
72
|
+
for (const key in meshNameConfig) {
|
|
73
|
+
model.userData[key] = meshNameConfig[key]
|
|
74
|
+
meshName += ':' + meshNameConfig[key]
|
|
75
|
+
}
|
|
71
76
|
drawObj.MapInstance.forEach((instance, index) => {
|
|
72
77
|
if (instance.instanceId == instances[i].instanceId) {
|
|
73
78
|
model.userData.instanceIndex = index;
|
|
74
|
-
model.name = instances[i].instanceId;
|
|
79
|
+
model.name = meshName !== '' ? (instances[i].instanceId + meshName) : instances[i].instanceId;
|
|
75
80
|
const matrixVal = instance.matrix?.val;
|
|
76
81
|
if (matrixVal) {
|
|
77
82
|
const m4 = new THREE.Matrix4();
|
|
@@ -93,6 +98,7 @@ function handleInstancedMeshModel(instances, drawObjs, type, scene, customColor)
|
|
|
93
98
|
modelGroup.add(group);
|
|
94
99
|
}
|
|
95
100
|
}
|
|
101
|
+
console.log('modelGroup', modelGroup)
|
|
96
102
|
return modelGroup;
|
|
97
103
|
// timeRender();
|
|
98
104
|
// console.log('scene', scene)
|