import * as THREE from 'three'; import { getTextCanvas, addEnvMap, setModalCenter } from '/@/utils/threejs/util'; import { CSS3DSprite } from 'three/examples/jsm/renderers/CSS3DRenderer.js'; // import * as dat from 'dat.gui'; // const gui = new dat.GUI(); // gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999'; class NitrogenOverground { model; modelName = 'nitrogen'; group; animationTimer; isLRAnimation = true; direction = 1; playerStartClickTime1 = new Date().getTime(); playerStartClickTime2 = new Date().getTime(); deviceRunState = ''; nitrogenNum = 0; nitrogenGroup = []; constructor(model) { this.model = model; this.group = new THREE.Object3D(); this.group.name = this.modelName; } addLight() { const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); directionalLight.position.set(32, -1, 60); this.group.add(directionalLight); directionalLight.target = this.group; // gui.add(directionalLight.position, 'x', -500, 500) // gui.add(directionalLight.position, 'y', -500, 500) // gui.add(directionalLight.position, 'z', -200, 200) const spotLight = new THREE.SpotLight(); spotLight.angle = Math.PI / 4; spotLight.penumbra = 0; spotLight.castShadow = true; spotLight.distance = 0; spotLight.position.set(-88, 85, -88); spotLight.target = this.group; this.group.add(spotLight); spotLight.shadow.camera.near = 0.5; // default spotLight.shadow.camera.far = 1000; // default spotLight.shadow.focus = 1; spotLight.shadow.bias = -0.000002; // gui.add(spotLight.position, 'x', -800, 800).onChange(function (value) { // spotLight.position.x = Number(value); // }); // gui.add(spotLight.position, 'y', -800, 800).onChange(function (value) { // spotLight.position.y = Number(value); // }); // gui.add(spotLight.position, 'z', -800, 800).onChange(function (value) { // spotLight.position.z = Number(value); // }); } // 设置模型位置 setModalPosition() { if (this.nitrogenNum == 4) { this.group.position.set(0, -17, 3); this.group?.scale.set(24.0, 24.0, 24.0); } if (this.nitrogenNum == 3) { this.group.position.set(0, -1, 3); this.group?.scale.set(24.0, 24.0, 24.0); } if (this.nitrogenNum == 2) { this.group.position.set(0, 0.42, 1.21); this.group?.scale.set(24.0, 24.0, 24.0); } if (this.nitrogenNum == 1) { this.group.position.set(0, 8, 3.0); this.group?.scale.set(24.0, 24.0, 24.0); } } /* 提取风门序列帧,初始化前后门动画 */ initAnimation() {} /* 点击 */ mousedownModel(intersects: THREE.Intersection>[]) { this.isLRAnimation = false; if (this.animationTimer) { clearTimeout(this.animationTimer); this.animationTimer = null; } intersects.find((intersect) => { const mesh = intersect.object; return false; }); } mouseUpModel() {} // 播放动画 play() {} /** * 生序排列模型的子元素 */ sortMeshChildren = (children: THREE.Mesh[]) => { //生序排列 children.sort((x, y) => { return x.geometry.attributes.position.count - y.geometry.attributes.position.count; }); return children; }; /** * 设置模型透明 */ transparentModel = (model: THREE.Mesh) => { const transparentMaterial = new THREE.MeshBasicMaterial({ transparent: true, opacity: 0, }); model.material = transparentMaterial; }; addCssText = () => { if (this.nitrogenNum > 0) { for (let i = 0; i < this.nitrogenNum; i++) { const nitrogenModal = this.group.getObjectByName('nitrogenModal' + i) as THREE.Object3D; if (nitrogenModal && !nitrogenModal.getObjectByName('monitorNitrogenText')) { const element = document.getElementById('nitrogenMonitor' + (i + 1)) as HTMLElement; if (element) { const nitrogenMonitorCSS3D = new CSS3DSprite(element); nitrogenMonitorCSS3D.name = 'monitorNitrogenText' + i; nitrogenMonitorCSS3D.scale.set(0.003, 0.003, 0.003); if (i == 0) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0); if (i == 1) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0.04); if (i == 2) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0.08); if (i == 3) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0.12); nitrogenModal.add(nitrogenMonitorCSS3D); } } } } }; clearCssText = () => { if (this.nitrogenNum > 0) { for (let i = 0; i < this.nitrogenNum; i++) { const nitrogenModal = this.group.getObjectByName('nitrogenModal' + i) as THREE.Object3D; if (nitrogenModal && nitrogenModal.getObjectByName('monitorNitrogenText')) { nitrogenModal.remove(nitrogenModal.getObjectByName('monitorNitrogenText') as THREE.Object3D); } } } }; /** * 处理杯子的纹理和杯子外层透明壳子 */ handleGlassAndWrap = ( objects: THREE.Object3D, withVolume: THREE.Object3D[], glassModel: THREE.Mesh, params: THREE.MeshPhysicalMaterialParameters, scale: number, position: THREE.Vector3, rotation?: THREE.Vector3 ) => { //辨别杯子和壳 大的是杯子 小的是壳 壳的点比杯子少 const children = glassModel.children as THREE.Mesh[]; this.sortMeshChildren(children); children.forEach((mesh) => { mesh.position.copy(position); mesh.scale.set(scale, scale, scale); rotation && mesh.rotation.setFromVector3(rotation, 'XYZ'); }); const [transparentWrap, glass] = children; this.transparentModel(transparentWrap); glass.material = new THREE.MeshPhysicalMaterial({ side: THREE.DoubleSide, // specularColor: new Color("#ffffff"), // color: new Color(0xffa000), ...params, }); objects.add(...children); //只检测壳子 减小开销 withVolume.push(transparentWrap); }; mountedThree(nitrogenNum) { // this.nitrogenNum = nitrogenNum; return new Promise((resolve) => { if (nitrogenNum < 1) { resolve(null); return; } this.model.setGLTFModel([this.modelName]).then(async (gltf) => { for (let i = 0; i < nitrogenNum; i++) { const nitrogenModal = gltf[0].clone(); nitrogenModal.name = 'nitrogenModal' + i; this.nitrogenGroup.push(nitrogenModal); // const c = Math.floor(nitrogenNum / 2); // if (flag) { // nitrogenModal.position.set(0, 0, 1.355 * (c - i)); // } else { // nitrogenModal.position.set(0, 0, (c - i - 0.5) * 1.355); // } } // this.group = nitrogenGroup; this.addLight(); resolve(null); }); }); } destroy() { this.nitrogenGroup.forEach((item) => { this.model.clearGroup(item); }); this.nitrogenGroup = undefined; if (this.group) { this.model.clearGroup(this.group); } this.model = null; this.group = null; } } export default NitrogenOverground;