|
@@ -11,6 +11,8 @@ import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPa
|
|
|
import * as TWEEN from '@tweenjs/tween.js';
|
|
|
import { getBottomMaterial } from './material.js';
|
|
|
import GltfModelManager from '@/views/largeScreen/three/GltfModelManager';
|
|
|
+import ComponentHandle from '@/utils/ComponentHandle';
|
|
|
+import usageReal from '@/views/largeScreen/dialog/usage-real.vue';
|
|
|
const dracoLoader = new DRACOLoader();
|
|
|
// 设置draco路径
|
|
|
dracoLoader.setDecoderPath('/draco/');
|
|
@@ -52,6 +54,7 @@ class renderModel {
|
|
|
this.mouse = new THREE.Vector2();
|
|
|
this.autoRotate = true;
|
|
|
this.labels = [];
|
|
|
+ this.roomLabelGroup = null;
|
|
|
}
|
|
|
controlRotate(bool) {
|
|
|
this.autoRotate = bool;
|
|
@@ -234,8 +237,8 @@ class renderModel {
|
|
|
logarithmicDepthBuffer: true,
|
|
|
antialias: true, // true/false表示是否开启反锯齿
|
|
|
alpha: true, // true/false 表示是否可以设置背景色透明
|
|
|
- precision: 'mediump', // highp/mediump/lowp 表示着色精度选择
|
|
|
- premultipliedAlpha: true // true/false 表示是否可以设置像素深度(用来度量图像的分辨率)
|
|
|
+ // precision: 'mediump', // highp/mediump/lowp 表示着色精度选择
|
|
|
+ // premultipliedAlpha: true // true/false 表示是否可以设置像素深度(用来度量图像的分辨率)
|
|
|
// preserveDrawingBuffer: false, // true/false 表示是否保存绘图缓冲
|
|
|
// physicallyCorrectLights: true, // true/false 表示是否开启物理光照
|
|
|
});
|
|
@@ -244,9 +247,8 @@ class renderModel {
|
|
|
//渲染的尺寸大小
|
|
|
const { clientHeight, clientWidth } = this.container;
|
|
|
this.renderer.setSize(clientWidth, clientHeight);
|
|
|
- this.renderer.outputEncoding = THREE.sRGBEncoding;
|
|
|
- this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
|
|
|
- this.renderer.toneMappingExposure = 1;
|
|
|
+ this.renderer.toneMapping = Number(THREE.LinearToneMapping);
|
|
|
+ this.renderer.toneMappingExposure = Math.pow(2, 0.0);
|
|
|
this.container.appendChild(this.renderer.domElement);
|
|
|
|
|
|
// 创建一个CSS3渲染器CSS3DRenderer
|
|
@@ -264,12 +266,11 @@ class renderModel {
|
|
|
|
|
|
// 创建光源
|
|
|
createLight() {
|
|
|
- this.scene.add(new THREE.AmbientLight(0xffffff, 2));
|
|
|
- // 2. 添加一个或多个定向光/点光源 - 提供方向性照明,产生明暗和阴影
|
|
|
- const directionalLight = new THREE.DirectionalLight(0xffffff, 1.5); // 白光,强度1
|
|
|
- directionalLight.position.set(5, 10, 5); // 调整这个位置,确保光线能照到您的模型
|
|
|
- directionalLight.castShadow = true; // (可选) 开启阴影
|
|
|
- this.scene.add(directionalLight);
|
|
|
+ const light1 = new THREE.AmbientLight('#FFFFFF', 1);
|
|
|
+ this.scene.add(light1);
|
|
|
+ const light2 = new THREE.DirectionalLight('#FFFFFF', 0.8 * Math.PI);
|
|
|
+ light2.position.set(0.5, 0, 0.866); // ~60º
|
|
|
+ this.scene.add(light2);
|
|
|
}
|
|
|
|
|
|
initControls() {
|
|
@@ -295,6 +296,8 @@ class renderModel {
|
|
|
this.controls.update();
|
|
|
this.css3DRenderer.render(this.scene, this.camera);
|
|
|
TWEEN.update();
|
|
|
+ console.log(this.camera.position);
|
|
|
+ console.log(this.controls.target);
|
|
|
if (this.model && this.autoRotate) {
|
|
|
this.model.rotation.z += 0.001; // 每帧绕y轴旋转0.01弧度
|
|
|
}
|
|
@@ -304,7 +307,6 @@ class renderModel {
|
|
|
sceneAnimation() {
|
|
|
this.renderer.setAnimationLoop(this.animate.bind(this));
|
|
|
}
|
|
|
-
|
|
|
flyTo(target, scale = 1, duration = 1000) {
|
|
|
const targetPosition = new THREE.Vector3().copy(target.position);
|
|
|
const targetFocus = new THREE.Vector3().copy(target.targetContent);
|
|
@@ -317,7 +319,6 @@ class renderModel {
|
|
|
this.controls.update(); // 更新控制器
|
|
|
})
|
|
|
.start();
|
|
|
-
|
|
|
// 移动控制器目标
|
|
|
new TWEEN.Tween(this.controls.target)
|
|
|
.to(targetFocus, target.time || 500)
|
|
@@ -428,16 +429,83 @@ class renderModel {
|
|
|
});
|
|
|
|
|
|
// 设置相机位置
|
|
|
- this.camera.position.set(-20, -652, 500);
|
|
|
- this.controls.target.set(-20, -20, 0);
|
|
|
- this.model.scale.set(1, 1, 1);
|
|
|
+ this.camera.position.set(-17.701772776272723, -728.8405392761424, 374.20604159261217);
|
|
|
+ this.controls.target.set(-17.701772776272723, -307.6331500346563, 148.44436360369687);
|
|
|
+ this.model.scale.set(0.8, 0.8, 0.8);
|
|
|
// 设置相机坐标系
|
|
|
this.camera.lookAt(0, 0, 0);
|
|
|
// 将模型添加到场景中去
|
|
|
this.scene.add(this.model);
|
|
|
});
|
|
|
}
|
|
|
- modelChange(type) {
|
|
|
+ setModelDisplay(type, areaInfo) {
|
|
|
+ if (type == 'model1' || type == 'model2') {
|
|
|
+ this.camera.position.set(2.9287885309866817, -403.9781890137868, 376.33849737114133);
|
|
|
+ this.controls.target.set(-22.9298060627659623, 15.311141772539067, 64.637911374941055);
|
|
|
+ const targetFocus = new THREE.Vector3(-22.9298060627659623, 15.311141772539067, 24.637911374941055);
|
|
|
+ new TWEEN.Tween(this.controls.target)
|
|
|
+ .to(targetFocus, 500)
|
|
|
+ .easing(TWEEN.Easing.Quadratic.InOut)
|
|
|
+ .onUpdate(() => {
|
|
|
+ this.controls.update(); // 更新控制器
|
|
|
+ })
|
|
|
+ .start();
|
|
|
+ this.addRoomDialog(
|
|
|
+ type,
|
|
|
+ ComponentHandle.createComponent({
|
|
|
+ component: usageReal,
|
|
|
+ props: {
|
|
|
+ areaCode: areaInfo.value
|
|
|
+ }
|
|
|
+ }),
|
|
|
+ `${areaInfo.name}${type == 'model1' ? '负一楼水泵' : '室内主机'}`,
|
|
|
+ type == 'model1'
|
|
|
+ ? {
|
|
|
+ x: -3,
|
|
|
+ y: 8,
|
|
|
+ z: 0
|
|
|
+ }
|
|
|
+ : {
|
|
|
+ x: -3,
|
|
|
+ y: 3,
|
|
|
+ z: 0
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ if (type == 'model1') {
|
|
|
+ new TWEEN.Tween(this.model1.scale)
|
|
|
+ .to(
|
|
|
+ {
|
|
|
+ x: 10,
|
|
|
+ y: 10,
|
|
|
+ z: 10
|
|
|
+ },
|
|
|
+ 500
|
|
|
+ )
|
|
|
+ .easing(TWEEN.Easing.Quadratic.InOut)
|
|
|
+ .start();
|
|
|
+ }
|
|
|
+ if (type == 'model2') {
|
|
|
+ new TWEEN.Tween(this.model2.scale)
|
|
|
+ .to(
|
|
|
+ {
|
|
|
+ x: 15,
|
|
|
+ y: 15,
|
|
|
+ z: 15
|
|
|
+ },
|
|
|
+ 500
|
|
|
+ )
|
|
|
+ .easing(TWEEN.Easing.Quadratic.InOut)
|
|
|
+ .start();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ modelChange(type, areaInfo) {
|
|
|
+ if (this.roomLabelGroup) {
|
|
|
+ this.model1.remove(this.roomLabelGroup);
|
|
|
+ this.model2.remove(this.roomLabelGroup);
|
|
|
+ this.roomLabelGroup.clear();
|
|
|
+ }
|
|
|
+ this.setModelDisplay(type, areaInfo);
|
|
|
if (type == 'model') {
|
|
|
this.model1.visible = false;
|
|
|
this.model2.visible = false;
|
|
@@ -470,64 +538,31 @@ class renderModel {
|
|
|
color: 0xcccccc, //
|
|
|
side: THREE.DoubleSide // 防止面片反向不可见
|
|
|
});
|
|
|
-
|
|
|
- object.scene.traverse(child => {
|
|
|
- if (child.isMesh) {
|
|
|
- if (child.name == '平面') {
|
|
|
- child.material = new THREE.MeshStandardMaterial({
|
|
|
- color: 0x66728a,
|
|
|
- side: THREE.DoubleSide
|
|
|
- });
|
|
|
- } else {
|
|
|
- child.material = perfectMaterial; // 强制替换所有材质
|
|
|
- }
|
|
|
-
|
|
|
- child.material.needsUpdate = true;
|
|
|
- }
|
|
|
- });
|
|
|
this.model1 = object.scene;
|
|
|
- // 设置相机位置
|
|
|
- this.camera.position.set(-20, -652, 500);
|
|
|
- this.controls.target.set(-20, -20, 0);
|
|
|
this.model1.scale.set(10, 10, 10);
|
|
|
this.model1.rotation.x = Math.PI / 2;
|
|
|
this.model1.rotation.y = Math.PI / 6;
|
|
|
- // 设置相机坐标系
|
|
|
- this.camera.lookAt(0, 0, 0);
|
|
|
// 将模型添加到场景中去
|
|
|
this.model1.visible = false;
|
|
|
this.scene.add(this.model1);
|
|
|
});
|
|
|
loader.load('/models/model2.glb', object => {
|
|
|
this.calcMeshCenter(object.scene);
|
|
|
- const perfectMaterial = new THREE.MeshStandardMaterial({
|
|
|
- color: 0xcccccc, //
|
|
|
- side: THREE.DoubleSide // 防止面片反向不可见
|
|
|
- });
|
|
|
-
|
|
|
object.scene.traverse(child => {
|
|
|
if (child.isMesh) {
|
|
|
if (child.name == '平面' || child.name == '平面001') {
|
|
|
child.material = new THREE.MeshStandardMaterial({
|
|
|
- color: 0x66728a,
|
|
|
+ color: '#B0C4E9',
|
|
|
side: THREE.DoubleSide
|
|
|
});
|
|
|
- } else {
|
|
|
- child.material = perfectMaterial; // 强制替换所有材质
|
|
|
}
|
|
|
-
|
|
|
child.material.needsUpdate = true;
|
|
|
}
|
|
|
});
|
|
|
this.model2 = object.scene;
|
|
|
- // 设置相机位置
|
|
|
- this.camera.position.set(-20, -652, 500);
|
|
|
- this.controls.target.set(-20, -20, 0);
|
|
|
this.model2.scale.set(15, 15, 15);
|
|
|
this.model2.rotation.x = Math.PI / 2;
|
|
|
this.model2.rotation.y = -Math.PI / 3;
|
|
|
- // 设置相机坐标系
|
|
|
- this.camera.lookAt(0, 0, 0);
|
|
|
// 将模型添加到场景中去
|
|
|
this.model2.visible = false;
|
|
|
this.scene.add(this.model2);
|
|
@@ -560,7 +595,31 @@ class renderModel {
|
|
|
group.position.y = 0;
|
|
|
group.position.z = 17;
|
|
|
}
|
|
|
-
|
|
|
+ addRoomDialog(modelType, html, labelName, position) {
|
|
|
+ const { x, y, z } = position;
|
|
|
+ if (this.roomLabelGroup && this[modelType]) {
|
|
|
+ this[modelType].remove(this.roomLabelGroup);
|
|
|
+ this.roomLabelGroup.clear();
|
|
|
+ }
|
|
|
+ const label3D = this.tag3D(labelName);
|
|
|
+ const dialog3D = this.createDialog(html);
|
|
|
+ if (modelType == 'model1') {
|
|
|
+ label3D.scale.set(0.015, 0.015, 0.015);
|
|
|
+ dialog3D.scale.set(0.015, 0.015, 0.15);
|
|
|
+ label3D.position.set(x - 0.2, y - 1.8, z);
|
|
|
+ } else {
|
|
|
+ label3D.position.set(x - 0.2, y - 1.5, z);
|
|
|
+ label3D.scale.set(0.011, 0.011, 0.011);
|
|
|
+ dialog3D.scale.set(0.011, 0.011, 0.11);
|
|
|
+ }
|
|
|
+ // 3. 创建一个组来容纳它们
|
|
|
+ const group = new THREE.Group();
|
|
|
+ dialog3D.position.set(x, y, z);
|
|
|
+ group.add(label3D);
|
|
|
+ group.add(dialog3D);
|
|
|
+ this[modelType].add(group);
|
|
|
+ this.roomLabelGroup = group; // 保存引用
|
|
|
+ }
|
|
|
addDialog(html, labelName, position) {
|
|
|
const { x, y, z } = position;
|
|
|
const label3D = this.tag3D(labelName);
|