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