public/models/agv/aa/SE-1.FBX | 补丁 | 查看 | 原始文档 | blame | 历史 | |
public/models/agv/aa/SE-2.FBX | 补丁 | 查看 | 原始文档 | blame | 历史 | |
public/models/agv/aa/SE-3.FBX | 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/assets/data/agv.js | 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/agv.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/box.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/warehouse.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
public/models/agv/aa/SE-1.FBXBinary files differ
public/models/agv/aa/SE-2.FBXBinary files differ
public/models/agv/aa/SE-3.FBXBinary files differ
src/assets/data/agv.js
src/components/agv.jsx
@@ -1,62 +1,69 @@ import { useRef, useEffect } from 'react'; import { useState, useMemo, useRef, useEffect } from 'react'; import { useFrame } from '@react-three/fiber'; import { useFBX, useAnimations } from '@react-three/drei'; import { AnimationMixer } from 'three'; import * as THREE from 'three'; import Box from './box'; const setShadow = (obj) => { obj.castShadow = true; obj.receiveShadow = true; if (obj.children) { obj.children.forEach((child) => { setShadow(child); }); } }; const setColor = (obj) => { if (obj.material) { obj.material.color.set(0x4680BF); } if (obj.children) { obj.children.forEach((child) => { setColor(child); }); } }; const Agv = (props) => { const fbxRef = useRef(); const mixerRef = useRef(); const { } = props; const fbx = useFBX('/models/agv/body.fbx'); const setShadow = (obj) => { obj.castShadow = true; obj.receiveShadow = true; if (obj.children) { obj.children.forEach((child) => { setShadow(child); }); const bodyModel = useMemo(() => { const fbx = useFBX('/models/agv/body.fbx'); if (!fbx.castShadow) { setShadow(fbx); } }; return fbx.clone(); }, []) const setColor = (obj) => { if (obj.material) { obj.material.color.set(0x4680BF); const loaderModel = useMemo(() => { const fbx = useFBX('/models/agv/loader.fbx'); if (!fbx.castShadow) { setShadow(fbx); } if (obj.children) { obj.children.forEach((child) => { setColor(child); }); } }; return fbx.clone(); }, []) // setColor(fbx) if (!fbx.castShadow) { setShadow(fbx); } const forkModel = useMemo(() => { const fbx = useFBX('/models/agv/fork.fbx'); if (!fbx.castShadow) { setShadow(fbx); } return fbx.clone(); }, []) useEffect(() => { mixerRef.current = new AnimationMixer(fbx); if (fbx.animations.length > 0) { useFrame((state, delta) => { mixerRef?.current?.update(delta); }); const action = mixerRef.current.clipAction(fbx.animations[0]); // 假设只有一个动画,可以根据实际情况修改 action.play(); } return () => { mixerRef.current.stopAllAction(); }; }, []); return ( <> <group rotation={[0, 0, 0]} scale={0.5} position={[0, 0, 0]}> <primitive object={fbx} castShadow /> <primitive object={bodyModel} castShadow /> <primitive object={loaderModel} castShadow position={[0, 100, 0]} /> <primitive object={forkModel} castShadow position={[0, 120, 0]} /> <Box position={[100, 100, 300]} /> </group> </> ) src/components/box.jsx
New file @@ -0,0 +1,52 @@ 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'; const setShadow = (obj) => { obj.castShadow = true; obj.receiveShadow = true; if (obj.children) { obj.children.forEach((child) => { setShadow(child); }); } }; const setColor = (obj) => { if (obj.material) { obj.material.color.set(0x4680BF); } if (obj.children) { obj.children.forEach((child) => { setColor(child); }); } }; const Box = (props) => { const { position = [0, 300, 0] } = props; const boxModel = useMemo(() => { const fbx = useFBX('/models/box/box.fbx'); if (!fbx.castShadow) { setShadow(fbx); } return fbx.clone(); }, []) useEffect(() => { }, []); return ( <> <group rotation={[0, 0, 0]} scale={0.5} position={position}> <primitive object={boxModel} castShadow /> </group> </> ) } export default Box; src/core/warehouse.jsx
@@ -2,34 +2,43 @@ import { useFrame } from '@react-three/fiber'; import * as THREE from 'three'; import Agv from '../components/agv'; import Box from '../components/box'; import tunnelData from '../assets/data/tunnel'; import Tunnel from '../components/tunnel'; const Warehouse = (props) => { const [agvData, setAgvData] = useState([]); const [agvData, setAgvData] = useState([ {} ]); const [boxData, setBoxData] = useState([ {} ]) useEffect(() => { }, []) const agvEl = agvData.map((data, idx) => <Agv key={idx} {...data} />) const tunnelEl = useMemo(() => { return tunnelData.map((tunnel, index) => <Tunnel key={index} {...tunnel} />) }, []); const agvEl = agvData.map((data, idx) => <Agv key={idx} {...data} />) const boxEl = boxData.map((data, idx) => <Box key={idx} {...data} />) useFrame((state, delta) => { // setAgvData(); // setBoxData(); }) return ( <> <group> {agvEl} {tunnelEl} {agvEl} {boxEl} </group> </> )