| | |
| | | import { |
| | | INTERVAL_TIME, |
| | | MODEL_AGV_SCALE, |
| | | MODEL_AGV_COLOR, |
| | | REAL_COMPARE_MAP_SCALE, |
| | | REAL_COMPARE_MAP_OFFSET_X, |
| | | REAL_COMPARE_MAP_OFFSET_Z, |
| | |
| | | const fbx = useFBX('/models/agv/body.fbx'); |
| | | if (!fbx.castShadow) { |
| | | Common.setShadow(fbx); |
| | | Common.setColor(fbx, MODEL_AGV_COLOR); |
| | | } |
| | | fbx.scale.set(MODEL_AGV_SCALE, MODEL_AGV_SCALE * 0.97, MODEL_AGV_SCALE); |
| | | return fbx.clone(); |
| | |
| | | const fbx = useFBX('/models/agv/loader.fbx'); |
| | | if (!fbx.castShadow) { |
| | | Common.setShadow(fbx); |
| | | Common.setColor(fbx, MODEL_AGV_COLOR); |
| | | } |
| | | fbx.scale.set(MODEL_AGV_SCALE, MODEL_AGV_SCALE, MODEL_AGV_SCALE); |
| | | return fbx.clone(); |
| | |
| | | const fbx = useFBX('/models/agv/fork.fbx'); |
| | | if (!fbx.castShadow) { |
| | | Common.setShadow(fbx); |
| | | Common.setColor(fbx, MODEL_AGV_COLOR); |
| | | } |
| | | fbx.scale.set(MODEL_AGV_SCALE, MODEL_AGV_SCALE, MODEL_AGV_SCALE); |
| | | return fbx.clone(); |
New file |
| | |
| | | import { useState, useMemo, useRef, useEffect } from 'react'; |
| | | import { useFrame } from '@react-three/fiber'; |
| | | import { useFBX, useAnimations } from '@react-three/drei'; |
| | | import * as THREE from 'three'; |
| | | import * as Common from '../utils/common'; |
| | | import * as TWEEN from "@tweenjs/tween.js"; |
| | | import { useStore } from '@/store'; |
| | | import { |
| | | INTERVAL_TIME, |
| | | MODEL_AGV_SCALE, |
| | | REAL_COMPARE_MAP_SCALE, |
| | | REAL_COMPARE_MAP_OFFSET_X, |
| | | REAL_COMPARE_MAP_OFFSET_Z, |
| | | } from '../config/setting' |
| | | |
| | | const width = 20; |
| | | |
| | | const getMajorPos = (position) => { |
| | | return { |
| | | x: position?.[2] * REAL_COMPARE_MAP_SCALE + REAL_COMPARE_MAP_OFFSET_X, |
| | | y: position?.[1] * REAL_COMPARE_MAP_SCALE, |
| | | z: position?.[0] * REAL_COMPARE_MAP_SCALE + REAL_COMPARE_MAP_OFFSET_Z, |
| | | } |
| | | } |
| | | |
| | | const Path = (props) => { |
| | | const { list } = props; |
| | | |
| | | const lineRef = useRef(); |
| | | |
| | | // Convert list of positions to THREE.Vector3 objects |
| | | const points = useMemo(() => { |
| | | return list.map(item => { |
| | | const { x, y, z } = getMajorPos(item.position); |
| | | return new THREE.Vector3(x, y, z); |
| | | }); |
| | | }, [list]); |
| | | |
| | | useEffect(() => { |
| | | if (lineRef.current) { |
| | | lineRef.current.geometry.setFromPoints(points); |
| | | } |
| | | console.log(points); |
| | | |
| | | }, [points]); |
| | | |
| | | useEffect(() => { |
| | | console.log(JSON.stringify(props.list)); |
| | | //[{"code":"00000052","position":[4961,0,2420],"serial":6},{"code":"00000053","position":[5491,0,2420],"serial":7},{"code":"00000054","position":[6021,0,2420],"serial":8}] |
| | | }, [props]) |
| | | |
| | | return ( |
| | | <> |
| | | <group> |
| | | {/* <mesh position={} rotation={[]}> |
| | | <planeGeometry |
| | | args={[width, height]} |
| | | ></planeGeometry> |
| | | <meshBasicMaterial color="rgb(23,146,247)"></meshBasicMaterial> |
| | | </mesh> */} |
| | | <line ref={lineRef}> |
| | | <bufferGeometry attach="geometry" /> |
| | | <lineBasicMaterial attach="material" color="rgb(23,146,247)" linewidth={width} /> |
| | | </line> |
| | | </group> |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default Path; |
| | |
| | | |
| | | export const BATCH_SCALE = 1.3; |
| | | |
| | | export const MODEL_AGV_COLOR = 0x4b4b4b; |
| | | |
| | | export const MODEL_AGV_SCALE = .7; |
| | | |
| | | export const MODEL_BOX_SCALE = .7; |
| | |
| | | import Shelf from '../components/shelf'; |
| | | import Box from '../components/box'; |
| | | import Agv from '../components/agv'; |
| | | import Path from '../components/path' |
| | | |
| | | import tunnelData from '@/assets/data/tunnel'; |
| | | import areaData from '@/assets/data/area'; |
| | |
| | | const [agv1Data, setAgv1Data] = useState({}); |
| | | const [agv2Data, setAgv2Data] = useState({}); |
| | | const [boxData, setBoxData] = useState([]); |
| | | const [path1Data, setPath1Data] = useState([]); |
| | | |
| | | useEffect(() => { |
| | | const websocket = new WebSocketClient('/ws/digitalTwin/websocket'); |
| | |
| | | break; |
| | | case "2": |
| | | setAgv2Data(data.obj); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | if (data.type === 'path') { |
| | | switch (data.no) { |
| | | case "1": |
| | | setPath1Data(data.obj); |
| | | break; |
| | | case "2": |
| | | break; |
| | | default: |
| | | break; |
| | |
| | | return <Agv key={2} {...agv2Data} /> |
| | | }, [agv2Data]); |
| | | |
| | | const path1El = useMemo(() => { |
| | | return <Path list={path1Data} /> |
| | | }, [path1Data]) |
| | | |
| | | useFrame((state, delta) => { |
| | | |
| | |
| | | {agv1El} |
| | | {agv2El} |
| | | {boxEl} |
| | | {path1El} |
| | | </group> |
| | | </> |
| | | ) |