Merge branch 'main' into rtViz
This commit is contained in:
commit
00933b34c8
|
@ -26,9 +26,14 @@ const Templates = () => {
|
||||||
templateData();
|
templateData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleDeleteTemplate = async (id: string) => {
|
const handleDeleteTemplate = async (
|
||||||
|
e: React.MouseEvent<HTMLButtonElement>,
|
||||||
|
id: string
|
||||||
|
) => {
|
||||||
try {
|
try {
|
||||||
|
e.stopPropagation();
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
|
|
||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
let deleteTemplate = {
|
let deleteTemplate = {
|
||||||
organization: organization,
|
organization: organization,
|
||||||
|
@ -49,7 +54,6 @@ const Templates = () => {
|
||||||
const handleLoadTemplate = async (template: any) => {
|
const handleLoadTemplate = async (template: any) => {
|
||||||
try {
|
try {
|
||||||
if (selectedZone.zoneName === "") return;
|
if (selectedZone.zoneName === "") return;
|
||||||
|
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
|
||||||
|
@ -108,7 +112,7 @@ const Templates = () => {
|
||||||
<RenameInput value={`Template ${index + 1}`} />
|
<RenameInput value={`Template ${index + 1}`} />
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleDeleteTemplate(template.id)}
|
onClick={(e) => handleDeleteTemplate(e, template.id)}
|
||||||
className="delete-button"
|
className="delete-button"
|
||||||
aria-label="Delete template"
|
aria-label="Delete template"
|
||||||
>
|
>
|
||||||
|
|
|
@ -33,7 +33,7 @@ const WidgetsFloating = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="floatingWidgets-wrapper">
|
<div className="floatingWidgets-wrapper widgets-wrapper">
|
||||||
{/* {widgets.map((widget) => (
|
{/* {widgets.map((widget) => (
|
||||||
<div
|
<div
|
||||||
key={widget.id}
|
key={widget.id}
|
||||||
|
|
|
@ -10,190 +10,227 @@ import { useNavigate } from "react-router-dom";
|
||||||
import { Html } from "@react-three/drei";
|
import { Html } from "@react-three/drei";
|
||||||
import CollabUserIcon from "./collabUserIcon";
|
import CollabUserIcon from "./collabUserIcon";
|
||||||
import { getAvatarColor } from "./users/functions/getAvatarColor";
|
import { getAvatarColor } from "./users/functions/getAvatarColor";
|
||||||
|
import useModuleStore from "../../store/useModuleStore";
|
||||||
|
|
||||||
const CamModelsGroup = () => {
|
const CamModelsGroup = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const groupRef = useRef<THREE.Group>(null);
|
const groupRef = useRef<THREE.Group>(null);
|
||||||
const email = localStorage.getItem("email");
|
const email = localStorage.getItem("email");
|
||||||
const { activeUsers, setActiveUsers } = useActiveUsers();
|
const { setActiveUsers } = useActiveUsers();
|
||||||
const { socket } = useSocketStore();
|
const { socket } = useSocketStore();
|
||||||
|
const { activeModule } = useModuleStore();
|
||||||
|
|
||||||
const loader = new GLTFLoader();
|
const loader = new GLTFLoader();
|
||||||
const dracoLoader = new DRACOLoader();
|
const dracoLoader = new DRACOLoader();
|
||||||
dracoLoader.setDecoderPath("three/examples/jsm/libs/draco/gltf/");
|
dracoLoader.setDecoderPath("three/examples/jsm/libs/draco/gltf/");
|
||||||
loader.setDRACOLoader(dracoLoader);
|
loader.setDRACOLoader(dracoLoader);
|
||||||
|
|
||||||
const [cams, setCams] = useState<any[]>([]);
|
const [cams, setCams] = useState<any[]>([]);
|
||||||
const [models, setModels] = useState<Record<string, { targetPosition: THREE.Vector3; targetRotation: THREE.Euler }>>({});
|
const [models, setModels] = useState<
|
||||||
|
Record<
|
||||||
|
string,
|
||||||
|
{ targetPosition: THREE.Vector3; targetRotation: THREE.Euler }
|
||||||
|
>
|
||||||
|
>({});
|
||||||
|
|
||||||
const dedupeCams = (cams: any[]) => {
|
const dedupeCams = (cams: any[]) => {
|
||||||
const seen = new Set();
|
const seen = new Set();
|
||||||
return cams.filter((cam) => {
|
return cams.filter((cam) => {
|
||||||
if (seen.has(cam.uuid)) return false;
|
if (seen.has(cam.uuid)) return false;
|
||||||
seen.add(cam.uuid);
|
seen.add(cam.uuid);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const dedupeUsers = (users: any[]) => {
|
const dedupeUsers = (users: any[]) => {
|
||||||
const seen = new Set();
|
const seen = new Set();
|
||||||
return users.filter((user) => {
|
return users.filter((user) => {
|
||||||
if (seen.has(user._id)) return false;
|
if (seen.has(user._id)) return false;
|
||||||
seen.add(user._id);
|
seen.add(user._id);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!email) navigate("/");
|
if (!email) navigate("/");
|
||||||
|
|
||||||
if (!socket) return;
|
if (!socket) return;
|
||||||
const organization = email!.split("@")[1].split(".")[0];
|
const organization = email!.split("@")[1].split(".")[0];
|
||||||
|
|
||||||
socket.on("userConnectResponse", (data: any) => {
|
socket.on("userConnectResponse", (data: any) => {
|
||||||
if (!groupRef.current) return;
|
if (!groupRef.current) return;
|
||||||
if (data.data.userData.email === email) return;
|
if (data.data.userData.email === email) return;
|
||||||
if (socket.id === data.socketId || organization !== data.organization) return;
|
if (socket.id === data.socketId || organization !== data.organization)
|
||||||
|
return;
|
||||||
|
|
||||||
const model = groupRef.current.getObjectByProperty("uuid", data.data.userData._id);
|
const model = groupRef.current.getObjectByProperty(
|
||||||
if (model) {
|
"uuid",
|
||||||
groupRef.current.remove(model);
|
data.data.userData._id
|
||||||
}
|
);
|
||||||
|
if (model) {
|
||||||
|
groupRef.current.remove(model);
|
||||||
|
}
|
||||||
|
|
||||||
loader.load(camModel, (gltf) => {
|
loader.load(camModel, (gltf) => {
|
||||||
const newModel = gltf.scene.clone();
|
const newModel = gltf.scene.clone();
|
||||||
newModel.uuid = data.data.userData._id;
|
newModel.uuid = data.data.userData._id;
|
||||||
newModel.position.set(
|
newModel.position.set(
|
||||||
data.data.position.x,
|
data.data.position.x,
|
||||||
data.data.position.y,
|
data.data.position.y,
|
||||||
data.data.position.z
|
data.data.position.z
|
||||||
);
|
);
|
||||||
newModel.rotation.set(
|
newModel.rotation.set(
|
||||||
data.data.rotation.x,
|
data.data.rotation.x,
|
||||||
data.data.rotation.y,
|
data.data.rotation.y,
|
||||||
data.data.rotation.z
|
data.data.rotation.z
|
||||||
);
|
);
|
||||||
newModel.userData = data.data.userData;
|
newModel.userData = data.data.userData;
|
||||||
|
|
||||||
setCams((prev) => dedupeCams([...prev, newModel]));
|
setCams((prev) => dedupeCams([...prev, newModel]));
|
||||||
setActiveUsers((prev: any) =>
|
setActiveUsers((prev: any) =>
|
||||||
dedupeUsers([...prev, data.data.userData])
|
dedupeUsers([...prev, data.data.userData])
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("userDisConnectResponse", (data: any) => {
|
socket.on("userDisConnectResponse", (data: any) => {
|
||||||
if (!groupRef.current) return;
|
if (!groupRef.current) return;
|
||||||
if (socket.id === data.socketId || organization !== data.organization) return;
|
if (socket.id === data.socketId || organization !== data.organization)
|
||||||
|
return;
|
||||||
|
|
||||||
setCams((prev) =>
|
setCams((prev) =>
|
||||||
prev.filter((cam) => cam.uuid !== data.data.userData._id)
|
prev.filter((cam) => cam.uuid !== data.data.userData._id)
|
||||||
);
|
);
|
||||||
setActiveUsers((prev: any) =>
|
setActiveUsers((prev: any) =>
|
||||||
prev.filter((user: any) => user._id !== data.data.userData._id)
|
prev.filter((user: any) => user._id !== data.data.userData._id)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("cameraUpdateResponse", (data: any) => {
|
socket.on("cameraUpdateResponse", (data: any) => {
|
||||||
if (
|
if (
|
||||||
!groupRef.current ||
|
!groupRef.current ||
|
||||||
socket.id === data.socketId ||
|
socket.id === data.socketId ||
|
||||||
organization !== data.organization
|
organization !== data.organization
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setModels((prev) => ({
|
setModels((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
[data.data.userId]: {
|
[data.data.userId]: {
|
||||||
targetPosition: new THREE.Vector3(
|
targetPosition: new THREE.Vector3(
|
||||||
data.data.position.x,
|
data.data.position.x,
|
||||||
data.data.position.y,
|
data.data.position.y,
|
||||||
data.data.position.z
|
data.data.position.z
|
||||||
),
|
),
|
||||||
targetRotation: new THREE.Euler(
|
targetRotation: new THREE.Euler(
|
||||||
data.data.rotation.x,
|
data.data.rotation.x,
|
||||||
data.data.rotation.y,
|
data.data.rotation.y,
|
||||||
data.data.rotation.z
|
data.data.rotation.z
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
socket.off("userConnectResponse");
|
socket.off("userConnectResponse");
|
||||||
socket.off("userDisConnectResponse");
|
socket.off("userDisConnectResponse");
|
||||||
socket.off("cameraUpdateResponse");
|
socket.off("cameraUpdateResponse");
|
||||||
};
|
};
|
||||||
}, [socket]);
|
}, [socket]);
|
||||||
|
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
if (!groupRef.current) return;
|
if (!groupRef.current) return;
|
||||||
Object.keys(models).forEach((uuid) => {
|
Object.keys(models).forEach((uuid) => {
|
||||||
const model = groupRef.current!.getObjectByProperty("uuid", uuid);
|
const model = groupRef.current!.getObjectByProperty("uuid", uuid);
|
||||||
if (!model) return;
|
if (!model) return;
|
||||||
|
|
||||||
const { targetPosition, targetRotation } = models[uuid];
|
const { targetPosition, targetRotation } = models[uuid];
|
||||||
model.position.lerp(targetPosition, 0.1);
|
model.position.lerp(targetPosition, 0.1);
|
||||||
model.rotation.x = THREE.MathUtils.lerp(model.rotation.x, targetRotation.x, 0.1);
|
model.rotation.x = THREE.MathUtils.lerp(
|
||||||
model.rotation.y = THREE.MathUtils.lerp(model.rotation.y, targetRotation.y, 0.1);
|
model.rotation.x,
|
||||||
model.rotation.z = THREE.MathUtils.lerp(model.rotation.z, targetRotation.z, 0.1);
|
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(() => {
|
useEffect(() => {
|
||||||
if (!groupRef.current) return;
|
if (!groupRef.current) return;
|
||||||
const organization = email!.split("@")[1].split(".")[0];
|
const organization = email!.split("@")[1].split(".")[0];
|
||||||
|
|
||||||
getActiveUsersData(organization).then((data) => {
|
getActiveUsersData(organization).then((data) => {
|
||||||
const filteredData = data.cameraDatas.filter(
|
const filteredData = data.cameraDatas.filter(
|
||||||
(camera: any) => camera.userData.email !== email
|
(camera: any) => camera.userData.email !== email
|
||||||
);
|
);
|
||||||
|
|
||||||
if (filteredData.length > 0) {
|
if (filteredData.length > 0) {
|
||||||
loader.load(camModel, (gltf) => {
|
loader.load(camModel, (gltf) => {
|
||||||
const newCams = filteredData.map((cam: any) => {
|
const newCams = filteredData.map((cam: any) => {
|
||||||
const newModel = gltf.scene.clone();
|
const newModel = gltf.scene.clone();
|
||||||
newModel.uuid = cam.userData._id;
|
newModel.uuid = cam.userData._id;
|
||||||
newModel.position.set(cam.position.x, cam.position.y, cam.position.z);
|
newModel.position.set(
|
||||||
newModel.rotation.set(cam.rotation.x, cam.rotation.y, cam.rotation.z);
|
cam.position.x,
|
||||||
newModel.userData = cam.userData;
|
cam.position.y,
|
||||||
return newModel;
|
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);
|
const users = filteredData.map((cam: any) => cam.userData);
|
||||||
setActiveUsers((prev: any) => dedupeUsers([...prev, ...users]));
|
setActiveUsers((prev: any) => dedupeUsers([...prev, ...users]));
|
||||||
setCams((prev) => dedupeCams([...prev, ...newCams]));
|
setCams((prev) => dedupeCams([...prev, ...newCams]));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<group ref={groupRef} name="Cam-Model-Group">
|
<group
|
||||||
{cams.map((cam, index) => (
|
ref={groupRef}
|
||||||
<primitive key={cam.uuid} object={cam}>
|
name="Cam-Model-Group"
|
||||||
<Html
|
visible={activeModule !== "visualization" ? true : false}
|
||||||
as="div"
|
>
|
||||||
center
|
{cams.map((cam, index) => (
|
||||||
zIndexRange={[1, 0]}
|
<primitive key={cam.uuid} object={cam}>
|
||||||
sprite
|
<Html
|
||||||
style={{
|
as="div"
|
||||||
color: "white",
|
center
|
||||||
textAlign: "center",
|
zIndexRange={[1, 0]}
|
||||||
fontFamily: "Arial, sans-serif",
|
sprite
|
||||||
}}
|
style={{
|
||||||
position={[-0.015, 0, 0.7]}
|
color: "white",
|
||||||
>
|
textAlign: "center",
|
||||||
<CollabUserIcon
|
fontFamily: "Arial, sans-serif",
|
||||||
userImage={cam.userData.userImage ||""}
|
display: `${activeModule !== "visualization" ? "" : "none"}`,
|
||||||
userName={cam.userData.userName}
|
}}
|
||||||
color={getAvatarColor(index, cam.userData.userName)}
|
position={[-0.015, 0, 0.7]}
|
||||||
/>
|
>
|
||||||
</Html>
|
<CollabUserIcon
|
||||||
</primitive>
|
userImage={cam.userData.userImage || ""}
|
||||||
))}
|
userName={cam.userData.userName}
|
||||||
</group>
|
color={getAvatarColor(index, cam.userData.userName)}
|
||||||
);
|
/>
|
||||||
|
</Html>
|
||||||
|
</primitive>
|
||||||
|
))}
|
||||||
|
</group>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CamModelsGroup;
|
export default CamModelsGroup;
|
||||||
|
|
Loading…
Reference in New Issue