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 { Html } from "@react-three/drei"; import CollabUserIcon from "./collabUserIcon"; import { getAvatarColor } from "./users/functions/getAvatarColor"; 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("userConnectResponse", (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("users:online", (data: any) => { // console.log('users online: ', data); // }) socket.on("userDisConnectResponse", (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, activeUsers]); // useEffect(() => { // console.log(activeUsers); // }, [activeUsers]) // useEffect(() => { // console.log(models); // }, [models]) 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 ); let a: any = []; 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; a.push(cam.userData); return newModel; }); setActiveUsers(a); setCams((prev) => [...prev, ...newCams]); }); } }); }, []); return ( {cams.map((cam, index) => ( ))} ); }; export default CamModelsGroup;