123
							parent
							
								
									59bbb8358c
								
							
						
					
					
						commit
						07189fa6a7
					
				| 
						 | 
				
			
			@ -42,7 +42,8 @@
 | 
			
		|||
    "vue": "3.2.45",
 | 
			
		||||
    "vue-cropper": "1.0.3",
 | 
			
		||||
    "vue-router": "4.1.4",
 | 
			
		||||
    "mitt": "^3.0.1"
 | 
			
		||||
    "mitt": "^3.0.1",
 | 
			
		||||
    "gsap": "^3.11.3"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@vitejs/plugin-vue": "3.1.0",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -1392,7 +1392,7 @@
 | 
			
		|||
        -54.6457,
 | 
			
		||||
        1
 | 
			
		||||
      ],
 | 
			
		||||
      "name": "4",
 | 
			
		||||
      "name": "set3",
 | 
			
		||||
      "extras": {
 | 
			
		||||
        "name": "4"
 | 
			
		||||
      },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,6 +37,7 @@ import homeIcon from '@/assets/image/bg7.jpg'
 | 
			
		|||
import TWEEN from "@tweenjs/tween.js";
 | 
			
		||||
import Bus from '@/utils/bus.js'
 | 
			
		||||
import bimStore from '@/store/modules/bim';
 | 
			
		||||
import gsap from "gsap";
 | 
			
		||||
 | 
			
		||||
let scene = ref(null);
 | 
			
		||||
let renderer = ref(null);
 | 
			
		||||
| 
						 | 
				
			
			@ -50,6 +51,7 @@ let labelRenderer = new CSS2DRenderer(); //新建CSS2DRenderer
 | 
			
		|||
let positionObj = ref(null);
 | 
			
		||||
// 选中的模型
 | 
			
		||||
let selectedObjects = ref([]);
 | 
			
		||||
let curve = ref(null);
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    background: { // 背景颜色
 | 
			
		||||
| 
						 | 
				
			
			@ -94,10 +96,12 @@ Bus.on('clickBuild', (isParent) => {
 | 
			
		|||
        // })
 | 
			
		||||
        // 高亮轮廓
 | 
			
		||||
        outlineObj([Floor]);
 | 
			
		||||
        // 拉近场景
 | 
			
		||||
         nearCamera(Floor);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    // 父级
 | 
			
		||||
    toHomeView();
 | 
			
		||||
    // toHomeView();
 | 
			
		||||
})
 | 
			
		||||
// 设备树点击
 | 
			
		||||
Bus.on('clickDevice', (isParent) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -107,10 +111,12 @@ Bus.on('clickDevice', (isParent) => {
 | 
			
		|||
        console.log(1, Floor);
 | 
			
		||||
        // 高亮轮廓
 | 
			
		||||
        outlineObj([Floor])
 | 
			
		||||
        // 拉近距离
 | 
			
		||||
        // nearCamera(Floor);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    // 父级
 | 
			
		||||
    toHomeView();
 | 
			
		||||
    // toHomeView();
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// 系统树点击
 | 
			
		||||
| 
						 | 
				
			
			@ -124,65 +130,11 @@ onMounted(() => {
 | 
			
		|||
    loadSence();
 | 
			
		||||
    // 启动动画
 | 
			
		||||
    renderScene();
 | 
			
		||||
    document.addEventListener("click", onMouseDown);
 | 
			
		||||
    // document.addEventListener("click", onMouseDown);
 | 
			
		||||
    document.addEventListener("mousemove", onMouseDown);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const setLabel = () => {
 | 
			
		||||
    if(isAddLabel.value) {
 | 
			
		||||
        addLabel();
 | 
			
		||||
    } else {
 | 
			
		||||
        removeLabel();
 | 
			
		||||
    }
 | 
			
		||||
    isAddLabel.value = !isAddLabel.value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const removeLabel = () => {
 | 
			
		||||
    document.body.removeChild(labelRenderer.domElement);
 | 
			
		||||
}
 | 
			
		||||
// 添加标签
 | 
			
		||||
 | 
			
		||||
const addLabel = () => {
 | 
			
		||||
    let obj = gltfObj.value.scene.getObjectByName('set2');
 | 
			
		||||
    let text = "设备二";
 | 
			
		||||
    let pointLabel = createLableObj(text);
 | 
			
		||||
    obj.add(pointLabel);
 | 
			
		||||
    labelRenderer.setSize(window.innerWidth, window.innerHeight);
 | 
			
		||||
    labelRenderer.domElement.style.position = "absolute";
 | 
			
		||||
    labelRenderer.domElement.style.top = 0;
 | 
			
		||||
    labelRenderer.domElement.style.pointerEvents = 'none';// 必须加上
 | 
			
		||||
    document.body.appendChild(labelRenderer.domElement);
 | 
			
		||||
 | 
			
		||||
    // 将呈现器的输出添加到HTML元素
 | 
			
		||||
    document.getElementById("dom").appendChild(renderer.domElement);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const createLableObj = (text) => {
 | 
			
		||||
    let laberDiv = document.createElement("div"); //创建div容器
 | 
			
		||||
    laberDiv.className = "laber_name";
 | 
			
		||||
    laberDiv.innerHTML = `<div class="arrow_outer"></div><span>设备名称:${text}</span><span>状态:启用</span><span>压力:50 Pa</span>`
 | 
			
		||||
    let pointLabel = new CSS2DObject(laberDiv);
 | 
			
		||||
    return pointLabel;
 | 
			
		||||
};
 | 
			
		||||
// 清除模型颜色
 | 
			
		||||
const cleanColor = () => {
 | 
			
		||||
 | 
			
		||||
    // 恢复之前被选中模型的材质
 | 
			
		||||
    if (objArr.length > 0 && objM.length > 0) {
 | 
			
		||||
        objArr.forEach((ele, index) => {
 | 
			
		||||
            console.log(objM[index]);
 | 
			
		||||
            ele.material = objM[index]
 | 
			
		||||
        })
 | 
			
		||||
        objArr = [];
 | 
			
		||||
        objM = [];
 | 
			
		||||
    }
 | 
			
		||||
    gltfObj.value.scene.traverse(e => {
 | 
			
		||||
        objArr.push(e);
 | 
			
		||||
        objM.push(e.material);
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
const init = () => {
 | 
			
		||||
    // 环境球
 | 
			
		||||
    // scene = new THREE.Scene("#00ffff");
 | 
			
		||||
    // const texture = new THREE.TextureLoader().load(homeIcon);
 | 
			
		||||
    // texture.mapping = THREE.EquirectangularReflectionMapping;
 | 
			
		||||
| 
						 | 
				
			
			@ -190,46 +142,44 @@ const init = () => {
 | 
			
		|||
    // scene.environment = texture
 | 
			
		||||
 | 
			
		||||
    scene = new THREE.Scene();
 | 
			
		||||
    console.log(123, props.background);
 | 
			
		||||
    scene.background = new THREE.Color(props.background);
 | 
			
		||||
    const canvas = document.querySelector("#three");
 | 
			
		||||
    var cubeLoader = new THREE.CubeTextureLoader();
 | 
			
		||||
    // 创建一个渲染器并设置大小,WebGLRenderer将会使用电脑显卡来渲染场景
 | 
			
		||||
    renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true, preserveDrawingBuffer: true });
 | 
			
		||||
    //曝光
 | 
			
		||||
    renderer.toneMappingExposure = 2;
 | 
			
		||||
    renderer.shadowMap.enabled = true;
 | 
			
		||||
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
 | 
			
		||||
 | 
			
		||||
    //相机
 | 
			
		||||
    camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.25, 2000)
 | 
			
		||||
    // 将摄像机对准场景的中心
 | 
			
		||||
    camera.position.set(-92.936, 180.990, -28.179);
 | 
			
		||||
    camera.lookAt(scene.position);
 | 
			
		||||
    // 创建控件对象
 | 
			
		||||
 | 
			
		||||
    // 创建控件对象 限制controls的上下角度范围
 | 
			
		||||
    orbit = new OrbitControls(camera, renderer.domElement);
 | 
			
		||||
    orbit.autoRotate = true;
 | 
			
		||||
    setTimeout(function () {
 | 
			
		||||
        orbit.autoRotate = false;
 | 
			
		||||
    }, 7000);
 | 
			
		||||
    // renderer.setClearColor(new THREE.Color("#0e0934"));
 | 
			
		||||
    orbit.maxPolarAngle = Math.PI / 2.1;
 | 
			
		||||
    orbit.maxDistance = 12;
 | 
			
		||||
 | 
			
		||||
    renderer.setSize(window.innerWidth, window.innerHeight);
 | 
			
		||||
    // 环境光 光源颜色从0x444444更改为0x888888,可以看到threejs场景中的网格模型表面变的更亮。
 | 
			
		||||
    // intensity 强度属性0.5
 | 
			
		||||
    var alight = new THREE.AmbientLight(props.light, 1);
 | 
			
		||||
    alight.name = "aLight";
 | 
			
		||||
    scene.add(alight);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
    // 增加漫游路线
 | 
			
		||||
    makeCurve();
 | 
			
		||||
    
 | 
			
		||||
};
 | 
			
		||||
// 加载场景
 | 
			
		||||
const loadSence = () => {
 | 
			
		||||
    const gltfLoader = new GLTFLoader();
 | 
			
		||||
    gltfLoader.load(props.sceneUrl, (gltf) => {
 | 
			
		||||
        // model.value = gltf.scene;
 | 
			
		||||
        gltfObj.value = gltf;
 | 
			
		||||
        var model = gltf.scene;
 | 
			
		||||
        scene.add(model);
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 渲染
 | 
			
		||||
const renderScene = () => {
 | 
			
		||||
    // orbit.update(); // 拖动
 | 
			
		||||
    // 使用requestAnimationFrame函数进行渲染
 | 
			
		||||
| 
						 | 
				
			
			@ -242,40 +192,46 @@ const renderScene = () => {
 | 
			
		|||
    }
 | 
			
		||||
};
 | 
			
		||||
// 相机移动动画
 | 
			
		||||
const initTween = (targetX, targetY, targetZ) => {
 | 
			
		||||
    let initPosition = {
 | 
			
		||||
        x: camera.position.x,
 | 
			
		||||
        y: camera.position.y,
 | 
			
		||||
        z: camera.position.z,
 | 
			
		||||
    };
 | 
			
		||||
    let tween = new TWEEN.Tween(initPosition)
 | 
			
		||||
        .to({ x: targetX, y: targetY, z: targetZ }, 2000)
 | 
			
		||||
        .easing(TWEEN.Easing.Sinusoidal.InOut);
 | 
			
		||||
    let onUpdate = (pos) => {
 | 
			
		||||
        let x = pos.x;
 | 
			
		||||
        let y = pos.y;
 | 
			
		||||
        let z = pos.z;
 | 
			
		||||
        if (pos.z < 0) {
 | 
			
		||||
            camera.position.set(x, y, z - 12);
 | 
			
		||||
        } else {
 | 
			
		||||
            camera.position.set(x, y, z + 12);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    tween.onUpdate(onUpdate);
 | 
			
		||||
    tween.start();
 | 
			
		||||
    if (positionObj.z < 0) {
 | 
			
		||||
        orbit.target.set(
 | 
			
		||||
            positionObj.x,
 | 
			
		||||
            positionObj.y - 0.4,
 | 
			
		||||
            -12
 | 
			
		||||
        );
 | 
			
		||||
    } else {
 | 
			
		||||
        orbit.target.set(
 | 
			
		||||
            positionObj.x,
 | 
			
		||||
            positionObj.y - 0.4,
 | 
			
		||||
            12
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
const makeCurve = () => {
 | 
			
		||||
  curve = new THREE.CatmullRomCurve3([
 | 
			
		||||
    new THREE.Vector3(11.5, 0, 18),
 | 
			
		||||
    new THREE.Vector3(11.5, 0, 34),
 | 
			
		||||
    new THREE.Vector3(35, 0, 34),
 | 
			
		||||
    new THREE.Vector3(35, 0, 31),
 | 
			
		||||
    new THREE.Vector3(11.5, 0, 31),
 | 
			
		||||
  ]);
 | 
			
		||||
  // 为曲线添加材质在场景中显示出来,不显示也不会影响运动轨迹,相当于一个Helper
 | 
			
		||||
  const points = curve.getPoints(0.1);
 | 
			
		||||
  const geometry = new THREE.BufferGeometry().setFromPoints(points);
 | 
			
		||||
  const material = new THREE.LineBasicMaterial({
 | 
			
		||||
    color: 0xff0000,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // 线条模型对象
 | 
			
		||||
  const line = new THREE.Line(geometry, material);
 | 
			
		||||
  scene.add(line)
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const changePosition = (t) => {
 | 
			
		||||
  const position = curve.getPointAt(t); // t: 当前点在线条上的位置百分比,后面计算
 | 
			
		||||
  mesh.position.copy(position);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const changeLookAt = (t) => {
 | 
			
		||||
  const tangent = curve.getTangentAt(t);
 | 
			
		||||
  const lookAtVec = tangent.add(mesh.position); // 位置向量和切线向量相加即为所需朝向的点向量
 | 
			
		||||
  mesh.lookAt(lookAtVec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const loopTime = 10 * 1000; // loopTime: 循环一圈的时间
 | 
			
		||||
const walk = () => {
 | 
			
		||||
    let time = Date.now();
 | 
			
		||||
    setInterval(() => {
 | 
			
		||||
        let t = (time % loopTime) / loopTime; // 计算当前时间进度百分比
 | 
			
		||||
        changePosition(t);
 | 
			
		||||
        changeLookAt(t);
 | 
			
		||||
    }, 1000)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 储存被选中的模型和材质
 | 
			
		||||
| 
						 | 
				
			
			@ -360,54 +316,75 @@ const outlineObj = (selectedObject_list) => {
 | 
			
		|||
    composer.addPass(effectFXAA)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const nearCamera = (intersects) => {
 | 
			
		||||
    console.log(5555, intersects)
 | 
			
		||||
    // 拉近场景
 | 
			
		||||
    if (!intersects[0]) {
 | 
			
		||||
        return;
 | 
			
		||||
    } else {
 | 
			
		||||
        if (intersects[0].object.name) {
 | 
			
		||||
            selectedObjects = [];
 | 
			
		||||
            selectedObjects.push(intersects[0].object);
 | 
			
		||||
            positionObj = {
 | 
			
		||||
                x: intersects[0].object.position.x,
 | 
			
		||||
                y: intersects[0].object.position.y,
 | 
			
		||||
                z: intersects[0].object.position.z,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            initTween(
 | 
			
		||||
                positionObj.x,
 | 
			
		||||
                positionObj.y,
 | 
			
		||||
                positionObj.z + 10
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
const nearCamera = (floor) => {
 | 
			
		||||
    orbit.reset();
 | 
			
		||||
    gsap.to(camera.position, {
 | 
			
		||||
        x: floor.position.x - 40,
 | 
			
		||||
        y: floor.position.y + 60,
 | 
			
		||||
        z: floor.position.z,
 | 
			
		||||
        duration: 2,
 | 
			
		||||
        ease: "power1.inOut",
 | 
			
		||||
        onComplete: () => {
 | 
			
		||||
        },
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
const toHomeView = () => {
 | 
			
		||||
    camera.position.set(-92.936, 180.990, -28.179);
 | 
			
		||||
    camera.lookAt(scene.position);
 | 
			
		||||
    // cleanColor();
 | 
			
		||||
    orbit.reset();
 | 
			
		||||
    outlineObj([]);
 | 
			
		||||
}
 | 
			
		||||
// 返回主页
 | 
			
		||||
const toHomeView1 = () => {
 | 
			
		||||
    let initPosition = {
 | 
			
		||||
        x: camera.position.x,
 | 
			
		||||
        y: camera.position.y,
 | 
			
		||||
        z: camera.position.z,
 | 
			
		||||
    };
 | 
			
		||||
    let tween = new TWEEN.Tween(initPosition)
 | 
			
		||||
        .to({ x: 0, y: -(5 * 24) / 12, z: (6 * 100) / 5 }, 2000)
 | 
			
		||||
        .easing(TWEEN.Easing.Sinusoidal.InOut);
 | 
			
		||||
    let onUpdate = (pos) => {
 | 
			
		||||
        let x = pos.x;
 | 
			
		||||
        let y = pos.y;
 | 
			
		||||
        let z = pos.z;
 | 
			
		||||
        camera.position.set(x, y, z);
 | 
			
		||||
    };
 | 
			
		||||
    tween.onUpdate(onUpdate);
 | 
			
		||||
    tween.start();
 | 
			
		||||
    orbit.target.set(0, 0, 0);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const setLabel = () => {
 | 
			
		||||
    if(isAddLabel.value) {
 | 
			
		||||
        addLabel();
 | 
			
		||||
    } else {
 | 
			
		||||
        removeLabel();
 | 
			
		||||
    }
 | 
			
		||||
    isAddLabel.value = !isAddLabel.value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const removeLabel = () => {
 | 
			
		||||
    document.body.removeChild(labelRenderer.domElement);
 | 
			
		||||
}
 | 
			
		||||
// 添加标签
 | 
			
		||||
const addLabel = () => {
 | 
			
		||||
    let obj = gltfObj.value.scene.getObjectByName('set2');
 | 
			
		||||
    let text = "设备二";
 | 
			
		||||
    let pointLabel = createLableObj(text);
 | 
			
		||||
    obj.add(pointLabel);
 | 
			
		||||
    labelRenderer.setSize(window.innerWidth, window.innerHeight);
 | 
			
		||||
    labelRenderer.domElement.style.position = "absolute";
 | 
			
		||||
    labelRenderer.domElement.style.top = 0;
 | 
			
		||||
    labelRenderer.domElement.style.pointerEvents = 'none';// 必须加上
 | 
			
		||||
    document.body.appendChild(labelRenderer.domElement);
 | 
			
		||||
 | 
			
		||||
    // 将呈现器的输出添加到HTML元素
 | 
			
		||||
    document.getElementById("dom").appendChild(renderer.domElement);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const createLableObj = (text) => {
 | 
			
		||||
    let laberDiv = document.createElement("div"); //创建div容器
 | 
			
		||||
    laberDiv.className = "laber_name";
 | 
			
		||||
    laberDiv.innerHTML = `<div class="arrow_outer"></div><span>设备名称:${text}</span><span>状态:启用</span><span>压力:50 Pa</span>`
 | 
			
		||||
    let pointLabel = new CSS2DObject(laberDiv);
 | 
			
		||||
    return pointLabel;
 | 
			
		||||
};
 | 
			
		||||
// 清除模型颜色
 | 
			
		||||
const cleanColor = () => {
 | 
			
		||||
    // 恢复之前被选中模型的材质
 | 
			
		||||
    if (objArr.length > 0 && objM.length > 0) {
 | 
			
		||||
        objArr.forEach((ele, index) => {
 | 
			
		||||
            console.log(objM[index]);
 | 
			
		||||
            ele.material = objM[index]
 | 
			
		||||
        })
 | 
			
		||||
        objArr = [];
 | 
			
		||||
        objM = [];
 | 
			
		||||
    }
 | 
			
		||||
    gltfObj.value.scene.traverse(e => {
 | 
			
		||||
        objArr.push(e);
 | 
			
		||||
        objM.push(e.material);
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang='scss'>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue