v2-ui #89
|
@ -4,305 +4,304 @@ import InputToggle from "../../../ui/inputs/InputToggle";
|
||||||
import { AIIcon } from "../../../icons/ExportCommonIcons";
|
import { AIIcon } from "../../../icons/ExportCommonIcons";
|
||||||
import LabeledButton from "../../../ui/inputs/LabledButton";
|
import LabeledButton from "../../../ui/inputs/LabledButton";
|
||||||
import {
|
import {
|
||||||
useAzimuth,
|
useAzimuth,
|
||||||
useElevation,
|
useElevation,
|
||||||
useLimitDistance,
|
useLimitDistance,
|
||||||
useRenderDistance,
|
useRenderDistance,
|
||||||
useResetCamera,
|
useResetCamera,
|
||||||
useRoofVisibility,
|
useRoofVisibility,
|
||||||
useSelectedWallItem,
|
useSelectedWallItem,
|
||||||
useShadows,
|
useShadows,
|
||||||
useSocketStore,
|
useSocketStore,
|
||||||
useTileDistance,
|
useTileDistance,
|
||||||
useToggleView,
|
useToggleView,
|
||||||
useWallVisibility,
|
useWallVisibility,
|
||||||
} from "../../../../store/builder/store";
|
} from "../../../../store/builder/store";
|
||||||
import { setEnvironment } from "../../../../services/factoryBuilder/environment/setEnvironment";
|
import { setEnvironment } from "../../../../services/factoryBuilder/environment/setEnvironment";
|
||||||
import * as CONSTANTS from "../../../../types/world/worldConstants";
|
import * as CONSTANTS from "../../../../types/world/worldConstants";
|
||||||
import { validateBBox } from "@turf/helpers";
|
import { validateBBox } from "@turf/helpers";
|
||||||
const GlobalProperties: React.FC = () => {
|
const GlobalProperties: React.FC = () => {
|
||||||
const { toggleView, setToggleView } = useToggleView();
|
const { toggleView, setToggleView } = useToggleView();
|
||||||
const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
|
const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
|
||||||
const { roofVisibility, setRoofVisibility } = useRoofVisibility();
|
const { roofVisibility, setRoofVisibility } = useRoofVisibility();
|
||||||
const { wallVisibility, setWallVisibility } = useWallVisibility();
|
const { wallVisibility, setWallVisibility } = useWallVisibility();
|
||||||
const { shadows, setShadows } = useShadows();
|
const { shadows, setShadows } = useShadows();
|
||||||
const { resetCamera, setResetCamera } = useResetCamera();
|
const { resetCamera, setResetCamera } = useResetCamera();
|
||||||
const { elevation, setElevation } = useElevation();
|
const { elevation, setElevation } = useElevation();
|
||||||
const { azimuth, setAzimuth } = useAzimuth();
|
const { azimuth, setAzimuth } = useAzimuth();
|
||||||
const { renderDistance, setRenderDistance } = useRenderDistance();
|
const { renderDistance, setRenderDistance } = useRenderDistance();
|
||||||
const { setPlaneValue, setGridValue, planeValue, gridValue } =
|
const { setPlaneValue, setGridValue, planeValue, gridValue } = useTileDistance();
|
||||||
useTileDistance();
|
const { socket } = useSocketStore();
|
||||||
useEffect(() => {}, [gridValue, planeValue]);
|
const { limitDistance, setLimitDistance } = useLimitDistance();
|
||||||
const { socket } = useSocketStore();
|
const [distance, setDistance] = useState<number>(40);
|
||||||
const { limitDistance, setLimitDistance } = useLimitDistance();
|
|
||||||
const [distance, setDistance] = useState<number>(40);
|
|
||||||
useEffect(() => {}, [limitDistance]);
|
|
||||||
|
|
||||||
const [limitGridDistance, setLimitGridDistance] = useState(false);
|
const [limitGridDistance, setLimitGridDistance] = useState(false);
|
||||||
const [gridDistance, setGridDistance] = useState<number>(3);
|
const [gridDistance, setGridDistance] = useState<number>(3);
|
||||||
|
|
||||||
const optimizeScene = async (value: any) => {
|
const optimizeScene = async (value: any) => {
|
||||||
const email = localStorage.getItem("email");
|
const email = localStorage.getItem("email");
|
||||||
const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg";
|
const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg";
|
||||||
|
|
||||||
const data = await setEnvironment(
|
const data = await setEnvironment(
|
||||||
organization,
|
organization,
|
||||||
localStorage.getItem("userId")!,
|
localStorage.getItem("userId")!,
|
||||||
wallVisibility,
|
wallVisibility,
|
||||||
roofVisibility,
|
roofVisibility,
|
||||||
shadows,
|
shadows,
|
||||||
30,
|
30,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
setRenderDistance(30);
|
setRenderDistance(30);
|
||||||
setLimitDistance(true);
|
setLimitDistance(true);
|
||||||
};
|
};
|
||||||
const limitRenderDistance = async () => {
|
|
||||||
const email = localStorage.getItem("email");
|
|
||||||
const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg";
|
|
||||||
|
|
||||||
if (limitDistance) {
|
const limitRenderDistance = async () => {
|
||||||
let data = await setEnvironment(
|
const email = localStorage.getItem("email");
|
||||||
organization,
|
const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg";
|
||||||
localStorage.getItem("userId")!,
|
|
||||||
wallVisibility,
|
if (limitDistance) {
|
||||||
roofVisibility,
|
let data = await setEnvironment(
|
||||||
shadows,
|
organization,
|
||||||
75,
|
localStorage.getItem("userId")!,
|
||||||
!limitDistance
|
wallVisibility,
|
||||||
);
|
roofVisibility,
|
||||||
setRenderDistance(75);
|
shadows,
|
||||||
} else {
|
75,
|
||||||
let data = await setEnvironment(
|
!limitDistance
|
||||||
organization,
|
);
|
||||||
localStorage.getItem("userId")!,
|
setRenderDistance(75);
|
||||||
wallVisibility,
|
} else {
|
||||||
roofVisibility,
|
let data = await setEnvironment(
|
||||||
shadows,
|
organization,
|
||||||
renderDistance,
|
localStorage.getItem("userId")!,
|
||||||
!limitDistance
|
wallVisibility,
|
||||||
);
|
roofVisibility,
|
||||||
|
shadows,
|
||||||
|
renderDistance,
|
||||||
|
!limitDistance
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setLimitDistance(!limitDistance);
|
||||||
|
};
|
||||||
|
|
||||||
|
function updateDistance(value: number) {
|
||||||
|
setDistance(value);
|
||||||
|
setRenderDistance(value);
|
||||||
}
|
}
|
||||||
setLimitDistance(!limitDistance);
|
function updateGridDistance(value: number) {
|
||||||
};
|
setGridDistance(value);
|
||||||
|
// setGridValue({ size: value * 100, divisions: (value * 100) / 4 });
|
||||||
function updateDistance(value: number) {
|
// setPlaneValue({ height: value * 100, width: value * 100 });
|
||||||
setDistance(value);
|
}
|
||||||
setRenderDistance(value);
|
function updatedGrid(value: number) {
|
||||||
}
|
// console.log(" (value * 100) / 4 : ", (value * 100) / 4);
|
||||||
function updateGridDistance(value: number) {
|
setGridValue({ size: value * 100, divisions: (value * 100) / 4 });
|
||||||
setGridDistance(value);
|
setPlaneValue({ height: value * 100, width: value * 100 });
|
||||||
// setGridValue({ size: value * 100, divisions: (value * 100) / 4 });
|
|
||||||
// setPlaneValue({ height: value * 100, width: value * 100 });
|
|
||||||
}
|
|
||||||
function updatedGrid(value: number) {
|
|
||||||
// console.log(" (value * 100) / 4 : ", (value * 100) / 4);
|
|
||||||
setGridValue({ size: value * 100, divisions: (value * 100) / 4 });
|
|
||||||
setPlaneValue({ height: value * 100, width: value * 100 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedDist = async (value: number) => {
|
|
||||||
const email = localStorage.getItem("email");
|
|
||||||
const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg";
|
|
||||||
setRenderDistance(value);
|
|
||||||
// setDistance(value);
|
|
||||||
const data = await setEnvironment(
|
|
||||||
organization,
|
|
||||||
localStorage.getItem("userId")!,
|
|
||||||
wallVisibility,
|
|
||||||
roofVisibility,
|
|
||||||
shadows,
|
|
||||||
value,
|
|
||||||
limitDistance
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Function to toggle roof visibility
|
|
||||||
const changeRoofVisibility = async () => {
|
|
||||||
const email = localStorage.getItem("email");
|
|
||||||
const organization = email!.split("@")[1].split(".")[0];
|
|
||||||
|
|
||||||
//using REST
|
|
||||||
const data = await setEnvironment(
|
|
||||||
organization,
|
|
||||||
localStorage.getItem("userId")!,
|
|
||||||
wallVisibility,
|
|
||||||
!roofVisibility,
|
|
||||||
shadows,
|
|
||||||
renderDistance,
|
|
||||||
limitDistance
|
|
||||||
);
|
|
||||||
//
|
|
||||||
|
|
||||||
//using Socket
|
|
||||||
// const visData = {
|
|
||||||
// organization: organization,
|
|
||||||
// userId: localStorage.getItem('userId')!,
|
|
||||||
// wallVisibility: wallVisibility,
|
|
||||||
// roofVisibility: !roofVisibility,
|
|
||||||
// shadowVisibility: shadows,
|
|
||||||
// socketId: socket.id
|
|
||||||
// };
|
|
||||||
// socket.emit('v1:Environment:set', visData)
|
|
||||||
|
|
||||||
setRoofVisibility(!roofVisibility); // Toggle roof visibility
|
|
||||||
};
|
|
||||||
// Function to toggle wall visibility
|
|
||||||
const changeWallVisibility = async () => {
|
|
||||||
const email = localStorage.getItem("email");
|
|
||||||
const organization = email!.split("@")[1].split(".")[0];
|
|
||||||
//using REST
|
|
||||||
const data = await setEnvironment(
|
|
||||||
organization,
|
|
||||||
localStorage.getItem("userId")!,
|
|
||||||
!wallVisibility,
|
|
||||||
roofVisibility,
|
|
||||||
shadows,
|
|
||||||
renderDistance,
|
|
||||||
limitDistance
|
|
||||||
);
|
|
||||||
//
|
|
||||||
|
|
||||||
//using Socket
|
|
||||||
// const visData = {
|
|
||||||
// organization: organization,
|
|
||||||
// userId: localStorage.getItem('userId')!,
|
|
||||||
// wallVisibility: !wallVisibility,
|
|
||||||
// roofVisibility: roofVisibility,
|
|
||||||
// shadowVisibility: shadows,
|
|
||||||
// socketId: socket.id
|
|
||||||
// };
|
|
||||||
// socket.emit('v1:Environment:set', visData)
|
|
||||||
|
|
||||||
setWallVisibility(!wallVisibility); // Toggle wall visibility
|
|
||||||
};
|
|
||||||
|
|
||||||
const shadowVisibility = async () => {
|
|
||||||
const email = localStorage.getItem("email");
|
|
||||||
const organization = email!.split("@")[1].split(".")[0];
|
|
||||||
//using REST
|
|
||||||
const data = await setEnvironment(
|
|
||||||
organization,
|
|
||||||
localStorage.getItem("userId")!,
|
|
||||||
wallVisibility,
|
|
||||||
roofVisibility,
|
|
||||||
!shadows,
|
|
||||||
renderDistance,
|
|
||||||
limitDistance
|
|
||||||
);
|
|
||||||
//
|
|
||||||
|
|
||||||
//using Socket
|
|
||||||
// const visData = {
|
|
||||||
// organization: organization,
|
|
||||||
// userId: localStorage.getItem('userId')!,
|
|
||||||
// wallVisibility: wallVisibility,
|
|
||||||
// roofVisibility: roofVisibility,
|
|
||||||
// shadowVisibility: !shadows,
|
|
||||||
// socketId: socket.id
|
|
||||||
// };
|
|
||||||
// socket.emit('v1:Environment:set', visData)
|
|
||||||
|
|
||||||
setShadows(!shadows);
|
|
||||||
};
|
|
||||||
const toggleResetCamera = () => {
|
|
||||||
if (!toggleView) {
|
|
||||||
setResetCamera(true); // Trigger reset camera action
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// function changeRenderDistance(e: any) {
|
const updatedDist = async (value: number) => {
|
||||||
// if (parseInt(e.target.value) < 20) {
|
const email = localStorage.getItem("email");
|
||||||
// setRenderDistance(20);
|
const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg";
|
||||||
// } else if (parseInt(e.target.value) > 75) {
|
setRenderDistance(value);
|
||||||
// setRenderDistance(75);
|
// setDistance(value);
|
||||||
// } else {
|
const data = await setEnvironment(
|
||||||
// setRenderDistance(parseInt(e.target.value));
|
organization,
|
||||||
// }
|
localStorage.getItem("userId")!,
|
||||||
// }
|
wallVisibility,
|
||||||
return (
|
roofVisibility,
|
||||||
<div className="global-properties-container">
|
shadows,
|
||||||
<section>
|
value,
|
||||||
<div className="header">Environment</div>
|
limitDistance
|
||||||
<div className="optimize-button" onClick={optimizeScene}>
|
);
|
||||||
<AIIcon />
|
};
|
||||||
Optimize
|
|
||||||
|
// Function to toggle roof visibility
|
||||||
|
const changeRoofVisibility = async () => {
|
||||||
|
const email = localStorage.getItem("email");
|
||||||
|
const organization = email!.split("@")[1].split(".")[0];
|
||||||
|
|
||||||
|
//using REST
|
||||||
|
const data = await setEnvironment(
|
||||||
|
organization,
|
||||||
|
localStorage.getItem("userId")!,
|
||||||
|
wallVisibility,
|
||||||
|
!roofVisibility,
|
||||||
|
shadows,
|
||||||
|
renderDistance,
|
||||||
|
limitDistance
|
||||||
|
);
|
||||||
|
//
|
||||||
|
|
||||||
|
//using Socket
|
||||||
|
// const visData = {
|
||||||
|
// organization: organization,
|
||||||
|
// userId: localStorage.getItem('userId')!,
|
||||||
|
// wallVisibility: wallVisibility,
|
||||||
|
// roofVisibility: !roofVisibility,
|
||||||
|
// shadowVisibility: shadows,
|
||||||
|
// socketId: socket.id
|
||||||
|
// };
|
||||||
|
// socket.emit('v1:Environment:set', visData)
|
||||||
|
|
||||||
|
setRoofVisibility(!roofVisibility); // Toggle roof visibility
|
||||||
|
};
|
||||||
|
// Function to toggle wall visibility
|
||||||
|
const changeWallVisibility = async () => {
|
||||||
|
const email = localStorage.getItem("email");
|
||||||
|
const organization = email!.split("@")[1].split(".")[0];
|
||||||
|
//using REST
|
||||||
|
const data = await setEnvironment(
|
||||||
|
organization,
|
||||||
|
localStorage.getItem("userId")!,
|
||||||
|
!wallVisibility,
|
||||||
|
roofVisibility,
|
||||||
|
shadows,
|
||||||
|
renderDistance,
|
||||||
|
limitDistance
|
||||||
|
);
|
||||||
|
//
|
||||||
|
|
||||||
|
//using Socket
|
||||||
|
// const visData = {
|
||||||
|
// organization: organization,
|
||||||
|
// userId: localStorage.getItem('userId')!,
|
||||||
|
// wallVisibility: !wallVisibility,
|
||||||
|
// roofVisibility: roofVisibility,
|
||||||
|
// shadowVisibility: shadows,
|
||||||
|
// socketId: socket.id
|
||||||
|
// };
|
||||||
|
// socket.emit('v1:Environment:set', visData)
|
||||||
|
|
||||||
|
setWallVisibility(!wallVisibility); // Toggle wall visibility
|
||||||
|
};
|
||||||
|
|
||||||
|
const shadowVisibility = async () => {
|
||||||
|
const email = localStorage.getItem("email");
|
||||||
|
const organization = email!.split("@")[1].split(".")[0];
|
||||||
|
//using REST
|
||||||
|
const data = await setEnvironment(
|
||||||
|
organization,
|
||||||
|
localStorage.getItem("userId")!,
|
||||||
|
wallVisibility,
|
||||||
|
roofVisibility,
|
||||||
|
!shadows,
|
||||||
|
renderDistance,
|
||||||
|
limitDistance
|
||||||
|
);
|
||||||
|
//
|
||||||
|
|
||||||
|
//using Socket
|
||||||
|
// const visData = {
|
||||||
|
// organization: organization,
|
||||||
|
// userId: localStorage.getItem('userId')!,
|
||||||
|
// wallVisibility: wallVisibility,
|
||||||
|
// roofVisibility: roofVisibility,
|
||||||
|
// shadowVisibility: !shadows,
|
||||||
|
// socketId: socket.id
|
||||||
|
// };
|
||||||
|
// socket.emit('v1:Environment:set', visData)
|
||||||
|
|
||||||
|
setShadows(!shadows);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleResetCamera = () => {
|
||||||
|
if (!toggleView) {
|
||||||
|
setResetCamera(true); // Trigger reset camera action
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// function changeRenderDistance(e: any) {
|
||||||
|
// if (parseInt(e.target.value) < 20) {
|
||||||
|
// setRenderDistance(20);
|
||||||
|
// } else if (parseInt(e.target.value) > 75) {
|
||||||
|
// setRenderDistance(75);
|
||||||
|
// } else {
|
||||||
|
// setRenderDistance(parseInt(e.target.value));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
return (
|
||||||
|
<div className="global-properties-container">
|
||||||
|
<section>
|
||||||
|
<div className="header">Environment</div>
|
||||||
|
<div className="optimize-button" onClick={optimizeScene}>
|
||||||
|
<AIIcon />
|
||||||
|
Optimize
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="split"></div>
|
||||||
|
|
||||||
|
<InputToggle
|
||||||
|
value={roofVisibility}
|
||||||
|
inputKey="1"
|
||||||
|
label="Roof Visibility"
|
||||||
|
onClick={changeRoofVisibility}
|
||||||
|
/>
|
||||||
|
<InputToggle
|
||||||
|
value={wallVisibility}
|
||||||
|
inputKey="2"
|
||||||
|
label="Wall Visibility"
|
||||||
|
onClick={changeWallVisibility}
|
||||||
|
/>
|
||||||
|
{/* <InputToggle
|
||||||
|
value={shadows}
|
||||||
|
inputKey="3"
|
||||||
|
label="Shadows Visibility"
|
||||||
|
onClick={shadowVisibility}
|
||||||
|
/> */}
|
||||||
|
<LabeledButton
|
||||||
|
label="Reset Camera"
|
||||||
|
onClick={toggleResetCamera}
|
||||||
|
value="Reset"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="split"></div>
|
||||||
|
{/* //visibleEdgeColor={CONSTANTS.outlineConfig.assetDeleteColor} */}
|
||||||
|
<InputToggle
|
||||||
|
inputKey="4"
|
||||||
|
label="Limit Render Distance"
|
||||||
|
value={limitDistance}
|
||||||
|
// onClick={() => {
|
||||||
|
// setLimitDistance(!limitDistance);
|
||||||
|
// // setDistance(75);
|
||||||
|
// // setRenderDistance(75);
|
||||||
|
// }}
|
||||||
|
onClick={async () => {
|
||||||
|
await limitRenderDistance(); // Call the function here
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<InputRange
|
||||||
|
label="Distance"
|
||||||
|
disabled={!limitDistance}
|
||||||
|
value={renderDistance}
|
||||||
|
min={CONSTANTS.distanceConfig.minDistance}
|
||||||
|
max={CONSTANTS.distanceConfig.maxDistance}
|
||||||
|
onChange={(value: number) => updateDistance(value)}
|
||||||
|
onPointerUp={updatedDist}
|
||||||
|
key={"6"}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* <div className="split"></div>
|
||||||
|
<InputToggle
|
||||||
|
inputKey="6"
|
||||||
|
label="Display Grid"
|
||||||
|
value={limitGridDistance}
|
||||||
|
onClick={() => {
|
||||||
|
setLimitGridDistance(!limitGridDistance);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<InputRange
|
||||||
|
label="Tile Distance"
|
||||||
|
disabled={!limitGridDistance}
|
||||||
|
value={gridDistance}
|
||||||
|
key={"7"}
|
||||||
|
min={1}
|
||||||
|
max={5}
|
||||||
|
onChange={(value: number) => updateGridDistance(value)}
|
||||||
|
onPointerUp={updatedGrid}
|
||||||
|
/> */}
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
<div className="split"></div>
|
|
||||||
|
|
||||||
<InputToggle
|
|
||||||
value={roofVisibility}
|
|
||||||
inputKey="1"
|
|
||||||
label="Roof Visibility"
|
|
||||||
onClick={changeRoofVisibility}
|
|
||||||
/>
|
|
||||||
<InputToggle
|
|
||||||
value={wallVisibility}
|
|
||||||
inputKey="2"
|
|
||||||
label="Wall Visibility"
|
|
||||||
onClick={changeWallVisibility}
|
|
||||||
/>
|
|
||||||
{/* <InputToggle
|
|
||||||
value={shadows}
|
|
||||||
inputKey="3"
|
|
||||||
label="Shadows Visibility"
|
|
||||||
onClick={shadowVisibility}
|
|
||||||
/> */}
|
|
||||||
<LabeledButton
|
|
||||||
label="Reset Camera"
|
|
||||||
onClick={toggleResetCamera}
|
|
||||||
value="Reset"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="split"></div>
|
|
||||||
{/* //visibleEdgeColor={CONSTANTS.outlineConfig.assetDeleteColor} */}
|
|
||||||
<InputToggle
|
|
||||||
inputKey="4"
|
|
||||||
label="Limit Render Distance"
|
|
||||||
value={limitDistance}
|
|
||||||
// onClick={() => {
|
|
||||||
// setLimitDistance(!limitDistance);
|
|
||||||
// // setDistance(75);
|
|
||||||
// // setRenderDistance(75);
|
|
||||||
// }}
|
|
||||||
onClick={async () => {
|
|
||||||
await limitRenderDistance(); // Call the function here
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<InputRange
|
|
||||||
label="Distance"
|
|
||||||
disabled={!limitDistance}
|
|
||||||
value={renderDistance}
|
|
||||||
min={CONSTANTS.distanceConfig.minDistance}
|
|
||||||
max={CONSTANTS.distanceConfig.maxDistance}
|
|
||||||
onChange={(value: number) => updateDistance(value)}
|
|
||||||
onPointerUp={updatedDist}
|
|
||||||
key={"6"}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* <div className="split"></div>
|
|
||||||
<InputToggle
|
|
||||||
inputKey="6"
|
|
||||||
label="Display Grid"
|
|
||||||
value={limitGridDistance}
|
|
||||||
onClick={() => {
|
|
||||||
setLimitGridDistance(!limitGridDistance);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<InputRange
|
|
||||||
label="Tile Distance"
|
|
||||||
disabled={!limitGridDistance}
|
|
||||||
value={gridDistance}
|
|
||||||
key={"7"}
|
|
||||||
min={1}
|
|
||||||
max={5}
|
|
||||||
onChange={(value: number) => updateGridDistance(value)}
|
|
||||||
onPointerUp={updatedGrid}
|
|
||||||
/> */}
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default GlobalProperties;
|
export default GlobalProperties;
|
||||||
|
|
|
@ -27,6 +27,7 @@ import addAssetModel from "../geomentries/assets/addAssetModel";
|
||||||
import { getFloorAssets } from "../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi";
|
import { getFloorAssets } from "../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi";
|
||||||
import useModuleStore from "../../../store/useModuleStore";
|
import useModuleStore from "../../../store/useModuleStore";
|
||||||
import { useEventsStore } from "../../../store/simulation/useEventsStore";
|
import { useEventsStore } from "../../../store/simulation/useEventsStore";
|
||||||
|
import { findEnvironment } from "../../../services/factoryBuilder/environment/findEnvironment";
|
||||||
|
|
||||||
const assetManagerWorker = new Worker(
|
const assetManagerWorker = new Worker(
|
||||||
new URL(
|
new URL(
|
||||||
|
@ -77,71 +78,77 @@ const FloorItemsGroup = ({
|
||||||
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 totalAssets = 0;
|
findEnvironment(
|
||||||
let loadedAssets = 0;
|
organization,
|
||||||
|
localStorage.getItem("userId")!
|
||||||
|
).then((evnironMentData) => {
|
||||||
|
|
||||||
const updateLoadingProgress = (progress: number) => {
|
let totalAssets = 0;
|
||||||
if (progress < 100) {
|
let loadedAssets = 0;
|
||||||
setLoadingProgress(progress);
|
|
||||||
} else if (progress === 100) {
|
const updateLoadingProgress = (progress: number) => {
|
||||||
setTimeout(() => {
|
if (progress < 100) {
|
||||||
setLoadingProgress(100);
|
setLoadingProgress(progress);
|
||||||
|
} else if (progress === 100) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setLoadingProgress(0);
|
setLoadingProgress(100);
|
||||||
}, 1500);
|
setTimeout(() => {
|
||||||
}, 1000);
|
setLoadingProgress(0);
|
||||||
}
|
}, 1500);
|
||||||
};
|
}, 1000);
|
||||||
|
|
||||||
getFloorAssets(organization).then((data) => {
|
|
||||||
if (data.length > 0) {
|
|
||||||
const uniqueItems = (data as Types.FloorItems).filter(
|
|
||||||
(item, index, self) =>
|
|
||||||
index === self.findIndex((t) => t.modelfileID === item.modelfileID)
|
|
||||||
);
|
|
||||||
totalAssets = uniqueItems.length;
|
|
||||||
if (totalAssets === 0) {
|
|
||||||
updateLoadingProgress(100);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
gltfLoaderWorker.postMessage({ floorItems: uniqueItems });
|
};
|
||||||
} else {
|
|
||||||
gltfLoaderWorker.postMessage({ floorItems: [] });
|
|
||||||
loadInitialFloorItems(
|
|
||||||
itemsGroup,
|
|
||||||
setFloorItems,
|
|
||||||
addEvent,
|
|
||||||
renderDistance
|
|
||||||
);
|
|
||||||
updateLoadingProgress(100);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
gltfLoaderWorker.onmessage = async (event) => {
|
getFloorAssets(organization).then((data) => {
|
||||||
if (event.data.message === "gltfLoaded" && event.data.modelBlob) {
|
if (data.length > 0) {
|
||||||
const blobUrl = URL.createObjectURL(event.data.modelBlob);
|
const uniqueItems = (data as Types.FloorItems).filter(
|
||||||
|
(item, index, self) =>
|
||||||
loader.load(blobUrl, (gltf) => {
|
index === self.findIndex((t) => t.modelfileID === item.modelfileID)
|
||||||
URL.revokeObjectURL(blobUrl);
|
);
|
||||||
THREE.Cache.remove(blobUrl);
|
totalAssets = uniqueItems.length;
|
||||||
THREE.Cache.add(event.data.modelID, gltf);
|
if (totalAssets === 0) {
|
||||||
|
|
||||||
loadedAssets++;
|
|
||||||
const progress = Math.round((loadedAssets / totalAssets) * 100);
|
|
||||||
updateLoadingProgress(progress);
|
|
||||||
|
|
||||||
if (loadedAssets === totalAssets) {
|
|
||||||
loadInitialFloorItems(
|
|
||||||
itemsGroup,
|
|
||||||
setFloorItems,
|
|
||||||
addEvent,
|
|
||||||
renderDistance
|
|
||||||
);
|
|
||||||
updateLoadingProgress(100);
|
updateLoadingProgress(100);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
gltfLoaderWorker.postMessage({ floorItems: uniqueItems });
|
||||||
}
|
} else {
|
||||||
};
|
gltfLoaderWorker.postMessage({ floorItems: [] });
|
||||||
|
loadInitialFloorItems(
|
||||||
|
itemsGroup,
|
||||||
|
setFloorItems,
|
||||||
|
addEvent,
|
||||||
|
evnironMentData.renderDistance
|
||||||
|
);
|
||||||
|
updateLoadingProgress(100);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
gltfLoaderWorker.onmessage = async (event) => {
|
||||||
|
if (event.data.message === "gltfLoaded" && event.data.modelBlob) {
|
||||||
|
const blobUrl = URL.createObjectURL(event.data.modelBlob);
|
||||||
|
|
||||||
|
loader.load(blobUrl, (gltf) => {
|
||||||
|
URL.revokeObjectURL(blobUrl);
|
||||||
|
THREE.Cache.remove(blobUrl);
|
||||||
|
THREE.Cache.add(event.data.modelID, gltf);
|
||||||
|
|
||||||
|
loadedAssets++;
|
||||||
|
const progress = Math.round((loadedAssets / totalAssets) * 100);
|
||||||
|
updateLoadingProgress(progress);
|
||||||
|
|
||||||
|
if (loadedAssets === totalAssets) {
|
||||||
|
loadInitialFloorItems(
|
||||||
|
itemsGroup,
|
||||||
|
setFloorItems,
|
||||||
|
addEvent,
|
||||||
|
evnironMentData.renderDistance
|
||||||
|
);
|
||||||
|
updateLoadingProgress(100);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -363,10 +370,10 @@ const FloorItemsGroup = ({
|
||||||
if (!event.dataTransfer?.files[0]) return;
|
if (!event.dataTransfer?.files[0]) return;
|
||||||
|
|
||||||
if (selectedItem.id !== "" && event.dataTransfer?.files[0] && selectedItem.category !== 'Fenestration') {
|
if (selectedItem.id !== "" && event.dataTransfer?.files[0] && selectedItem.category !== 'Fenestration') {
|
||||||
|
|
||||||
state.pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
|
state.pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
|
||||||
state.pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
|
state.pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
|
||||||
|
|
||||||
addAssetModel(
|
addAssetModel(
|
||||||
raycaster,
|
raycaster,
|
||||||
state.camera,
|
state.camera,
|
||||||
|
|
|
@ -6,20 +6,22 @@ import { useSelectedProduct } from "../../../../../store/simulation/useSimulatio
|
||||||
import { useStorageUnitStore } from "../../../../../store/simulation/useStorageUnitStore";
|
import { useStorageUnitStore } from "../../../../../store/simulation/useStorageUnitStore";
|
||||||
import { useArmBotStore } from "../../../../../store/simulation/useArmBotStore";
|
import { useArmBotStore } from "../../../../../store/simulation/useArmBotStore";
|
||||||
import { useVehicleStore } from "../../../../../store/simulation/useVehicleStore";
|
import { useVehicleStore } from "../../../../../store/simulation/useVehicleStore";
|
||||||
import { usePlayButtonStore, usePauseButtonStore, useResetButtonStore } from "../../../../../store/usePlayButtonStore";
|
import { usePlayButtonStore, usePauseButtonStore, useResetButtonStore, useAnimationPlaySpeed } from "../../../../../store/usePlayButtonStore";
|
||||||
|
|
||||||
export function useRetrieveHandler() {
|
export function useRetrieveHandler() {
|
||||||
const { addMaterial } = useMaterialStore();
|
const { addMaterial } = useMaterialStore();
|
||||||
const { getModelUuidByActionUuid, getPointUuidByActionUuid, getEventByModelUuid } = useProductStore();
|
const { getModelUuidByActionUuid, getPointUuidByActionUuid, getEventByModelUuid, getActionByUuid } = useProductStore();
|
||||||
const { getStorageUnitById, getLastMaterial, updateCurrentLoad, removeLastMaterial } = useStorageUnitStore();
|
const { getStorageUnitById, getLastMaterial, updateCurrentLoad, removeLastMaterial } = useStorageUnitStore();
|
||||||
const { getVehicleById, incrementVehicleLoad, addCurrentMaterial } = useVehicleStore();
|
const { getVehicleById, incrementVehicleLoad, addCurrentMaterial } = useVehicleStore();
|
||||||
const { selectedProduct } = useSelectedProduct();
|
const { selectedProduct } = useSelectedProduct();
|
||||||
const { getArmBotById, addCurrentAction } = useArmBotStore();
|
const { getArmBotById, addCurrentAction } = useArmBotStore();
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
|
const { speed } = useAnimationPlaySpeed();
|
||||||
const { isPaused } = usePauseButtonStore();
|
const { isPaused } = usePauseButtonStore();
|
||||||
const { isReset } = useResetButtonStore();
|
const { isReset } = useResetButtonStore();
|
||||||
|
|
||||||
const [activeRetrievals, setActiveRetrievals] = useState<Map<string, { action: StorageAction, isProcessing: boolean, lastCheckTime: number }>>(new Map());
|
const [activeRetrievals, setActiveRetrievals] = useState<Map<string, { action: StorageAction, isProcessing: boolean, lastCheckTime: number }>>(new Map());
|
||||||
|
const retrievalTimeRef = useRef<Map<string, number>>(new Map());
|
||||||
|
|
||||||
const [initialDelayComplete, setInitialDelayComplete] = useState(false);
|
const [initialDelayComplete, setInitialDelayComplete] = useState(false);
|
||||||
const delayTimerRef = useRef<NodeJS.Timeout | null>(null);
|
const delayTimerRef = useRef<NodeJS.Timeout | null>(null);
|
||||||
|
@ -125,7 +127,26 @@ export function useRetrieveHandler() {
|
||||||
const armBot = getArmBotById(triggeredModel.modelUuid);
|
const armBot = getArmBotById(triggeredModel.modelUuid);
|
||||||
isIdle = (armBot && !armBot.isActive && armBot.state === 'idle' && !armBot.currentAction) || false;
|
isIdle = (armBot && !armBot.isActive && armBot.state === 'idle' && !armBot.currentAction) || false;
|
||||||
|
|
||||||
if (isIdle) {
|
if (!armBot) return;
|
||||||
|
if (!retrievalTimeRef.current.has(actionUuid) && isIdle) {
|
||||||
|
retrievalTimeRef.current.set(actionUuid, currentTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const idleStartTime = retrievalTimeRef.current.get(actionUuid);
|
||||||
|
const minIdleTimeBeforeFirstRetrieval = 5000 / speed;
|
||||||
|
const minDelayBetweenRetrievals = 5000 / speed;
|
||||||
|
|
||||||
|
const canProceedFirstRetrieval = idleStartTime !== undefined &&
|
||||||
|
(currentTime - idleStartTime) >= minIdleTimeBeforeFirstRetrieval;
|
||||||
|
|
||||||
|
const lastRetrievalTime = retrievalTimeRef.current.get(`${actionUuid}_last`) ?? null;
|
||||||
|
const canProceedSubsequent = lastRetrievalTime === null ||
|
||||||
|
(currentTime - lastRetrievalTime) >= minDelayBetweenRetrievals;
|
||||||
|
|
||||||
|
const canProceed = lastRetrievalTime === null ? canProceedFirstRetrieval : canProceedSubsequent;
|
||||||
|
|
||||||
|
if (isIdle && canProceed) {
|
||||||
setActiveRetrievals(prev => {
|
setActiveRetrievals(prev => {
|
||||||
const newRetrievals = new Map(prev);
|
const newRetrievals = new Map(prev);
|
||||||
newRetrievals.set(actionUuid, {
|
newRetrievals.set(actionUuid, {
|
||||||
|
@ -138,42 +159,97 @@ export function useRetrieveHandler() {
|
||||||
|
|
||||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||||
if (lastMaterial) {
|
if (lastMaterial) {
|
||||||
const material = createNewMaterial(
|
|
||||||
lastMaterial.materialId,
|
|
||||||
lastMaterial.materialType,
|
|
||||||
storageUnit.point.action
|
|
||||||
);
|
|
||||||
|
|
||||||
if (material) {
|
if (retrieval.action.triggers[0].triggeredAsset.triggeredAction?.actionUuid) {
|
||||||
addCurrentAction(
|
const action = getActionByUuid(selectedProduct.productId, retrieval.action.triggers[0].triggeredAsset.triggeredAction.actionUuid);
|
||||||
triggeredModel.modelUuid,
|
if (action && action.triggers.length > 0 && action.triggers[0].triggeredAsset?.triggeredModel.modelUuid) {
|
||||||
retrieval.action.triggers[0].triggeredAsset.triggeredAction?.actionUuid ?? '',
|
const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0].triggeredAsset.triggeredModel.modelUuid);
|
||||||
material.materialType,
|
if (model) {
|
||||||
material.materialId
|
if (model.type === 'vehicle') {
|
||||||
);
|
const vehicle = getVehicleById(model.modelUuid);
|
||||||
retrieveLogStatus(material.materialName, `is being picked by ${armBot?.modelName}`);
|
if (vehicle && !vehicle.isActive && vehicle.state === 'idle' && vehicle.isPicking && vehicle.currentLoad < vehicle.point.action.loadCapacity) {
|
||||||
|
|
||||||
|
const material = createNewMaterial(
|
||||||
|
lastMaterial.materialId,
|
||||||
|
lastMaterial.materialType,
|
||||||
|
storageUnit.point.action
|
||||||
|
);
|
||||||
|
if (material) {
|
||||||
|
|
||||||
|
addCurrentAction(
|
||||||
|
triggeredModel.modelUuid,
|
||||||
|
retrieval.action.triggers[0].triggeredAsset.triggeredAction?.actionUuid ?? '',
|
||||||
|
material.materialType,
|
||||||
|
material.materialId
|
||||||
|
);
|
||||||
|
retrieveLogStatus(material.materialName, `is being picked by ${armBot?.modelName}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const material = createNewMaterial(
|
||||||
|
lastMaterial.materialId,
|
||||||
|
lastMaterial.materialType,
|
||||||
|
storageUnit.point.action
|
||||||
|
);
|
||||||
|
if (material) {
|
||||||
|
|
||||||
|
addCurrentAction(
|
||||||
|
triggeredModel.modelUuid,
|
||||||
|
retrieval.action.triggers[0].triggeredAsset.triggeredAction?.actionUuid ?? '',
|
||||||
|
material.materialType,
|
||||||
|
material.materialId
|
||||||
|
);
|
||||||
|
retrieveLogStatus(material.materialName, `is being picked by ${armBot?.modelName}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setActiveRetrievals(prev => {
|
||||||
|
const newRetrievals = new Map(prev);
|
||||||
|
newRetrievals.set(actionUuid, {
|
||||||
|
...retrieval,
|
||||||
|
isProcessing: false,
|
||||||
|
lastCheckTime: currentTime,
|
||||||
|
});
|
||||||
|
return newRetrievals;
|
||||||
|
});
|
||||||
|
|
||||||
|
retrievalTimeRef.current.set(actionUuid, currentTime);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
setActiveRetrievals(prev => {
|
}
|
||||||
const newRetrievals = new Map(prev);
|
} else if (!isIdle) {
|
||||||
newRetrievals.set(actionUuid, {
|
retrievalTimeRef.current.delete(actionUuid);
|
||||||
...retrieval,
|
|
||||||
isProcessing: false,
|
|
||||||
lastCheckTime: currentTime
|
|
||||||
});
|
|
||||||
return newRetrievals;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (triggeredModel.type === 'vehicle') {
|
} else if (triggeredModel.type === 'vehicle') {
|
||||||
const vehicle = getVehicleById(triggeredModel.modelUuid);
|
const vehicle = getVehicleById(triggeredModel.modelUuid);
|
||||||
isIdle = (vehicle && !vehicle.isActive && vehicle.state === 'idle' && vehicle.isPicking) || false;
|
isIdle = (vehicle && !vehicle.isActive && vehicle.state === 'idle' && vehicle.isPicking && vehicle.currentLoad < vehicle.point.action.loadCapacity) || false;
|
||||||
|
|
||||||
if (!vehicle) return;
|
if (!vehicle) return;
|
||||||
// const loadDuration = vehicle.point.action.unLoadDuration;
|
|
||||||
|
|
||||||
if (isIdle) {
|
const loadDuration = vehicle.point.action.unLoadDuration;
|
||||||
|
let minDelayBetweenRetrievals = (loadDuration * 1000) / speed;
|
||||||
|
const minIdleTimeBeforeFirstRetrieval = 3000 / speed;
|
||||||
|
|
||||||
|
if (!retrievalTimeRef.current.has(actionUuid) && isIdle) {
|
||||||
|
retrievalTimeRef.current.set(actionUuid, currentTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const idleStartTime = retrievalTimeRef.current.get(actionUuid);
|
||||||
|
const lastRetrievalTime = retrievalTimeRef.current.get(`${actionUuid}_last`) ?? null;
|
||||||
|
|
||||||
|
const canProceedFirstRetrieval = idleStartTime !== undefined &&
|
||||||
|
(currentTime - idleStartTime) >= minIdleTimeBeforeFirstRetrieval;
|
||||||
|
|
||||||
|
const canProceedSubsequent = lastRetrievalTime === null ||
|
||||||
|
(currentTime - lastRetrievalTime) >= minDelayBetweenRetrievals;
|
||||||
|
|
||||||
|
const canProceed = lastRetrievalTime === null ? canProceedFirstRetrieval : canProceedSubsequent;
|
||||||
|
|
||||||
|
if (isIdle && canProceed) {
|
||||||
setActiveRetrievals(prev => {
|
setActiveRetrievals(prev => {
|
||||||
const newRetrievals = new Map(prev);
|
const newRetrievals = new Map(prev);
|
||||||
newRetrievals.set(actionUuid, {
|
newRetrievals.set(actionUuid, {
|
||||||
|
@ -208,12 +284,17 @@ export function useRetrieveHandler() {
|
||||||
newRetrievals.set(actionUuid, {
|
newRetrievals.set(actionUuid, {
|
||||||
...retrieval,
|
...retrieval,
|
||||||
isProcessing: false,
|
isProcessing: false,
|
||||||
lastCheckTime: currentTime
|
lastCheckTime: currentTime,
|
||||||
});
|
});
|
||||||
return newRetrievals;
|
return newRetrievals;
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
|
retrievalTimeRef.current.set(actionUuid, currentTime);
|
||||||
|
retrievalTimeRef.current.set(`${actionUuid}_last`, currentTime);
|
||||||
|
} else if (!isIdle) {
|
||||||
|
retrievalTimeRef.current.delete(actionUuid);
|
||||||
|
retrievalTimeRef.current.delete(`${actionUuid}_last`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -234,7 +315,7 @@ export function useRetrieveHandler() {
|
||||||
newRetrievals.set(action.actionUuid, {
|
newRetrievals.set(action.actionUuid, {
|
||||||
action,
|
action,
|
||||||
isProcessing: false,
|
isProcessing: false,
|
||||||
lastCheckTime: performance.now()
|
lastCheckTime: performance.now(),
|
||||||
});
|
});
|
||||||
return newRetrievals;
|
return newRetrievals;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import MaterialInstances from './instances/materialInstances'
|
import MaterialInstances from './instances/materialInstances'
|
||||||
import { usePlayButtonStore, useResetButtonStore } from '../../../store/usePlayButtonStore';
|
import { usePlayButtonStore, useResetButtonStore } from '../../../store/usePlayButtonStore';
|
||||||
import { useMaterialStore } from '../../../store/simulation/useMaterialStore';
|
import { useMaterialStore } from '../../../store/simulation/useMaterialStore';
|
||||||
|
|
|
@ -228,11 +228,11 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
||||||
logStatus(armBot.modelUuid, "Moving armBot from rest point to start position.")
|
logStatus(armBot.modelUuid, "Moving armBot from rest point to start position.")
|
||||||
}
|
}
|
||||||
// Moving to Pick to Drop position
|
// Moving to Pick to Drop position
|
||||||
else if (armBot && !armBot.isActive && armBot.state === "idle" && currentPhase === "picking" && armBot.currentAction) {
|
else if (armBot && !armBot.isActive && armBot.state === "running" && currentPhase === "picking" && armBot.currentAction) {
|
||||||
requestAnimationFrame(firstFrame);
|
requestAnimationFrame(firstFrame);
|
||||||
}
|
}
|
||||||
//Moving to drop point to restPosition
|
//Moving to drop point to restPosition
|
||||||
else if (armBot && !armBot.isActive && armBot.state === "idle" && currentPhase === "dropping" && armBot.currentAction) {
|
else if (armBot && !armBot.isActive && armBot.state === "running" && currentPhase === "dropping" && armBot.currentAction) {
|
||||||
requestAnimationFrame(firstFrame);
|
requestAnimationFrame(firstFrame);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -270,14 +270,14 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
||||||
else if (armBot.isActive && armBot.state == "running" && currentPhase == "rest-to-start") {
|
else if (armBot.isActive && armBot.state == "running" && currentPhase == "rest-to-start") {
|
||||||
logStatus(armBot.modelUuid, "Callback triggered: pick.");
|
logStatus(armBot.modelUuid, "Callback triggered: pick.");
|
||||||
setArmBotActive(armBot.modelUuid, false)
|
setArmBotActive(armBot.modelUuid, false)
|
||||||
setArmBotState(armBot.modelUuid, "idle")
|
setArmBotState(armBot.modelUuid, "running")
|
||||||
setCurrentPhase("picking");
|
setCurrentPhase("picking");
|
||||||
setPath([])
|
setPath([])
|
||||||
}
|
}
|
||||||
else if (armBot.isActive && armBot.state == "running" && currentPhase == "start-to-end") {
|
else if (armBot.isActive && armBot.state == "running" && currentPhase == "start-to-end") {
|
||||||
logStatus(armBot.modelUuid, "Callback triggered: drop.");
|
logStatus(armBot.modelUuid, "Callback triggered: drop.");
|
||||||
setArmBotActive(armBot.modelUuid, false)
|
setArmBotActive(armBot.modelUuid, false)
|
||||||
setArmBotState(armBot.modelUuid, "idle")
|
setArmBotState(armBot.modelUuid, "running")
|
||||||
setCurrentPhase("dropping");
|
setCurrentPhase("dropping");
|
||||||
setPath([])
|
setPath([])
|
||||||
}
|
}
|
||||||
|
|
|
@ -414,6 +414,10 @@ export function useTriggerHandler() {
|
||||||
|
|
||||||
handleAction(action, material.materialId);
|
handleAction(action, material.materialId);
|
||||||
}
|
}
|
||||||
|
} else if (action) {
|
||||||
|
setNextLocation(material.materialId, null)
|
||||||
|
|
||||||
|
handleAction(action, material.materialId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import { NavMeshQuery } from '@recast-navigation/core';
|
||||||
import { useNavMesh } from '../../../../../store/builder/store';
|
import { useNavMesh } from '../../../../../store/builder/store';
|
||||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
|
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||||
import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore';
|
import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore';
|
||||||
|
import { useArmBotStore } from '../../../../../store/simulation/useArmBotStore';
|
||||||
|
import { useConveyorStore } from '../../../../../store/simulation/useConveyorStore';
|
||||||
import { useStorageUnitStore } from '../../../../../store/simulation/useStorageUnitStore';
|
import { useStorageUnitStore } from '../../../../../store/simulation/useStorageUnitStore';
|
||||||
import { useMaterialStore } from '../../../../../store/simulation/useMaterialStore';
|
import { useMaterialStore } from '../../../../../store/simulation/useMaterialStore';
|
||||||
import { useProductStore } from '../../../../../store/simulation/useProductStore';
|
import { useProductStore } from '../../../../../store/simulation/useProductStore';
|
||||||
|
@ -20,10 +22,12 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
const { removeMaterial, setEndTime } = useMaterialStore();
|
const { removeMaterial, setEndTime } = useMaterialStore();
|
||||||
const { getStorageUnitById } = useStorageUnitStore();
|
const { getStorageUnitById } = useStorageUnitStore();
|
||||||
|
const { getArmBotById } = useArmBotStore();
|
||||||
|
const { getConveyorById } = useConveyorStore();
|
||||||
const { triggerPointActions } = useTriggerHandler();
|
const { triggerPointActions } = useTriggerHandler();
|
||||||
const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = useProductStore();
|
const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = useProductStore();
|
||||||
const { selectedProduct } = useSelectedProduct();
|
const { selectedProduct } = useSelectedProduct();
|
||||||
const { vehicles, setVehicleActive, setVehicleState, setVehiclePicking, clearCurrentMaterials, setVehicleLoad, decrementVehicleLoad, removeLastMaterial } = useVehicleStore();
|
const { vehicles, setVehicleActive, setVehicleState, setVehiclePicking, clearCurrentMaterials, setVehicleLoad, decrementVehicleLoad, removeLastMaterial, getLastMaterial } = useVehicleStore();
|
||||||
const [currentPhase, setCurrentPhase] = useState<string>('stationed');
|
const [currentPhase, setCurrentPhase] = useState<string>('stationed');
|
||||||
const [path, setPath] = useState<[number, number, number][]>([]);
|
const [path, setPath] = useState<[number, number, number][]>([]);
|
||||||
const pauseTimeRef = useRef<number | null>(null);
|
const pauseTimeRef = useRef<number | null>(null);
|
||||||
|
@ -147,9 +151,6 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function startUnloadingProcess() {
|
function startUnloadingProcess() {
|
||||||
if (agvDetail.point.action.triggers.length > 0) {
|
if (agvDetail.point.action.triggers.length > 0) {
|
||||||
const trigger = getTriggerByUuid(selectedProduct.productId, agvDetail.point.action.triggers[0].triggerUuid);
|
const trigger = getTriggerByUuid(selectedProduct.productId, agvDetail.point.action.triggers[0].triggerUuid);
|
||||||
|
@ -159,19 +160,19 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||||
if (model.type === 'transfer') {
|
if (model.type === 'transfer') {
|
||||||
const action = getActionByUuid(selectedProduct.productId, agvDetail.point.action.actionUuid);
|
const action = getActionByUuid(selectedProduct.productId, agvDetail.point.action.actionUuid);
|
||||||
if (action) {
|
if (action) {
|
||||||
handleMaterialDropToConveyor(action);
|
handleMaterialDropToConveyor(model);
|
||||||
}
|
}
|
||||||
} else if (model.type === 'machine') {
|
} else if (model.type === 'machine') {
|
||||||
//
|
//
|
||||||
} else if (model.type === 'roboticArm') {
|
} else if (model.type === 'roboticArm') {
|
||||||
const action = getActionByUuid(selectedProduct.productId, agvDetail.point.action.actionUuid);
|
const action = getActionByUuid(selectedProduct.productId, agvDetail.point.action.actionUuid);
|
||||||
if (action) {
|
if (action) {
|
||||||
handleMaterialDropToArmBot(action);
|
handleMaterialDropToArmBot(model);
|
||||||
}
|
}
|
||||||
} else if (model.type === 'storageUnit') {
|
} else if (model.type === 'storageUnit') {
|
||||||
const action = getActionByUuid(selectedProduct.productId, agvDetail.point.action.actionUuid);
|
const action = getActionByUuid(selectedProduct.productId, agvDetail.point.action.actionUuid);
|
||||||
if (action) {
|
if (action) {
|
||||||
handleMaterialDropToStorageUnit(action);
|
handleMaterialDropToStorageUnit(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -186,25 +187,22 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMaterialDropToStorageUnit(action: Action) {
|
function handleMaterialDropToStorageUnit(model: StorageEventSchema) {
|
||||||
if (action.triggers.length > 0 && action.triggers[0].triggeredAsset?.triggeredModel.modelUuid) {
|
if (model) {
|
||||||
const storageUnit = getStorageUnitById(action.triggers[0].triggeredAsset?.triggeredModel.modelUuid);
|
if (model.point.action.actionType === 'store') {
|
||||||
if (storageUnit) {
|
loopMaterialDropToStorage(
|
||||||
if (storageUnit.point.action.actionType === 'store') {
|
agvDetail.modelUuid,
|
||||||
handleMaterialDropToStorage(
|
agvDetail.currentLoad,
|
||||||
agvDetail.modelUuid,
|
agvDetail.point.action.unLoadDuration,
|
||||||
agvDetail.currentLoad,
|
model.modelUuid,
|
||||||
agvDetail.point.action.unLoadDuration,
|
model.point.action.storageCapacity,
|
||||||
storageUnit.modelUuid,
|
agvDetail.point.action
|
||||||
storageUnit.point.action.storageCapacity,
|
);
|
||||||
agvDetail.point.action
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMaterialDropToStorage(
|
function loopMaterialDropToStorage(
|
||||||
vehicleId: string,
|
vehicleId: string,
|
||||||
vehicleCurrentLoad: number,
|
vehicleCurrentLoad: number,
|
||||||
unLoadDuration: number,
|
unLoadDuration: number,
|
||||||
|
@ -262,24 +260,140 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMaterialDropToConveyor(action: Action) {
|
function handleMaterialDropToConveyor(model: ConveyorEventSchema) {
|
||||||
if (agvDetail.currentLoad > 1) {
|
const conveyor = getConveyorById(model.modelUuid);
|
||||||
//
|
if (conveyor) {
|
||||||
} else if (agvDetail.currentLoad === 1 && agvDetail.currentMaterials.length === 1) {
|
loopMaterialDropToConveyor(
|
||||||
triggerPointActions(action, agvDetail.currentMaterials[0].materialId);
|
agvDetail.modelUuid,
|
||||||
decrementVehicleLoad(agvDetail.modelUuid, 1);
|
agvDetail.currentLoad,
|
||||||
removeLastMaterial(agvDetail.modelUuid);
|
conveyor.modelUuid,
|
||||||
|
agvDetail.point.action.unLoadDuration,
|
||||||
|
agvDetail.point.action
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMaterialDropToArmBot(action: Action) {
|
function loopMaterialDropToConveyor(
|
||||||
if (agvDetail.currentLoad > 1) {
|
vehicleId: string,
|
||||||
//
|
vehicleCurrentLoad: number,
|
||||||
} else if (agvDetail.currentLoad === 1 && agvDetail.currentMaterials.length === 1) {
|
conveyorId: string,
|
||||||
triggerPointActions(action, agvDetail.currentMaterials[0].materialId);
|
unLoadDuration: number,
|
||||||
|
action: VehicleAction
|
||||||
|
) {
|
||||||
|
startTime = performance.now();
|
||||||
|
const fixedInterval = unLoadDuration * (1000 / speed);
|
||||||
|
|
||||||
|
const dropLoop = () => {
|
||||||
|
if (isPausedRef.current) {
|
||||||
|
pauseTimeRef.current ??= performance.now();
|
||||||
|
requestAnimationFrame(dropLoop);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pauseTimeRef.current) {
|
||||||
|
const pauseDuration = performance.now() - pauseTimeRef.current;
|
||||||
|
startTime += pauseDuration;
|
||||||
|
pauseTimeRef.current = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const elapsedTime = performance.now() - startTime;
|
||||||
|
const conveyor = getConveyorById(conveyorId);
|
||||||
|
if (elapsedTime >= fixedInterval) {
|
||||||
|
if (conveyor && !conveyor.isPaused && vehicleCurrentLoad > 0) {
|
||||||
|
decrementVehicleLoad(vehicleId, 1);
|
||||||
|
vehicleCurrentLoad -= 1;
|
||||||
|
|
||||||
|
const material = removeLastMaterial(vehicleId);
|
||||||
|
if (material) {
|
||||||
|
triggerPointActions(action, material.materialId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vehicleCurrentLoad > 0) {
|
||||||
|
startTime = performance.now();
|
||||||
|
requestAnimationFrame(dropLoop);
|
||||||
|
}
|
||||||
|
} else if (!conveyor?.isActive) {
|
||||||
|
requestAnimationFrame(dropLoop);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
requestAnimationFrame(dropLoop);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dropLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMaterialDropToArmBot(model: RoboticArmEventSchema) {
|
||||||
|
const armBot = getArmBotById(model.modelUuid);
|
||||||
|
if (armBot && armBot.state === 'idle' && !armBot.isActive) {
|
||||||
|
loopMaterialDropToArmBot(
|
||||||
|
agvDetail.modelUuid,
|
||||||
|
agvDetail.currentLoad,
|
||||||
|
agvDetail.point.action.unLoadDuration,
|
||||||
|
model.modelUuid,
|
||||||
|
agvDetail.point.action
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loopMaterialDropToArmBot(
|
||||||
|
vehicleId: string,
|
||||||
|
vehicleCurrentLoad: number,
|
||||||
|
unLoadDuration: number,
|
||||||
|
armBotId: string,
|
||||||
|
action: VehicleAction
|
||||||
|
) {
|
||||||
|
startTime = performance.now();
|
||||||
|
const armBot = getArmBotById(armBotId);
|
||||||
|
|
||||||
|
if (!armBot || armBot.state !== 'idle' || armBot.isActive || vehicleCurrentLoad <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkIdleDuration = () => {
|
||||||
|
if (isPausedRef.current) {
|
||||||
|
pauseTimeRef.current ??= performance.now();
|
||||||
|
requestAnimationFrame(checkIdleDuration);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pauseTimeRef.current) {
|
||||||
|
const pauseDuration = performance.now() - pauseTimeRef.current;
|
||||||
|
startTime += pauseDuration;
|
||||||
|
pauseTimeRef.current = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const elapsedTime = performance.now() - startTime;
|
||||||
|
|
||||||
|
if (elapsedTime >= unLoadDuration * (1000 / speed)) {
|
||||||
|
const material = getLastMaterial(vehicleId);
|
||||||
|
if (material) {
|
||||||
|
vehicleCurrentLoad -= 1;
|
||||||
|
|
||||||
|
triggerPointActions(action, material.materialId);
|
||||||
|
|
||||||
|
if (vehicleCurrentLoad > 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
const waitForNextTransfer = () => {
|
||||||
|
const currentArmBot = getArmBotById(armBotId);
|
||||||
|
if (currentArmBot && currentArmBot.state === 'idle' && !currentArmBot.isActive) {
|
||||||
|
startTime = performance.now();
|
||||||
|
loopMaterialDropToArmBot(vehicleId, vehicleCurrentLoad, unLoadDuration, armBotId, action);
|
||||||
|
} else {
|
||||||
|
requestAnimationFrame(waitForNextTransfer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
waitForNextTransfer();
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
requestAnimationFrame(checkIdleDuration);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
checkIdleDuration();
|
||||||
|
}
|
||||||
|
|
||||||
function handleMaterialDropByDefault(droppedMaterial: number) {
|
function handleMaterialDropByDefault(droppedMaterial: number) {
|
||||||
if (isPausedRef.current) {
|
if (isPausedRef.current) {
|
||||||
pauseTimeRef.current ??= performance.now();
|
pauseTimeRef.current ??= performance.now();
|
||||||
|
|
|
@ -25,6 +25,7 @@ interface VehiclesStore {
|
||||||
addCurrentMaterial: (modelUuid: string, materialType: string, materialId: string) => void;
|
addCurrentMaterial: (modelUuid: string, materialType: string, materialId: string) => void;
|
||||||
setCurrentMaterials: (modelUuid: string, materials: { materialType: string; materialId: string; }[]) => void;
|
setCurrentMaterials: (modelUuid: string, materials: { materialType: string; materialId: string; }[]) => void;
|
||||||
removeLastMaterial: (modelUuid: string) => { materialId: string; materialType: string; } | undefined;
|
removeLastMaterial: (modelUuid: string) => { materialId: string; materialType: string; } | undefined;
|
||||||
|
getLastMaterial: (modelUuid: string) => { materialId: string; materialType: string; } | undefined;
|
||||||
clearCurrentMaterials: (modelUuid: string) => void;
|
clearCurrentMaterials: (modelUuid: string) => void;
|
||||||
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
|
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
|
||||||
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
|
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
|
||||||
|
@ -179,6 +180,22 @@ export const useVehicleStore = create<VehiclesStore>()(
|
||||||
return removedMaterial;
|
return removedMaterial;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getLastMaterial: (modelUuid) => {
|
||||||
|
let removedMaterial: { materialId: string; materialType: string; } | undefined;
|
||||||
|
set((state) => {
|
||||||
|
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
|
||||||
|
if (vehicle) {
|
||||||
|
if (vehicle.currentMaterials.length > 0) {
|
||||||
|
removedMaterial = {
|
||||||
|
materialId: vehicle.currentMaterials[vehicle.currentMaterials.length - 1].materialId,
|
||||||
|
materialType: vehicle.currentMaterials[vehicle.currentMaterials.length - 1].materialType
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return removedMaterial;
|
||||||
|
},
|
||||||
|
|
||||||
clearCurrentMaterials: (modelUuid) => {
|
clearCurrentMaterials: (modelUuid) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
|
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
|
||||||
|
|
Loading…
Reference in New Issue