|
@@ -1,12 +1,15 @@
|
|
import * as THREE from 'three';
|
|
import * as THREE from 'three';
|
|
import { CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
|
|
import { CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
|
|
-import { animateCamera, getTextCanvas, renderVideo } from '/@/utils/threejs/util';
|
|
|
|
|
|
+import { animateCamera, getTextCanvas, renderVideo, updateAxisCenter } from '/@/utils/threejs/util';
|
|
import UseThree from '../../../../utils/threejs/useThree';
|
|
import UseThree from '../../../../utils/threejs/useThree';
|
|
import fcFan from './fcfanLocal.three';
|
|
import fcFan from './fcfanLocal.three';
|
|
import fmFan from './fmfanLocal.three';
|
|
import fmFan from './fmfanLocal.three';
|
|
import Smoke from '/@/views/vent/comment/threejs/Smoke';
|
|
import Smoke from '/@/views/vent/comment/threejs/Smoke';
|
|
import gsap from 'gsap';
|
|
import gsap from 'gsap';
|
|
import { useAppStore } from '/@/store/modules/app';
|
|
import { useAppStore } from '/@/store/modules/app';
|
|
|
|
+// import * as dat from 'dat.gui';
|
|
|
|
+// const gui = new dat.GUI();
|
|
|
|
+// gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
|
|
|
|
|
|
const modelName = 'jbfj_hd';
|
|
const modelName = 'jbfj_hd';
|
|
// 模型对象、 文字对象
|
|
// 模型对象、 文字对象
|
|
@@ -25,6 +28,15 @@ const appStore = useAppStore();
|
|
|
|
|
|
// 打灯光
|
|
// 打灯光
|
|
const addLight = (scene) => {
|
|
const addLight = (scene) => {
|
|
|
|
+ const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
|
|
|
+ directionalLight.position.set(106, -348, 19.9);
|
|
|
|
+ group.add(directionalLight);
|
|
|
|
+ directionalLight.target = group;
|
|
|
|
+
|
|
|
|
+ // gui.add(directionalLight.position, 'x', -1000, 1000);
|
|
|
|
+ // gui.add(directionalLight.position, 'y', -1000, 1000);
|
|
|
|
+ // gui.add(directionalLight.position, 'z', -1000, 1000);
|
|
|
|
+
|
|
// const pointLight2 = new THREE.PointLight(0xffeeee, 1.5, 100);
|
|
// const pointLight2 = new THREE.PointLight(0xffeeee, 1.5, 100);
|
|
// pointLight2.position.set(-120, 16, -33);
|
|
// pointLight2.position.set(-120, 16, -33);
|
|
// pointLight2.shadow.bias = 0.05;
|
|
// pointLight2.shadow.bias = 0.05;
|
|
@@ -50,10 +62,10 @@ const addLight = (scene) => {
|
|
// pointLight6.shadow.bias = 0.05;
|
|
// pointLight6.shadow.bias = 0.05;
|
|
// scene.add(pointLight6);
|
|
// scene.add(pointLight6);
|
|
|
|
|
|
- const pointLight7 = new THREE.PointLight(0xffffff, 0.8, 500);
|
|
|
|
- pointLight7.position.set(-20, -43, 12);
|
|
|
|
- pointLight7.shadow.bias = -0.05;
|
|
|
|
- scene.add(pointLight7);
|
|
|
|
|
|
+ // const pointLight7 = new THREE.PointLight(0xffffff, 0.8, 500);
|
|
|
|
+ // pointLight7.position.set(-20, -43, 12);
|
|
|
|
+ // pointLight7.shadow.bias = -0.05;
|
|
|
|
+ // scene.add(pointLight7);
|
|
|
|
|
|
const spotLight = new THREE.SpotLight();
|
|
const spotLight = new THREE.SpotLight();
|
|
spotLight.angle = Math.PI / 16;
|
|
spotLight.angle = Math.PI / 16;
|
|
@@ -66,6 +78,7 @@ const addLight = (scene) => {
|
|
spotLight.shadow.camera.far = 1000; // default
|
|
spotLight.shadow.camera.far = 1000; // default
|
|
spotLight.shadow.focus = 1;
|
|
spotLight.shadow.focus = 1;
|
|
spotLight.shadow.bias = -0.000002;
|
|
spotLight.shadow.bias = -0.000002;
|
|
|
|
+ spotLight.target = group;
|
|
|
|
|
|
// gui.add(pointLight6.position, 'x', -200, 200);
|
|
// gui.add(pointLight6.position, 'x', -200, 200);
|
|
// gui.add(pointLight6.position, 'y', -200, 200);
|
|
// gui.add(pointLight6.position, 'y', -200, 200);
|
|
@@ -85,7 +98,7 @@ const resetCamera = () => {
|
|
|
|
|
|
// 设置模型位置
|
|
// 设置模型位置
|
|
const setModalPosition = () => {
|
|
const setModalPosition = () => {
|
|
- group.position.set(0, 18, -50);
|
|
|
|
|
|
+ group.position.set(0, 13, -50);
|
|
group.rotation.y = Math.PI / 2;
|
|
group.rotation.y = Math.PI / 2;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -111,7 +124,7 @@ export const setModelType = (type) => {
|
|
await animateCamera(
|
|
await animateCamera(
|
|
oldCameraPosition,
|
|
oldCameraPosition,
|
|
oldCameraPosition,
|
|
oldCameraPosition,
|
|
- { x: 0, y: 30, z: 80 },
|
|
|
|
|
|
+ { x: 0, y: 20, z: 80 },
|
|
{ x: position.x, y: position.y, z: position.z },
|
|
{ x: position.x, y: position.y, z: position.z },
|
|
model,
|
|
model,
|
|
0.8
|
|
0.8
|
|
@@ -130,7 +143,7 @@ export const setModelType = (type) => {
|
|
await animateCamera(
|
|
await animateCamera(
|
|
oldCameraPosition,
|
|
oldCameraPosition,
|
|
oldCameraPosition,
|
|
oldCameraPosition,
|
|
- { x: 0, y: 30, z: 80 },
|
|
|
|
|
|
+ { x: 0, y: 20, z: 80 },
|
|
{ x: position.x, y: position.y, z: position.z },
|
|
{ x: position.x, y: position.y, z: position.z },
|
|
model,
|
|
model,
|
|
0.8
|
|
0.8
|
|
@@ -245,7 +258,7 @@ export const addCssText = () => {
|
|
fanLocalCSS3D.name = 'text1';
|
|
fanLocalCSS3D.name = 'text1';
|
|
fanLocalCSS3D.scale.set(0.04, 0.04, 0.04);
|
|
fanLocalCSS3D.scale.set(0.04, 0.04, 0.04);
|
|
fanLocalCSS3D.rotation.y = -Math.PI / 2;
|
|
fanLocalCSS3D.rotation.y = -Math.PI / 2;
|
|
- fanLocalCSS3D.position.set(-82.96, 5.97, -0.84);
|
|
|
|
|
|
+ fanLocalCSS3D.position.set(-85.68, 5.97, -17.74);
|
|
group.add(fanLocalCSS3D);
|
|
group.add(fanLocalCSS3D);
|
|
}
|
|
}
|
|
if (!group.getObjectByName('text2')) {
|
|
if (!group.getObjectByName('text2')) {
|
|
@@ -263,7 +276,7 @@ export const addCssText = () => {
|
|
fanLocalCSS3D.name = 'text3';
|
|
fanLocalCSS3D.name = 'text3';
|
|
fanLocalCSS3D.scale.set(0.1, 0.1, 0.1);
|
|
fanLocalCSS3D.scale.set(0.1, 0.1, 0.1);
|
|
fanLocalCSS3D.rotation.y = -Math.PI / 2;
|
|
fanLocalCSS3D.rotation.y = -Math.PI / 2;
|
|
- fanLocalCSS3D.position.set(74.63, 10.05, -37.23);
|
|
|
|
|
|
+ fanLocalCSS3D.position.set(35.28, 10.05, -37.23);
|
|
group.add(fanLocalCSS3D);
|
|
group.add(fanLocalCSS3D);
|
|
}
|
|
}
|
|
if (!group.getObjectByName('text4')) {
|
|
if (!group.getObjectByName('text4')) {
|
|
@@ -281,7 +294,7 @@ export const addCssText = () => {
|
|
if (!group.getObjectByName('text5')) {
|
|
if (!group.getObjectByName('text5')) {
|
|
const element = document.getElementById('windownBox') as HTMLElement;
|
|
const element = document.getElementById('windownBox') as HTMLElement;
|
|
if (element) {
|
|
if (element) {
|
|
- element.innerHTML = '';
|
|
|
|
|
|
+ // element.innerHTML = '';
|
|
const fanLocalCSS3D = new CSS3DObject(element);
|
|
const fanLocalCSS3D = new CSS3DObject(element);
|
|
fanLocalCSS3D.name = 'text5';
|
|
fanLocalCSS3D.name = 'text5';
|
|
fanLocalCSS3D.scale.set(0.07, 0.07, 0.07);
|
|
fanLocalCSS3D.scale.set(0.07, 0.07, 0.07);
|
|
@@ -468,15 +481,22 @@ const startAnimation = () => {
|
|
};
|
|
};
|
|
// 鼠标点击、松开事件
|
|
// 鼠标点击、松开事件
|
|
const mouseEvent = (event) => {
|
|
const mouseEvent = (event) => {
|
|
|
|
+ const factor = 3;
|
|
event.stopPropagation();
|
|
event.stopPropagation();
|
|
const widthScale = appStore.getWidthScale;
|
|
const widthScale = appStore.getWidthScale;
|
|
const heightScale = appStore.getHeightScale;
|
|
const heightScale = appStore.getHeightScale;
|
|
|
|
+
|
|
// 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
|
|
// 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
|
|
model.mouse.x =
|
|
model.mouse.x =
|
|
((-model.canvasContainer.getBoundingClientRect().left * widthScale + event.clientX) / (model.canvasContainer.clientWidth * widthScale)) * 2 - 1;
|
|
((-model.canvasContainer.getBoundingClientRect().left * widthScale + event.clientX) / (model.canvasContainer.clientWidth * widthScale)) * 2 - 1;
|
|
model.mouse.y =
|
|
model.mouse.y =
|
|
-((-model.canvasContainer.getBoundingClientRect().top + event.clientY) / (model.canvasContainer.clientHeight * heightScale)) * 2 + 1;
|
|
-((-model.canvasContainer.getBoundingClientRect().top + event.clientY) / (model.canvasContainer.clientHeight * heightScale)) * 2 + 1;
|
|
|
|
+ // model.orbitControls.target.set()
|
|
|
|
+
|
|
(model.rayCaster as THREE.Raycaster).setFromCamera(model.mouse, model.camera as THREE.Camera);
|
|
(model.rayCaster as THREE.Raycaster).setFromCamera(model.mouse, model.camera as THREE.Camera);
|
|
|
|
+
|
|
|
|
+ updateAxisCenter(model, event);
|
|
|
|
+
|
|
if (group) {
|
|
if (group) {
|
|
const intersects = model.rayCaster?.intersectObjects(group.children, false) as THREE.Intersection[];
|
|
const intersects = model.rayCaster?.intersectObjects(group.children, false) as THREE.Intersection[];
|
|
if (intersects.length > 0) {
|
|
if (intersects.length > 0) {
|
|
@@ -501,8 +521,8 @@ export const mountedThree = (playerVal1) => {
|
|
return new Promise((resolve) => {
|
|
return new Promise((resolve) => {
|
|
model = new UseThree('#fanLocal3D', '#fanLocal3DCSS');
|
|
model = new UseThree('#fanLocal3D', '#fanLocal3DCSS');
|
|
model.setEnvMap('test1');
|
|
model.setEnvMap('test1');
|
|
- model.renderer.toneMappingExposure = 0.8;
|
|
|
|
- addLight(model.scene);
|
|
|
|
|
|
+ model.renderer.toneMappingExposure = 1;
|
|
|
|
+
|
|
resetCamera();
|
|
resetCamera();
|
|
model.setModel([modelName]).then(async (gltf) => {
|
|
model.setModel([modelName]).then(async (gltf) => {
|
|
group = gltf[0];
|
|
group = gltf[0];
|
|
@@ -512,6 +532,7 @@ export const mountedThree = (playerVal1) => {
|
|
setControls();
|
|
setControls();
|
|
initFly();
|
|
initFly();
|
|
model.animate();
|
|
model.animate();
|
|
|
|
+ addLight(model.scene);
|
|
|
|
|
|
fcFanObj = new fcFan(model);
|
|
fcFanObj = new fcFan(model);
|
|
await fcFanObj.mountedThree();
|
|
await fcFanObj.mountedThree();
|
|
@@ -526,6 +547,40 @@ export const mountedThree = (playerVal1) => {
|
|
mesh.position.set(-84.87, 0.298, 24.76);
|
|
mesh.position.set(-84.87, 0.298, 24.76);
|
|
mesh.rotation.y = -Math.PI / 2;
|
|
mesh.rotation.y = -Math.PI / 2;
|
|
group.add(mesh);
|
|
group.add(mesh);
|
|
|
|
+ } else {
|
|
|
|
+ const textArr = [
|
|
|
|
+ {
|
|
|
|
+ text: `无信号输入`,
|
|
|
|
+ font: 'normal 40px Arial',
|
|
|
|
+ color: '#009900',
|
|
|
|
+ strokeStyle: '#002200',
|
|
|
|
+ x: 170,
|
|
|
|
+ y: 40,
|
|
|
|
+ },
|
|
|
|
+ ];
|
|
|
|
+ getTextCanvas(560, 346, textArr, '').then((canvas: HTMLCanvasElement) => {
|
|
|
|
+ const textMap = new THREE.CanvasTexture(canvas); // 关键一步
|
|
|
|
+ const textMaterial = new THREE.MeshBasicMaterial({
|
|
|
|
+ map: textMap, // 设置纹理贴图
|
|
|
|
+ transparent: true,
|
|
|
|
+ side: THREE.DoubleSide, // 这里是双面渲染的意思
|
|
|
|
+ });
|
|
|
|
+ textMaterial.blending = THREE.CustomBlending;
|
|
|
|
+ const monitorPlane = group?.getObjectByName('noPlayer');
|
|
|
|
+ if (monitorPlane) {
|
|
|
|
+ monitorPlane.material = textMaterial;
|
|
|
|
+ } else {
|
|
|
|
+ const planeGeometry = new THREE.PlaneGeometry(100, 100); // 平面3维几何体PlaneGeometry
|
|
|
|
+ const planeMesh = new THREE.Mesh(planeGeometry, textMaterial);
|
|
|
|
+ if (!videoPlayer1) {
|
|
|
|
+ planeMesh.name = 'noPlayer';
|
|
|
|
+ planeMesh.scale.set(0.07, 0.05, 0.07);
|
|
|
|
+ planeMesh.position.set(-84.82, -1.53, 24.94);
|
|
|
|
+ planeMesh.rotation.y = -Math.PI / 2;
|
|
|
|
+ group?.add(planeMesh.clone());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
}
|
|
}
|
|
startAnimation();
|
|
startAnimation();
|
|
resolve(model);
|
|
resolve(model);
|