import * as THREE from 'three'; import { useEffect, useRef, useState } from 'react'; import { useFrame } from '@react-three/fiber'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; import camModel from '../../assets/gltf-glb/camera face 2.gltf'; import getActiveUsersData from '../../services/factoryBuilder/collab/getActiveUsers'; import { useActiveUsers, useSocketStore } from '../../store/store'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; import { useNavigate } from 'react-router-dom'; import { Text, Html } from '@react-three/drei'; import CollabUserIcon from './collabUserIcon'; import image from '../../assets/image/userImage.png'; const CamModelsGroup = () => { let navigate = useNavigate(); const groupRef = useRef(null); const email = localStorage.getItem('email'); const { activeUsers, setActiveUsers } = useActiveUsers(); const { socket } = useSocketStore(); const loader = new GLTFLoader(); const dracoLoader = new DRACOLoader(); const [cams, setCams] = useState([]); const [models, setModels] = useState>({}); dracoLoader.setDecoderPath('three/examples/jsm/libs/draco/gltf/'); loader.setDRACOLoader(dracoLoader); useEffect(() => { if (!email) { navigate('/'); } if (!socket) return; const organization = email!.split('@')[1].split('.')[0]; socket.on('userConnectRespones', (data: any) => { if (!groupRef.current) return; if (data.data.userData.email === email) return if (socket.id === data.socketId || organization !== data.organization) return; const model = groupRef.current.getObjectByProperty('uuid', data.data.userData._id); if (model) { groupRef.current.remove(model); } loader.load(camModel, (gltf) => { const newModel = gltf.scene.clone(); newModel.uuid = data.data.userData._id; newModel.position.set(data.data.position.x, data.data.position.y, data.data.position.z); newModel.rotation.set(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z); newModel.userData = data.data.userData; setCams((prev) => [...prev, newModel]); setActiveUsers([...activeUsers, data.data.userData]); }); }); socket.on('userDisConnectRespones', (data: any) => { if (!groupRef.current) return; if (socket.id === data.socketId || organization !== data.organization) return; setCams((prev) => prev.filter((cam) => cam.uuid !== data.data.userData._id)); setActiveUsers(activeUsers.filter((user: any) => user._id !== data.data.userData._id)); }); socket.on('cameraUpdateResponse', (data: any) => { if (!groupRef.current || socket.id === data.socketId || organization !== data.organization) return; setModels((prev) => ({ ...prev, [data.data.userId]: { targetPosition: new THREE.Vector3(data.data.position.x, data.data.position.y, data.data.position.z), targetRotation: new THREE.Euler(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z), }, })); }); return () => { socket.off('userConnectRespones'); socket.off('userDisConnectRespones'); socket.off('cameraUpdateResponse'); }; }, [socket]); useFrame(() => { if (!groupRef.current) return; Object.keys(models).forEach((uuid) => { const model = groupRef.current!.getObjectByProperty('uuid', uuid); if (!model) return; const { targetPosition, targetRotation } = models[uuid]; model.position.lerp(targetPosition, 0.1); model.rotation.x = THREE.MathUtils.lerp(model.rotation.x, targetRotation.x, 0.1); model.rotation.y = THREE.MathUtils.lerp(model.rotation.y, targetRotation.y, 0.1); model.rotation.z = THREE.MathUtils.lerp(model.rotation.z, targetRotation.z, 0.1); }); }); useEffect(() => { if (!groupRef.current) return; const organization = email!.split('@')[1].split('.')[0]; getActiveUsersData(organization).then((data) => { const filteredData = data.cameraDatas.filter((camera: any) => camera.userData.email !== email); if (filteredData.length > 0) { loader.load(camModel, (gltf) => { const newCams = filteredData.map((cam: any) => { const newModel = gltf.scene.clone(); newModel.uuid = cam.userData._id; newModel.position.set(cam.position.x, cam.position.y, cam.position.z); newModel.rotation.set(cam.rotation.x, cam.rotation.y, cam.rotation.z); newModel.userData = cam.userData; setActiveUsers([...activeUsers, cam.userData]); return newModel; }); setCams((prev) => [...prev, ...newCams]); }); } }); }, []); return ( {cams.map((cam, index) => ( ))} ); }; export default CamModelsGroup;