feat: Log camera update response data for debugging purposes; adjust user position parameter in findEnvironment function

This commit is contained in:
Jerald-Golden-B 2025-04-05 17:40:46 +05:30
parent 58d82da349
commit c5d4507400
6 changed files with 211 additions and 188 deletions

View File

@ -12,203 +12,189 @@ import CollabUserIcon from "./collabUserIcon";
import { getAvatarColor } from "./users/functions/getAvatarColor";
const CamModelsGroup = () => {
let navigate = useNavigate();
const groupRef = useRef<THREE.Group>(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<any[]>([]);
const [models, setModels] = useState<Record<string, { targetPosition: THREE.Vector3; targetRotation: THREE.Euler }>>({});
const navigate = useNavigate();
const groupRef = useRef<THREE.Group>(null);
const email = localStorage.getItem("email");
const { activeUsers, setActiveUsers } = useActiveUsers();
const { socket } = useSocketStore();
dracoLoader.setDecoderPath("three/examples/jsm/libs/draco/gltf/");
loader.setDRACOLoader(dracoLoader);
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
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];
const [cams, setCams] = useState<any[]>([]);
const [models, setModels] = useState<Record<string, { targetPosition: THREE.Vector3; targetRotation: THREE.Euler }>>({});
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 dedupeCams = (cams: any[]) => {
const seen = new Set();
return cams.filter((cam) => {
if (seen.has(cam.uuid)) return false;
seen.add(cam.uuid);
return true;
});
};
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]);
});
});
const dedupeUsers = (users: any[]) => {
const seen = new Set();
return users.filter((user) => {
if (seen.has(user._id)) return false;
seen.add(user._id);
return true;
});
};
// socket.on("users:online", (data: any) => {
// console.log('users online: ', data);
// })
useEffect(() => {
if (!email) navigate("/");
socket.on("userDisConnectResponse", (data: any) => {
if (!groupRef.current) return;
if (socket.id === data.socketId || organization !== data.organization)
return;
if (!socket) return;
const organization = email!.split("@")[1].split(".")[0];
setCams((prev) =>
prev.filter((cam) => cam.uuid !== data.data.userData._id)
);
setActiveUsers(
activeUsers.filter((user: any) => user._id !== data.data.userData._id)
);
});
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;
socket.on("cameraUpdateResponse", (data: any) => {
if (
!groupRef.current ||
socket.id === data.socketId ||
organization !== data.organization
)
return;
const model = groupRef.current.getObjectByProperty("uuid", data.data.userData._id);
if (model) {
groupRef.current.remove(model);
}
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
),
},
}));
});
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;
return () => {
socket.off("userConnectRespones");
socket.off("userDisConnectRespones");
socket.off("cameraUpdateResponse");
};
}, [socket]);
setCams((prev) => dedupeCams([...prev, newModel]));
setActiveUsers((prev: any) =>
dedupeUsers([...prev, data.data.userData])
);
});
});
socket.on("userDisConnectResponse", (data: any) => {
if (!groupRef.current) return;
if (socket.id === data.socketId || organization !== data.organization) return;
// useEffect(() => {
// console.log(activeUsers);
// }, [activeUsers])
setCams((prev) =>
prev.filter((cam) => cam.uuid !== data.data.userData._id)
);
setActiveUsers((prev: any) =>
prev.filter((user: any) => user._id !== data.data.userData._id)
);
});
// useEffect(() => {
// console.log(models);
// }, [models])
socket.on("cameraUpdateResponse", (data: any) => {
if (
!groupRef.current ||
socket.id === data.socketId ||
organization !== data.organization
)
return;
useFrame(() => {
if (!groupRef.current) return;
Object.keys(models).forEach((uuid) => {
const model = groupRef.current!.getObjectByProperty("uuid", uuid);
if (!model) 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
),
},
}));
});
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
);
});
});
return () => {
socket.off("userConnectResponse");
socket.off("userDisConnectResponse");
socket.off("cameraUpdateResponse");
};
}, [socket]);
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]);
});
}
});
}, []);
useFrame(() => {
if (!groupRef.current) return;
Object.keys(models).forEach((uuid) => {
const model = groupRef.current!.getObjectByProperty("uuid", uuid);
if (!model) return;
return (
<group ref={groupRef} name="Cam-Model-Group">
{cams.map((cam, index) => (
<primitive key={index} object={cam}>
<Html
as="div"
center
zIndexRange={[1, 0]}
sprite
style={{
color: "white",
textAlign: "center",
fontFamily: "Arial, sans-serif",
}}
position={[-0.015, 0, 0.7]}
>
<CollabUserIcon
userImage={""}
userName={cam.userData.userName}
index={index}
color={getAvatarColor(index)}
/>
</Html>
</primitive>
))}
</group>
);
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;
return newModel;
});
const users = filteredData.map((cam: any) => cam.userData);
setActiveUsers((prev: any) => dedupeUsers([...prev, ...users]));
setCams((prev) => dedupeCams([...prev, ...newCams]));
});
}
});
}, []);
return (
<group ref={groupRef} name="Cam-Model-Group">
{cams.map((cam, index) => (
<primitive key={cam.uuid} object={cam}>
<Html
as="div"
center
zIndexRange={[1, 0]}
sprite
style={{
color: "white",
textAlign: "center",
fontFamily: "Arial, sans-serif",
}}
position={[-0.015, 0, 0.7]}
>
<CollabUserIcon
userImage={""}
userName={cam.userData.userName}
index={index}
color={getAvatarColor(index)}
/>
</Html>
</primitive>
))}
</group>
);
};
export default CamModelsGroup;

View File

@ -20,7 +20,24 @@ const CollabUserIcon: React.FC<CollabUserIconProps> = ({
{userImage ? (
<img className="user-image" src={userImage} alt={userName} />
) : (
<CustomAvatar name={userName} index={index} />
<CustomAvatar name={userName} index={index} color={color} />
// <div
// className="user-image"
// style={{
// lineHeight: "30px",
// textTransform: "uppercase",
// textAlign: "center",
// fontSize: "16px",
// borderRadius: "50%",
// backgroundColor: color,
// overflow: "hidden",
// backgroundSize: "cover",
// backgroundPosition: "center",
// color: "white",
// fontWeight: "bold",
// }}>
// {userName[0]}
// </div>
)}
</div>
<div className="user-name" style={{ backgroundColor: color }}>

View File

@ -233,7 +233,7 @@ export default function SocketResponses({
}
} else if (data.message === "Model updated successfully") {
itemsGroup.current.children.forEach((item: THREE.Group) => {
itemsGroup.current?.children.forEach((item: THREE.Group) => {
if (item.uuid === data.data.modeluuid) {
item.position.set(...data.data.position as [number, number, number]);
item.rotation.set(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z);

View File

@ -7,6 +7,7 @@ interface AvatarProps {
size?: number;
index?: number;
textColor?: string;
color?: string; // Optional color prop for future use
}
const CustomAvatar: React.FC<AvatarProps> = ({
@ -14,6 +15,7 @@ const CustomAvatar: React.FC<AvatarProps> = ({
size = 100,
index = 0,
textColor = "#ffffff",
color, // Optional color prop for future use
}) => {
const [imageSrc, setImageSrc] = useState<string | null>(null);
@ -26,7 +28,7 @@ const CustomAvatar: React.FC<AvatarProps> = ({
const initials = getInitials(name); // Convert name to initials if needed
// Draw background
ctx.fillStyle = getAvatarColor(index);
ctx.fillStyle = color || getAvatarColor(index); // Use color prop or generate color based on index
ctx.fillRect(0, 0, size, size);
// Draw initials
@ -40,7 +42,7 @@ const CustomAvatar: React.FC<AvatarProps> = ({
const dataURL = canvas.toDataURL("image/png");
setImageSrc(dataURL);
}
}, [name, size, textColor]);
}, [name, size, textColor, index]);
if (!imageSrc) {
return null; // Return null while the image is being generated
@ -53,6 +55,18 @@ const CustomAvatar: React.FC<AvatarProps> = ({
alt="User Avatar"
style={{ width: "100%", height: "100%" }}
/>
// <div
// className="user-image"
// style={{
// width: size,
// height: size,
// borderRadius: "50%",
// overflow: "hidden",
// backgroundSize: "cover",
// backgroundPosition: "center",
// }}>
// {name[0]}
// </div>
);
};

View File

@ -26,7 +26,7 @@ export const findEnvironment = async (organization: string, userId: string) => {
false,
false,
false,
0,
40,
true
);
return userpos;

View File

@ -14,7 +14,7 @@ export const useSocketStore = create<any>((set: any, get: any) => ({
const socket = io(
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`,
{
reconnection: false,
reconnection: true,
auth: { email, organization },
}
);
@ -22,7 +22,7 @@ export const useSocketStore = create<any>((set: any, get: any) => ({
const visualizationSocket = io(
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization`,
{
reconnection: false,
reconnection: true,
auth: { email, organization },
}
);
@ -302,7 +302,13 @@ export const useDrieTemp = create<any>((set: any) => ({
export const useActiveUsers = create<any>((set: any) => ({
activeUsers: [],
setActiveUsers: (x: any) => set({ activeUsers: x }),
setActiveUsers: (callback: (prev: any[]) => any[] | any[]) =>
set((state: { activeUsers: any[] }) => ({
activeUsers:
typeof callback === "function"
? callback(state.activeUsers)
: callback,
})),
}));
export const useDrieUIValue = create<any>((set: any) => ({