import React, { useEffect, useRef, useState, useContext, useMemo } from "react"; import * as BABYLON from "@babylonjs/core"; import "@babylonjs/core/Debug/debugLayer"; import "@babylonjs/inspector"; import "@babylonjs/loaders/glTF"; import { GridMaterial } from "@babylonjs/materials/"; import { Animatable, HemisphericLight, Mesh, Observable, Vector3, } from "@babylonjs/core"; import { useAppSelector } from "../store/hooks"; import { EquStatusInterface, selectEquStatus } from "../store/EquStatusEntity"; import eqInfoIcon from "../assets/image/eqInfoIcon.png"; import axios from "axios"; const onEquObservable = new Observable(); const myStyle = { width: "2635px", height: "536px", outline: "none", }; interface EqSubListInterface { eqName: string; subList: string[]; } function MybabylonJS() { const EquStatus = useAppSelector(selectEquStatus); const canvasRef = useRef(null); onEquObservable.notifyObservers(EquStatus); // const [selectedMeshName, setSelectedMeshName] = useState(null); const [eqSubList, setEqSubList] = useState(); // 使用 useRef 来存储当前加载的模型引用 const currentMeshesRef = useRef>([]); useEffect(() => { // 确保 canvas 引用存在 if (!canvasRef.current) return; const canvas = canvasRef.current; const engine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true, }); const createScene = async function () { // This creates a basic Babylon Scene object (non-mesh) const scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color4(0, 0, 0, 0); const baseLight = new HemisphericLight( "hemiLight", new Vector3(1, 1, 0), scene ); baseLight.intensity = 0.7; // baseLight.diffuse = new BABYLON.Color3(1, 1, 1); // baseLight.specular = new BABYLON.Color3(0.25, 0.25, 0.25); // baseLight.groundColor = new BABYLON.Color3(0.5, 0.5, 0.5); //add an arcRotateCamera to the scene const camera = new BABYLON.ArcRotateCamera( "camera", -Math.PI / 2, Math.PI / 2.9, 120, new BABYLON.Vector3(0, 10, 0) ); // console.log("camera", camera); camera.lowerRadiusLimit = 10; camera.upperRadiusLimit = 600; camera.fov = 0.4; // This attaches the camera to the canvas camera.attachControl(canvas, true); //创建一个材质 const newMt = new BABYLON.StandardMaterial("newMt"); newMt.diffuseColor = BABYLON.Color3.Blue(); const ground = BABYLON.MeshBuilder.CreateGround( "ground", { width: 1000, height: 1000, subdivisions: 1, }, scene ); ground.scaling.x = 100; ground.scaling.z = ground.scaling.x; ground.isPickable = false; let grid = new GridMaterial("grid", scene); grid.majorUnitFrequency = 10; grid.minorUnitVisibility = 0.3; grid.gridRatio = 0.04; grid.backFaceCulling = !1; grid.mainColor = new BABYLON.Color3(1, 1, 1); grid.lineColor = new BABYLON.Color3(1, 1, 1); grid.opacity = 0; grid.zOffset = 1; // grid.opacityTexture = new BABYLON.Texture( // "/public/png/backgroundGround.png", // scene // ); ground.material = grid; let hl = new BABYLON.HighlightLayer("hl1", scene); let hl2 = new BABYLON.HighlightLayer("hl2", scene); // 定义一个函数来加载或重新加载模型 const loadOrReloadModel = async () => { // 在加载新模型之前卸载已加载的模型 currentMeshesRef.current.forEach((mesh) => { if (mesh && mesh.parent) { scene.removeMesh(mesh, true); } }); currentMeshesRef.current = []; // 重置模型数组 try { // 使用 ImportMeshAsync 加载新模型 var LOD0MESH = await BABYLON.SceneLoader.ImportMeshAsync( "", "/Line/", "line.babylon", scene ); // 将新加载的模型添加到 currentMeshesRef 中 currentMeshesRef.current.push(...LOD0MESH.meshes); // ...为新加载的模型设置交互逻辑 LOD0MESH.meshes.map((mesh) => { mesh.isPickable = true; mesh.actionManager = new BABYLON.ActionManager(scene); //鼠标移动到物体上亮显 mesh.actionManager.registerAction( new BABYLON.ExecuteCodeAction( BABYLON.ActionManager.OnPointerOverTrigger, () => { // @ts-ignore hl.addMesh(mesh, BABYLON.Color3.Green()); } ) ); mesh.actionManager.registerAction( new BABYLON.ExecuteCodeAction( BABYLON.ActionManager.OnPointerOutTrigger, () => { // @ts-ignore hl.removeMesh(mesh); } ) ); // mesh._scene.onPointerDown = async (event, _pickResult) => { // const pickInfo = mesh._scene.pick( // mesh._scene.pointerX, // mesh._scene.pointerY // ); // const clickedPosition = _pickResult.pickedPoint; // //如果需要获取吗模型根节点,而不是模型中某个组件,请用一下方法 // // getRootNode(pickInfo.pickedMesh as BABYLON.Node) 如上篇文章getRootNode函数 // //判断是否是右键 // if (!(event.buttons === 1 && pickInfo.pickedMesh)) return; // const MeshId = pickInfo.pickedMesh.metadata.tags; // if (MeshId) { // // setSelectedMeshName(pickInfo.pickedMesh.name); // // axios.get("/wsconfig.json").then((r) => { // // console.log(r.data.url) // axios // .post( // "api/visual/DataCenter/equipmentSubstrateList", // { id: MeshId } // ) // .then((res) => { // let obj = { eqName: "-", subList: [] }; // obj.eqName = res.data.data.eqName || "-"; // obj.subList = res.data.data.subList || []; // setEqSubList(obj); // }); // // }); // } // }; }); } catch (error) { console.error("加载模型失败:", error); } }; // 调用函数以加载或重新加载模型 loadOrReloadModel(); function reset() { camera.target = new BABYLON.Vector3(0, 10, 0); camera.alpha = -Math.PI / 2; camera.beta = Math.PI / 2.9; camera.radius = 120; camera.fov = 0.4; } let resetCamera = setTimeout(reset, 15000); scene.onPointerObservable.add((pointerInfo) => { switch (pointerInfo.type) { case BABYLON.PointerEventTypes.POINTERMOVE: clearTimeout(resetCamera); resetCamera = setTimeout(reset, 15000); } }); return scene; }; // call the createScene function const scene = createScene(); scene.then((scene) => {}); // run the render loop scene.then( (scene) => { engine.runRenderLoop(function () { scene.render(); }); }, (reason) => { console.log(reason); } ); // Resize window.addEventListener("resize", function () { engine.resize(); }); // 组件卸载时的清理逻辑 return () => { // 清理场景和引擎资源 engine.dispose(); }; }, []); return (
{/*

当前选中的设备是:{selectedMeshName}

*/} {/*
设备名称:{eqSubList?.eqName || "-"}
{eqSubList?.subList[0] || "-"} {eqSubList?.subList[1] || "-"} {eqSubList?.subList[2] || "-"} {eqSubList?.subList[3] || "-"} {eqSubList?.subList[4] || "-"} {eqSubList?.subList[5] || "-"} {eqSubList?.subList[6] || "-"} {eqSubList?.subList[7] || "-"} {eqSubList?.subList[8] || "-"} {eqSubList?.subList[9] || "-"}
*/}
); } export default MybabylonJS;