@ -1,447 +0,0 @@
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 "../page/style/standard.css" ;
import { EquStatusInterface , selectEquStatus } from "../store/EquStatusEntity" ;
import EquMap from "./EquMap" ;
// const onEquObservable = new Observable();
const myStyle = {
width : "1041px" ,
height : "562px" ,
outline : "none" ,
} ;
interface MybabylonJSProps {
modelPath : string ; // 明确 modelPath 属性的类型为 string
}
interface EqInfoListInterface {
[ key : string ] : EqInfo [ ] ;
}
interface EqInfo {
name : string ;
inputNum : number ;
outPut : number ;
position : [ number , number ] ;
}
const eqInfoList : EqInfoListInterface = {
"Line1-1" : [
{ name : "磨边机" , inputNum : 100 , outPut : 100 , position : [ 134 , 202 ] } ,
{ name : "磨边机" , inputNum : 101 , outPut : 101 , position : [ 82 , 306 ] } ,
{ name : "磨边机" , inputNum : 105 , outPut : 105 , position : [ 342 , 400 ] } ,
{ name : "打孔机" , inputNum : 100 , outPut : 100 , position : [ 337 , 51 ] } ,
{ name : "打孔机" , inputNum : 101 , outPut : 101 , position : [ 338 , 156 ] } ,
{ name : "打孔机" , inputNum : 105 , outPut : 105 , position : [ 510 , 310 ] } ,
{ name : "丝印机" , inputNum : 100 , outPut : 100 , position : [ 521 , 4 ] } ,
{ name : "丝印机" , inputNum : 101 , outPut : 101 , position : [ 520 , 90 ] } ,
{ name : "丝印机" , inputNum : 105 , outPut : 105 , position : [ 672 , 226 ] } ,
{ name : "一次固化" , inputNum : 100 , outPut : 100 , position : [ 756 , 2 ] } ,
{ name : "一次固化" , inputNum : 101 , outPut : 101 , position : [ 833 , 90 ] } ,
{ name : "一次固化" , inputNum : 105 , outPut : 105 , position : [ 835 , 186 ] } ,
] ,
"Line1-2" : [
{ name : "退火" , inputNum : 100 , outPut : 100 , position : [ 100 , 210 ] } ,
{ name : "铺纸机" , inputNum : 100 , outPut : 100 , position : [ 410 , 58 ] } ,
{ name : "铺纸机" , inputNum : 100 , outPut : 100 , position : [ 594 , 252 ] } ,
{ name : "下片机" , inputNum : 100 , outPut : 100 , position : [ 610 , 5 ] } ,
{ name : "下片机" , inputNum : 100 , outPut : 100 , position : [ 838 , 1 ] } ,
{ name : "下片机" , inputNum : 100 , outPut : 100 , position : [ 837 , 145 ] } ,
] ,
"Line2-1" : [
{ name : "磨边机" , inputNum : 100 , outPut : 100 , position : [ 134 , 202 ] } ,
{ name : "磨边机" , inputNum : 105 , outPut : 105 , position : [ 342 , 400 ] } ,
{ name : "打孔机" , inputNum : 101 , outPut : 101 , position : [ 338 , 156 ] } ,
{ name : "打孔机" , inputNum : 105 , outPut : 105 , position : [ 510 , 310 ] } ,
{ name : "丝印机" , inputNum : 101 , outPut : 101 , position : [ 520 , 90 ] } ,
{ name : "丝印机" , inputNum : 105 , outPut : 105 , position : [ 672 , 226 ] } ,
{ name : "一次固化" , inputNum : 100 , outPut : 100 , position : [ 724 , 38 ] } ,
{ name : "一次固化" , inputNum : 105 , outPut : 105 , position : [ 835 , 186 ] } ,
] ,
"Line2-2" : [
{ name : "退火" , inputNum : 100 , outPut : 100 , position : [ 215 , 247 ] } ,
{ name : "铺纸机" , inputNum : 100 , outPut : 100 , position : [ 710 , 237 ] } ,
{ name : "下片机" , inputNum : 100 , outPut : 100 , position : [ 502 , 58 ] } ,
{ name : "下片机" , inputNum : 100 , outPut : 100 , position : [ 733 , 3 ] } ,
] ,
"Line3-1" : [
{ name : "磨边机" , inputNum : 100 , outPut : 100 , position : [ 134 , 202 ] } ,
{ name : "磨边机" , inputNum : 105 , outPut : 105 , position : [ 342 , 400 ] } ,
{ name : "打孔机" , inputNum : 101 , outPut : 101 , position : [ 338 , 156 ] } ,
{ name : "打孔机" , inputNum : 105 , outPut : 105 , position : [ 510 , 310 ] } ,
{ name : "丝印机" , inputNum : 101 , outPut : 101 , position : [ 520 , 90 ] } ,
{ name : "丝印机" , inputNum : 105 , outPut : 105 , position : [ 672 , 226 ] } ,
{ name : "一次固化" , inputNum : 100 , outPut : 100 , position : [ 724 , 38 ] } ,
{ name : "一次固化" , inputNum : 105 , outPut : 105 , position : [ 835 , 186 ] } ,
] ,
"Line3-2" : [
{ name : "退火" , inputNum : 100 , outPut : 100 , position : [ 187 , 247 ] } ,
{ name : "铺纸机" , inputNum : 100 , outPut : 100 , position : [ 502 , 58 ] } ,
{ name : "下片机" , inputNum : 100 , outPut : 100 , position : [ 733 , 3 ] } ,
{ name : "下片机" , inputNum : 100 , outPut : 100 , position : [ 710 , 237 ] } ,
] ,
"Line4-1" : [
{ name : "磨边机" , inputNum : 100 , outPut : 100 , position : [ 231 , 216 ] } ,
{ name : "磨边机" , inputNum : 105 , outPut : 105 , position : [ 403 , 400 ] } ,
{ name : "一次固化" , inputNum : 101 , outPut : 101 , position : [ 520 , 90 ] } ,
{ name : "一次固化" , inputNum : 105 , outPut : 105 , position : [ 643 , 276 ] } ,
{ name : "二次固化" , inputNum : 100 , outPut : 100 , position : [ 724 , 38 ] } ,
{ name : "二次固化" , inputNum : 105 , outPut : 105 , position : [ 835 , 186 ] } ,
] ,
"Line4-2" : [
{ name : "退火" , inputNum : 100 , outPut : 100 , position : [ 187 , 247 ] } ,
{ name : "铺纸机" , inputNum : 100 , outPut : 100 , position : [ 710 , 237 ] } ,
{ name : "铺纸机" , inputNum : 100 , outPut : 100 , position : [ 820 , 237 ] } ,
{ name : "下片机" , inputNum : 100 , outPut : 100 , position : [ 553 , 7 ] } ,
{ name : "下片机" , inputNum : 100 , outPut : 100 , position : [ 839 , 137 ] } ,
] ,
"Line5-1" : [
{ name : "磨边机" , inputNum : 100 , outPut : 100 , position : [ 134 , 202 ] } ,
{ name : "磨边机" , inputNum : 101 , outPut : 101 , position : [ 82 , 306 ] } ,
{ name : "磨边机" , inputNum : 105 , outPut : 105 , position : [ 342 , 400 ] } ,
{ name : "一次固化" , inputNum : 100 , outPut : 100 , position : [ 521 , 4 ] } ,
{ name : "一次固化" , inputNum : 101 , outPut : 101 , position : [ 520 , 90 ] } ,
{ name : "一次固化" , inputNum : 105 , outPut : 105 , position : [ 672 , 287 ] } ,
{ name : "二次固化" , inputNum : 100 , outPut : 100 , position : [ 756 , 2 ] } ,
{ name : "二次固化" , inputNum : 101 , outPut : 101 , position : [ 833 , 90 ] } ,
{ name : "二次固化" , inputNum : 105 , outPut : 105 , position : [ 835 , 186 ] } ,
] ,
"Line5-2" : [
{ name : "退火" , inputNum : 100 , outPut : 100 , position : [ 100 , 270 ] } ,
{ name : "铺纸机" , inputNum : 100 , outPut : 100 , position : [ 434 , 133 ] } ,
{ name : "铺纸机" , inputNum : 100 , outPut : 100 , position : [ 640 , 305 ] } ,
{ name : "下片机" , inputNum : 100 , outPut : 100 , position : [ 645 , 54 ] } ,
{ name : "下片机" , inputNum : 100 , outPut : 100 , position : [ 838 , 1 ] } ,
{ name : "下片机" , inputNum : 100 , outPut : 100 , position : [ 837 , 226 ] } ,
] ,
} ;
function MybabylonJS ( { modelPath } : MybabylonJSProps ) {
console . log ( "modelPath:;;;;;;" , modelPath ) ;
// const EquStatus = useAppSelector(selectEquStatus);
const canvasRef = useRef ( null ) ;
// onEquObservable.notifyObservers(EquStatus);
const [ SelectedMeshName , setSelectedMeshName ] = useState < string | null > ( null ) ;
// 使用 useRef 来存储当前加载的模型引用
const currentMeshesRef = useRef < Array < BABYLON.AbstractMesh > > ( [ ] ) ;
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 = 1 ;
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" ,
BABYLON . Tools . ToRadians ( 245 ) ,
BABYLON . Tools . ToRadians ( 25 ) ,
modelPath . slice ( - 1 ) === "1"
? 110
: modelPath . slice ( - 3 ) === "5-2"
? 100
: 75 ,
new BABYLON . Vector3 ( - 13 , 0 , 0 )
) ;
console . log ( "camera" , camera ) ;
camera . lowerRadiusLimit = 10 ;
camera . upperRadiusLimit = 600 ;
// 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/" ,
` ${ modelPath } .babylon ` ,
scene
) ;
// 将新加载的模型添加到 currentMeshesRef 中
currentMeshesRef . current . push ( . . . LOD0MESH . meshes ) ;
// ...为新加载的模型设置交互逻辑
LOD0MESH . meshes . map ( ( mesh ) = > {
mesh . isPickable = true ;
mesh . actionManager = new BABYLON . ActionManager ( scene ) ;
// console.log("mesh==========", mesh);
if ( modelPath . slice ( - 1 ) === "1" ) {
if (
mesh . name . includes ( "磨边机" ) ||
mesh . name . includes ( "打孔机" ) ||
mesh . name . includes ( "丝印机" ) ||
mesh . name . includes ( "固化" )
) {
// @ts-ignore
hl . addMesh ( mesh , BABYLON . Color3 . Green ( ) ) ;
}
} else {
if (
mesh . name . includes ( "钢化" ) ||
mesh . name . includes ( "铺纸机" ) ||
mesh . name . includes ( "下片机械手" )
) {
// @ts-ignore
hl . addMesh ( mesh , BABYLON . Color3 . Green ( ) ) ;
}
}
//鼠标移动到物体上亮显
// mesh.actionManager.registerAction(
// new BABYLON.ExecuteCodeAction(
// BABYLON.ActionManager.OnPointerOverTrigger,
// (a) => {
// console.log("================", a);
// // @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 MeshName1 = pickInfo . pickedMesh . name . split ( "." ) [ 0 ] ;
setSelectedMeshName ( MeshName1 ) ;
} ;
} ) ;
// onEquObservable.add((eventData, eventState) => {
// LOD0MESH.meshes.find((mesh) => {
// // @ts-ignore
// hl2.removeMesh(mesh);
// });
// Object.keys(eventData as EquStatusInterface).map((key) => {
// // @ts-ignore
// if (eventData[key] == 2) {
// // @ts-ignore
// EquMap[key].map((name) => {
// LOD0MESH.meshes.find((mesh) => {
// if (mesh.name == name) {
// // @ts-ignore
// hl2.addMesh(mesh, BABYLON.Color3.Red());
// }
// });
// });
// }
// });
// });
} catch ( error ) {
console . error ( "加载模型失败:" , error ) ;
}
} ;
// 调用函数以加载或重新加载模型
loadOrReloadModel ( ) ;
function reset() {
camera . target = new BABYLON . Vector3 ( - 13 , 0 , 0 ) ;
camera . alpha = BABYLON . Tools . ToRadians ( 245 ) ;
camera . beta = BABYLON . Tools . ToRadians ( 25 ) ;
camera . radius =
modelPath . slice ( - 1 ) === "1"
? 110
: modelPath . slice ( - 3 ) === "5-2"
? 100
: 75 ;
}
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();
// };
} , [ modelPath ] ) ;
const resetModel = ( ) = > {
//模型初始位置
console . log ( "回到初始位置" ) ;
} ;
return (
< div style = { myStyle } >
< h2 className = "model_name" > 当 前 选 择 : { SelectedMeshName } < / h2 >
< div className = "model_info" >
< span className = "reset_btn" onClick = { resetModel } > < / span >
< span className = "title" > 第 五 产 线 钢 化 后 段 < / span >
< / div >
{ / * < d i v c l a s s N a m e = " e q _ d e t a i l _ i n f o " >
< div >
< span className = "left_name" > 设 备 名 称 : < / span >
< span className = "right_value" > 下 片 机 械 手 < / span >
< / div >
< div >
< span className = "left_name" > 进 口 数 量 : < / span >
< span className = "right_value" > 12 , 302 < / span >
< / div >
< div >
< span className = "left_name" > 出 口 数 量 : < / span >
< span className = "right_value" > 1 , 302 < / span >
< / div >
< div >
< span className = "left_name" > 报 警 状 态 : < / span >
< span className = "right_value" > 未 报 警 < / span >
< / div >
< div >
< span className = "left_name" > 在 线 状 态 : < / span >
< span className = "right_value" > 在 线 < / span >
< / div >
< / div > * / }
{ eqInfoList [ modelPath ] &&
eqInfoList [ modelPath ] . map ( ( item , index ) = > {
return (
< div
className = "eq_info"
key = { index }
style = { { left : item.position [ 0 ] , top : item.position [ 1 ] } }
>
< div >
< span className = "left_name" > 设 备 名 称 : < / span >
< span className = "right_value" > { item . name } < / span >
< / div >
< div >
< span className = "left_name" > 进 口 数 量 : < / span >
< span className = "right_value" > { item . inputNum } < / span >
< / div >
< div >
< span className = "left_name" > 出 口 数 量 : < / span >
< span className = "right_value" > { item . outPut } < / span >
< / div >
< / div >
) ;
} ) }
< canvas ref = { canvasRef } style = { myStyle } / >
< / div >
) ;
}
export default MybabylonJS ;