Compare commits
43 Commits
ui
...
simulation
| Author | SHA1 | Date | |
|---|---|---|---|
| 686c4e60c6 | |||
| 967f1741b0 | |||
| 1e901c327d | |||
| cc074a5913 | |||
| 8e491a0002 | |||
| f7e4f5c580 | |||
| 64885f246e | |||
| 16cf1b96cc | |||
| ee319c28e4 | |||
|
|
9b9164c600 | ||
|
|
496c8b0305 | ||
|
|
0eedbdd58e | ||
| 8b7b7f589a | |||
| a59aa1d61c | |||
|
|
43d21a522c | ||
|
|
b46b468e1c | ||
| e0082cb55a | |||
| 5c24d7ca71 | |||
| 939f6e5086 | |||
| 83f92d4b01 | |||
| a26e0dacd0 | |||
| 693f58ff36 | |||
| 318ac6d939 | |||
| 1607532cf4 | |||
| fa6404d86c | |||
| 5b42bd9c40 | |||
|
|
c7147773c5 | ||
| db9c9fb8b5 | |||
| e2fd4ef15d | |||
| 109f88949c | |||
| f62d231a79 | |||
| c2a29fc893 | |||
| 5cef9bdb8a | |||
| 3446507307 | |||
| 05214997f1 | |||
| 82a7cd0001 | |||
| ca3028985f | |||
| d60d9812e4 | |||
| 5219d545b8 | |||
| 1e76fcb71c | |||
| 4ac8826399 | |||
| 37df5e8801 | |||
| 372bfc7727 |
@@ -73,7 +73,7 @@ const Assets: React.FC = () => {
|
||||
try {
|
||||
const filt = await fetchAssets();
|
||||
setFiltereredAssets(filt);
|
||||
} catch {}
|
||||
} catch { }
|
||||
};
|
||||
filteredAssets();
|
||||
}, [categoryAssets]);
|
||||
@@ -133,10 +133,9 @@ const Assets: React.FC = () => {
|
||||
} else {
|
||||
try {
|
||||
const res = await getCategoryAsset(asset);
|
||||
console.log('res: ', res);
|
||||
setCategoryAssets(res);
|
||||
setFiltereredAssets(res);
|
||||
} catch (error) {}
|
||||
} catch (error) { }
|
||||
}
|
||||
};
|
||||
return (
|
||||
@@ -235,6 +234,7 @@ const Assets: React.FC = () => {
|
||||
src={categoryInfo?.categoryImage || ""}
|
||||
alt={category}
|
||||
className="category-image"
|
||||
draggable={false}
|
||||
/>
|
||||
<div className="category-name">{category}</div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useRef, useMemo, useCallback, useState } from "react";
|
||||
import { InfoIcon, AddIcon, RemoveIcon, ResizeHeightIcon } from "../../../icons/ExportCommonIcons";
|
||||
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||
import { useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store";
|
||||
import * as Types from '../../../../types/world/worldTypes';
|
||||
import * as SimulationTypes from '../../../../types/simulationTypes';
|
||||
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
|
||||
import { handleResize } from "../../../../functions/handleResizePannel";
|
||||
|
||||
@@ -34,7 +34,7 @@ const ArmBotMechanics: React.FC = () => {
|
||||
if (!selectedActionSphere?.points?.uuid) return [];
|
||||
|
||||
const armBotPaths = simulationStates.filter(
|
||||
(path): path is Types.ArmBotEventsSchema => path.type === "ArmBot"
|
||||
(path): path is SimulationTypes.ArmBotEventsSchema => path.type === "ArmBot"
|
||||
);
|
||||
|
||||
const currentPoint = armBotPaths.find(
|
||||
@@ -54,7 +54,7 @@ const ArmBotMechanics: React.FC = () => {
|
||||
let points: { uuid: string; position: [number, number, number] }[] = [];
|
||||
|
||||
if (connectedModel.type === "Conveyor") {
|
||||
const conveyor = connectedModel as Types.ConveyorEventsSchema;
|
||||
const conveyor = connectedModel as SimulationTypes.ConveyorEventsSchema;
|
||||
|
||||
const connectedPointUUIDs = currentPoint?.connections?.targets
|
||||
.filter(t => t.modelUUID === connectedModel.modeluuid)
|
||||
@@ -72,7 +72,7 @@ const ArmBotMechanics: React.FC = () => {
|
||||
triggers = conveyor.points.flatMap(p => p.triggers?.filter(t => t.isUsed) || []);
|
||||
}
|
||||
else if (connectedModel.type === "StaticMachine") {
|
||||
const staticMachine = connectedModel as Types.StaticMachineEventsSchema;
|
||||
const staticMachine = connectedModel as SimulationTypes.StaticMachineEventsSchema;
|
||||
|
||||
points = [{
|
||||
uuid: staticMachine.points.uuid,
|
||||
@@ -128,7 +128,7 @@ const ArmBotMechanics: React.FC = () => {
|
||||
if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null };
|
||||
|
||||
const armBotPaths = simulationStates.filter(
|
||||
(path): path is Types.ArmBotEventsSchema => path.type === "ArmBot"
|
||||
(path): path is SimulationTypes.ArmBotEventsSchema => path.type === "ArmBot"
|
||||
);
|
||||
|
||||
const points = armBotPaths.find(
|
||||
@@ -140,7 +140,7 @@ const ArmBotMechanics: React.FC = () => {
|
||||
};
|
||||
}, [selectedActionSphere, simulationStates]);
|
||||
|
||||
const updateBackend = async (updatedPath: Types.ArmBotEventsSchema | undefined) => {
|
||||
const updateBackend = async (updatedPath: SimulationTypes.ArmBotEventsSchema | undefined) => {
|
||||
if (!updatedPath) return;
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email ? email.split("@")[1].split(".")[0] : "";
|
||||
@@ -150,12 +150,11 @@ const ArmBotMechanics: React.FC = () => {
|
||||
modeluuid: updatedPath.modeluuid,
|
||||
eventData: { type: "ArmBot", points: updatedPath.points }
|
||||
}
|
||||
console.log('data: ', data);
|
||||
|
||||
socket.emit('v2:model-asset:updateEventData', data);
|
||||
}
|
||||
|
||||
const handleActionUpdate = useCallback((updatedAction: Partial<Types.ArmBotEventsSchema['points']['actions']>) => {
|
||||
const handleActionUpdate = useCallback((updatedAction: Partial<SimulationTypes.ArmBotEventsSchema['points']['actions']>) => {
|
||||
if (!selectedActionSphere?.points?.uuid || !selectedPoint) return;
|
||||
|
||||
const updatedPaths = simulationStates.map((path) => {
|
||||
@@ -175,7 +174,7 @@ const ArmBotMechanics: React.FC = () => {
|
||||
});
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ArmBotEventsSchema =>
|
||||
(path): path is SimulationTypes.ArmBotEventsSchema =>
|
||||
path.type === "ArmBot" &&
|
||||
path.points.uuid === selectedActionSphere.points.uuid
|
||||
);
|
||||
@@ -188,7 +187,7 @@ const ArmBotMechanics: React.FC = () => {
|
||||
handleActionUpdate({ speed });
|
||||
}, [handleActionUpdate]);
|
||||
|
||||
const handleProcessChange = useCallback((processes: Types.ArmBotEventsSchema['points']['actions']['processes']) => {
|
||||
const handleProcessChange = useCallback((processes: SimulationTypes.ArmBotEventsSchema['points']['actions']['processes']) => {
|
||||
handleActionUpdate({ processes });
|
||||
}, [handleActionUpdate]);
|
||||
|
||||
@@ -225,19 +224,28 @@ const ArmBotMechanics: React.FC = () => {
|
||||
}, [selectedPoint, selectedProcessIndex, handleProcessChange]);
|
||||
|
||||
const handleTriggerSelect = useCallback((displayName: string, index: number) => {
|
||||
const selected = connectedTriggers.find(t => t.displayName === displayName);
|
||||
const availableOptions = getFilteredTriggerOptions(index);
|
||||
const selectedDisplayIndex = availableOptions.indexOf(displayName);
|
||||
|
||||
const filteredTriggers = connectedTriggers.filter(trigger =>
|
||||
!selectedPoint?.actions.processes
|
||||
?.filter((_, i) => i !== index)
|
||||
.map(p => p.triggerId)
|
||||
.includes(trigger.uuid)
|
||||
);
|
||||
|
||||
const selected = filteredTriggers[selectedDisplayIndex];
|
||||
|
||||
if (!selected || !selectedPoint?.actions.processes) return;
|
||||
|
||||
const oldProcess = selectedPoint.actions.processes[index];
|
||||
|
||||
const updatedProcesses = [...selectedPoint.actions.processes];
|
||||
|
||||
// Only reset start/end if new trigger invalidates them (your logic can expand this)
|
||||
updatedProcesses[index] = {
|
||||
...oldProcess,
|
||||
triggerId: selected.uuid,
|
||||
startPoint: oldProcess.startPoint || "", // preserve if exists
|
||||
endPoint: oldProcess.endPoint || "" // preserve if exists
|
||||
startPoint: oldProcess.startPoint || "",
|
||||
endPoint: oldProcess.endPoint || ""
|
||||
};
|
||||
|
||||
handleProcessChange(updatedProcesses);
|
||||
@@ -299,8 +307,10 @@ const ArmBotMechanics: React.FC = () => {
|
||||
<InputWithDropDown
|
||||
key={`speed-${selectedPoint.uuid}`}
|
||||
label="ArmBot Speed"
|
||||
min={0.1}
|
||||
step={0.1}
|
||||
value={selectedPoint.actions.speed.toString()}
|
||||
onChange={(value) => handleSpeedChange(parseInt(value))}
|
||||
onChange={(value) => handleSpeedChange(parseFloat(value))}
|
||||
/>
|
||||
|
||||
<div className="actions">
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
useSocketStore,
|
||||
} from "../../../../store/store";
|
||||
import * as THREE from "three";
|
||||
import * as Types from "../../../../types/world/worldTypes";
|
||||
import * as SimulationTypes from "../../../../types/simulationTypes";
|
||||
import InputToggle from "../../../ui/inputs/InputToggle";
|
||||
import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
|
||||
import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
|
||||
@@ -36,13 +36,13 @@ const ConveyorMechanics: React.FC = () => {
|
||||
if (!selectedActionSphere) return null;
|
||||
return simulationStates
|
||||
.filter(
|
||||
(path): path is Types.ConveyorEventsSchema => path.type === "Conveyor"
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor"
|
||||
)
|
||||
.flatMap((path) => path.points)
|
||||
.find((point) => point.uuid === selectedActionSphere.points.uuid);
|
||||
}, [selectedActionSphere, simulationStates]);
|
||||
|
||||
const updateBackend = async (updatedPath: Types.ConveyorEventsSchema | undefined) => {
|
||||
const updateBackend = async (updatedPath: SimulationTypes.ConveyorEventsSchema | undefined) => {
|
||||
if (!updatedPath) return;
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email ? email.split("@")[1].split(".")[0] : "";
|
||||
@@ -93,7 +93,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||
});
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ConveyorEventsSchema =>
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema =>
|
||||
path.type === "Conveyor" &&
|
||||
path.points.some(
|
||||
(point) => point.uuid === selectedActionSphere.points.uuid
|
||||
@@ -126,7 +126,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||
);
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ConveyorEventsSchema =>
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema =>
|
||||
path.type === "Conveyor" &&
|
||||
path.points.some(
|
||||
(point) => point.uuid === selectedActionSphere.points.uuid
|
||||
@@ -174,7 +174,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||
);
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ConveyorEventsSchema =>
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema =>
|
||||
path.type === "Conveyor" &&
|
||||
path.points.some(
|
||||
(point) => point.uuid === selectedActionSphere.points.uuid
|
||||
@@ -188,7 +188,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||
if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
|
||||
const updatedAction = updatedPaths
|
||||
.filter(
|
||||
(path): path is Types.ConveyorEventsSchema => path.type === "Conveyor"
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema => path.type === "Conveyor"
|
||||
)
|
||||
.flatMap((path) => path.points)
|
||||
.find((p) => p.uuid === selectedActionSphere.points.uuid)
|
||||
@@ -229,7 +229,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||
);
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ConveyorEventsSchema =>
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema =>
|
||||
path.type === "Conveyor" &&
|
||||
path.points.some(
|
||||
(point) => point.uuid === selectedActionSphere.points.uuid
|
||||
@@ -273,7 +273,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||
);
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ConveyorEventsSchema =>
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema =>
|
||||
path.type === "Conveyor" &&
|
||||
path.points.some(
|
||||
(point) => point.uuid === selectedActionSphere.points.uuid
|
||||
@@ -311,7 +311,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||
);
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ConveyorEventsSchema =>
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema =>
|
||||
path.type === "Conveyor" &&
|
||||
path.points.some(
|
||||
(point) => point.uuid === selectedActionSphere.points.uuid
|
||||
@@ -330,7 +330,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||
);
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ConveyorEventsSchema =>
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema =>
|
||||
path.type === "Conveyor" &&
|
||||
path.modeluuid === selectedPath.path.modeluuid
|
||||
);
|
||||
@@ -367,7 +367,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||
);
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ConveyorEventsSchema =>
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema =>
|
||||
path.type === "Conveyor" &&
|
||||
path.points.some(
|
||||
(point) => point.uuid === selectedActionSphere.points.uuid
|
||||
@@ -400,7 +400,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||
);
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ConveyorEventsSchema =>
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema =>
|
||||
path.type === "Conveyor" &&
|
||||
path.points.some(
|
||||
(point) => point.uuid === selectedActionSphere.points.uuid
|
||||
@@ -435,7 +435,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||
);
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ConveyorEventsSchema =>
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema =>
|
||||
path.type === "Conveyor" &&
|
||||
path.points.some(
|
||||
(point) => point.uuid === selectedActionSphere.points.uuid
|
||||
@@ -479,7 +479,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||
);
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ConveyorEventsSchema =>
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema =>
|
||||
path.type === "Conveyor" &&
|
||||
path.points.some(
|
||||
(point) => point.uuid === selectedActionSphere.points.uuid
|
||||
@@ -525,7 +525,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||
);
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ConveyorEventsSchema =>
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema =>
|
||||
path.type === "Conveyor" &&
|
||||
path.points.some(
|
||||
(point) => point.uuid === selectedActionSphere.points.uuid
|
||||
@@ -571,7 +571,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||
);
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ConveyorEventsSchema =>
|
||||
(path): path is SimulationTypes.ConveyorEventsSchema =>
|
||||
path.type === "Conveyor" &&
|
||||
path.points.some(
|
||||
(point) => point.uuid === selectedActionSphere.points.uuid
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useRef, useMemo, useCallback } from "react";
|
||||
import { InfoIcon } from "../../../icons/ExportCommonIcons";
|
||||
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||
import { useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store";
|
||||
import * as Types from '../../../../types/world/worldTypes';
|
||||
import * as SimulationTypes from '../../../../types/simulationTypes';
|
||||
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
|
||||
import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
|
||||
|
||||
@@ -17,7 +17,7 @@ const StaticMachineMechanics: React.FC = () => {
|
||||
if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null, connectedPointUuids: [] };
|
||||
|
||||
const staticMachinePaths = simulationStates.filter(
|
||||
(path): path is Types.StaticMachineEventsSchema => path.type === "StaticMachine"
|
||||
(path): path is SimulationTypes.StaticMachineEventsSchema => path.type === "StaticMachine"
|
||||
);
|
||||
|
||||
const points = staticMachinePaths.find(
|
||||
@@ -39,7 +39,7 @@ const StaticMachineMechanics: React.FC = () => {
|
||||
};
|
||||
}, [selectedActionSphere, simulationStates]);
|
||||
|
||||
const updateBackend = async (updatedPath: Types.StaticMachineEventsSchema | undefined) => {
|
||||
const updateBackend = async (updatedPath: SimulationTypes.StaticMachineEventsSchema | undefined) => {
|
||||
if (!updatedPath) return;
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email ? email.split("@")[1].split(".")[0] : "";
|
||||
@@ -59,7 +59,7 @@ const StaticMachineMechanics: React.FC = () => {
|
||||
socket.emit('v2:model-asset:updateEventData', data);
|
||||
}
|
||||
|
||||
const handleActionUpdate = useCallback((updatedAction: Partial<Types.StaticMachineEventsSchema['points']['actions']>) => {
|
||||
const handleActionUpdate = useCallback((updatedAction: Partial<SimulationTypes.StaticMachineEventsSchema['points']['actions']>) => {
|
||||
if (!selectedActionSphere?.points?.uuid) return;
|
||||
|
||||
const updatedPaths = simulationStates.map((path) => {
|
||||
@@ -79,7 +79,7 @@ const StaticMachineMechanics: React.FC = () => {
|
||||
});
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.StaticMachineEventsSchema =>
|
||||
(path): path is SimulationTypes.StaticMachineEventsSchema =>
|
||||
path.type === "StaticMachine" &&
|
||||
path.points.uuid === selectedActionSphere.points.uuid
|
||||
);
|
||||
@@ -96,7 +96,7 @@ const StaticMachineMechanics: React.FC = () => {
|
||||
handleActionUpdate({ material });
|
||||
}, [handleActionUpdate]);
|
||||
|
||||
const handleTriggerChange = useCallback((updatedTrigger: Partial<Types.StaticMachineEventsSchema['points']['triggers']>) => {
|
||||
const handleTriggerChange = useCallback((updatedTrigger: Partial<SimulationTypes.StaticMachineEventsSchema['points']['triggers']>) => {
|
||||
if (!selectedActionSphere?.points?.uuid) return;
|
||||
|
||||
const updatedPaths = simulationStates.map((path) => {
|
||||
@@ -116,7 +116,7 @@ const StaticMachineMechanics: React.FC = () => {
|
||||
});
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.StaticMachineEventsSchema =>
|
||||
(path): path is SimulationTypes.StaticMachineEventsSchema =>
|
||||
path.type === "StaticMachine" &&
|
||||
path.points.uuid === selectedActionSphere.points.uuid
|
||||
);
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useRef, useMemo } from "react";
|
||||
import { InfoIcon } from "../../../icons/ExportCommonIcons";
|
||||
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||
import { useEditingPoint, useEyeDropMode, usePreviewPosition, useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store";
|
||||
import * as Types from '../../../../types/world/worldTypes';
|
||||
import * as SimulationTypes from '../../../../types/simulationTypes';
|
||||
import PositionInput from "../customInput/PositionInputs";
|
||||
import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
|
||||
import LabeledButton from "../../../ui/inputs/LabledButton";
|
||||
@@ -21,7 +21,7 @@ const VehicleMechanics: React.FC = () => {
|
||||
if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null, connectedPointUuids: [] };
|
||||
|
||||
const vehiclePaths = simulationStates.filter(
|
||||
(path): path is Types.VehicleEventsSchema => path.type === "Vehicle"
|
||||
(path): path is SimulationTypes.VehicleEventsSchema => path.type === "Vehicle"
|
||||
);
|
||||
|
||||
const points = vehiclePaths.find(
|
||||
@@ -43,7 +43,7 @@ const VehicleMechanics: React.FC = () => {
|
||||
};
|
||||
}, [selectedActionSphere, simulationStates]);
|
||||
|
||||
const updateBackend = async (updatedPath: Types.VehicleEventsSchema | undefined) => {
|
||||
const updateBackend = async (updatedPath: SimulationTypes.VehicleEventsSchema | undefined) => {
|
||||
if (!updatedPath) return;
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email ? email.split("@")[1].split(".")[0] : "";
|
||||
@@ -64,7 +64,7 @@ const VehicleMechanics: React.FC = () => {
|
||||
|
||||
}
|
||||
|
||||
const handleActionUpdate = React.useCallback((updatedAction: Partial<Types.VehicleEventsSchema['points']['actions']>) => {
|
||||
const handleActionUpdate = React.useCallback((updatedAction: Partial<SimulationTypes.VehicleEventsSchema['points']['actions']>) => {
|
||||
if (!selectedActionSphere?.points?.uuid) return;
|
||||
|
||||
const updatedPaths = simulationStates.map((path) => {
|
||||
@@ -84,7 +84,7 @@ const VehicleMechanics: React.FC = () => {
|
||||
});
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.VehicleEventsSchema =>
|
||||
(path): path is SimulationTypes.VehicleEventsSchema =>
|
||||
path.type === "Vehicle" &&
|
||||
path.points.uuid === selectedActionSphere.points.uuid
|
||||
);
|
||||
@@ -118,7 +118,7 @@ const VehicleMechanics: React.FC = () => {
|
||||
});
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.VehicleEventsSchema =>
|
||||
(path): path is SimulationTypes.VehicleEventsSchema =>
|
||||
path.type === "Vehicle" &&
|
||||
path.points.uuid === selectedActionSphere.points.uuid
|
||||
);
|
||||
@@ -145,7 +145,7 @@ const VehicleMechanics: React.FC = () => {
|
||||
});
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.VehicleEventsSchema =>
|
||||
(path): path is SimulationTypes.VehicleEventsSchema =>
|
||||
path.type === "Vehicle" &&
|
||||
path.points.uuid === selectedActionSphere.points.uuid
|
||||
);
|
||||
|
||||
@@ -62,19 +62,25 @@ const ZoneProperties: React.FC = () => {
|
||||
: zone
|
||||
)
|
||||
);
|
||||
}else{
|
||||
} else {
|
||||
// console.log(response?.message);
|
||||
}
|
||||
}
|
||||
function handleVectorChange(key: "zoneViewPortTarget" | "zoneViewPortPosition", newValue: [number, number, number]) {
|
||||
setSelectedZone((prev) => ({ ...prev, [key]: newValue }));
|
||||
}
|
||||
|
||||
const checkZoneNameDuplicate = (name: string) => {
|
||||
return zones.some(
|
||||
(zone: any) =>
|
||||
zone.zoneName.trim().toLowerCase() === name.trim().toLowerCase() &&
|
||||
zone.zoneId !== selectedZone.zoneId
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="zone-properties-container">
|
||||
<div className="header">
|
||||
<RenameInput value={selectedZone.zoneName} onRename={handleZoneNameChange} />
|
||||
<RenameInput value={selectedZone.zoneName} onRename={handleZoneNameChange} checkDuplicate={checkZoneNameDuplicate} />
|
||||
<div className="button" onClick={handleEditView}>
|
||||
{Edit ? "Cancel" : "Edit"}
|
||||
</div>
|
||||
|
||||
@@ -21,14 +21,17 @@ const BarChartInput = (props: Props) => {
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
const [isLoading, setLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
|
||||
if (response.status === 200) {
|
||||
// console.log("dropdown data:", response.data);
|
||||
setDropDownData(response.data);
|
||||
setLoading(false);
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
@@ -59,7 +62,7 @@ const BarChartInput = (props: Props) => {
|
||||
|
||||
fetchSavedInputes();
|
||||
|
||||
}, [selectedChartId.id]);
|
||||
}, [selectedChartId]);
|
||||
|
||||
// Sync Zustand state when component mounts
|
||||
useEffect(() => {
|
||||
@@ -135,7 +138,7 @@ const BarChartInput = (props: Props) => {
|
||||
<div className="inputs-wrapper">
|
||||
<div className="datas">
|
||||
<div className="datas__label">Title</div>
|
||||
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/>
|
||||
<RenameInput value={widgetName || selectedChartId?.title} onRename={handleNameChange}/>
|
||||
</div>
|
||||
{[...Array(3)].map((_, index) => {
|
||||
const inputKey = `input${index + 1}`;
|
||||
@@ -148,6 +151,8 @@ const BarChartInput = (props: Props) => {
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]} // Load from Zustand
|
||||
isLoading={isLoading}
|
||||
allSelections={selections}
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
|
||||
@@ -21,14 +21,21 @@ const FleetEfficiencyInputComponent = (props: Props) => {
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
const [isLoading, setLoading] = useState<boolean>(true);
|
||||
|
||||
const isSelected = () => {
|
||||
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
|
||||
setLoading(true)
|
||||
if (response.status === 200) {
|
||||
// console.log("dropdown data:", response.data);
|
||||
setDropDownData(response.data);
|
||||
setLoading(false)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
@@ -136,7 +143,7 @@ const FleetEfficiencyInputComponent = (props: Props) => {
|
||||
<div className="inputs-wrapper">
|
||||
<div className="datas">
|
||||
<div className="datas__label">Title</div>
|
||||
<RenameInput value={selectedChartId?.header || "untited"} onRename={handleNameChange}/>
|
||||
<RenameInput value={widgetName || selectedChartId?.header} onRename={handleNameChange}/>
|
||||
</div>
|
||||
{[...Array(1)].map((_, index) => {
|
||||
const inputKey = `input${index + 1}`;
|
||||
@@ -149,6 +156,8 @@ const FleetEfficiencyInputComponent = (props: Props) => {
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]} // Load from Zustand
|
||||
isLoading={isLoading}
|
||||
allSelections={selections}
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
|
||||
@@ -21,14 +21,17 @@ const FlotingWidgetInput = (props: Props) => {
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
const [isLoading, setLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
|
||||
if (response.status === 200) {
|
||||
// console.log("dropdown data:", response.data);
|
||||
setDropDownData(response.data);
|
||||
setLoading(false);
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
@@ -136,7 +139,7 @@ const FlotingWidgetInput = (props: Props) => {
|
||||
<div className="inputs-wrapper">
|
||||
<div className="datas">
|
||||
<div className="datas__label">Title</div>
|
||||
<RenameInput value={selectedChartId?.header || "untited"} onRename={handleNameChange}/>
|
||||
<RenameInput value={widgetName || selectedChartId?.header} onRename={handleNameChange}/>
|
||||
</div>
|
||||
{[...Array(6)].map((_, index) => {
|
||||
const inputKey = `input${index + 1}`;
|
||||
@@ -149,6 +152,8 @@ const FlotingWidgetInput = (props: Props) => {
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]} // Load from Zustand
|
||||
isLoading={isLoading}
|
||||
allSelections={selections}
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
|
||||
@@ -140,14 +140,17 @@ const LineGrapInput = (props: Props) => {
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
const [isLoading, setLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
|
||||
if (response.status === 200) {
|
||||
// console.log("dropdown data:", response.data);
|
||||
setDropDownData(response.data);
|
||||
setLoading(false)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
@@ -254,7 +257,7 @@ const LineGrapInput = (props: Props) => {
|
||||
<div className="inputs-wrapper">
|
||||
<div className="datas">
|
||||
<div className="datas__label">Title</div>
|
||||
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/>
|
||||
<RenameInput value={widgetName || selectedChartId?.title} onRename={handleNameChange}/>
|
||||
</div>
|
||||
{[...Array(4)].map((_, index) => {
|
||||
const inputKey = `input${index + 1}`;
|
||||
@@ -267,6 +270,8 @@ const LineGrapInput = (props: Props) => {
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]} // Load from Zustand
|
||||
isLoading={isLoading}
|
||||
allSelections={selections}
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
|
||||
@@ -21,14 +21,17 @@ const PieChartInput = (props: Props) => {
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
const [isLoading, setLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
|
||||
if (response.status === 200) {
|
||||
// console.log("dropdown data:", response.data);
|
||||
setDropDownData(response.data);
|
||||
setLoading(false)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
@@ -135,7 +138,7 @@ const PieChartInput = (props: Props) => {
|
||||
<div className="inputs-wrapper">
|
||||
<div className="datas">
|
||||
<div className="datas__label">Title</div>
|
||||
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/>
|
||||
<RenameInput value={widgetName || selectedChartId?.title} onRename={handleNameChange}/>
|
||||
</div>
|
||||
{[...Array(2)].map((_, index) => {
|
||||
const inputKey = `input${index + 1}`;
|
||||
@@ -148,6 +151,8 @@ const PieChartInput = (props: Props) => {
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]} // Load from Zustand
|
||||
isLoading={isLoading}
|
||||
allSelections={selections}
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
|
||||
@@ -21,14 +21,17 @@ const Progress1Input = (props: Props) => {
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
const [isLoading, setLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
|
||||
if (response.status === 200) {
|
||||
// console.log("dropdown data:", response.data);
|
||||
setDropDownData(response.data);
|
||||
setLoading(false)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
@@ -129,7 +132,7 @@ const Progress1Input = (props: Props) => {
|
||||
<div className="inputs-wrapper">
|
||||
<div className="datas">
|
||||
<div className="datas__label">Title</div>
|
||||
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/>
|
||||
<RenameInput value={widgetName || selectedChartId?.title} onRename={handleNameChange}/>
|
||||
</div>
|
||||
{[...Array(1)].map((_, index) => {
|
||||
const inputKey = `input${index + 1}`;
|
||||
@@ -142,6 +145,8 @@ const Progress1Input = (props: Props) => {
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]} // Load from Zustand
|
||||
isLoading={isLoading}
|
||||
allSelections={selections}
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
|
||||
@@ -21,14 +21,17 @@ const Progress2Input = (props: Props) => {
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
const [isLoading, setLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
|
||||
if (response.status === 200) {
|
||||
// console.log("dropdown data:", response.data);
|
||||
setDropDownData(response.data);
|
||||
setLoading(false)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
@@ -129,7 +132,7 @@ const Progress2Input = (props: Props) => {
|
||||
<div className="inputs-wrapper">
|
||||
<div className="datas">
|
||||
<div className="datas__label">Title</div>
|
||||
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/>
|
||||
<RenameInput value={widgetName || selectedChartId?.title} onRename={handleNameChange}/>
|
||||
</div>
|
||||
{[...Array(2)].map((_, index) => {
|
||||
const inputKey = `input${index + 1}`;
|
||||
@@ -142,6 +145,8 @@ const Progress2Input = (props: Props) => {
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]} // Load from Zustand
|
||||
isLoading={isLoading}
|
||||
allSelections={selections}
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
|
||||
@@ -21,14 +21,17 @@ const WarehouseThroughputInputComponent = (props: Props) => {
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
const [isLoading, setLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
|
||||
if (response.status === 200) {
|
||||
// console.log("dropdown data:", response.data);
|
||||
setDropDownData(response.data);
|
||||
setLoading(false)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
@@ -136,7 +139,7 @@ const WarehouseThroughputInputComponent = (props: Props) => {
|
||||
<div className="inputs-wrapper">
|
||||
<div className="datas">
|
||||
<div className="datas__label">Title</div>
|
||||
<RenameInput value={selectedChartId?.header || "untited"} onRename={handleNameChange}/>
|
||||
<RenameInput value={widgetName || selectedChartId?.header} onRename={handleNameChange}/>
|
||||
</div>
|
||||
{[...Array(1)].map((_, index) => {
|
||||
const inputKey = `input${index + 1}`;
|
||||
@@ -149,6 +152,8 @@ const WarehouseThroughputInputComponent = (props: Props) => {
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]} // Load from Zustand
|
||||
isLoading={isLoading}
|
||||
allSelections={selections}
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
|
||||
@@ -21,14 +21,17 @@ const Widget2InputCard3D = (props: Props) => {
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
const [isLoading, setLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
|
||||
if (response.status === 200) {
|
||||
// console.log("dropdown data:", response.data);
|
||||
setDropDownData(response.data);
|
||||
setLoading(false)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
@@ -147,6 +150,8 @@ const Widget2InputCard3D = (props: Props) => {
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]} // Load from Zustand
|
||||
isLoading={isLoading}
|
||||
allSelections={selections}
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
|
||||
@@ -19,14 +19,17 @@ const Widget3InputCard3D = () => {
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
const [isLoading, setLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
const response = await axios.get(`http://${iotApiUrl}/getinput`);
|
||||
if (response.status === 200) {
|
||||
// console.log("dropdown data:", response.data);
|
||||
setDropDownData(response.data);
|
||||
setLoading(false)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
@@ -140,6 +143,8 @@ const Widget3InputCard3D = () => {
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]} // Load from Zustand
|
||||
isLoading={isLoading}
|
||||
allSelections={selections}
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
|
||||
@@ -21,14 +21,17 @@ const Widget4InputCard3D = (props: Props) => {
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
const [isLoading, setLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
|
||||
if (response.status === 200) {
|
||||
// console.log("dropdown data:", response.data);
|
||||
setDropDownData(response.data);
|
||||
setLoading(false)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
@@ -147,6 +150,8 @@ const Widget4InputCard3D = (props: Props) => {
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]} // Load from Zustand
|
||||
isLoading={isLoading}
|
||||
allSelections={selections}
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
|
||||
@@ -4,7 +4,8 @@ import RenameInput from "./RenameInput";
|
||||
type InputWithDropDownProps = {
|
||||
label: string;
|
||||
value: string;
|
||||
min?: number
|
||||
min?: number;
|
||||
step?: number;
|
||||
defaultValue?: string;
|
||||
options?: string[]; // Array of dropdown options
|
||||
activeOption?: string; // The currently active dropdown option
|
||||
@@ -18,6 +19,7 @@ const InputWithDropDown: React.FC<InputWithDropDownProps> = ({
|
||||
label,
|
||||
value,
|
||||
min,
|
||||
step,
|
||||
defaultValue,
|
||||
options,
|
||||
activeOption,
|
||||
@@ -45,6 +47,7 @@ const InputWithDropDown: React.FC<InputWithDropDownProps> = ({
|
||||
<div className="input default" id={separatedWords}>
|
||||
<input
|
||||
min={min}
|
||||
step={step}
|
||||
type="number"
|
||||
defaultValue={value}
|
||||
onChange={(e) => {
|
||||
|
||||
@@ -1,145 +1,3 @@
|
||||
// import React, { useState, useRef, useEffect } from "react";
|
||||
|
||||
// // Dropdown Item Component
|
||||
// const DropdownItem = ({
|
||||
// label,
|
||||
// href,
|
||||
// onClick,
|
||||
// }: {
|
||||
// label: string;
|
||||
// href?: string;
|
||||
// onClick?: () => void;
|
||||
// }) => (
|
||||
// <a
|
||||
// href={href || "#"}
|
||||
// className="dropdown-item"
|
||||
// onClick={(e) => {
|
||||
// e.preventDefault();
|
||||
// onClick?.();
|
||||
// }}
|
||||
// >
|
||||
// {label}
|
||||
// </a>
|
||||
// );
|
||||
|
||||
// // Nested Dropdown Component
|
||||
// const NestedDropdown = ({
|
||||
// label,
|
||||
// children,
|
||||
// onSelect,
|
||||
// }: {
|
||||
// label: string;
|
||||
// children: React.ReactNode;
|
||||
// onSelect: (selectedLabel: string) => void;
|
||||
// }) => {
|
||||
// const [open, setOpen] = useState(false);
|
||||
|
||||
// return (
|
||||
// <div className="nested-dropdown">
|
||||
// {/* Dropdown Trigger */}
|
||||
// <div
|
||||
// className={`dropdown-trigger ${open ? "open" : ""}`}
|
||||
// onClick={() => setOpen(!open)} // Toggle submenu on click
|
||||
// >
|
||||
// {label} <span className="icon">{open ? "▼" : "▶"}</span>
|
||||
// </div>
|
||||
|
||||
// {/* Submenu */}
|
||||
// {open && (
|
||||
// <div className="submenu">
|
||||
// {React.Children.map(children, (child) => {
|
||||
// if (React.isValidElement(child)) {
|
||||
// // Clone the element and pass the `onSelect` prop only if it's expected
|
||||
// return React.cloneElement(child as React.ReactElement<any>, { onSelect });
|
||||
// }
|
||||
// return child; // Return non-element children as-is
|
||||
// })}
|
||||
// </div>
|
||||
// )}
|
||||
// </div>
|
||||
// );
|
||||
// };
|
||||
|
||||
// // Recursive Function to Render Nested Data
|
||||
// const renderNestedData = (
|
||||
// data: Record<string, any>,
|
||||
// onSelect: (selectedLabel: string) => void
|
||||
// ) => {
|
||||
// return Object.entries(data).map(([key, value]) => {
|
||||
// if (typeof value === "object" && !Array.isArray(value)) {
|
||||
// // If the value is an object, render it as a nested dropdown
|
||||
// return (
|
||||
// <NestedDropdown key={key} label={key} onSelect={onSelect}>
|
||||
// {renderNestedData(value, onSelect)}
|
||||
// </NestedDropdown>
|
||||
// );
|
||||
// } else if (Array.isArray(value)) {
|
||||
// // If the value is an array, render each item as a dropdown item
|
||||
// return value.map((item, index) => (
|
||||
// <DropdownItem key={index} label={item} onClick={() => onSelect(item)} />
|
||||
// ));
|
||||
// } else {
|
||||
// // If the value is a simple string, render it as a dropdown item
|
||||
// return (
|
||||
// <DropdownItem key={key} label={value} onClick={() => onSelect(value)} />
|
||||
// );
|
||||
// }
|
||||
// });
|
||||
// };
|
||||
|
||||
// // Main Multi-Level Dropdown Component
|
||||
// const MultiLevelDropdown = ({ data }: { data: Record<string, any> }) => {
|
||||
// const [open, setOpen] = useState(false);
|
||||
// const [selectedLabel, setSelectedLabel] = useState("Dropdown trigger");
|
||||
// const dropdownRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// // Handle outer click to close the dropdown
|
||||
// useEffect(() => {
|
||||
// const handleClickOutside = (event: MouseEvent) => {
|
||||
// if (
|
||||
// dropdownRef.current &&
|
||||
// !dropdownRef.current.contains(event.target as Node)
|
||||
// ) {
|
||||
// setOpen(false);
|
||||
// }
|
||||
// };
|
||||
|
||||
// document.addEventListener("mousedown", handleClickOutside);
|
||||
// return () => {
|
||||
// document.removeEventListener("mousedown", handleClickOutside);
|
||||
// };
|
||||
// }, []);
|
||||
|
||||
// // Handle selection of an item
|
||||
// const handleSelect = (selectedLabel: string) => {
|
||||
// setSelectedLabel(selectedLabel); // Update the dropdown trigger text
|
||||
// setOpen(false); // Close the dropdown
|
||||
// };
|
||||
|
||||
// return (
|
||||
// <div className="multi-level-dropdown" ref={dropdownRef}>
|
||||
// {/* Dropdown Trigger Button */}
|
||||
// <button
|
||||
// className={`dropdown-button ${open ? "open" : ""}`}
|
||||
// onClick={() => setOpen(!open)} // Toggle main menu on click
|
||||
// >
|
||||
// {selectedLabel} <span className="icon">▾</span>
|
||||
// </button>
|
||||
|
||||
// {/* Dropdown Menu */}
|
||||
// {open && (
|
||||
// <div className="dropdown-menu">
|
||||
// <div className="dropdown-content">
|
||||
// {renderNestedData(data, handleSelect)}
|
||||
// </div>
|
||||
// </div>
|
||||
// )}
|
||||
// </div>
|
||||
// );
|
||||
// };
|
||||
|
||||
// export default MultiLevelDropdown;
|
||||
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import { ArrowIcon } from "../../icons/ExportCommonIcons";
|
||||
|
||||
@@ -147,11 +5,19 @@ import { ArrowIcon } from "../../icons/ExportCommonIcons";
|
||||
const DropdownItem = ({
|
||||
label,
|
||||
onClick,
|
||||
disabled = false,
|
||||
}: {
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
disabled?: boolean;
|
||||
}) => (
|
||||
<div className="dropdown-item" onClick={onClick}>
|
||||
<div
|
||||
className={`dropdown-item ${disabled ? "disabled" : ""}`}
|
||||
onClick={() => {
|
||||
if (!disabled) onClick();
|
||||
}}
|
||||
style={{ cursor: disabled ? "not-allowed": "default", opacity: disabled ? 0.5 : 1 }}
|
||||
>
|
||||
{label}
|
||||
</div>
|
||||
);
|
||||
@@ -161,10 +27,12 @@ const NestedDropdown = ({
|
||||
label,
|
||||
fields,
|
||||
onSelect,
|
||||
disabledFields = [],
|
||||
}: {
|
||||
label: string;
|
||||
fields: string[];
|
||||
onSelect: (selectedData: { name: string; fields: string }) => void;
|
||||
disabledFields?: string[];
|
||||
}) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
@@ -184,13 +52,17 @@ const NestedDropdown = ({
|
||||
</div>
|
||||
{open && (
|
||||
<div className="submenu">
|
||||
{fields.map((field) => (
|
||||
<DropdownItem
|
||||
key={field}
|
||||
label={field}
|
||||
onClick={() => onSelect({ name: label, fields: field })}
|
||||
/>
|
||||
))}
|
||||
{fields.map((field) => {
|
||||
const isDisabled = disabledFields.includes(`${label}-${field}`);
|
||||
return (
|
||||
<DropdownItem
|
||||
key={field}
|
||||
label={field}
|
||||
onClick={() => onSelect({ name: label, fields: field })}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -203,6 +75,8 @@ interface MultiLevelDropdownProps {
|
||||
onSelect: (selectedData: { name: string; fields: string }) => void;
|
||||
onUnselect: () => void;
|
||||
selectedValue?: { name: string; fields: string };
|
||||
allSelections?: Record<string, { name: string; fields: string }>;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
// Main Multi-Level Dropdown Component
|
||||
@@ -211,6 +85,8 @@ const MultiLevelDropdown = ({
|
||||
onSelect,
|
||||
onUnselect,
|
||||
selectedValue,
|
||||
allSelections = {},
|
||||
isLoading = false,
|
||||
}: MultiLevelDropdownProps) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const dropdownRef = useRef<HTMLDivElement>(null);
|
||||
@@ -247,6 +123,14 @@ const MultiLevelDropdown = ({
|
||||
? `${selectedValue.name} - ${selectedValue.fields}`
|
||||
: "Dropdown trigger";
|
||||
|
||||
// Build list of disabled selections
|
||||
const disabledFieldsList = Object.values(allSelections)
|
||||
.filter(
|
||||
(sel) =>
|
||||
!(sel.name === selectedValue?.name && sel.fields === selectedValue?.fields)
|
||||
)
|
||||
.map((sel) => `${sel.name}-${sel.fields}`);
|
||||
|
||||
return (
|
||||
<div className="multi-level-dropdown" ref={dropdownRef}>
|
||||
<button
|
||||
@@ -258,22 +142,23 @@ const MultiLevelDropdown = ({
|
||||
</button>
|
||||
{open && (
|
||||
<div className="dropdown-menu">
|
||||
<div className="dropdown-content ">
|
||||
|
||||
{/* loading list */}
|
||||
{/* <div className="loading" /> */}
|
||||
|
||||
{/* Unselect Option */}
|
||||
<DropdownItem label="Unselect" onClick={handleItemUnselect} />
|
||||
{/* Nested Dropdown Items */}
|
||||
{Object.entries(data).map(([key, value]) => (
|
||||
<NestedDropdown
|
||||
key={key}
|
||||
label={key}
|
||||
fields={Object.keys(value)}
|
||||
onSelect={handleItemSelect}
|
||||
/>
|
||||
))}
|
||||
<div className="dropdown-content">
|
||||
{isLoading ? (
|
||||
<div className="loading" />
|
||||
) : (
|
||||
<>
|
||||
<DropdownItem label="Unselect" onClick={handleItemUnselect} />
|
||||
{Object.entries(data).map(([key, value]) => (
|
||||
<NestedDropdown
|
||||
key={key}
|
||||
label={key}
|
||||
fields={Object.keys(value)}
|
||||
onSelect={handleItemSelect}
|
||||
disabledFields={disabledFieldsList}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1,26 +1,42 @@
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
|
||||
// interface RenameInputProps {
|
||||
// value: string;
|
||||
// onRename?: (newText: string) => void;
|
||||
// }
|
||||
|
||||
interface RenameInputProps {
|
||||
value: string;
|
||||
onRename?: (newText: string) => void;
|
||||
checkDuplicate?: (name: string) => boolean;
|
||||
}
|
||||
|
||||
const RenameInput: React.FC<RenameInputProps> = ({ value, onRename }) => {
|
||||
const RenameInput: React.FC<RenameInputProps> = ({ value, onRename, checkDuplicate }) => {
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
const [text, setText] = useState(value);
|
||||
const [isDuplicate, setIsDuplicate] = useState(false);
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setText(value); // Ensure state updates when parent value changes
|
||||
setText(value);
|
||||
}, [value]);
|
||||
|
||||
useEffect(() => {
|
||||
if (checkDuplicate) {
|
||||
setIsDuplicate(checkDuplicate(text));
|
||||
}
|
||||
}, [text, checkDuplicate]);
|
||||
|
||||
const handleDoubleClick = () => {
|
||||
setIsEditing(true);
|
||||
setTimeout(() => inputRef.current?.focus(), 0); // Focus the input after rendering
|
||||
setTimeout(() => inputRef.current?.focus(), 0);
|
||||
};
|
||||
|
||||
const handleBlur = () => {
|
||||
|
||||
if(isDuplicate) return
|
||||
setIsEditing(false);
|
||||
if (onRename) {
|
||||
if (onRename && !isDuplicate) {
|
||||
onRename(text);
|
||||
}
|
||||
};
|
||||
@@ -30,7 +46,7 @@ const RenameInput: React.FC<RenameInputProps> = ({ value, onRename }) => {
|
||||
};
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (e.key === "Enter") {
|
||||
if (e.key === "Enter" && !isDuplicate) {
|
||||
setIsEditing(false);
|
||||
if (onRename) {
|
||||
onRename(text);
|
||||
@@ -41,15 +57,18 @@ const RenameInput: React.FC<RenameInputProps> = ({ value, onRename }) => {
|
||||
return (
|
||||
<>
|
||||
{isEditing ? (
|
||||
<input
|
||||
ref={inputRef}
|
||||
type="text"
|
||||
value={text}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
onKeyDown={handleKeyDown}
|
||||
className="rename-input"
|
||||
/>
|
||||
<>
|
||||
<input
|
||||
ref={inputRef}
|
||||
type="text"
|
||||
value={text}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
onKeyDown={handleKeyDown}
|
||||
className={`rename-input ${isDuplicate ? "input-error" : ""}`}
|
||||
/>
|
||||
{/* {isDuplicate && <div className="error-msg">Name already exists!</div>} */}
|
||||
</>
|
||||
) : (
|
||||
<span onDoubleClick={handleDoubleClick} className="input-value">
|
||||
{text}
|
||||
@@ -58,5 +77,4 @@ const RenameInput: React.FC<RenameInputProps> = ({ value, onRename }) => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default RenameInput;
|
||||
export default RenameInput
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
RmoveIcon,
|
||||
} from "../../icons/ExportCommonIcons";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { useFloorItems, useZoneAssetId } from "../../../store/store";
|
||||
import { useFloorItems, useZoneAssetId, useZones } from "../../../store/store";
|
||||
import { zoneCameraUpdate } from "../../../services/realTimeVisulization/zoneData/zoneCameraUpdation";
|
||||
import { setFloorItemApi } from "../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
|
||||
|
||||
@@ -40,7 +40,7 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||
const { activeModule, setActiveModule } = useModuleStore();
|
||||
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||
const { zoneAssetId, setZoneAssetId } = useZoneAssetId();
|
||||
|
||||
const { zones, setZones } = useZones();
|
||||
const { setSubModule } = useSubModuleStore();
|
||||
const [expandedZones, setExpandedZones] = useState<Record<string, boolean>>(
|
||||
{}
|
||||
@@ -100,19 +100,33 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||
function handleAssetClick(asset: Asset) {
|
||||
setZoneAssetId(asset)
|
||||
}
|
||||
|
||||
async function handleZoneNameChange(newName: string) {
|
||||
//zone apiiiiii
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0];
|
||||
let zonesdata = {
|
||||
|
||||
const isDuplicate = zones.some(
|
||||
(zone: any) =>
|
||||
zone.zoneName.trim().toLowerCase() === newName.trim().toLowerCase() &&
|
||||
zone.zoneId !== selectedZone.zoneId
|
||||
);
|
||||
|
||||
if (isDuplicate) {
|
||||
alert("Zone name already exists. Please choose a different name.");
|
||||
return; // DO NOT update state
|
||||
}
|
||||
|
||||
const zonesdata = {
|
||||
zoneId: selectedZone.zoneId,
|
||||
zoneName: newName
|
||||
zoneName: newName,
|
||||
};
|
||||
let response = await zoneCameraUpdate(zonesdata, organization);
|
||||
|
||||
const response = await zoneCameraUpdate(zonesdata, organization);
|
||||
if (response.message === "updated successfully") {
|
||||
setSelectedZone((prev) => ({ ...prev, zoneName: newName }));
|
||||
}
|
||||
}
|
||||
|
||||
async function handleZoneAssetName(newName: string) {
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0];
|
||||
@@ -128,10 +142,17 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
console.log('newName: ', newName);
|
||||
|
||||
}
|
||||
const checkZoneNameDuplicate = (name: string) => {
|
||||
return zones.some(
|
||||
(zone: any) =>
|
||||
zone.zoneName.trim().toLowerCase() === name.trim().toLowerCase() &&
|
||||
zone.zoneId !== selectedZone.zoneId
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -146,7 +167,12 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||
className="value"
|
||||
onClick={() => handleSelectZone(item.id)}
|
||||
>
|
||||
<RenameInput value={item.name} onRename={handleZoneNameChange} />
|
||||
<RenameInput
|
||||
value={item.name}
|
||||
onRename={handleZoneNameChange}
|
||||
checkDuplicate={checkZoneNameDuplicate}
|
||||
/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div className="options-container">
|
||||
|
||||
@@ -79,8 +79,9 @@ const Agv: React.FC<ProcessContainerProps> = ({
|
||||
return (
|
||||
<>
|
||||
{pathPoints.map((pair, i) => (
|
||||
<group key={i} visible={!isPlaying}>
|
||||
<group key={i}>
|
||||
<PathNavigator
|
||||
key={i}
|
||||
navMesh={navMesh}
|
||||
pathPoints={pair.points}
|
||||
id={pair.modelUuid}
|
||||
@@ -94,7 +95,7 @@ const Agv: React.FC<ProcessContainerProps> = ({
|
||||
/>
|
||||
|
||||
{pair.points.slice(1).map((point, idx) => (
|
||||
<mesh position={[point.x, point.y, point.z]} key={idx}>
|
||||
<mesh position={[point.x, point.y, point.z]} key={idx} visible={!isPlaying}>
|
||||
<sphereGeometry args={[0.3, 15, 15]} />
|
||||
<meshStandardMaterial color="red" />
|
||||
</mesh>
|
||||
|
||||
@@ -19,7 +19,7 @@ function NavMeshCreator({ lines }: NavMeshCreatorProps) {
|
||||
<NavMeshDetails lines={lines} setNavMesh={setNavMesh} groupRef={groupRef} />
|
||||
|
||||
<group ref={groupRef} visible={false} name="Meshes">
|
||||
<mesh rotation-x={CONSTANTS.planeConfig.rotation} position={CONSTANTS.planeConfig.position3D} name="Plane" receiveShadow>
|
||||
<mesh rotation-x={CONSTANTS.planeConfig.rotation} position={CONSTANTS.planeConfig.position3D} receiveShadow>
|
||||
<planeGeometry args={[300, 300]} />
|
||||
<meshBasicMaterial color={CONSTANTS.planeConfig.color} />
|
||||
</mesh>
|
||||
|
||||
@@ -3,7 +3,10 @@ import * as THREE from "three";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { NavMeshQuery } from "@recast-navigation/core";
|
||||
import { Line } from "@react-three/drei";
|
||||
import { useAnimationPlaySpeed, usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
||||
import {
|
||||
useAnimationPlaySpeed,
|
||||
usePlayButtonStore,
|
||||
} from "../../../store/usePlayButtonStore";
|
||||
import { usePlayAgv } from "../../../store/store";
|
||||
|
||||
interface PathNavigatorProps {
|
||||
@@ -11,7 +14,7 @@ interface PathNavigatorProps {
|
||||
pathPoints: any;
|
||||
id: string;
|
||||
speed: number;
|
||||
globalSpeed: number,
|
||||
globalSpeed: number;
|
||||
bufferTime: number;
|
||||
hitCount: number;
|
||||
processes: any[];
|
||||
@@ -40,11 +43,21 @@ export default function PathNavigator({
|
||||
}: PathNavigatorProps) {
|
||||
const [currentPhase, setCurrentPhase] = useState<Phase>("initial");
|
||||
const [path, setPath] = useState<[number, number, number][]>([]);
|
||||
const [toPickupPath, setToPickupPath] = useState<[number, number, number][]>([]);
|
||||
const [pickupDropPath, setPickupDropPath] = useState<[number, number, number][]>([]);
|
||||
const [dropPickupPath, setDropPickupPath] = useState<[number, number, number][]>([]);
|
||||
const [initialPosition, setInitialPosition] = useState<THREE.Vector3 | null>(null);
|
||||
const [initialRotation, setInitialRotation] = useState<THREE.Euler | null>(null);
|
||||
const [toPickupPath, setToPickupPath] = useState<[number, number, number][]>(
|
||||
[]
|
||||
);
|
||||
const [pickupDropPath, setPickupDropPath] = useState<
|
||||
[number, number, number][]
|
||||
>([]);
|
||||
const [dropPickupPath, setDropPickupPath] = useState<
|
||||
[number, number, number][]
|
||||
>([]);
|
||||
const [initialPosition, setInitialPosition] = useState<THREE.Vector3 | null>(
|
||||
null
|
||||
);
|
||||
const [initialRotation, setInitialRotation] = useState<THREE.Euler | null>(
|
||||
null
|
||||
);
|
||||
const [boxVisible, setBoxVisible] = useState(false);
|
||||
|
||||
const distancesRef = useRef<number[]>([]);
|
||||
@@ -61,11 +74,14 @@ export default function PathNavigator({
|
||||
|
||||
const boxRef = useRef<THREE.Mesh | null>(null);
|
||||
|
||||
const baseMaterials = useMemo(() => ({
|
||||
Box: new THREE.MeshStandardMaterial({ color: 0x8b4513 }),
|
||||
Crate: new THREE.MeshStandardMaterial({ color: 0x00ff00 }),
|
||||
Default: new THREE.MeshStandardMaterial({ color: 0xcccccc })
|
||||
}), []);
|
||||
const baseMaterials = useMemo(
|
||||
() => ({
|
||||
Box: new THREE.MeshStandardMaterial({ color: 0x8b4513 }),
|
||||
Crate: new THREE.MeshStandardMaterial({ color: 0x00ff00 }),
|
||||
Default: new THREE.MeshStandardMaterial({ color: 0xcccccc }),
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const object = scene.getObjectByProperty("uuid", id);
|
||||
@@ -135,7 +151,11 @@ export default function PathNavigator({
|
||||
const pickupToDropPath = computePath(pickup, drop);
|
||||
const dropToPickupPath = computePath(drop, pickup);
|
||||
|
||||
if (toPickupPath.length && pickupToDropPath.length && dropToPickupPath.length) {
|
||||
if (
|
||||
toPickupPath.length &&
|
||||
pickupToDropPath.length &&
|
||||
dropToPickupPath.length
|
||||
) {
|
||||
setPickupDropPath(pickupToDropPath);
|
||||
setDropPickupPath(dropToPickupPath);
|
||||
setToPickupPath(toPickupPath);
|
||||
@@ -163,7 +183,10 @@ export default function PathNavigator({
|
||||
}, [path]);
|
||||
|
||||
function logAgvStatus(id: string, status: string) {
|
||||
// console.log(`AGV ${id}: ${status}`);
|
||||
// console.log(
|
||||
// `AGV ${id}: ${status}`
|
||||
|
||||
// );
|
||||
}
|
||||
|
||||
function findProcessByTargetModelUUID(processes: any, targetModelUUID: any) {
|
||||
@@ -223,7 +246,9 @@ export default function PathNavigator({
|
||||
}, [processes, MaterialRef, boxVisible, scene, id, baseMaterials]);
|
||||
|
||||
useFrame((_, delta) => {
|
||||
const currentAgv = (agvRef.current || []).find((agv: AGVData) => agv.vehicleId === id);
|
||||
const currentAgv = (agvRef.current || []).find(
|
||||
(agv: AGVData) => agv.vehicleId === id
|
||||
);
|
||||
|
||||
if (!scene || !id || !isPlaying) return;
|
||||
|
||||
@@ -243,6 +268,7 @@ export default function PathNavigator({
|
||||
const isAgvReady = () => {
|
||||
if (!agvRef.current || agvRef.current.length === 0) return false;
|
||||
if (!currentAgv) return false;
|
||||
|
||||
return currentAgv.isActive && hitCount >= currentAgv.maxHitCount;
|
||||
};
|
||||
|
||||
@@ -266,12 +292,19 @@ export default function PathNavigator({
|
||||
}
|
||||
|
||||
if (isPlaying && currentPhase === "initial" && !hasReachedPickup.current) {
|
||||
const reached = moveAlongPath(object, path, distancesRef.current, speed, delta, progressRef);
|
||||
const reached = moveAlongPath(
|
||||
object,
|
||||
path,
|
||||
distancesRef.current,
|
||||
speed,
|
||||
delta,
|
||||
progressRef
|
||||
);
|
||||
|
||||
if (reached) {
|
||||
hasReachedPickup.current = true;
|
||||
if (currentAgv) {
|
||||
currentAgv.status = 'picking';
|
||||
currentAgv.status = "picking";
|
||||
}
|
||||
logAgvStatus(id, "Reached pickup point, Waiting for material");
|
||||
}
|
||||
@@ -287,20 +320,28 @@ export default function PathNavigator({
|
||||
progressRef.current = 0;
|
||||
logAgvStatus(id, "Started from pickup point, heading to drop point");
|
||||
if (currentAgv) {
|
||||
currentAgv.status = 'toDrop';
|
||||
currentAgv.status = "toDrop";
|
||||
}
|
||||
}, 0)
|
||||
}, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPlaying && currentPhase === "toDrop") {
|
||||
const reached = moveAlongPath(object, path, distancesRef.current, speed, delta, progressRef);
|
||||
const reached = moveAlongPath(
|
||||
object,
|
||||
path,
|
||||
distancesRef.current,
|
||||
speed,
|
||||
delta,
|
||||
progressRef
|
||||
);
|
||||
|
||||
if (reached && !isWaiting.current) {
|
||||
isWaiting.current = true;
|
||||
logAgvStatus(id, "Reached drop point");
|
||||
if (currentAgv) {
|
||||
currentAgv.status = 'droping';
|
||||
currentAgv.status = "droping";
|
||||
currentAgv.hitCount = currentAgv.hitCount--;
|
||||
}
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
setPath([...dropPickupPath]);
|
||||
@@ -309,16 +350,26 @@ export default function PathNavigator({
|
||||
isWaiting.current = false;
|
||||
setBoxVisible(false);
|
||||
if (currentAgv) {
|
||||
currentAgv.status = 'toPickup';
|
||||
currentAgv.status = "toPickup";
|
||||
}
|
||||
logAgvStatus(id, "Started from droping point, heading to pickup point");
|
||||
logAgvStatus(
|
||||
id,
|
||||
"Started from droping point, heading to pickup point"
|
||||
);
|
||||
}, bufferTime * 1000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPlaying && currentPhase === "toPickup") {
|
||||
const reached = moveAlongPath(object, path, distancesRef.current, speed, delta, progressRef);
|
||||
const reached = moveAlongPath(
|
||||
object,
|
||||
path,
|
||||
distancesRef.current,
|
||||
speed,
|
||||
delta,
|
||||
progressRef
|
||||
);
|
||||
|
||||
if (reached) {
|
||||
if (currentAgv) {
|
||||
@@ -326,14 +377,21 @@ export default function PathNavigator({
|
||||
}
|
||||
setCurrentPhase("initial");
|
||||
if (currentAgv) {
|
||||
currentAgv.status = 'picking';
|
||||
currentAgv.status = "picking";
|
||||
}
|
||||
logAgvStatus(id, "Reached pickup point again, cycle complete");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
moveAlongPath(object, path, distancesRef.current, speed, delta, progressRef);
|
||||
moveAlongPath(
|
||||
object,
|
||||
path,
|
||||
distancesRef.current,
|
||||
speed,
|
||||
delta,
|
||||
progressRef
|
||||
);
|
||||
});
|
||||
|
||||
function moveAlongPath(
|
||||
@@ -379,7 +437,11 @@ export default function PathNavigator({
|
||||
const targetRotationY = Math.atan2(targetDirection.x, targetDirection.z);
|
||||
|
||||
const rotationSpeed = Math.min(5 * delta, 1);
|
||||
object.rotation.y = THREE.MathUtils.lerp(object.rotation.y, targetRotationY, rotationSpeed);
|
||||
object.rotation.y = THREE.MathUtils.lerp(
|
||||
object.rotation.y,
|
||||
targetRotationY,
|
||||
rotationSpeed
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -394,7 +456,7 @@ export default function PathNavigator({
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<group name="path-navigator-lines" visible={!isPlaying}>
|
||||
<group name="path-navigator-lines" visible={!isPlaying} >
|
||||
{toPickupPath.length > 0 && (
|
||||
<Line
|
||||
points={toPickupPath}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { toast } from 'react-toastify';
|
||||
import TempLoader from './tempLoader';
|
||||
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
|
||||
import * as Types from "../../../../types/world/worldTypes";
|
||||
import * as SimulationTypes from "../../../../types/simulationTypes";
|
||||
import { retrieveGLTF, storeGLTF } from '../../../../utils/indexDB/idbUtils';
|
||||
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
|
||||
import { Socket } from 'socket.io-client';
|
||||
@@ -136,7 +137,7 @@ async function handleModelLoad(
|
||||
tempLoader.current = undefined;
|
||||
}
|
||||
|
||||
const newFloorItem: Types.EventData = {
|
||||
const newFloorItem: SimulationTypes.EventData = {
|
||||
modeluuid: model.uuid,
|
||||
modelname: selectedItem.name,
|
||||
modelfileID: selectedItem.id,
|
||||
@@ -150,12 +151,11 @@ async function handleModelLoad(
|
||||
const organization = email ? email.split("@")[1].split(".")[0] : "";
|
||||
|
||||
getAssetEventType(selectedItem.id, organization).then(async (res) => {
|
||||
console.log('res: ', res);
|
||||
|
||||
if (res.type === "Conveyor") {
|
||||
const pointUUIDs = res.points.map(() => THREE.MathUtils.generateUUID());
|
||||
|
||||
const backendEventData: Extract<Types.EventData['eventData'], { type: 'Conveyor' }> = {
|
||||
const backendEventData: Extract<SimulationTypes.EventData['eventData'], { type: 'Conveyor' }> = {
|
||||
type: 'Conveyor',
|
||||
points: res.points.map((point: any, index: number) => ({
|
||||
uuid: pointUUIDs[index],
|
||||
@@ -220,19 +220,18 @@ async function handleModelLoad(
|
||||
eventData.position = newFloorItem.position;
|
||||
eventData.rotation = [model.rotation.x, model.rotation.y, model.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
eventData as Types.ConveyorEventsSchema
|
||||
eventData as SimulationTypes.ConveyorEventsSchema
|
||||
]);
|
||||
|
||||
console.log('data: ', data);
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
|
||||
} else if (res.type === "Vehicle") {
|
||||
|
||||
const pointUUID = THREE.MathUtils.generateUUID();
|
||||
|
||||
const backendEventData: Extract<Types.EventData['eventData'], { type: 'Vehicle' }> = {
|
||||
const backendEventData: Extract<SimulationTypes.EventData['eventData'], { type: 'Vehicle' }> = {
|
||||
type: "Vehicle",
|
||||
points: {
|
||||
uuid: pointUUID,
|
||||
@@ -284,9 +283,9 @@ async function handleModelLoad(
|
||||
return updatedItems;
|
||||
});
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
eventData as Types.VehicleEventsSchema
|
||||
eventData as SimulationTypes.VehicleEventsSchema
|
||||
]);
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
@@ -295,7 +294,7 @@ async function handleModelLoad(
|
||||
|
||||
const pointUUID = THREE.MathUtils.generateUUID();
|
||||
|
||||
const backendEventData: Extract<Types.EventData['eventData'], { type: 'StaticMachine' }> = {
|
||||
const backendEventData: Extract<SimulationTypes.EventData['eventData'], { type: 'StaticMachine' }> = {
|
||||
type: "StaticMachine",
|
||||
points: {
|
||||
uuid: pointUUID,
|
||||
@@ -348,9 +347,9 @@ async function handleModelLoad(
|
||||
return updatedItems;
|
||||
});
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
eventData as Types.StaticMachineEventsSchema
|
||||
eventData as SimulationTypes.StaticMachineEventsSchema
|
||||
]);
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
@@ -359,13 +358,13 @@ async function handleModelLoad(
|
||||
|
||||
const pointUUID = THREE.MathUtils.generateUUID();
|
||||
|
||||
const backendEventData: Extract<Types.EventData['eventData'], { type: 'ArmBot' }> = {
|
||||
const backendEventData: Extract<SimulationTypes.EventData['eventData'], { type: 'ArmBot' }> = {
|
||||
type: "ArmBot",
|
||||
points: {
|
||||
uuid: pointUUID,
|
||||
position: res.points.position as [number, number, number],
|
||||
rotation: res.points.rotation as [number, number, number],
|
||||
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', speed: 1, processes: [] },
|
||||
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', speed: 0.2, processes: [] },
|
||||
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
|
||||
connections: { source: { modelUUID: model.uuid, pointUUID: pointUUID }, targets: [] },
|
||||
}
|
||||
@@ -412,9 +411,9 @@ async function handleModelLoad(
|
||||
return updatedItems;
|
||||
});
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
eventData as Types.ArmBotEventsSchema
|
||||
eventData as SimulationTypes.ArmBotEventsSchema
|
||||
]);
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
@@ -455,7 +454,6 @@ async function handleModelLoad(
|
||||
return updatedItems;
|
||||
});
|
||||
|
||||
console.log('data: ', data);
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { toast } from 'react-toastify';
|
||||
import * as THREE from 'three';
|
||||
|
||||
import * as Types from "../../../../types/world/worldTypes";
|
||||
import * as SimulationTypes from "../../../../types/simulationTypes";
|
||||
// import { deleteFloorItem } from '../../../../services/factoryBuilder/assest/floorAsset/deleteFloorItemApi';
|
||||
import { Socket } from 'socket.io-client';
|
||||
import { getFloorAssets } from '../../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi';
|
||||
@@ -76,7 +77,7 @@ async function DeleteFloorItems(
|
||||
}
|
||||
setFloorItems(updatedItems);
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => {
|
||||
const updatedEvents = (prevEvents || []).filter(event => event.modeluuid !== removedItem.modeluuid);
|
||||
return updatedEvents;
|
||||
});
|
||||
|
||||
@@ -313,7 +313,7 @@ const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject
|
||||
|
||||
useFrame(() => {
|
||||
if (controls)
|
||||
assetVisibility(itemsGroup, state.camera.position, renderDistance);
|
||||
// assetVisibility(itemsGroup, state.camera.position, renderDistance);
|
||||
if (deleteTool && activeModule === "builder") {
|
||||
DeletableHoveredFloorItems(state, itemsGroup, hoveredDeletableFloorItem, setDeletableFloorItem);
|
||||
} else if (!deleteTool) {
|
||||
|
||||
@@ -26,12 +26,7 @@ const CamModelsGroup = () => {
|
||||
loader.setDRACOLoader(dracoLoader);
|
||||
|
||||
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 seen = new Set();
|
||||
|
||||
@@ -5,6 +5,7 @@ import * as THREE from 'three';
|
||||
import * as CONSTANTS from '../../../types/world/worldConstants';
|
||||
import { toast } from 'react-toastify';
|
||||
import * as Types from "../../../types/world/worldTypes";
|
||||
import * as SimulationTypes from "../../../types/simulationTypes";
|
||||
import { initializeDB, retrieveGLTF, storeGLTF } from '../../../utils/indexDB/idbUtils';
|
||||
import { getCamera } from '../../../services/factoryBuilder/camera/getCameraApi';
|
||||
import { getFloorAssets } from '../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi';
|
||||
@@ -12,7 +13,7 @@ import { getFloorAssets } from '../../../services/factoryBuilder/assest/floorAss
|
||||
async function loadInitialFloorItems(
|
||||
itemsGroup: Types.RefGroup,
|
||||
setFloorItems: Types.setFloorItemSetState,
|
||||
setSimulationStates: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => void
|
||||
setSimulationStates: (paths: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => void
|
||||
): Promise<void> {
|
||||
if (!itemsGroup.current) return;
|
||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||
@@ -26,7 +27,7 @@ async function loadInitialFloorItems(
|
||||
if (items.message === "floorItems not found") return;
|
||||
|
||||
if (items) {
|
||||
const storedFloorItems: Types.EventData[] = items;
|
||||
const storedFloorItems: SimulationTypes.EventData[] = items;
|
||||
const loader = new GLTFLoader();
|
||||
const dracoLoader = new DRACOLoader();
|
||||
|
||||
@@ -150,10 +151,10 @@ async function loadInitialFloorItems(
|
||||
|
||||
function processLoadedModel(
|
||||
gltf: any,
|
||||
item: Types.EventData,
|
||||
item: SimulationTypes.EventData,
|
||||
itemsGroup: Types.RefGroup,
|
||||
setFloorItems: Types.setFloorItemSetState,
|
||||
setSimulationStates: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => void
|
||||
setSimulationStates: (paths: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => void
|
||||
) {
|
||||
const model = gltf;
|
||||
model.uuid = item.modeluuid;
|
||||
@@ -196,7 +197,7 @@ function processLoadedModel(
|
||||
gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: 'power2.out' });
|
||||
}
|
||||
|
||||
function processEventData(item: Types.EventData, setSimulationStates: any) {
|
||||
function processEventData(item: SimulationTypes.EventData, setSimulationStates: any) {
|
||||
|
||||
if (item.eventData?.type === 'Conveyor') {
|
||||
|
||||
@@ -206,9 +207,9 @@ function processEventData(item: Types.EventData, setSimulationStates: any) {
|
||||
data.position = item.position;
|
||||
data.rotation = [item.rotation.x, item.rotation.y, item.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
data as Types.ConveyorEventsSchema
|
||||
data as SimulationTypes.ConveyorEventsSchema
|
||||
]);
|
||||
|
||||
} else if (item.eventData?.type === 'Vehicle') {
|
||||
@@ -219,9 +220,9 @@ function processEventData(item: Types.EventData, setSimulationStates: any) {
|
||||
data.position = item.position;
|
||||
data.rotation = [item.rotation.x, item.rotation.y, item.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
data as Types.VehicleEventsSchema
|
||||
data as SimulationTypes.VehicleEventsSchema
|
||||
]);
|
||||
|
||||
} else if (item.eventData?.type === 'StaticMachine') {
|
||||
@@ -232,9 +233,9 @@ function processEventData(item: Types.EventData, setSimulationStates: any) {
|
||||
data.position = item.position;
|
||||
data.rotation = [item.rotation.x, item.rotation.y, item.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
data as Types.StaticMachineEventsSchema
|
||||
data as SimulationTypes.StaticMachineEventsSchema
|
||||
]);
|
||||
|
||||
} else if (item.eventData?.type === 'ArmBot') {
|
||||
@@ -245,9 +246,9 @@ function processEventData(item: Types.EventData, setSimulationStates: any) {
|
||||
data.position = item.position;
|
||||
data.rotation = [item.rotation.x, item.rotation.y, item.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
data as Types.ArmBotEventsSchema
|
||||
data as SimulationTypes.ArmBotEventsSchema
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useFloorItems, useSelectedAssets, useSimulationStates, useSocketStore,
|
||||
import { toast } from "react-toastify";
|
||||
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
|
||||
import * as Types from "../../../../types/world/worldTypes";
|
||||
import * as SimulationTypes from "../../../../types/simulationTypes";
|
||||
import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys";
|
||||
|
||||
const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, selectionGroup, setDuplicatedObjects, movedObjects, setMovedObjects, rotatedObjects, setRotatedObjects, boundingBoxRef }: any) => {
|
||||
@@ -154,7 +155,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||
return updatedItems;
|
||||
});
|
||||
|
||||
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||
let eventData: SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
||||
@@ -162,7 +163,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||
if (eventData.type === 'Conveyor' && eventData) {
|
||||
const createConveyorPoint = (index: number) => {
|
||||
const pointUUID = THREE.MathUtils.generateUUID();
|
||||
const hasActions = (eventData as Types.ConveyorEventsSchema)?.points[index].actions.length > 0;
|
||||
const hasActions = (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].actions.length > 0;
|
||||
|
||||
const defaultAction = {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
@@ -176,15 +177,15 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||
|
||||
return {
|
||||
uuid: pointUUID,
|
||||
position: (eventData as Types.ConveyorEventsSchema)?.points[index].position,
|
||||
rotation: (eventData as Types.ConveyorEventsSchema)?.points[index].rotation,
|
||||
position: (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].position,
|
||||
rotation: (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].rotation,
|
||||
actions: hasActions
|
||||
? (eventData as Types.ConveyorEventsSchema)?.points[index].actions.map(action => ({
|
||||
? (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].actions.map(action => ({
|
||||
...action,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
}))
|
||||
: [defaultAction],
|
||||
triggers: (eventData as Types.ConveyorEventsSchema)?.points[index].triggers.map(trigger => ({
|
||||
triggers: (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].triggers.map(trigger => ({
|
||||
...trigger,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
})),
|
||||
@@ -202,7 +203,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||
createConveyorPoint(1), // middlePoint
|
||||
createConveyorPoint(2) // point2
|
||||
],
|
||||
speed: (eventData as Types.ConveyorEventsSchema)?.speed
|
||||
speed: (eventData as SimulationTypes.ConveyorEventsSchema)?.speed
|
||||
};
|
||||
|
||||
//REST
|
||||
@@ -240,9 +241,9 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
newEventData as Types.ConveyorEventsSchema
|
||||
newEventData as SimulationTypes.ConveyorEventsSchema
|
||||
]);
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
@@ -250,7 +251,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||
} else if (eventData.type === 'Vehicle' && eventData) {
|
||||
const createVehiclePoint = () => {
|
||||
const pointUUID = THREE.MathUtils.generateUUID();
|
||||
const vehiclePoint = (eventData as Types.VehicleEventsSchema)?.points;
|
||||
const vehiclePoint = (eventData as SimulationTypes.VehicleEventsSchema)?.points;
|
||||
const hasActions = vehiclePoint?.actions !== undefined;
|
||||
|
||||
const defaultAction = {
|
||||
@@ -321,9 +322,9 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
newEventData as Types.VehicleEventsSchema
|
||||
newEventData as SimulationTypes.VehicleEventsSchema
|
||||
]);
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
@@ -331,8 +332,8 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||
} else if (eventData.type === 'StaticMachine' && eventData) {
|
||||
const createStaticMachinePoint = () => {
|
||||
const pointUUID = THREE.MathUtils.generateUUID();
|
||||
const vehiclePoint = (eventData as Types.StaticMachineEventsSchema)?.points;
|
||||
const hasActions = vehiclePoint?.actions !== undefined;
|
||||
const staticMachinePoint = (eventData as SimulationTypes.StaticMachineEventsSchema)?.points;
|
||||
const hasActions = staticMachinePoint?.actions !== undefined;
|
||||
|
||||
const defaultAction = {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
@@ -343,11 +344,11 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||
|
||||
return {
|
||||
uuid: pointUUID,
|
||||
position: vehiclePoint?.position,
|
||||
// rotation: vehiclePoint?.rotation,
|
||||
position: staticMachinePoint?.position,
|
||||
rotation: staticMachinePoint?.rotation,
|
||||
actions: hasActions
|
||||
? {
|
||||
...vehiclePoint.actions,
|
||||
...staticMachinePoint.actions,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
}
|
||||
: defaultAction,
|
||||
@@ -399,9 +400,9 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
newEventData as Types.StaticMachineEventsSchema
|
||||
newEventData as SimulationTypes.StaticMachineEventsSchema
|
||||
]);
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
@@ -409,8 +410,8 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||
} else if (eventData.type === 'ArmBot' && eventData) {
|
||||
const createArmBotPoint = () => {
|
||||
const pointUUID = THREE.MathUtils.generateUUID();
|
||||
const vehiclePoint = (eventData as Types.ArmBotEventsSchema)?.points;
|
||||
const hasActions = vehiclePoint?.actions !== undefined;
|
||||
const armBotPoint = (eventData as SimulationTypes.ArmBotEventsSchema)?.points;
|
||||
const hasActions = armBotPoint?.actions !== undefined;
|
||||
|
||||
const defaultAction = {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
@@ -421,18 +422,19 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||
|
||||
return {
|
||||
uuid: pointUUID,
|
||||
position: vehiclePoint?.position,
|
||||
// rotation: vehiclePoint?.rotation,
|
||||
position: armBotPoint?.position,
|
||||
rotation: armBotPoint?.rotation,
|
||||
actions: hasActions
|
||||
? {
|
||||
...vehiclePoint.actions,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
...armBotPoint.actions,
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
processes: []
|
||||
}
|
||||
: defaultAction,
|
||||
triggers: {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
name: vehiclePoint.triggers.name,
|
||||
type: vehiclePoint.triggers.type,
|
||||
name: armBotPoint.triggers.name,
|
||||
type: armBotPoint.triggers.type,
|
||||
},
|
||||
connections: {
|
||||
source: { modelUUID: obj.uuid, pointUUID },
|
||||
@@ -481,9 +483,9 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
newEventData as Types.ArmBotEventsSchema
|
||||
newEventData as SimulationTypes.ArmBotEventsSchema
|
||||
]);
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useFloorItems, useSelectedAssets, useSimulationStates, useSocketStore,
|
||||
import { toast } from "react-toastify";
|
||||
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
|
||||
import * as Types from "../../../../types/world/worldTypes";
|
||||
import * as SimulationTypes from "../../../../types/simulationTypes";
|
||||
import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
|
||||
import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys";
|
||||
|
||||
@@ -40,11 +41,11 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
};
|
||||
|
||||
const onKeyDown = (event: KeyboardEvent) => {
|
||||
const keyCombination = detectModifierKeys(event);
|
||||
const keyCombination = detectModifierKeys(event);
|
||||
|
||||
if (keyCombination === "Ctrl+D" && selectedAssets.length > 0 && duplicatedObjects.length === 0 && movedObjects.length === 0 && rotatedObjects.length === 0) {
|
||||
duplicateSelection();
|
||||
}
|
||||
if (keyCombination === "Ctrl+D" && selectedAssets.length > 0 && duplicatedObjects.length === 0 && movedObjects.length === 0 && rotatedObjects.length === 0) {
|
||||
duplicateSelection();
|
||||
}
|
||||
};
|
||||
|
||||
if (!toggleView) {
|
||||
@@ -132,7 +133,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
return updatedItems;
|
||||
});
|
||||
|
||||
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||
let eventData: SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
||||
@@ -141,7 +142,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
if (eventData.type === 'Conveyor' && eventData) {
|
||||
const createConveyorPoint = (index: number) => {
|
||||
const pointUUID = THREE.MathUtils.generateUUID();
|
||||
const hasActions = (eventData as Types.ConveyorEventsSchema)?.points[index].actions.length > 0;
|
||||
const hasActions = (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].actions.length > 0;
|
||||
|
||||
const defaultAction = {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
@@ -155,15 +156,15 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
|
||||
return {
|
||||
uuid: pointUUID,
|
||||
position: (eventData as Types.ConveyorEventsSchema)?.points[index].position,
|
||||
rotation: (eventData as Types.ConveyorEventsSchema)?.points[index].rotation,
|
||||
position: (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].position,
|
||||
rotation: (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].rotation,
|
||||
actions: hasActions
|
||||
? (eventData as Types.ConveyorEventsSchema)?.points[index].actions.map(action => ({
|
||||
? (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].actions.map(action => ({
|
||||
...action,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
}))
|
||||
: [defaultAction],
|
||||
triggers: (eventData as Types.ConveyorEventsSchema)?.points[index].triggers.map(trigger => ({
|
||||
triggers: (eventData as SimulationTypes.ConveyorEventsSchema)?.points[index].triggers.map(trigger => ({
|
||||
...trigger,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
})),
|
||||
@@ -181,7 +182,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
createConveyorPoint(1),
|
||||
createConveyorPoint(2)
|
||||
],
|
||||
speed: (eventData as Types.ConveyorEventsSchema)?.speed
|
||||
speed: (eventData as SimulationTypes.ConveyorEventsSchema)?.speed
|
||||
};
|
||||
|
||||
//REST
|
||||
@@ -219,9 +220,9 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
newEventData as Types.ConveyorEventsSchema
|
||||
newEventData as SimulationTypes.ConveyorEventsSchema
|
||||
]);
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
@@ -229,7 +230,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
} else if (eventData.type === 'Vehicle' && eventData) {
|
||||
const createVehiclePoint = () => {
|
||||
const pointUUID = THREE.MathUtils.generateUUID();
|
||||
const vehiclePoint = (eventData as Types.VehicleEventsSchema)?.points;
|
||||
const vehiclePoint = (eventData as SimulationTypes.VehicleEventsSchema)?.points;
|
||||
const hasActions = vehiclePoint?.actions !== undefined;
|
||||
|
||||
const defaultAction = {
|
||||
@@ -245,7 +246,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
return {
|
||||
uuid: pointUUID,
|
||||
position: vehiclePoint?.position,
|
||||
// rotation: vehiclePoint?.rotation,
|
||||
rotation: vehiclePoint?.rotation,
|
||||
actions: hasActions
|
||||
? {
|
||||
...vehiclePoint.actions,
|
||||
@@ -300,9 +301,9 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
newEventData as Types.VehicleEventsSchema
|
||||
newEventData as SimulationTypes.VehicleEventsSchema
|
||||
]);
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
@@ -310,8 +311,8 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
} else if (eventData.type === 'StaticMachine' && eventData) {
|
||||
const createStaticMachinePoint = () => {
|
||||
const pointUUID = THREE.MathUtils.generateUUID();
|
||||
const vehiclePoint = (eventData as Types.StaticMachineEventsSchema)?.points;
|
||||
const hasActions = vehiclePoint?.actions !== undefined;
|
||||
const staticMachinePoint = (eventData as SimulationTypes.StaticMachineEventsSchema)?.points;
|
||||
const hasActions = staticMachinePoint?.actions !== undefined;
|
||||
|
||||
const defaultAction = {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
@@ -322,11 +323,11 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
|
||||
return {
|
||||
uuid: pointUUID,
|
||||
position: vehiclePoint?.position,
|
||||
// rotation: vehiclePoint?.rotation,
|
||||
position: staticMachinePoint?.position,
|
||||
rotation: staticMachinePoint?.rotation,
|
||||
actions: hasActions
|
||||
? {
|
||||
...vehiclePoint.actions,
|
||||
...staticMachinePoint.actions,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
}
|
||||
: defaultAction,
|
||||
@@ -378,9 +379,9 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
newEventData as Types.StaticMachineEventsSchema
|
||||
newEventData as SimulationTypes.StaticMachineEventsSchema
|
||||
]);
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
@@ -388,8 +389,8 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
} else if (eventData.type === 'ArmBot' && eventData) {
|
||||
const createArmBotPoint = () => {
|
||||
const pointUUID = THREE.MathUtils.generateUUID();
|
||||
const vehiclePoint = (eventData as Types.ArmBotEventsSchema)?.points;
|
||||
const hasActions = vehiclePoint?.actions !== undefined;
|
||||
const armBotPoint = (eventData as SimulationTypes.ArmBotEventsSchema)?.points;
|
||||
const hasActions = armBotPoint?.actions !== undefined;
|
||||
|
||||
const defaultAction = {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
@@ -400,18 +401,19 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
|
||||
return {
|
||||
uuid: pointUUID,
|
||||
position: vehiclePoint?.position,
|
||||
// rotation: vehiclePoint?.rotation,
|
||||
position: armBotPoint?.position,
|
||||
rotation: armBotPoint?.rotation,
|
||||
actions: hasActions
|
||||
? {
|
||||
...vehiclePoint.actions,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
...armBotPoint.actions,
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
processes: []
|
||||
}
|
||||
: defaultAction,
|
||||
triggers: {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
name: vehiclePoint.triggers.name,
|
||||
type: vehiclePoint.triggers.type,
|
||||
name: armBotPoint.triggers.name,
|
||||
type: armBotPoint.triggers.type,
|
||||
},
|
||||
connections: {
|
||||
source: { modelUUID: obj.uuid, pointUUID },
|
||||
@@ -460,9 +462,9 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
newEventData as Types.ArmBotEventsSchema
|
||||
newEventData as SimulationTypes.ArmBotEventsSchema
|
||||
]);
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useFloorItems, useSelectedAssets, useSimulationStates, useSocketStore,
|
||||
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
|
||||
import { toast } from "react-toastify";
|
||||
import * as Types from "../../../../types/world/worldTypes";
|
||||
import * as SimulationTypes from "../../../../types/simulationTypes";
|
||||
import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys";
|
||||
|
||||
function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, rotatedObjects, setRotatedObjects, boundingBoxRef }: any) {
|
||||
@@ -183,7 +184,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||
return updatedItems;
|
||||
});
|
||||
|
||||
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||
let eventData: SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
||||
@@ -194,7 +195,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||
const backendEventData = {
|
||||
type: 'Conveyor',
|
||||
points: eventData.points,
|
||||
speed: (eventData as Types.ConveyorEventsSchema)?.speed
|
||||
speed: (eventData as SimulationTypes.ConveyorEventsSchema)?.speed
|
||||
};
|
||||
|
||||
//REST
|
||||
@@ -232,7 +233,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => {
|
||||
const updatedEvents = (prevEvents || []).map(event =>
|
||||
event.modeluuid === newFloorItem.modeluuid
|
||||
? { ...event, ...newEventData }
|
||||
@@ -284,7 +285,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => {
|
||||
const updatedEvents = (prevEvents || []).map(event =>
|
||||
event.modeluuid === newFloorItem.modeluuid
|
||||
? { ...event, ...newEventData }
|
||||
@@ -337,7 +338,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => {
|
||||
const updatedEvents = (prevEvents || []).map(event =>
|
||||
event.modeluuid === newFloorItem.modeluuid
|
||||
? { ...event, ...newEventData }
|
||||
@@ -390,7 +391,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => {
|
||||
const updatedEvents = (prevEvents || []).map(event =>
|
||||
event.modeluuid === newFloorItem.modeluuid
|
||||
? { ...event, ...newEventData }
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useFloorItems, useSelectedAssets, useSimulationStates, useSocketStore,
|
||||
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
|
||||
import { toast } from "react-toastify";
|
||||
import * as Types from "../../../../types/world/worldTypes";
|
||||
import * as SimulationTypes from "../../../../types/simulationTypes";
|
||||
import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
|
||||
|
||||
function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, boundingBoxRef }: any) {
|
||||
@@ -184,7 +185,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||
return updatedItems;
|
||||
});
|
||||
|
||||
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||
let eventData: SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
||||
@@ -195,7 +196,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||
const backendEventData = {
|
||||
type: 'Conveyor',
|
||||
points: eventData.points,
|
||||
speed: (eventData as Types.ConveyorEventsSchema)?.speed
|
||||
speed: (eventData as SimulationTypes.ConveyorEventsSchema)?.speed
|
||||
};
|
||||
|
||||
// REST
|
||||
@@ -233,7 +234,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => {
|
||||
const updatedEvents = (prevEvents || []).map(event =>
|
||||
event.modeluuid === newFloorItem.modeluuid
|
||||
? { ...event, ...newEventData }
|
||||
@@ -286,7 +287,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => {
|
||||
const updatedEvents = (prevEvents || []).map(event =>
|
||||
event.modeluuid === newFloorItem.modeluuid
|
||||
? { ...event, ...newEventData }
|
||||
@@ -339,7 +340,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => {
|
||||
const updatedEvents = (prevEvents || []).map(event =>
|
||||
event.modeluuid === newFloorItem.modeluuid
|
||||
? { ...event, ...newEventData }
|
||||
@@ -392,7 +393,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||
newEventData.position = newFloorItem.position;
|
||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||
setSimulationStates((prevEvents: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => {
|
||||
const updatedEvents = (prevEvents || []).map(event =>
|
||||
event.modeluuid === newFloorItem.modeluuid
|
||||
? { ...event, ...newEventData }
|
||||
|
||||
@@ -3,11 +3,12 @@ import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { SelectionBox } from "three/examples/jsm/interactive/SelectionBox";
|
||||
import { SelectionHelper } from "./selectionHelper";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { useFloorItems, useSelectedAssets, useSimulationStates, useSocketStore, useToggleView } from "../../../../store/store";
|
||||
import { useFloorItems, useSelectedAssets, useSimulationStates, useSocketStore, useToggleView, } from "../../../../store/store";
|
||||
import BoundingBox from "./boundingBoxHelper";
|
||||
import { toast } from "react-toastify";
|
||||
// import { deleteFloorItem } from '../../../../services/factoryBuilder/assest/floorAsset/deleteFloorItemApi';
|
||||
import * as Types from "../../../../types/world/worldTypes";
|
||||
import * as SimulationTypes from "../../../../types/simulationTypes";
|
||||
|
||||
import DuplicationControls from "./duplicationControls";
|
||||
import CopyPasteControls from "./copyPasteControls";
|
||||
@@ -20,7 +21,7 @@ const SelectionControls: React.FC = () => {
|
||||
const itemsGroupRef = useRef<THREE.Group | undefined>(undefined);
|
||||
const selectionGroup = useRef() as Types.RefGroup;
|
||||
const { toggleView } = useToggleView();
|
||||
const { setSimulationStates } = useSimulationStates();
|
||||
const { simulationStates, setSimulationStates } = useSimulationStates();
|
||||
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
||||
const [movedObjects, setMovedObjects] = useState<THREE.Object3D[]>([]);
|
||||
const [rotatedObjects, setRotatedObjects] = useState<THREE.Object3D[]>([]);
|
||||
@@ -112,7 +113,6 @@ const SelectionControls: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const onContextMenu = (event: MouseEvent) => {
|
||||
event.preventDefault();
|
||||
if (!rightClickMoved) {
|
||||
@@ -146,7 +146,7 @@ const SelectionControls: React.FC = () => {
|
||||
helper.enabled = false;
|
||||
helper.dispose();
|
||||
};
|
||||
}, [camera, controls, scene, toggleView, selectedAssets, copiedObjects, pastedObjects, duplicatedObjects, movedObjects, socket, floorItems, rotatedObjects, activeModule]);
|
||||
}, [camera, controls, scene, toggleView, selectedAssets, copiedObjects, pastedObjects, duplicatedObjects, movedObjects, socket, floorItems, rotatedObjects, activeModule,]);
|
||||
|
||||
useEffect(() => {
|
||||
if (activeModule !== "builder") {
|
||||
@@ -176,7 +176,7 @@ const SelectionControls: React.FC = () => {
|
||||
}
|
||||
currentObject = currentObject.parent || null;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
if (Objects.size === 0) {
|
||||
clearSelection();
|
||||
@@ -184,9 +184,7 @@ const SelectionControls: React.FC = () => {
|
||||
}
|
||||
|
||||
const updatedSelections = new Set(selectedAssets);
|
||||
Objects.forEach((obj) => {
|
||||
updatedSelections.has(obj) ? updatedSelections.delete(obj) : updatedSelections.add(obj);
|
||||
});
|
||||
Objects.forEach((obj) => { updatedSelections.has(obj) ? updatedSelections.delete(obj) : updatedSelections.add(obj); });
|
||||
|
||||
const selected = Array.from(updatedSelections);
|
||||
|
||||
@@ -200,21 +198,217 @@ const SelectionControls: React.FC = () => {
|
||||
setpastedObjects([]);
|
||||
setDuplicatedObjects([]);
|
||||
setSelectedAssets([]);
|
||||
}
|
||||
};
|
||||
const updateBackend = async (updatedPaths: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => {
|
||||
if (updatedPaths.length === 0) return;
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email ? email.split("@")[1].split(".")[0] : "";
|
||||
|
||||
updatedPaths.forEach(async (updatedPath) => {
|
||||
if (updatedPath.type === "Conveyor") {
|
||||
// await setEventApi(
|
||||
// organization,
|
||||
// updatedPath.modeluuid,
|
||||
// { type: "Conveyor", points: updatedPath.points, speed: updatedPath.speed }
|
||||
// );
|
||||
|
||||
const data = {
|
||||
organization: organization,
|
||||
modeluuid: updatedPath.modeluuid,
|
||||
eventData: {
|
||||
type: "Conveyor",
|
||||
points: updatedPath.points,
|
||||
speed: updatedPath.speed,
|
||||
},
|
||||
};
|
||||
|
||||
socket.emit("v2:model-asset:updateEventData", data);
|
||||
} else if (updatedPath.type === "Vehicle") {
|
||||
// await setEventApi(
|
||||
// organization,
|
||||
// updatedPath.modeluuid,
|
||||
// { type: "Vehicle", points: updatedPath.points }
|
||||
// );
|
||||
|
||||
const data = {
|
||||
organization: organization,
|
||||
modeluuid: updatedPath.modeluuid,
|
||||
eventData: { type: "Vehicle", points: updatedPath.points },
|
||||
};
|
||||
|
||||
socket.emit("v2:model-asset:updateEventData", data);
|
||||
} else if (updatedPath.type === "StaticMachine") {
|
||||
// await setEventApi(
|
||||
// organization,
|
||||
// updatedPath.modeluuid,
|
||||
// { type: "StaticMachine", points: updatedPath.points }
|
||||
// );
|
||||
|
||||
const data = {
|
||||
organization: organization,
|
||||
modeluuid: updatedPath.modeluuid,
|
||||
eventData: { type: "StaticMachine", points: updatedPath.points },
|
||||
};
|
||||
|
||||
socket.emit("v2:model-asset:updateEventData", data);
|
||||
} else if (updatedPath.type === "ArmBot") {
|
||||
// await setEventApi(
|
||||
// organization,
|
||||
// updatedPath.modeluuid,
|
||||
// { type: "ArmBot", points: updatedPath.points }
|
||||
// );
|
||||
|
||||
const data = {
|
||||
organization: organization,
|
||||
modeluuid: updatedPath.modeluuid,
|
||||
eventData: { type: "ArmBot", points: updatedPath.points },
|
||||
};
|
||||
|
||||
socket.emit("v2:model-asset:updateEventData", data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const removeConnections = (deletedModelUUIDs: string[]) => {
|
||||
|
||||
const deletedPointUUIDs = new Set<string>();
|
||||
simulationStates.forEach(state => {
|
||||
if (deletedModelUUIDs.includes(state.modeluuid)) {
|
||||
if (state.type === "Conveyor" && state.points) {
|
||||
state.points.forEach(point => {
|
||||
deletedPointUUIDs.add(point.uuid);
|
||||
});
|
||||
} else if (state.points && 'uuid' in state.points) {
|
||||
deletedPointUUIDs.add(state.points.uuid);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const updatedStates = simulationStates.map((state) => {
|
||||
// Handle Conveyor
|
||||
if (state.type === "Conveyor") {
|
||||
const updatedConveyor: SimulationTypes.ConveyorEventsSchema = {
|
||||
...state,
|
||||
points: state.points.map((point) => {
|
||||
return {
|
||||
...point,
|
||||
connections: {
|
||||
...point.connections,
|
||||
targets: point.connections.targets.filter(
|
||||
(target) => !deletedModelUUIDs.includes(target.modelUUID)
|
||||
),
|
||||
},
|
||||
};
|
||||
}),
|
||||
};
|
||||
return updatedConveyor;
|
||||
}
|
||||
|
||||
// Handle Vehicle
|
||||
else if (state.type === "Vehicle") {
|
||||
const updatedVehicle: SimulationTypes.VehicleEventsSchema = {
|
||||
...state,
|
||||
points: {
|
||||
...state.points,
|
||||
connections: {
|
||||
...state.points.connections,
|
||||
targets: state.points.connections.targets.filter(
|
||||
(target) => !deletedModelUUIDs.includes(target.modelUUID)
|
||||
),
|
||||
},
|
||||
},
|
||||
};
|
||||
return updatedVehicle;
|
||||
}
|
||||
|
||||
// Handle StaticMachine
|
||||
else if (state.type === "StaticMachine") {
|
||||
const updatedStaticMachine: SimulationTypes.StaticMachineEventsSchema =
|
||||
{
|
||||
...state,
|
||||
points: {
|
||||
...state.points,
|
||||
connections: {
|
||||
...state.points.connections,
|
||||
targets: state.points.connections.targets.filter(
|
||||
(target) => !deletedModelUUIDs.includes(target.modelUUID)
|
||||
),
|
||||
},
|
||||
},
|
||||
};
|
||||
return updatedStaticMachine;
|
||||
}
|
||||
|
||||
// Handle ArmBot
|
||||
else if (state.type === "ArmBot") {
|
||||
const updatedArmBot: SimulationTypes.ArmBotEventsSchema = {
|
||||
...state,
|
||||
points: {
|
||||
...state.points,
|
||||
connections: {
|
||||
...state.points.connections,
|
||||
targets: state.points.connections.targets.filter(
|
||||
(target: any) => !deletedModelUUIDs.includes(target.modelUUID)
|
||||
),
|
||||
},
|
||||
actions: {
|
||||
...state.points.actions,
|
||||
processes: state.points.actions.processes?.filter((process) => {
|
||||
// Check if trigger is from deleted model
|
||||
const matchedStates = simulationStates.filter((s) => deletedModelUUIDs.includes(s.modeluuid));
|
||||
|
||||
if (matchedStates.length > 0) {
|
||||
if (matchedStates[0]?.type === "StaticMachine") {
|
||||
const trigPoints = matchedStates[0]?.points;
|
||||
if (process.triggerId === trigPoints?.triggers?.uuid) {
|
||||
return false;
|
||||
}
|
||||
} else if (matchedStates[0]?.type === "Conveyor") {
|
||||
const trigPoints = matchedStates[0]?.points;
|
||||
if (Array.isArray(trigPoints)) {
|
||||
const nonEmptyTriggers = trigPoints.filter((point) => point && point.triggers && point.triggers.length > 0);
|
||||
const allTriggerUUIDs = nonEmptyTriggers.flatMap((point) => point.triggers).map((trigger) => trigger.uuid);
|
||||
if (allTriggerUUIDs.includes(process.triggerId)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if startPoint or endPoint is from deleted model
|
||||
if (deletedPointUUIDs.has(process.startPoint) || deletedPointUUIDs.has(process.endPoint)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}),
|
||||
},
|
||||
},
|
||||
};
|
||||
return updatedArmBot;
|
||||
}
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
const filteredStates = updatedStates.filter((state) => !deletedModelUUIDs.includes(state.modeluuid));
|
||||
|
||||
updateBackend(filteredStates);
|
||||
setSimulationStates(filteredStates);
|
||||
};
|
||||
|
||||
const deleteSelection = () => {
|
||||
if (selectedAssets.length > 0 && duplicatedObjects.length === 0) {
|
||||
const email = localStorage.getItem('email');
|
||||
const organization = (email!.split("@")[1]).split(".")[0];
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email!.split("@")[1].split(".")[0];
|
||||
|
||||
const storedItems = JSON.parse(localStorage.getItem("FloorItems") || '[]');
|
||||
const storedItems = JSON.parse(localStorage.getItem("FloorItems") || "[]");
|
||||
const selectedUUIDs = selectedAssets.map((mesh: THREE.Object3D) => mesh.uuid);
|
||||
|
||||
const updatedStoredItems = storedItems.filter((item: { modeluuid: string }) => !selectedUUIDs.includes(item.modeluuid));
|
||||
localStorage.setItem("FloorItems", JSON.stringify(updatedStoredItems));
|
||||
|
||||
selectedAssets.forEach((selectedMesh: THREE.Object3D) => {
|
||||
|
||||
//REST
|
||||
|
||||
// const response = await deleteFloorItem(organization, selectedMesh.uuid, selectedMesh.userData.name);
|
||||
@@ -225,10 +419,10 @@ const SelectionControls: React.FC = () => {
|
||||
organization: organization,
|
||||
modeluuid: selectedMesh.uuid,
|
||||
modelname: selectedMesh.userData.name,
|
||||
socketId: socket.id
|
||||
socketId: socket.id,
|
||||
};
|
||||
|
||||
socket.emit('v2:model-asset:delete', data);
|
||||
socket.emit("v2:model-asset:delete", data);
|
||||
|
||||
selectedMesh.traverse((child: THREE.Object3D) => {
|
||||
if (child instanceof THREE.Mesh) {
|
||||
@@ -245,17 +439,19 @@ const SelectionControls: React.FC = () => {
|
||||
}
|
||||
});
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||
const updatedEvents = (prevEvents || []).filter(event => event.modeluuid !== selectedMesh.uuid);
|
||||
setSimulationStates((prevEvents: (| SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]) => {
|
||||
const updatedEvents = (prevEvents || []).filter((event) => event.modeluuid !== selectedMesh.uuid);
|
||||
return updatedEvents;
|
||||
});
|
||||
|
||||
itemsGroupRef.current?.remove(selectedMesh);
|
||||
});
|
||||
|
||||
const allUUIDs = selectedAssets.map((val: any) => val.uuid);
|
||||
removeConnections(allUUIDs);
|
||||
|
||||
const updatedItems = floorItems.filter((item: { modeluuid: string }) => !selectedUUIDs.includes(item.modeluuid));
|
||||
setFloorItems(updatedItems);
|
||||
|
||||
}
|
||||
toast.success("Selected models removed!");
|
||||
clearSelection();
|
||||
@@ -263,17 +459,21 @@ const SelectionControls: React.FC = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<group name="SelectionGroup" >
|
||||
<group ref={selectionGroup} name="selectionAssetGroup" >
|
||||
<group name="SelectionGroup">
|
||||
<group ref={selectionGroup} name="selectionAssetGroup">
|
||||
<BoundingBox boundingBoxRef={boundingBoxRef} />
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<MoveControls movedObjects={movedObjects} setMovedObjects={setMovedObjects} itemsGroupRef={itemsGroupRef} copiedObjects={copiedObjects} setCopiedObjects={setCopiedObjects} pastedObjects={pastedObjects} setpastedObjects={setpastedObjects} duplicatedObjects={duplicatedObjects} setDuplicatedObjects={setDuplicatedObjects} rotatedObjects={rotatedObjects} setRotatedObjects={setRotatedObjects} selectionGroup={selectionGroup} boundingBoxRef={boundingBoxRef} />
|
||||
|
||||
<RotateControls rotatedObjects={rotatedObjects} setRotatedObjects={setRotatedObjects} movedObjects={movedObjects} setMovedObjects={setMovedObjects} itemsGroupRef={itemsGroupRef} copiedObjects={copiedObjects} setCopiedObjects={setCopiedObjects} pastedObjects={pastedObjects} setpastedObjects={setpastedObjects} duplicatedObjects={duplicatedObjects} setDuplicatedObjects={setDuplicatedObjects} selectionGroup={selectionGroup} boundingBoxRef={boundingBoxRef} />
|
||||
|
||||
<DuplicationControls itemsGroupRef={itemsGroupRef} duplicatedObjects={duplicatedObjects} setDuplicatedObjects={setDuplicatedObjects} setpastedObjects={setpastedObjects} selectionGroup={selectionGroup} movedObjects={movedObjects} setMovedObjects={setMovedObjects} rotatedObjects={rotatedObjects} setRotatedObjects={setRotatedObjects} boundingBoxRef={boundingBoxRef} />
|
||||
|
||||
<CopyPasteControls itemsGroupRef={itemsGroupRef} copiedObjects={copiedObjects} setCopiedObjects={setCopiedObjects} pastedObjects={pastedObjects} setpastedObjects={setpastedObjects} selectionGroup={selectionGroup} setDuplicatedObjects={setDuplicatedObjects} movedObjects={movedObjects} setMovedObjects={setMovedObjects} rotatedObjects={rotatedObjects} setRotatedObjects={setRotatedObjects} boundingBoxRef={boundingBoxRef} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SelectionControls;
|
||||
export default SelectionControls;
|
||||
|
||||
@@ -55,7 +55,6 @@ import DrieHtmlTemp from "../mqttTemp/drieHtmlTemp";
|
||||
import ZoneGroup from "../../builder/groups/zoneGroup";
|
||||
import useModuleStore from "../../../store/useModuleStore";
|
||||
import NavMeshCreator from "../../builder/agv/navMeshCreator";
|
||||
import ArmReplace from "../../simulation/ik/ArmReplace";
|
||||
|
||||
export default function World() {
|
||||
const state = useThree<Types.ThreeState>(); // Importing the state from the useThree hook, which contains the scene, camera, and other Three.js elements.
|
||||
@@ -110,8 +109,7 @@ export default function World() {
|
||||
|
||||
const cursorPosition = new THREE.Vector3(); // 3D vector for storing the cursor position.
|
||||
|
||||
const [selectedItemsIndex, setSelectedItemsIndex] =
|
||||
useState<Types.Number | null>(null); // State for tracking the index of the selected item.
|
||||
const [selectedItemsIndex, setSelectedItemsIndex] = useState<Types.Number | null>(null); // State for tracking the index of the selected item.
|
||||
const { activeLayer, setActiveLayer } = useActiveLayer(); // State that changes based on which layer the user chooses in Layers.jsx.
|
||||
const { toggleView, setToggleView } = useToggleView(); // State for toggling between 2D and 3D.
|
||||
const { toolMode, setToolMode } = useToolMode();
|
||||
@@ -371,9 +369,6 @@ export default function World() {
|
||||
|
||||
<NavMeshCreator lines={lines} />
|
||||
|
||||
{/* replacing exsisting arms with rigged ones */}
|
||||
<ArmReplace />
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
87
app/src/modules/simulation/armbot/ArmBot.tsx
Normal file
87
app/src/modules/simulation/armbot/ArmBot.tsx
Normal file
@@ -0,0 +1,87 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import useModuleStore from "../../../store/useModuleStore";
|
||||
import { useSimulationStates } from "../../../store/store";
|
||||
import * as SimulationTypes from '../../../types/simulationTypes';
|
||||
import { ArmbotInstances } from "./ArmBotInstances";
|
||||
import { useResetButtonStore } from "../../../store/usePlayButtonStore";
|
||||
|
||||
interface ArmBotState {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
interface StaticMachineState {
|
||||
uuid: string;
|
||||
status: string;
|
||||
actions: { uuid: string; name: string; buffer: number; material: string; };
|
||||
machineTriggerId: string;
|
||||
connectedArmBot: string;
|
||||
}
|
||||
|
||||
interface ArmBotProps {
|
||||
armBots: ArmBotState[];
|
||||
setArmBots: React.Dispatch<React.SetStateAction<ArmBotState[]>>;
|
||||
setStaticMachines: React.Dispatch<React.SetStateAction<StaticMachineState[]>>;
|
||||
}
|
||||
|
||||
const ArmBot = ({ armBots, setArmBots, setStaticMachines }: ArmBotProps) => {
|
||||
const { activeModule } = useModuleStore();
|
||||
const { scene } = useThree();
|
||||
const { simulationStates } = useSimulationStates();
|
||||
const { isReset } = useResetButtonStore();
|
||||
|
||||
useEffect(() => {
|
||||
const filtered = simulationStates.filter((s): s is SimulationTypes.ArmBotEventsSchema => s.type === "ArmBot");
|
||||
const initialStates: ArmBotState[] = filtered
|
||||
.filter(bot => bot.points.connections.targets.length > 0)
|
||||
.map(bot => ({
|
||||
uuid: bot.modeluuid,
|
||||
position: bot.position,
|
||||
rotation: bot.rotation,
|
||||
status: "idle",
|
||||
material: "default",
|
||||
triggerId: '',
|
||||
actions: bot.points.actions,
|
||||
connections: bot.points.connections,
|
||||
isActive: false
|
||||
}));
|
||||
setArmBots(initialStates);
|
||||
}, [simulationStates, isReset]);
|
||||
|
||||
useEffect(() => {
|
||||
armBots.forEach((bot) => {
|
||||
const object = scene.getObjectByProperty("uuid", bot.uuid);
|
||||
if (object) {
|
||||
object.visible = activeModule !== "simulation";
|
||||
}
|
||||
});
|
||||
}, [scene, activeModule, armBots]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{activeModule === "simulation" &&
|
||||
armBots.map((bot, i) => (
|
||||
<ArmbotInstances
|
||||
key={i}
|
||||
index={i}
|
||||
armBot={bot}
|
||||
setArmBots={setArmBots}
|
||||
setStaticMachines={setStaticMachines}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ArmBot;
|
||||
90
app/src/modules/simulation/armbot/ArmBotInstances.tsx
Normal file
90
app/src/modules/simulation/armbot/ArmBotInstances.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
import IkInstances from "./IkInstances";
|
||||
import armModel from "../../../assets/gltf-glb/rigged/ik_arm_4.glb";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { Vector3 } from "three";
|
||||
|
||||
interface Process {
|
||||
triggerId: string;
|
||||
startPoint?: Vector3;
|
||||
endPoint?: Vector3;
|
||||
speed: number;
|
||||
}
|
||||
|
||||
interface ArmBotState {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
interface StaticMachineState {
|
||||
uuid: string;
|
||||
status: string;
|
||||
actions: { uuid: string; name: string; buffer: number; material: string; };
|
||||
machineTriggerId: string;
|
||||
connectedArmBot: string;
|
||||
}
|
||||
|
||||
interface ArmbotInstancesProps {
|
||||
index: number;
|
||||
armBot: ArmBotState;
|
||||
setArmBots: React.Dispatch<React.SetStateAction<ArmBotState[]>>;
|
||||
setStaticMachines: React.Dispatch<React.SetStateAction<StaticMachineState[]>>;
|
||||
}
|
||||
|
||||
export const ArmbotInstances: React.FC<ArmbotInstancesProps> = ({ index, armBot, setArmBots, setStaticMachines }) => {
|
||||
const { scene } = useThree();
|
||||
const [processes, setProcesses] = useState<Process[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (armBot.actions.processes.length > 0) {
|
||||
const mappedProcesses = armBot.actions.processes.map((process) => {
|
||||
return {
|
||||
triggerId: process.triggerId,
|
||||
startPoint: scene.getObjectByProperty('uuid', process.startPoint)?.getWorldPosition(new Vector3()),
|
||||
endPoint: scene.getObjectByProperty('uuid', process.endPoint)?.getWorldPosition(new Vector3()),
|
||||
speed: armBot.actions.speed
|
||||
};
|
||||
});
|
||||
setProcesses(mappedProcesses);
|
||||
} else {
|
||||
setProcesses([]);
|
||||
}
|
||||
}, [armBot, scene]);
|
||||
|
||||
const updateArmBotStatus = (status: string) => {
|
||||
setArmBots((prevArmBots) => {
|
||||
return prevArmBots.map(bot => {
|
||||
if (bot.uuid === armBot.uuid) {
|
||||
return { ...bot, status, triggerId: status === 'idle' ? '' : armBot.triggerId };
|
||||
}
|
||||
return bot;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<IkInstances
|
||||
key={index}
|
||||
uuid={armBot.uuid}
|
||||
selectedTrigger={armBot.triggerId}
|
||||
modelUrl={armModel}
|
||||
position={armBot.position}
|
||||
rotation={armBot.rotation}
|
||||
processes={processes}
|
||||
armBot={armBot}
|
||||
setArmBots={setArmBots}
|
||||
setStaticMachines={setStaticMachines}
|
||||
updateArmBotStatus={updateArmBotStatus}
|
||||
/>
|
||||
);
|
||||
};
|
||||
379
app/src/modules/simulation/armbot/IKAnimationController.tsx
Normal file
379
app/src/modules/simulation/armbot/IKAnimationController.tsx
Normal file
@@ -0,0 +1,379 @@
|
||||
import { useEffect, useMemo, useState, useRef } from "react";
|
||||
import { useFrame } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
import { usePlayButtonStore, useResetButtonStore } from "../../../store/usePlayButtonStore";
|
||||
import { useSimulationStates } from "../../../store/store";
|
||||
import MaterialInstances from "./MaterialInstances";
|
||||
import { Line } from "react-chartjs-2";
|
||||
import { QuadraticBezierLine } from "@react-three/drei";
|
||||
|
||||
|
||||
interface StaticMachineState {
|
||||
uuid: string;
|
||||
status: string;
|
||||
actions: { uuid: string; name: string; buffer: number; material: string; };
|
||||
machineTriggerId: string;
|
||||
connectedArmBot: string;
|
||||
}
|
||||
|
||||
interface ArmBotState {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
type IKAnimationControllerProps = {
|
||||
ikSolver: any;
|
||||
processes: {
|
||||
triggerId: string;
|
||||
startPoint: THREE.Vector3;
|
||||
endPoint: THREE.Vector3;
|
||||
speed: number;
|
||||
}[];
|
||||
selectedTrigger: string;
|
||||
targetBoneName: string;
|
||||
uuid: string;
|
||||
logStatus: (status: string) => void;
|
||||
groupRef: React.RefObject<THREE.Group>;
|
||||
armBot: ArmBotState;
|
||||
setArmBots: React.Dispatch<React.SetStateAction<ArmBotState[]>>;
|
||||
setStaticMachines: React.Dispatch<React.SetStateAction<StaticMachineState[]>>;
|
||||
updateArmBotStatus: (status: string) => void;
|
||||
}
|
||||
|
||||
const IKAnimationController = ({
|
||||
ikSolver,
|
||||
processes,
|
||||
selectedTrigger,
|
||||
targetBoneName,
|
||||
uuid,
|
||||
logStatus,
|
||||
groupRef,
|
||||
armBot,
|
||||
setArmBots,
|
||||
setStaticMachines,
|
||||
updateArmBotStatus
|
||||
}: IKAnimationControllerProps) => {
|
||||
const [progress, setProgress] = useState(0);
|
||||
const [initialProgress, setInitialProgress] = useState(0);
|
||||
const [needsInitialMovement, setNeedsInitialMovement] = useState(true);
|
||||
const [isInitializing, setIsInitializing] = useState(true);
|
||||
const restSpeed = 0.1;
|
||||
const restPosition = new THREE.Vector3(0, 2, 1.6);
|
||||
const { isPlaying } = usePlayButtonStore();;
|
||||
const statusRef = useRef("idle");
|
||||
const { simulationStates } = useSimulationStates();
|
||||
const { isReset } = useResetButtonStore();
|
||||
|
||||
const initialCurveRef = useRef<THREE.CatmullRomCurve3 | null>(null);
|
||||
const initialStartPositionRef = useRef<THREE.Vector3 | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setProgress(0);
|
||||
}, [selectedTrigger]);
|
||||
|
||||
useEffect(() => {
|
||||
setProgress(0);
|
||||
setNeedsInitialMovement(true);
|
||||
setInitialProgress(0);
|
||||
setIsInitializing(true);
|
||||
}, [isReset]);
|
||||
|
||||
useEffect(() => {
|
||||
if (ikSolver) {
|
||||
const targetBone = ikSolver.mesh.skeleton.bones.find(
|
||||
(b: any) => b.name === targetBoneName
|
||||
);
|
||||
if (targetBone) {
|
||||
initialStartPositionRef.current = targetBone.position.clone();
|
||||
calculateInitialCurve(targetBone.position);
|
||||
logStatus(`[Arm ${uuid}] Initializing IK system, starting position: ${targetBone.position.toArray()}`);
|
||||
}
|
||||
}
|
||||
}, [ikSolver]);
|
||||
|
||||
|
||||
const calculateInitialCurve = (startPosition: THREE.Vector3) => {
|
||||
const direction = new THREE.Vector3().subVectors(restPosition, startPosition);
|
||||
const distance = direction.length();
|
||||
direction.normalize();
|
||||
|
||||
const perpendicular = new THREE.Vector3(-direction.z, 0, direction.x).normalize();
|
||||
|
||||
const midHeight = 0.5;
|
||||
const tiltAmount = 1;
|
||||
const mid = new THREE.Vector3()
|
||||
.addVectors(startPosition, restPosition)
|
||||
.multiplyScalar(0.5)
|
||||
.add(perpendicular.clone().multiplyScalar(distance * 0.3 * tiltAmount))
|
||||
.add(new THREE.Vector3(0, midHeight, 0));
|
||||
|
||||
initialCurveRef.current = new THREE.CatmullRomCurve3([
|
||||
startPosition,
|
||||
new THREE.Vector3().lerpVectors(startPosition, mid, 0.33),
|
||||
mid,
|
||||
new THREE.Vector3().lerpVectors(mid, restPosition, 0.66),
|
||||
restPosition
|
||||
]);
|
||||
};
|
||||
|
||||
const processedCurves = useMemo(() => {
|
||||
if (!isPlaying) return [];
|
||||
|
||||
return processes.map(process => {
|
||||
const localStart = groupRef.current?.worldToLocal(process.startPoint.clone());
|
||||
const localEnd = groupRef.current?.worldToLocal(process.endPoint.clone());
|
||||
|
||||
if (!localStart || !localEnd) return null;
|
||||
|
||||
const midPoint = new THREE.Vector3(
|
||||
(localStart.x + localEnd.x) / 2,
|
||||
Math.max(localStart.y, localEnd.y) + 1,
|
||||
(localStart.z + localEnd.z) / 2
|
||||
);
|
||||
const restToStartCurve = new THREE.CatmullRomCurve3([
|
||||
restPosition,
|
||||
new THREE.Vector3().lerpVectors(restPosition, localStart, 0.5),
|
||||
localStart
|
||||
]);
|
||||
|
||||
const processCurve = new THREE.CatmullRomCurve3([
|
||||
localStart,
|
||||
midPoint,
|
||||
localEnd
|
||||
]);
|
||||
|
||||
const endToRestCurve = new THREE.CatmullRomCurve3([
|
||||
localEnd,
|
||||
new THREE.Vector3().lerpVectors(localEnd, restPosition, 0.5),
|
||||
restPosition
|
||||
]);
|
||||
|
||||
return {
|
||||
triggerId: process.triggerId,
|
||||
restToStartCurve,
|
||||
processCurve,
|
||||
endToRestCurve,
|
||||
speed: process.speed,
|
||||
totalDistance:
|
||||
restPosition.distanceTo(localStart) +
|
||||
localStart.distanceTo(localEnd) +
|
||||
localEnd.distanceTo(restPosition)
|
||||
};
|
||||
}).filter(Boolean);
|
||||
}, [processes, isPlaying]);
|
||||
|
||||
const activeProcess = useMemo(() => {
|
||||
if (!selectedTrigger) return null;
|
||||
return processedCurves.find(p => p?.triggerId === selectedTrigger);
|
||||
}, [processedCurves, selectedTrigger]);
|
||||
|
||||
// Initial movement to rest position
|
||||
useFrame((_, delta) => {
|
||||
if (!ikSolver || !needsInitialMovement || !isInitializing || !initialCurveRef.current) return;
|
||||
|
||||
const targetBone = ikSolver.mesh.skeleton.bones.find(
|
||||
(b: any) => b.name === targetBoneName
|
||||
);
|
||||
if (!targetBone) return;
|
||||
|
||||
setInitialProgress((prev) => {
|
||||
const next = prev + delta * 0.5;
|
||||
if (next >= 1) {
|
||||
targetBone.position.copy(restPosition);
|
||||
setNeedsInitialMovement(false);
|
||||
setIsInitializing(false);
|
||||
return 1;
|
||||
}
|
||||
targetBone.position.copy(initialCurveRef.current!.getPoint(next));
|
||||
return next;
|
||||
});
|
||||
|
||||
ikSolver.update();
|
||||
});
|
||||
|
||||
// Main animation loop
|
||||
useFrame((_, delta) => {
|
||||
if (isInitializing || !isPlaying || !selectedTrigger || !activeProcess || !ikSolver) return;
|
||||
|
||||
const bone = ikSolver.mesh.skeleton.bones.find((b: any) => b.name === targetBoneName);
|
||||
if (!bone) return;
|
||||
|
||||
const {
|
||||
restToStartCurve,
|
||||
processCurve,
|
||||
endToRestCurve,
|
||||
speed,
|
||||
totalDistance
|
||||
} = activeProcess;
|
||||
|
||||
// Calculate current segment and progress
|
||||
const restToStartDist = restPosition.distanceTo(restToStartCurve.points[2]);
|
||||
const processDist = processCurve.getLength();
|
||||
const endToRestDist = endToRestCurve.getLength();
|
||||
|
||||
const restToStartEnd = restToStartDist / totalDistance;
|
||||
const processEnd = (restToStartDist + processDist) / totalDistance;
|
||||
|
||||
setProgress(prev => {
|
||||
let currentStatus = statusRef.current;
|
||||
let currentPosition: THREE.Vector3;
|
||||
const newProgress = Math.min(prev + delta * ((currentStatus === 'returning to rest') ? restSpeed : speed), 1);
|
||||
|
||||
if (newProgress < restToStartEnd) {
|
||||
// Moving from rest to start position
|
||||
currentStatus = "moving to start";
|
||||
const segmentProgress = newProgress / restToStartEnd;
|
||||
currentPosition = restToStartCurve.getPoint(segmentProgress);
|
||||
} else if (newProgress < processEnd) {
|
||||
// Processing - moving from start to end
|
||||
currentStatus = "processing";
|
||||
const segmentProgress = (newProgress - restToStartEnd) / (processEnd - restToStartEnd);
|
||||
currentPosition = processCurve.getPoint(segmentProgress);
|
||||
if (statusRef.current !== "processing") {
|
||||
updateConveyorOrStaticMachineStatusOnStart(selectedTrigger);
|
||||
}
|
||||
} else {
|
||||
// Returning to rest position
|
||||
currentStatus = "returning to rest";
|
||||
const segmentProgress = (newProgress - processEnd) / (1 - processEnd);
|
||||
currentPosition = endToRestCurve.getPoint(segmentProgress);
|
||||
}
|
||||
|
||||
// Update status if changed
|
||||
if (currentStatus !== statusRef.current) {
|
||||
statusRef.current = currentStatus;
|
||||
// updateArmBotStatus(currentStatus);
|
||||
logStatus(`[Arm ${uuid}] Status: ${currentStatus}`);
|
||||
}
|
||||
|
||||
// Only trigger when the entire animation is complete (newProgress === 1)
|
||||
if (newProgress === 1 && currentStatus === "returning to rest") {
|
||||
updateConveyorOrStaticMachineStatusOnEnd(selectedTrigger);
|
||||
}
|
||||
|
||||
bone.position.copy(currentPosition);
|
||||
ikSolver.update();
|
||||
return newProgress;
|
||||
});
|
||||
});
|
||||
|
||||
const updateConveyorOrStaticMachineStatusOnStart = (selectedTrigger: string) => {
|
||||
const currentProcess = processes.find(p => p.triggerId === selectedTrigger);
|
||||
if (currentProcess) {
|
||||
const triggerId = currentProcess.triggerId;
|
||||
|
||||
const startPoint = armBot.actions.processes.find((process) => process.triggerId === triggerId)?.startPoint;
|
||||
|
||||
const matchedMachine = simulationStates.find((state) => {
|
||||
if (state.type === "Conveyor") {
|
||||
return (state).points.some(
|
||||
(point) => point.uuid === startPoint
|
||||
);
|
||||
} else if (state.type === "StaticMachine") {
|
||||
return state.points.uuid === startPoint;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (matchedMachine) {
|
||||
if (matchedMachine.type === "Conveyor") {
|
||||
logStatus(`[Arm ${uuid}] start point which is a conveyor (${matchedMachine.modelName})`);
|
||||
} else {
|
||||
logStatus(`[Arm ${uuid}] started form start point which is a static machine (${matchedMachine.modelName})`);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
if (matchedMachine.type === "StaticMachine") {
|
||||
updateArmBotStatus('dropping');
|
||||
}
|
||||
|
||||
if (matchedMachine.type === "Conveyor") {
|
||||
updateArmBotStatus('picking');
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const updateConveyorOrStaticMachineStatusOnEnd = (selectedTrigger: string) => {
|
||||
const currentProcess = processes.find(p => p.triggerId === selectedTrigger);
|
||||
if (currentProcess) {
|
||||
const triggerId = currentProcess.triggerId;
|
||||
|
||||
const endPoint = armBot.actions.processes.find((process) => process.triggerId === triggerId)?.endPoint;
|
||||
|
||||
const matchedMachine = simulationStates.find((state) => {
|
||||
if (state.type === "Conveyor") {
|
||||
return (state).points.some(
|
||||
(point) => point.uuid === endPoint
|
||||
);
|
||||
} else if (state.type === "StaticMachine") {
|
||||
return state.points.uuid === endPoint;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (matchedMachine) {
|
||||
if (matchedMachine.type === "Conveyor") {
|
||||
logStatus(`[Arm ${uuid}] Reached end point which is a conveyor (${matchedMachine.modelName})`);
|
||||
} else {
|
||||
logStatus(`[Arm ${uuid}] Reached end point which is a static machine (${matchedMachine.modelName})`);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
if (matchedMachine.type === "StaticMachine") {
|
||||
setStaticMachines((machines) => {
|
||||
return machines.map((machine) => {
|
||||
if (machine.uuid === matchedMachine.modeluuid) {
|
||||
return { ...machine, status: "running" };
|
||||
} else {
|
||||
return machine;
|
||||
}
|
||||
});
|
||||
});
|
||||
updateArmBotStatus('idle');
|
||||
}
|
||||
|
||||
if (matchedMachine.type === "Conveyor") {
|
||||
setArmBots((prev) =>
|
||||
prev.map((arm) => {
|
||||
if (arm.uuid === uuid && arm.isActive === true) {
|
||||
return {
|
||||
...arm,
|
||||
isActive: false,
|
||||
status: "idle",
|
||||
};
|
||||
}
|
||||
else {
|
||||
return arm;
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<MaterialInstances
|
||||
statusRef={statusRef}
|
||||
ikSolver={ikSolver}
|
||||
targetBoneName={targetBoneName}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default IKAnimationController;
|
||||
150
app/src/modules/simulation/armbot/IkInstances.tsx
Normal file
150
app/src/modules/simulation/armbot/IkInstances.tsx
Normal file
@@ -0,0 +1,150 @@
|
||||
import * as THREE from "three";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useFrame, useLoader } from "@react-three/fiber";
|
||||
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
|
||||
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
|
||||
import { clone } from "three/examples/jsm/utils/SkeletonUtils";
|
||||
import { CCDIKSolver, CCDIKHelper, } from "three/examples/jsm/animation/CCDIKSolver";
|
||||
import IKAnimationController from "./IKAnimationController";
|
||||
import { TransformControls } from "@react-three/drei";
|
||||
|
||||
interface StaticMachineState {
|
||||
uuid: string;
|
||||
status: string;
|
||||
actions: { uuid: string; name: string; buffer: number; material: string; };
|
||||
machineTriggerId: string;
|
||||
connectedArmBot: string;
|
||||
}
|
||||
|
||||
interface ArmBotState {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
const IkInstances = ({
|
||||
uuid,
|
||||
selectedTrigger,
|
||||
modelUrl,
|
||||
processes,
|
||||
position,
|
||||
rotation,
|
||||
armBot,
|
||||
setArmBots,
|
||||
setStaticMachines,
|
||||
updateArmBotStatus
|
||||
}: {
|
||||
uuid: string;
|
||||
selectedTrigger: string;
|
||||
modelUrl: string;
|
||||
processes: any;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
armBot: ArmBotState;
|
||||
setArmBots: React.Dispatch<React.SetStateAction<ArmBotState[]>>;
|
||||
setStaticMachines: React.Dispatch<React.SetStateAction<StaticMachineState[]>>;
|
||||
updateArmBotStatus: (status: string) => void;
|
||||
}) => {
|
||||
const [ikSolver, setIkSolver] = useState<any>(null);
|
||||
const gltf = useLoader(GLTFLoader, modelUrl, (loader) => {
|
||||
const draco = new DRACOLoader();
|
||||
draco.setDecoderPath("https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/");
|
||||
loader.setDRACOLoader(draco);
|
||||
});
|
||||
const cloned = useMemo(() => clone(gltf.scene), [gltf]);
|
||||
const groupRef = useRef<any>(null);
|
||||
const targetBoneName = "Target";
|
||||
const skinnedMeshName = "link_0";
|
||||
|
||||
useEffect(() => {
|
||||
if (!gltf) return;
|
||||
const OOI: any = {};
|
||||
cloned.traverse((n: any) => {
|
||||
if (n.name === targetBoneName) OOI.Target_Bone = n;
|
||||
if (n.name === skinnedMeshName) OOI.Skinned_Mesh = n;
|
||||
});
|
||||
|
||||
if (!OOI.Target_Bone || !OOI.Skinned_Mesh) return;
|
||||
|
||||
const iks = [
|
||||
{
|
||||
target: 7,
|
||||
effector: 6,
|
||||
links: [
|
||||
{
|
||||
index: 5,
|
||||
enabled: true,
|
||||
rotationMin: new THREE.Vector3(-Math.PI / 2, 0, 0),
|
||||
rotationMax: new THREE.Vector3(Math.PI / 2, 0, 0),
|
||||
},
|
||||
{
|
||||
index: 4,
|
||||
enabled: true,
|
||||
rotationMin: new THREE.Vector3(-Math.PI / 2, 0, 0),
|
||||
rotationMax: new THREE.Vector3(0, 0, 0),
|
||||
},
|
||||
{
|
||||
index: 3,
|
||||
enabled: true,
|
||||
rotationMin: new THREE.Vector3(0, 0, 0),
|
||||
rotationMax: new THREE.Vector3(2, 0, 0),
|
||||
},
|
||||
{ index: 1, enabled: true, limitation: new THREE.Vector3(0, 1, 0) },
|
||||
{ index: 0, enabled: false, limitation: new THREE.Vector3(0, 0, 0) },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const solver = new CCDIKSolver(OOI.Skinned_Mesh, iks);
|
||||
setIkSolver(solver);
|
||||
|
||||
const helper = new CCDIKHelper(OOI.Skinned_Mesh, iks, 0.05);
|
||||
// groupRef.current.add(helper);
|
||||
|
||||
}, [gltf]);
|
||||
|
||||
|
||||
const logStatus = (status: string) => {
|
||||
// console.log(status);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<group
|
||||
ref={groupRef}
|
||||
position={position}
|
||||
rotation={rotation}
|
||||
>
|
||||
<primitive
|
||||
object={cloned}
|
||||
scale={[1, 1, 1]}
|
||||
name={`arm-bot`}
|
||||
/>
|
||||
</group>
|
||||
<IKAnimationController
|
||||
ikSolver={ikSolver}
|
||||
processes={processes}
|
||||
selectedTrigger={selectedTrigger}
|
||||
targetBoneName={targetBoneName}
|
||||
uuid={uuid}
|
||||
logStatus={logStatus}
|
||||
groupRef={groupRef}
|
||||
armBot={armBot}
|
||||
setArmBots={setArmBots}
|
||||
setStaticMachines={setStaticMachines}
|
||||
updateArmBotStatus={updateArmBotStatus}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default IkInstances;
|
||||
31
app/src/modules/simulation/armbot/MaterialInstances.tsx
Normal file
31
app/src/modules/simulation/armbot/MaterialInstances.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
import * as THREE from 'three';
|
||||
import { Box } from '@react-three/drei';
|
||||
|
||||
type MaterialInstancesProps = {
|
||||
statusRef: React.RefObject<string>;
|
||||
ikSolver: any;
|
||||
targetBoneName: string;
|
||||
};
|
||||
|
||||
function MaterialInstances({
|
||||
statusRef,
|
||||
ikSolver,
|
||||
targetBoneName
|
||||
}: MaterialInstancesProps) {
|
||||
if (!ikSolver) return null;
|
||||
|
||||
const targetBone = ikSolver.mesh.skeleton.bones.find((b: any) => b.name === targetBoneName);
|
||||
if (!targetBone) return null;
|
||||
|
||||
const worldPos = new THREE.Vector3();
|
||||
targetBone.getWorldPosition(worldPos);
|
||||
|
||||
return (
|
||||
<Box args={[0.5, 0.5, 0.5]} position={worldPos} visible={statusRef.current === 'processing'}>
|
||||
<meshStandardMaterial color="orange" />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default MaterialInstances;
|
||||
@@ -1,88 +0,0 @@
|
||||
import { useFloorItems, useSimulationStates } from '../../../store/store';
|
||||
import * as THREE from 'three';
|
||||
import * as Types from '../../../types/world/worldTypes';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
function Behaviour() {
|
||||
const { setSimulationStates } = useSimulationStates();
|
||||
const { floorItems } = useFloorItems();
|
||||
|
||||
useEffect(() => {
|
||||
const newPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[] = [];
|
||||
|
||||
// floorItems.forEach((item: Types.FloorItemType) => {
|
||||
// if (item.modelfileID === "672a090f80d91ac979f4d0bd") {
|
||||
// const point1Position = new THREE.Vector3(0, 0.85, 2.2);
|
||||
// const middlePointPosition = new THREE.Vector3(0, 0.85, 0);
|
||||
// const point2Position = new THREE.Vector3(0, 0.85, -2.2);
|
||||
|
||||
// const point1UUID = THREE.MathUtils.generateUUID();
|
||||
// const middlePointUUID = THREE.MathUtils.generateUUID();
|
||||
// const point2UUID = THREE.MathUtils.generateUUID();
|
||||
|
||||
// const newPath: Types.ConveyorEventsSchema = {
|
||||
// modeluuid: item.modeluuid,
|
||||
// modelName: item.modelname,
|
||||
// type: 'Conveyor',
|
||||
// points: [
|
||||
// {
|
||||
// uuid: point1UUID,
|
||||
// position: [point1Position.x, point1Position.y, point1Position.z],
|
||||
// rotation: [0, 0, 0],
|
||||
// actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: true }],
|
||||
// triggers: [],
|
||||
// connections: { source: { modelUUID: item.modeluuid, pointUUID: point1UUID }, targets: [] },
|
||||
// },
|
||||
// {
|
||||
// uuid: middlePointUUID,
|
||||
// position: [middlePointPosition.x, middlePointPosition.y, middlePointPosition.z],
|
||||
// rotation: [0, 0, 0],
|
||||
// actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: true }],
|
||||
// triggers: [],
|
||||
// connections: { source: { modelUUID: item.modeluuid, pointUUID: middlePointUUID }, targets: [] },
|
||||
// },
|
||||
// {
|
||||
// uuid: point2UUID,
|
||||
// position: [point2Position.x, point2Position.y, point2Position.z],
|
||||
// rotation: [0, 0, 0],
|
||||
// actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: true }],
|
||||
// triggers: [],
|
||||
// connections: { source: { modelUUID: item.modeluuid, pointUUID: point2UUID }, targets: [] },
|
||||
// },
|
||||
// ],
|
||||
// position: [...item.position],
|
||||
// rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
// speed: 'Inherit',
|
||||
// };
|
||||
|
||||
// newPaths.push(newPath);
|
||||
// } else if (item.modelfileID === "67e3da19c2e8f37134526e6a") {
|
||||
// const pointUUID = THREE.MathUtils.generateUUID();
|
||||
// const pointPosition = new THREE.Vector3(0, 1.3, 0);
|
||||
|
||||
// const newVehiclePath: Types.VehicleEventsSchema = {
|
||||
// modeluuid: item.modeluuid,
|
||||
// modelName: item.modelname,
|
||||
// type: 'Vehicle',
|
||||
// point: {
|
||||
// uuid: pointUUID,
|
||||
// position: [pointPosition.x, pointPosition.y, pointPosition.z],
|
||||
// actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Start', start: {}, hitCount: 1, end: {}, buffer: 0 },
|
||||
// connections: { source: { modelUUID: item.modeluuid, pointUUID: pointUUID }, targets: [] },
|
||||
// speed: 2,
|
||||
// },
|
||||
// position: [...item.position],
|
||||
// };
|
||||
|
||||
// newPaths.push(newVehiclePath);
|
||||
// }
|
||||
// });
|
||||
|
||||
// setSimulationStates(newPaths);
|
||||
// console.log('floorItems: ', floorItems);
|
||||
}, [floorItems]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export default Behaviour;
|
||||
@@ -1,56 +0,0 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
|
||||
// store
|
||||
import useModuleStore from "../../../store/useModuleStore";
|
||||
|
||||
// functions
|
||||
import { findLinkObjects } from "./functions/findLinkObjects";
|
||||
// components
|
||||
import { MultiGLTFInstances } from "./MultiGLTFInstances";
|
||||
|
||||
// impory model from model folder
|
||||
import armModel from "../../../assets/gltf-glb/rigged/ik_arm_4.glb";
|
||||
|
||||
// Main component to include the logic
|
||||
const ArmReplace: React.FC = () => {
|
||||
const { activeModule } = useModuleStore();
|
||||
|
||||
const { scene } = useThree(); // Access the Three.js scene from the React Fiber context
|
||||
|
||||
// State to store positions, rotations, and count
|
||||
const [positions, setPositions] = React.useState<[number, number, number][]>(
|
||||
[]
|
||||
);
|
||||
const [rotations, setRotations] = React.useState<[number, number, number][]>(
|
||||
[]
|
||||
);
|
||||
const [count, setCount] = React.useState<string[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
// Call the function to find objects and update states
|
||||
findLinkObjects(
|
||||
scene,
|
||||
setPositions,
|
||||
setRotations,
|
||||
setCount,
|
||||
activeModule === "simulation" ? false : true
|
||||
);
|
||||
}, [scene, activeModule]); // Re-run this effect if the scene changes or activeModule changes
|
||||
|
||||
return (
|
||||
<>
|
||||
{useModuleStore.getState().activeModule === "simulation" &&
|
||||
count.map((_, i: number) => (
|
||||
<MultiGLTFInstances
|
||||
index={i}
|
||||
modelUrl={armModel}
|
||||
position={positions[i]}
|
||||
rotation={rotations[i]}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ArmReplace;
|
||||
@@ -1,43 +0,0 @@
|
||||
import { useLoader } from "@react-three/fiber";
|
||||
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
|
||||
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
|
||||
import { clone } from "three/examples/jsm/utils/SkeletonUtils";
|
||||
|
||||
interface MultiGLTFInstancesProps {
|
||||
index: number;
|
||||
modelUrl: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
}
|
||||
|
||||
export const MultiGLTFInstances: React.FC<MultiGLTFInstancesProps> = ({
|
||||
index,
|
||||
modelUrl,
|
||||
position,
|
||||
rotation,
|
||||
}) => {
|
||||
// Load GLTF model with DRACO loader for compression
|
||||
const originalGltf = useLoader(GLTFLoader, modelUrl, (loader) => {
|
||||
const draco = new DRACOLoader();
|
||||
draco.setDecoderPath(
|
||||
"https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/"
|
||||
);
|
||||
loader.setDRACOLoader(draco);
|
||||
});
|
||||
|
||||
// Clone the model for independent transformations
|
||||
const cloned = clone(originalGltf.scene);
|
||||
|
||||
// Render the cloned model
|
||||
return (
|
||||
<mesh>
|
||||
<primitive
|
||||
name="rigged_arm"
|
||||
key={index}
|
||||
object={cloned}
|
||||
position={position}
|
||||
rotation={rotation}
|
||||
/>
|
||||
</mesh>
|
||||
);
|
||||
};
|
||||
@@ -1,43 +0,0 @@
|
||||
import { Object3D, Vector3 } from "three";
|
||||
|
||||
// Function to find objects named 'link_0' and update positions, rotations, and count
|
||||
export const findLinkObjects = (
|
||||
scene: Object3D,
|
||||
setPositions: React.Dispatch<
|
||||
React.SetStateAction<[number, number, number][]>
|
||||
>,
|
||||
setRotations: React.Dispatch<
|
||||
React.SetStateAction<[number, number, number][]>
|
||||
>,
|
||||
setCount: React.Dispatch<React.SetStateAction<string[]>>,
|
||||
visibility: boolean
|
||||
) => {
|
||||
const positions: [number, number, number][] = [];
|
||||
const rotations: [number, number, number][] = [];
|
||||
const count: string[] = [];
|
||||
let i = 0;
|
||||
|
||||
scene.traverse((object) => {
|
||||
if (object.name === "link_0") {
|
||||
if (object.parent && object.type !== "SkinnedMesh") {
|
||||
// count
|
||||
count[i] = object.uuid;
|
||||
i++;
|
||||
// Save the position and rotation of the parent object
|
||||
const { x: px, y: py, z: pz } = object.parent.position;
|
||||
positions.push([px, py, pz]);
|
||||
|
||||
const { x: rx, y: ry, z: rz } = object.parent.rotation;
|
||||
rotations.push([rx, ry, rz]);
|
||||
|
||||
// Change visibility of the object
|
||||
object.visible = visibility;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Update the state with the collected positions, rotations, and count
|
||||
setPositions(positions);
|
||||
setRotations(rotations);
|
||||
setCount(count);
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
import * as THREE from "three";
|
||||
import * as Types from "../../../types/world/worldTypes";
|
||||
import * as SimulationTypes from "../../../types/simulationTypes";
|
||||
import { useRef, useState, useEffect, useMemo } from "react";
|
||||
import { Sphere, TransformControls } from "@react-three/drei";
|
||||
import {
|
||||
@@ -66,45 +66,6 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec
|
||||
});
|
||||
});
|
||||
|
||||
const updateSimulationPaths = () => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationStates.map((path) => {
|
||||
if (path.type === "Conveyor") {
|
||||
return {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.points.uuid
|
||||
? {
|
||||
...point,
|
||||
position: [
|
||||
selectedActionSphere.points.position.x,
|
||||
selectedActionSphere.points.position.y,
|
||||
selectedActionSphere.points.position.z,
|
||||
],
|
||||
rotation: [
|
||||
selectedActionSphere.points.rotation.x,
|
||||
selectedActionSphere.points.rotation.y,
|
||||
selectedActionSphere.points.rotation.z,
|
||||
],
|
||||
}
|
||||
: point
|
||||
),
|
||||
};
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}) as Types.ConveyorEventsSchema[];
|
||||
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path) => path.type === "Conveyor" && path.points.some((point) => point.uuid === selectedActionSphere.points.uuid)
|
||||
);
|
||||
|
||||
// console.log("Updated Path:", updatedPath);
|
||||
|
||||
setSimulationStates(updatedPaths);
|
||||
};
|
||||
|
||||
useFrame(() => {
|
||||
if (eyeDropMode) {
|
||||
raycaster.setFromCamera(pointer, camera);
|
||||
@@ -161,7 +122,7 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec
|
||||
};
|
||||
}, [eyeDropMode, editingPoint, previewPosition]);
|
||||
|
||||
const updateBackend = async (updatedPath: Types.VehicleEventsSchema | undefined) => {
|
||||
const updateBackend = async (updatedPath: SimulationTypes.VehicleEventsSchema | undefined) => {
|
||||
if (!updatedPath) return;
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email ? email.split("@")[1].split(".")[0] : "";
|
||||
@@ -191,7 +152,7 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec
|
||||
return path;
|
||||
});
|
||||
|
||||
const updatedPath = updatedPaths.find((path): path is Types.VehicleEventsSchema => path.type === "Vehicle" && path.points.uuid === selectedActionSphere.points.uuid);
|
||||
const updatedPath = updatedPaths.find((path): path is SimulationTypes.VehicleEventsSchema => path.type === "Vehicle" && path.points.uuid === selectedActionSphere.points.uuid);
|
||||
updateBackend(updatedPath);
|
||||
|
||||
setSimulationStates(updatedPaths);
|
||||
@@ -282,6 +243,7 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec
|
||||
key={path.modeluuid}
|
||||
ref={(el) => (groupRefs.current[path.modeluuid] = el!)}
|
||||
position={path.position}
|
||||
rotation={path.rotation}
|
||||
onClick={(e) => {
|
||||
if (isConnecting || eyeDropMode) return;
|
||||
e.stopPropagation();
|
||||
@@ -335,6 +297,7 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec
|
||||
key={path.modeluuid}
|
||||
ref={(el) => (groupRefs.current[path.modeluuid] = el!)}
|
||||
position={path.position}
|
||||
rotation={path.rotation}
|
||||
onClick={(e) => {
|
||||
if (isConnecting || eyeDropMode) return;
|
||||
e.stopPropagation();
|
||||
@@ -388,6 +351,7 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec
|
||||
key={path.modeluuid}
|
||||
ref={(el) => (groupRefs.current[path.modeluuid] = el!)}
|
||||
position={path.position}
|
||||
rotation={path.rotation}
|
||||
onClick={(e) => {
|
||||
if (isConnecting || eyeDropMode) return;
|
||||
e.stopPropagation();
|
||||
@@ -442,7 +406,6 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec
|
||||
ref={transformRef}
|
||||
object={selectedActionSphere.points}
|
||||
mode={transformMode}
|
||||
onMouseUp={updateSimulationPaths}
|
||||
/>
|
||||
)}
|
||||
</group>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useRef, useEffect, useMemo } from "react";
|
||||
import React, { useRef, useEffect, useMemo, useCallback } from "react";
|
||||
import { useLoader, useFrame } from "@react-three/fiber";
|
||||
import { GLTFLoader } from "three-stdlib";
|
||||
import * as THREE from "three";
|
||||
@@ -8,14 +8,33 @@ import crate from "../../../assets/gltf-glb/crate_box.glb";
|
||||
import { useProcessAnimation } from "./useProcessAnimations";
|
||||
import ProcessObject from "./processObject";
|
||||
import { ProcessData } from "./types";
|
||||
import { useSimulationStates } from "../../../store/store";
|
||||
import { retrieveGLTF } from "../../../utils/indexDB/idbUtils";
|
||||
|
||||
interface ArmBotState {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: {
|
||||
uuid: string;
|
||||
name: string;
|
||||
speed: number;
|
||||
processes: { triggerId: string; startPoint: string; endPoint: string }[];
|
||||
};
|
||||
isActive?: boolean;
|
||||
}
|
||||
interface ProcessContainerProps {
|
||||
processes: ProcessData[];
|
||||
setProcesses: React.Dispatch<React.SetStateAction<any[]>>;
|
||||
agvRef: any;
|
||||
MaterialRef: any;
|
||||
armBots: ArmBotState[];
|
||||
setArmBots: React.Dispatch<React.SetStateAction<ArmBotState[]>>;
|
||||
}
|
||||
|
||||
const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
@@ -23,6 +42,8 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
setProcesses,
|
||||
agvRef,
|
||||
MaterialRef,
|
||||
armBots,
|
||||
setArmBots,
|
||||
}) => {
|
||||
const gltf = useLoader(GLTFLoader, crate) as GLTF;
|
||||
const groupRef = useRef<THREE.Group>(null);
|
||||
@@ -42,21 +63,25 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
getPointDataForAnimationIndex,
|
||||
processes: processedProcesses,
|
||||
checkAndCountTriggers,
|
||||
} = useProcessAnimation(processes, setProcesses, agvRef);
|
||||
} = useProcessAnimation(processes, setProcesses, agvRef, armBots, setArmBots);
|
||||
|
||||
const baseMaterials = useMemo(() => ({
|
||||
Box: new THREE.MeshStandardMaterial({ color: 0x8b4513 }),
|
||||
Crate: new THREE.MeshStandardMaterial({ color: 0x00ff00 }),
|
||||
Default: new THREE.MeshStandardMaterial(),
|
||||
}), []);
|
||||
const baseMaterials = useMemo(
|
||||
() => ({
|
||||
Box: new THREE.MeshStandardMaterial({ color: 0x8b4513 }),
|
||||
Crate: new THREE.MeshStandardMaterial({ color: 0x00ff00 }),
|
||||
Default: new THREE.MeshStandardMaterial(),
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// Update material references for all spawned objects
|
||||
Object.entries(animationStates).forEach(([processId, processState]) => {
|
||||
Object.keys(processState.spawnedObjects).forEach((objectId) => {
|
||||
const entry = { processId, objectId, };
|
||||
const entry = { processId, objectId };
|
||||
|
||||
const materialType = processState.spawnedObjects[objectId]?.currentMaterialType;
|
||||
const materialType =
|
||||
processState.spawnedObjects[objectId]?.currentMaterialType;
|
||||
|
||||
if (!materialType) {
|
||||
return;
|
||||
@@ -65,13 +90,17 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
const matRefArray = MaterialRef.current;
|
||||
|
||||
// Find existing material group
|
||||
const existing = matRefArray.find((entryGroup: { material: string; objects: any[] }) =>
|
||||
entryGroup.material === materialType
|
||||
const existing = matRefArray.find(
|
||||
(entryGroup: { material: string; objects: any[] }) =>
|
||||
entryGroup.material === materialType
|
||||
);
|
||||
|
||||
if (existing) {
|
||||
// Check if this processId + objectId already exists
|
||||
const alreadyExists = existing.objects.some((o: any) => o.processId === entry.processId && o.objectId === entry.objectId);
|
||||
const alreadyExists = existing.objects.some(
|
||||
(o: any) =>
|
||||
o.processId === entry.processId && o.objectId === entry.objectId
|
||||
);
|
||||
|
||||
if (!alreadyExists) {
|
||||
existing.objects.push(entry);
|
||||
@@ -89,9 +118,31 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
|
||||
// In processAnimator.tsx - only the relevant spawn logic part that needs fixes
|
||||
|
||||
// Add this function to ProcessAnimator component
|
||||
const isConnectedToActiveArmBot = useCallback(
|
||||
(processId: any) => {
|
||||
// Check if any active armbot is connected to this process
|
||||
return armBots.some((armbot) => {
|
||||
if (!armbot.isActive) return false;
|
||||
|
||||
// Check if this armbot is connected to the process
|
||||
return armbot.connections?.targets?.some((connection) => {
|
||||
// Find the process that owns this modelUUID
|
||||
const connectedProcess = processes.find((p) =>
|
||||
p.paths?.some((path) => path.modeluuid === connection.modelUUID)
|
||||
);
|
||||
return connectedProcess?.id === processId;
|
||||
});
|
||||
});
|
||||
},
|
||||
[armBots, processes]
|
||||
);
|
||||
|
||||
// First useFrame for spawn logic
|
||||
useFrame(() => {
|
||||
// Spawn logic frame
|
||||
const currentTime = clockRef.current.getElapsedTime() - elapsedBeforePauseRef.current;
|
||||
const currentTime =
|
||||
clockRef.current.getElapsedTime() - elapsedBeforePauseRef.current;
|
||||
|
||||
setAnimationStates((prev) => {
|
||||
const newStates = { ...prev };
|
||||
@@ -100,26 +151,47 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
const processState = newStates[process.id];
|
||||
if (!processState) return;
|
||||
|
||||
// Check connection status
|
||||
const isConnected = isConnectedToActiveArmBot(process.id);
|
||||
|
||||
if (processState.isProcessDelaying) {
|
||||
// Existing delay handling logic...
|
||||
return;
|
||||
}
|
||||
|
||||
if (isConnected) {
|
||||
newStates[process.id] = {
|
||||
...processState,
|
||||
nextSpawnTime: Infinity, // Prevent future spawns
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
const spawnPoint = findSpawnPoint(process);
|
||||
if (!spawnPoint || !spawnPoint.actions) return;
|
||||
if (!spawnPoint || !spawnPoint.actions) {
|
||||
// console.log(
|
||||
// `Process ${process.id} has no valid spawn point or actions`
|
||||
// );
|
||||
return;
|
||||
}
|
||||
|
||||
const spawnAction = spawnPoint.actions.find(
|
||||
(a) => a.isUsed && a.type === "Spawn"
|
||||
);
|
||||
if (!spawnAction) return;
|
||||
if (!spawnAction) {
|
||||
return;
|
||||
}
|
||||
|
||||
const spawnInterval =
|
||||
typeof spawnAction.spawnInterval === "number"
|
||||
? spawnAction.spawnInterval
|
||||
: parseFloat(spawnAction.spawnInterval as string) || 0;
|
||||
: parseFloat(spawnAction.spawnInterval || "0") || 0;
|
||||
|
||||
// Check if this is a zero interval spawn and we already spawned an object
|
||||
if (spawnInterval === 0 && processState.hasSpawnedZeroIntervalObject === true) {
|
||||
if (
|
||||
spawnInterval === 0 &&
|
||||
processState.hasSpawnedZeroIntervalObject === true
|
||||
) {
|
||||
return; // Don't spawn more objects for zero interval
|
||||
}
|
||||
|
||||
@@ -135,6 +207,15 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
baseMaterials
|
||||
);
|
||||
|
||||
// Initialize state properly to ensure animation
|
||||
newObject.state = {
|
||||
...newObject.state,
|
||||
isAnimating: true,
|
||||
isDelaying: false,
|
||||
delayComplete: false,
|
||||
progress: 0.005, // Start with tiny progress to ensure animation begins
|
||||
};
|
||||
|
||||
// Update state with the new object and flag for zero interval
|
||||
newStates[process.id] = {
|
||||
...processState,
|
||||
@@ -157,6 +238,7 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
});
|
||||
});
|
||||
|
||||
// Second useFrame for animation logic
|
||||
useFrame((_, delta) => {
|
||||
// Animation logic frame
|
||||
const currentTime =
|
||||
@@ -167,8 +249,42 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
|
||||
processedProcesses.forEach((process) => {
|
||||
const processState = newStates[process.id];
|
||||
if (!processState) return;
|
||||
if (!processState) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check connection status with debugging
|
||||
const isConnected = isConnectedToActiveArmBot(process.id);
|
||||
// console.log(
|
||||
// `Process ${process.id} animation - connected:`,
|
||||
// isConnected
|
||||
// );
|
||||
|
||||
if (isConnected) {
|
||||
// Stop all animations when connected to active arm bot
|
||||
newStates[process.id] = {
|
||||
...processState,
|
||||
spawnedObjects: Object.entries(processState.spawnedObjects).reduce(
|
||||
(acc, [id, obj]) => ({
|
||||
...acc,
|
||||
[id]: {
|
||||
...obj,
|
||||
state: {
|
||||
...obj.state,
|
||||
isAnimating: false, // Stop animation
|
||||
isDelaying: false, // Clear delays
|
||||
delayComplete: false, // Reset delays
|
||||
progress: 0, // Reset progress
|
||||
},
|
||||
},
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
// Process delay handling
|
||||
if (processState.isProcessDelaying) {
|
||||
const effectiveDelayTime =
|
||||
processState.processDelayDuration / speedRef.current;
|
||||
@@ -177,6 +293,9 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
currentTime - processState.processDelayStartTime >=
|
||||
effectiveDelayTime
|
||||
) {
|
||||
// console.log(
|
||||
// `Process ${process.id} delay completed, resuming animation`
|
||||
// );
|
||||
newStates[process.id] = {
|
||||
...processState,
|
||||
isProcessDelaying: false,
|
||||
@@ -200,26 +319,42 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
{}
|
||||
),
|
||||
};
|
||||
return newStates;
|
||||
return;
|
||||
} else {
|
||||
return newStates;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure we have a valid path to follow
|
||||
const path =
|
||||
process.animationPath?.map((p) => new THREE.Vector3(p.x, p.y, p.z)) ||
|
||||
[];
|
||||
if (path.length < 2) return;
|
||||
|
||||
if (path.length < 2) {
|
||||
// console.log(
|
||||
// `Process ${process.id} has insufficient path points: ${path.length}`
|
||||
// );
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedObjects = { ...processState.spawnedObjects };
|
||||
let animationOccurring = false; // Track if any animation is happening
|
||||
|
||||
Object.entries(processState.spawnedObjects).forEach(
|
||||
([objectId, obj]) => {
|
||||
if (!obj.visible) return;
|
||||
if (!obj.visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentRef = gltf?.scene ? obj.ref.current : obj.ref.current;
|
||||
if (!currentRef) return;
|
||||
if (!currentRef) {
|
||||
// console.log(
|
||||
// `No reference for object ${objectId}, skipping animation`
|
||||
// );
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize position for new objects
|
||||
if (
|
||||
obj.position &&
|
||||
obj.state.currentIndex === 0 &&
|
||||
@@ -230,11 +365,22 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
|
||||
const stateRef = obj.state;
|
||||
|
||||
// Ensure animation state is properly set for objects
|
||||
if (!stateRef.isAnimating && !stateRef.isDelaying && !isConnected) {
|
||||
stateRef.isAnimating = true;
|
||||
stateRef.progress =
|
||||
stateRef.progress > 0 ? stateRef.progress : 0.005;
|
||||
}
|
||||
|
||||
// Handle delay logic
|
||||
if (stateRef.isDelaying) {
|
||||
const effectiveDelayTime =
|
||||
stateRef.currentDelayDuration / speedRef.current;
|
||||
|
||||
if (currentTime - stateRef.delayStartTime >= effectiveDelayTime) {
|
||||
// console.log(
|
||||
// `Delay complete for object ${objectId}, resuming animation`
|
||||
// );
|
||||
stateRef.isDelaying = false;
|
||||
stateRef.delayComplete = true;
|
||||
stateRef.isAnimating = true;
|
||||
@@ -260,8 +406,17 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
}
|
||||
}
|
||||
|
||||
if (!stateRef.isAnimating) return;
|
||||
// Skip non-animating objects
|
||||
if (!stateRef.isAnimating) {
|
||||
// console.log(
|
||||
// `Object ${objectId} not animating, skipping animation updates`
|
||||
// );
|
||||
return;
|
||||
}
|
||||
|
||||
animationOccurring = true; // Mark that animation is happening
|
||||
|
||||
// Handle point actions
|
||||
const currentPointData = getPointDataForAnimationIndex(
|
||||
process,
|
||||
stateRef.currentIndex
|
||||
@@ -286,51 +441,22 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
const nextPointIdx = stateRef.currentIndex + 1;
|
||||
const isLastPoint = nextPointIdx >= path.length;
|
||||
|
||||
// if (isLastPoint) {
|
||||
// if (currentPointData?.actions) {
|
||||
// const shouldStop = !hasNonInheritActions(
|
||||
// currentPointData.actions
|
||||
// );
|
||||
// if (shouldStop) {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (isLastPoint) {
|
||||
// if (currentPointData?.actions) {
|
||||
// const hasNonInherit = hasNonInheritActions(
|
||||
// currentPointData.actions
|
||||
// );
|
||||
// if (!hasNonInherit) {
|
||||
// // Remove the object if all actions are inherit
|
||||
// updatedObjects[objectId] = {
|
||||
// ...obj,
|
||||
// visible: false,
|
||||
// state: { ...stateRef, isAnimating: false },
|
||||
// };
|
||||
// return;
|
||||
// }
|
||||
// } else {
|
||||
// // No actions at last point - remove the object
|
||||
// updatedObjects[objectId] = {
|
||||
// ...obj,
|
||||
// visible: false,
|
||||
// state: { ...stateRef, isAnimating: false },
|
||||
// };
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
// Handle objects at the last point
|
||||
if (isLastPoint) {
|
||||
const isAgvPicking = agvRef.current.some(
|
||||
(agv: any) => agv.processId === process.id && agv.status === "picking"
|
||||
(agv: any) =>
|
||||
agv.processId === process.id && agv.status === "picking"
|
||||
);
|
||||
|
||||
const shouldHide = !currentPointData?.actions || !hasNonInheritActions(currentPointData.actions);
|
||||
const shouldHide =
|
||||
!currentPointData?.actions ||
|
||||
!hasNonInheritActions(currentPointData.actions);
|
||||
|
||||
if (shouldHide) {
|
||||
if (isAgvPicking) {
|
||||
// console.log(
|
||||
// `AGV picking at last point for object ${objectId}, hiding object`
|
||||
// );
|
||||
updatedObjects[objectId] = {
|
||||
...obj,
|
||||
visible: false,
|
||||
@@ -356,9 +482,11 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
}
|
||||
}
|
||||
|
||||
// Handle stacked objects when AGV picks
|
||||
if (tempStackedObjectsRef.current[objectId]) {
|
||||
const isAgvPicking = agvRef.current.some(
|
||||
(agv: any) => agv.processId === process.id && agv.status === "picking"
|
||||
(agv: any) =>
|
||||
agv.processId === process.id && agv.status === "picking"
|
||||
);
|
||||
|
||||
if (isAgvPicking) {
|
||||
@@ -372,22 +500,34 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
isAnimating: false,
|
||||
},
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle normal animation progress for objects not at last point
|
||||
if (!isLastPoint) {
|
||||
const nextPoint = path[nextPointIdx];
|
||||
const distance = path[stateRef.currentIndex].distanceTo(nextPoint);
|
||||
const distance =
|
||||
path[stateRef.currentIndex].distanceTo(nextPoint);
|
||||
const effectiveSpeed = stateRef.speed * speedRef.current;
|
||||
const movement = effectiveSpeed * delta;
|
||||
|
||||
// Ensure progress is always moving forward
|
||||
if (stateRef.delayComplete && stateRef.progress < 0.01) {
|
||||
stateRef.progress = 0.05;
|
||||
stateRef.delayComplete = false;
|
||||
// console.log(
|
||||
// `Boosting progress for object ${objectId} after delay`
|
||||
// );
|
||||
} else {
|
||||
stateRef.progress += movement / distance;
|
||||
// console.log(
|
||||
// `Object ${objectId} progress: ${stateRef.progress.toFixed(3)}`
|
||||
// );
|
||||
}
|
||||
|
||||
// Handle point transition
|
||||
if (stateRef.progress >= 1) {
|
||||
stateRef.currentIndex = nextPointIdx;
|
||||
stateRef.progress = 0;
|
||||
@@ -406,7 +546,10 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
process,
|
||||
stateRef.currentIndex
|
||||
);
|
||||
|
||||
// No action needed with newPointData here - will be handled in next frame
|
||||
} else {
|
||||
// Update position with lerp
|
||||
currentRef.position.lerpVectors(
|
||||
path[stateRef.currentIndex],
|
||||
nextPoint,
|
||||
@@ -419,6 +562,13 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
||||
}
|
||||
);
|
||||
|
||||
// Log if no animation is occurring when it should
|
||||
if (!animationOccurring && !isConnected) {
|
||||
// console.log(
|
||||
// `Warning: No animation occurring for process ${process.id} despite not being connected`
|
||||
// );
|
||||
}
|
||||
|
||||
newStates[process.id] = {
|
||||
...processState,
|
||||
spawnedObjects: updatedObjects,
|
||||
|
||||
@@ -2,11 +2,28 @@ import React, { useState } from "react";
|
||||
import ProcessCreator from "./processCreator";
|
||||
import ProcessAnimator from "./processAnimator";
|
||||
|
||||
interface ArmBotState {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
interface ProcessContainerProps {
|
||||
processes: any[];
|
||||
setProcesses: React.Dispatch<React.SetStateAction<any[]>>;
|
||||
agvRef: any;
|
||||
MaterialRef: any;
|
||||
armBots: ArmBotState[];
|
||||
setArmBots: React.Dispatch<React.SetStateAction<ArmBotState[]>>;
|
||||
}
|
||||
|
||||
const ProcessContainer: React.FC<ProcessContainerProps> = ({
|
||||
@@ -14,6 +31,8 @@ const ProcessContainer: React.FC<ProcessContainerProps> = ({
|
||||
setProcesses,
|
||||
agvRef,
|
||||
MaterialRef,
|
||||
armBots,
|
||||
setArmBots
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
@@ -23,6 +42,8 @@ const ProcessContainer: React.FC<ProcessContainerProps> = ({
|
||||
setProcesses={setProcesses}
|
||||
agvRef={agvRef}
|
||||
MaterialRef={MaterialRef}
|
||||
armBots={armBots}
|
||||
setArmBots={setArmBots}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,450 +1,3 @@
|
||||
// import React, {
|
||||
// useEffect,
|
||||
// useMemo,
|
||||
// useState,
|
||||
// useCallback,
|
||||
// useRef,
|
||||
// } from "react";
|
||||
// import { useSimulationStates } from "../../../store/store";
|
||||
// import * as THREE from "three";
|
||||
// import { useThree } from "@react-three/fiber";
|
||||
// import {
|
||||
// ConveyorEventsSchema,
|
||||
// VehicleEventsSchema,
|
||||
// } from "../../../types/world/worldTypes";
|
||||
|
||||
// // Type definitions
|
||||
// export interface PointAction {
|
||||
// uuid: string;
|
||||
// name: string;
|
||||
// type: string;
|
||||
// material: string;
|
||||
// delay: number | string;
|
||||
// spawnInterval: string | number;
|
||||
// isUsed: boolean;
|
||||
// }
|
||||
|
||||
// export interface PointTrigger {
|
||||
// uuid: string;
|
||||
// bufferTime: number;
|
||||
// name: string;
|
||||
// type: string;
|
||||
// isUsed: boolean;
|
||||
// }
|
||||
|
||||
// export interface PathPoint {
|
||||
// uuid: string;
|
||||
// position: [number, number, number];
|
||||
// actions: PointAction[];
|
||||
// triggers: PointTrigger[];
|
||||
// connections: {
|
||||
// targets: Array<{ modelUUID: string }>;
|
||||
// };
|
||||
// }
|
||||
|
||||
// export interface SimulationPath {
|
||||
// type: string;
|
||||
// modeluuid: string;
|
||||
// points: PathPoint[];
|
||||
// pathPosition: [number, number, number];
|
||||
// speed?: number;
|
||||
// }
|
||||
|
||||
// export interface Process {
|
||||
// id: string;
|
||||
// paths: SimulationPath[];
|
||||
// animationPath: THREE.Vector3[];
|
||||
// pointActions: PointAction[][];
|
||||
// pointTriggers: PointTrigger[][];
|
||||
// speed: number;
|
||||
// isActive: boolean;
|
||||
// }
|
||||
|
||||
// interface ProcessCreatorProps {
|
||||
// onProcessesCreated: (processes: Process[]) => void;
|
||||
// }
|
||||
|
||||
// // Convert event schemas to SimulationPath
|
||||
// function convertToSimulationPath(
|
||||
// path: ConveyorEventsSchema | VehicleEventsSchema
|
||||
// ): SimulationPath {
|
||||
// const { modeluuid } = path;
|
||||
|
||||
// // Normalized action handler
|
||||
// const normalizeAction = (action: any): PointAction => {
|
||||
// return { ...action }; // Return exact copy with no modifications
|
||||
// };
|
||||
|
||||
// // Normalized trigger handler
|
||||
// const normalizeTrigger = (trigger: any): PointTrigger => {
|
||||
// return { ...trigger }; // Return exact copy with no modifications
|
||||
// };
|
||||
|
||||
// if (path.type === "Conveyor") {
|
||||
// return {
|
||||
// type: path.type,
|
||||
// modeluuid,
|
||||
// points: path.points.map((point) => ({
|
||||
// uuid: point.uuid,
|
||||
// position: point.position,
|
||||
// actions: Array.isArray(point.actions)
|
||||
// ? point.actions.map(normalizeAction)
|
||||
// : point.actions
|
||||
// ? [normalizeAction(point.actions)]
|
||||
// : [],
|
||||
// triggers: Array.isArray(point.triggers)
|
||||
// ? point.triggers.map(normalizeTrigger)
|
||||
// : point.triggers
|
||||
// ? [normalizeTrigger(point.triggers)]
|
||||
// : [],
|
||||
// connections: {
|
||||
// targets: point.connections.targets.map((target) => ({
|
||||
// modelUUID: target.modelUUID,
|
||||
// })),
|
||||
// },
|
||||
// })),
|
||||
// pathPosition: path.position,
|
||||
// speed:
|
||||
// typeof path.speed === "string"
|
||||
// ? parseFloat(path.speed) || 1
|
||||
// : path.speed || 1,
|
||||
// };
|
||||
// } else {
|
||||
// // For vehicle paths, handle the case where triggers might not exist
|
||||
// return {
|
||||
// type: path.type,
|
||||
// modeluuid,
|
||||
// points: [
|
||||
// {
|
||||
// uuid: path.points.uuid,
|
||||
// position: path.points.position,
|
||||
// actions: Array.isArray(path.points.actions)
|
||||
// ? path.points.actions.map(normalizeAction)
|
||||
// : path.points.actions
|
||||
// ? [normalizeAction(path.points.actions)]
|
||||
// : [],
|
||||
// // For vehicle paths, since triggers might not exist in the schema,
|
||||
// // we always define default to an empty array
|
||||
// triggers: [],
|
||||
// connections: {
|
||||
// targets: path.points.connections.targets.map((target) => ({
|
||||
// modelUUID: target.modelUUID,
|
||||
// })),
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// pathPosition: path.position,
|
||||
// speed: path.points.speed || 1,
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Helper function to create an empty process
|
||||
// const createEmptyProcess = (): Process => ({
|
||||
// id: `process-${Math.random().toString(36).substring(2, 11)}`,
|
||||
// paths: [],
|
||||
// animationPath: [],
|
||||
// pointActions: [],
|
||||
// pointTriggers: [], // Added point triggers array
|
||||
// speed: 1,
|
||||
// isActive: false,
|
||||
// });
|
||||
|
||||
// // Enhanced connection checking function
|
||||
// function shouldReverseNextPath(
|
||||
// currentPath: SimulationPath,
|
||||
// nextPath: SimulationPath
|
||||
// ): boolean {
|
||||
// if (nextPath.points.length !== 3) return false;
|
||||
|
||||
// const currentLastPoint = currentPath.points[currentPath.points.length - 1];
|
||||
// const nextFirstPoint = nextPath.points[0];
|
||||
// const nextLastPoint = nextPath.points[nextPath.points.length - 1];
|
||||
|
||||
// // Check if current last connects to next last (requires reversal)
|
||||
// const connectsToLast = currentLastPoint.connections.targets.some(
|
||||
// (target) =>
|
||||
// target.modelUUID === nextPath.modeluuid &&
|
||||
// nextLastPoint.connections.targets.some(
|
||||
// (t) => t.modelUUID === currentPath.modeluuid
|
||||
// )
|
||||
// );
|
||||
|
||||
// // Check if current last connects to next first (no reversal needed)
|
||||
// const connectsToFirst = currentLastPoint.connections.targets.some(
|
||||
// (target) =>
|
||||
// target.modelUUID === nextPath.modeluuid &&
|
||||
// nextFirstPoint.connections.targets.some(
|
||||
// (t) => t.modelUUID === currentPath.modeluuid
|
||||
// )
|
||||
// );
|
||||
|
||||
// // Only reverse if connected to last point and not to first point
|
||||
// return connectsToLast && !connectsToFirst;
|
||||
// }
|
||||
|
||||
// // Check if a point has a spawn action
|
||||
// function hasSpawnAction(point: PathPoint): boolean {
|
||||
// return point.actions.some((action) => action.type.toLowerCase() === "spawn");
|
||||
// }
|
||||
|
||||
// // Ensure spawn point is always at the beginning of the path
|
||||
// function ensureSpawnPointIsFirst(path: SimulationPath): SimulationPath {
|
||||
// if (path.points.length !== 3) return path;
|
||||
|
||||
// // If the third point has spawn action and first doesn't, reverse the array
|
||||
// if (hasSpawnAction(path.points[2]) && !hasSpawnAction(path.points[0])) {
|
||||
// return {
|
||||
// ...path,
|
||||
// points: [...path.points].reverse(),
|
||||
// };
|
||||
// }
|
||||
|
||||
// return path;
|
||||
// }
|
||||
|
||||
// // Updated path adjustment function
|
||||
// function adjustPathPointsOrder(paths: SimulationPath[]): SimulationPath[] {
|
||||
// if (paths.length < 1) return paths;
|
||||
|
||||
// const adjustedPaths = [...paths];
|
||||
|
||||
// // First ensure all paths have spawn points at the beginning
|
||||
// for (let i = 0; i < adjustedPaths.length; i++) {
|
||||
// adjustedPaths[i] = ensureSpawnPointIsFirst(adjustedPaths[i]);
|
||||
// }
|
||||
|
||||
// // Then handle connections between paths
|
||||
// for (let i = 0; i < adjustedPaths.length - 1; i++) {
|
||||
// const currentPath = adjustedPaths[i];
|
||||
// const nextPath = adjustedPaths[i + 1];
|
||||
|
||||
// if (shouldReverseNextPath(currentPath, nextPath)) {
|
||||
// const reversedPoints = [
|
||||
// nextPath.points[2],
|
||||
// nextPath.points[1],
|
||||
// nextPath.points[0],
|
||||
// ];
|
||||
|
||||
// adjustedPaths[i + 1] = {
|
||||
// ...nextPath,
|
||||
// points: reversedPoints,
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
|
||||
// return adjustedPaths;
|
||||
// }
|
||||
|
||||
// // Main hook for process creation
|
||||
// export function useProcessCreation() {
|
||||
// const { scene } = useThree();
|
||||
// const [processes, setProcesses] = useState<Process[]>([]);
|
||||
|
||||
// const hasSpawnAction = useCallback((path: SimulationPath): boolean => {
|
||||
// if (path.type !== "Conveyor") return false;
|
||||
// return path.points.some((point) =>
|
||||
// point.actions.some((action) => action.type.toLowerCase() === "spawn")
|
||||
// );
|
||||
// }, []);
|
||||
|
||||
// const createProcess = useCallback(
|
||||
// (paths: SimulationPath[]): Process => {
|
||||
// if (!paths || paths.length === 0) {
|
||||
// return createEmptyProcess();
|
||||
// }
|
||||
|
||||
// const animationPath: THREE.Vector3[] = [];
|
||||
// const pointActions: PointAction[][] = [];
|
||||
// const pointTriggers: PointTrigger[][] = []; // Added point triggers collection
|
||||
// const processSpeed = paths[0]?.speed || 1;
|
||||
|
||||
// for (const path of paths) {
|
||||
// for (const point of path.points) {
|
||||
// if (path.type === "Conveyor") {
|
||||
// const obj = scene.getObjectByProperty("uuid", point.uuid);
|
||||
// if (!obj) {
|
||||
// console.warn(`Object with UUID ${point.uuid} not found in scene`);
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// const position = obj.getWorldPosition(new THREE.Vector3());
|
||||
// animationPath.push(position.clone());
|
||||
// pointActions.push(point.actions);
|
||||
// pointTriggers.push(point.triggers); // Collect triggers for each point
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// return {
|
||||
// id: `process-${Math.random().toString(36).substring(2, 11)}`,
|
||||
// paths,
|
||||
// animationPath,
|
||||
// pointActions,
|
||||
// pointTriggers,
|
||||
// speed: processSpeed,
|
||||
// isActive: false,
|
||||
// };
|
||||
// },
|
||||
// [scene]
|
||||
// );
|
||||
|
||||
// const getAllConnectedPaths = useCallback(
|
||||
// (
|
||||
// initialPath: SimulationPath,
|
||||
// allPaths: SimulationPath[],
|
||||
// visited: Set<string> = new Set()
|
||||
// ): SimulationPath[] => {
|
||||
// const connectedPaths: SimulationPath[] = [];
|
||||
// const queue: SimulationPath[] = [initialPath];
|
||||
// visited.add(initialPath.modeluuid);
|
||||
|
||||
// const pathMap = new Map<string, SimulationPath>();
|
||||
// allPaths.forEach((path) => pathMap.set(path.modeluuid, path));
|
||||
|
||||
// while (queue.length > 0) {
|
||||
// const currentPath = queue.shift()!;
|
||||
// connectedPaths.push(currentPath);
|
||||
|
||||
// // Process outgoing connections
|
||||
// for (const point of currentPath.points) {
|
||||
// for (const target of point.connections.targets) {
|
||||
// if (!visited.has(target.modelUUID)) {
|
||||
// const targetPath = pathMap.get(target.modelUUID);
|
||||
// if (targetPath) {
|
||||
// visited.add(target.modelUUID);
|
||||
// queue.push(targetPath);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Process incoming connections
|
||||
// for (const [uuid, path] of pathMap) {
|
||||
// if (!visited.has(uuid)) {
|
||||
// const hasConnectionToCurrent = path.points.some((point) =>
|
||||
// point.connections.targets.some(
|
||||
// (t) => t.modelUUID === currentPath.modeluuid
|
||||
// )
|
||||
// );
|
||||
// if (hasConnectionToCurrent) {
|
||||
// visited.add(uuid);
|
||||
// queue.push(path);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// return connectedPaths;
|
||||
// },
|
||||
// []
|
||||
// );
|
||||
|
||||
// const createProcessesFromPaths = useCallback(
|
||||
// (paths: SimulationPath[]): Process[] => {
|
||||
// if (!paths || paths.length === 0) return [];
|
||||
|
||||
// const visited = new Set<string>();
|
||||
// const processes: Process[] = [];
|
||||
// const pathMap = new Map<string, SimulationPath>();
|
||||
// paths.forEach((path) => pathMap.set(path.modeluuid, path));
|
||||
|
||||
// for (const path of paths) {
|
||||
// if (!visited.has(path.modeluuid) && hasSpawnAction(path)) {
|
||||
// const connectedPaths = getAllConnectedPaths(path, paths, visited);
|
||||
// const adjustedPaths = adjustPathPointsOrder(connectedPaths);
|
||||
// const process = createProcess(adjustedPaths);
|
||||
// processes.push(process);
|
||||
// }
|
||||
// }
|
||||
|
||||
// return processes;
|
||||
// },
|
||||
// [createProcess, getAllConnectedPaths, hasSpawnAction]
|
||||
// );
|
||||
|
||||
// return {
|
||||
// processes,
|
||||
// createProcessesFromPaths,
|
||||
// setProcesses,
|
||||
// };
|
||||
// }
|
||||
|
||||
// const ProcessCreator: React.FC<ProcessCreatorProps> = React.memo(
|
||||
// ({ onProcessesCreated }) => {
|
||||
// const { simulationStates } = useSimulationStates();
|
||||
// const { createProcessesFromPaths } = useProcessCreation();
|
||||
// const prevPathsRef = useRef<SimulationPath[]>([]);
|
||||
// const prevProcessesRef = useRef<Process[]>([]);
|
||||
|
||||
// const convertedPaths = useMemo((): SimulationPath[] => {
|
||||
// if (!simulationStates) return [];
|
||||
// return simulationStates.map((path) =>
|
||||
// convertToSimulationPath(
|
||||
// path as ConveyorEventsSchema | VehicleEventsSchema
|
||||
// )
|
||||
// );
|
||||
// }, [simulationStates]);
|
||||
|
||||
// // Enhanced dependency tracking that includes action and trigger types
|
||||
// const pathsDependency = useMemo(() => {
|
||||
// if (!convertedPaths) return null;
|
||||
// return convertedPaths.map((path) => ({
|
||||
// id: path.modeluuid,
|
||||
// // Track all action types for each point
|
||||
// actionSignature: path.points
|
||||
// .map((point, index) =>
|
||||
// point.actions.map((action) => `${index}-${action.type}`).join("|")
|
||||
// )
|
||||
// .join(","),
|
||||
// // Track all trigger types for each point
|
||||
// triggerSignature: path.points
|
||||
// .map((point, index) =>
|
||||
// point.triggers
|
||||
// .map((trigger) => `${index}-${trigger.type}`)
|
||||
// .join("|")
|
||||
// )
|
||||
// .join(","),
|
||||
// connections: path.points
|
||||
// .flatMap((p: PathPoint) =>
|
||||
// p.connections.targets.map((t: { modelUUID: string }) => t.modelUUID)
|
||||
// )
|
||||
// .join(","),
|
||||
// isActive: false,
|
||||
// }));
|
||||
// }, [convertedPaths]);
|
||||
|
||||
// // Force process recreation when paths change
|
||||
// useEffect(() => {
|
||||
// if (!convertedPaths || convertedPaths.length === 0) {
|
||||
// if (prevProcessesRef.current.length > 0) {
|
||||
// onProcessesCreated([]);
|
||||
// prevProcessesRef.current = [];
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // Always regenerate processes if the pathsDependency has changed
|
||||
// // This ensures action and trigger type changes will be detected
|
||||
// const newProcesses = createProcessesFromPaths(convertedPaths);
|
||||
// prevPathsRef.current = convertedPaths;
|
||||
|
||||
// // Always update processes when action or trigger types change
|
||||
// onProcessesCreated(newProcesses);
|
||||
// prevProcessesRef.current = newProcesses;
|
||||
// }, [
|
||||
// pathsDependency, // This now includes action and trigger types
|
||||
// onProcessesCreated,
|
||||
// convertedPaths,
|
||||
// createProcessesFromPaths,
|
||||
// ]);
|
||||
|
||||
// return null;
|
||||
// }
|
||||
// );
|
||||
|
||||
// export default ProcessCreator;
|
||||
|
||||
import React, {
|
||||
useEffect,
|
||||
useMemo,
|
||||
@@ -456,9 +9,10 @@ import { useSimulationStates } from "../../../store/store";
|
||||
import * as THREE from "three";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import {
|
||||
ArmBotEventsSchema,
|
||||
ConveyorEventsSchema,
|
||||
VehicleEventsSchema,
|
||||
} from "../../../types/world/worldTypes";
|
||||
} from "../../../types/simulationTypes";
|
||||
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
||||
|
||||
// Type definitions
|
||||
@@ -480,13 +34,14 @@ export interface PointTrigger {
|
||||
isUsed: boolean;
|
||||
}
|
||||
|
||||
// Update the connections type in your interfaces
|
||||
export interface PathPoint {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
actions: PointAction[];
|
||||
triggers: PointTrigger[];
|
||||
connections: {
|
||||
targets: Array<{ modelUUID: string }>;
|
||||
targets: Array<{ modelUUID: string; pointUUID?: string }>;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -498,6 +53,14 @@ export interface SimulationPath {
|
||||
speed?: number;
|
||||
isActive: boolean;
|
||||
}
|
||||
export interface ArmBot {
|
||||
type: string;
|
||||
modeluuid: string;
|
||||
points: PathPoint[];
|
||||
pathPosition: [number, number, number];
|
||||
speed?: number;
|
||||
isActive: boolean;
|
||||
}
|
||||
|
||||
export interface Process {
|
||||
id: string;
|
||||
@@ -515,7 +78,7 @@ interface ProcessCreatorProps {
|
||||
|
||||
// Convert event schemas to SimulationPath
|
||||
function convertToSimulationPath(
|
||||
path: ConveyorEventsSchema | VehicleEventsSchema
|
||||
path: ConveyorEventsSchema | VehicleEventsSchema | ArmBotEventsSchema
|
||||
): SimulationPath {
|
||||
const { modeluuid } = path;
|
||||
|
||||
@@ -539,13 +102,13 @@ function convertToSimulationPath(
|
||||
actions: Array.isArray(point.actions)
|
||||
? point.actions.map(normalizeAction)
|
||||
: point.actions
|
||||
? [normalizeAction(point.actions)]
|
||||
: [],
|
||||
? [normalizeAction(point.actions)]
|
||||
: [],
|
||||
triggers: Array.isArray(point.triggers)
|
||||
? point.triggers.map(normalizeTrigger)
|
||||
: point.triggers
|
||||
? [normalizeTrigger(point.triggers)]
|
||||
: [],
|
||||
? [normalizeTrigger(point.triggers)]
|
||||
: [],
|
||||
connections: {
|
||||
targets: point.connections.targets.map((target) => ({
|
||||
modelUUID: target.modelUUID,
|
||||
@@ -559,6 +122,36 @@ function convertToSimulationPath(
|
||||
: path.speed || 1,
|
||||
isActive: false, // Added missing property
|
||||
};
|
||||
} else if (path.type === "ArmBot") {
|
||||
return {
|
||||
type: path.type,
|
||||
modeluuid,
|
||||
points: [
|
||||
{
|
||||
uuid: path.points.uuid,
|
||||
position: path.points.position,
|
||||
actions: Array.isArray(path.points.actions)
|
||||
? path.points.actions.map(normalizeAction)
|
||||
: path.points.actions
|
||||
? [normalizeAction(path.points.actions)]
|
||||
: [],
|
||||
triggers: Array.isArray(path.points.triggers)
|
||||
? path.points.triggers.map(normalizeTrigger)
|
||||
: path.points.triggers
|
||||
? [normalizeTrigger(path.points.triggers)]
|
||||
: [],
|
||||
connections: {
|
||||
targets: path.points.connections.targets.map((target) => ({
|
||||
modelUUID: target.modelUUID,
|
||||
pointUUID: target.pointUUID, // Include if available
|
||||
})),
|
||||
},
|
||||
},
|
||||
],
|
||||
pathPosition: path.position,
|
||||
speed: path.points.actions?.speed || 1,
|
||||
isActive: false,
|
||||
};
|
||||
} else {
|
||||
// For vehicle paths, handle the case where triggers might not exist
|
||||
return {
|
||||
@@ -571,8 +164,8 @@ function convertToSimulationPath(
|
||||
actions: Array.isArray(path.points.actions)
|
||||
? path.points.actions.map(normalizeAction)
|
||||
: path.points.actions
|
||||
? [normalizeAction(path.points.actions)]
|
||||
: [],
|
||||
? [normalizeAction(path.points.actions)]
|
||||
: [],
|
||||
triggers: [],
|
||||
connections: {
|
||||
targets: path.points.connections.targets.map((target) => ({
|
||||
@@ -831,7 +424,10 @@ const ProcessCreator: React.FC<ProcessCreatorProps> = React.memo(
|
||||
if (!simulationStates) return [];
|
||||
return simulationStates.map((path) =>
|
||||
convertToSimulationPath(
|
||||
path as ConveyorEventsSchema | VehicleEventsSchema
|
||||
path as
|
||||
| ConveyorEventsSchema
|
||||
| VehicleEventsSchema
|
||||
| ArmBotEventsSchema
|
||||
)
|
||||
);
|
||||
}, [simulationStates]);
|
||||
|
||||
@@ -21,15 +21,15 @@ export interface PointAction {
|
||||
}
|
||||
|
||||
export interface ProcessPoint {
|
||||
uuid: string;
|
||||
uuid: string;
|
||||
position: number[];
|
||||
rotation: number[];
|
||||
actions: PointAction[];
|
||||
rotation: number[];
|
||||
actions: PointAction[];
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
triggers?: Trigger[];
|
||||
triggers?: Trigger[];
|
||||
}
|
||||
export interface ProcessPath {
|
||||
modeluuid: string;
|
||||
@@ -38,7 +38,7 @@ export interface ProcessPath {
|
||||
pathPosition: number[];
|
||||
pathRotation: number[];
|
||||
speed: number;
|
||||
type: "Conveyor" | "Vehicle";
|
||||
type: "Conveyor" | "Vehicle" | "ArmBot";
|
||||
isActive: boolean
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,46 +1,74 @@
|
||||
import { useState, useEffect, useRef, useMemo } from "react";
|
||||
import {
|
||||
useSelectedActionSphere,
|
||||
useSelectedPath,
|
||||
useSimulationStates,
|
||||
} from "../../store/store";
|
||||
import { useState, useRef } from "react";
|
||||
import * as THREE from "three";
|
||||
import Behaviour from "./behaviour/behaviour";
|
||||
import PathCreation from "./path/pathCreation";
|
||||
import PathConnector from "./path/pathConnector";
|
||||
import useModuleStore from "../../store/useModuleStore";
|
||||
import ProcessContainer from "./process/processContainer";
|
||||
import Agv from "../builder/agv/agv";
|
||||
import ArmBot from "./armbot/ArmBot";
|
||||
import StaticMachine from "./staticMachine/staticMachine";
|
||||
|
||||
interface ArmBotState {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
interface StaticMachineState {
|
||||
uuid: string;
|
||||
status: string;
|
||||
actions: { uuid: string; name: string; buffer: number; material: string; };
|
||||
machineTriggerId: string;
|
||||
connectedArmBot: string;
|
||||
}
|
||||
|
||||
function Simulation() {
|
||||
const { activeModule } = useModuleStore();
|
||||
const pathsGroupRef = useRef() as React.MutableRefObject<THREE.Group>;
|
||||
const [processes, setProcesses] = useState<any[]>([]);
|
||||
const agvRef = useRef([]);
|
||||
const MaterialRef = useRef([]);
|
||||
const { activeModule } = useModuleStore();
|
||||
const pathsGroupRef = useRef() as React.MutableRefObject<THREE.Group>;
|
||||
const [armBots, setArmBots] = useState<ArmBotState[]>([]);
|
||||
const [staticMachines, setStaticMachines] = useState<StaticMachineState[]>([]);
|
||||
const [processes, setProcesses] = useState<any[]>([]);
|
||||
const agvRef = useRef([]);
|
||||
const MaterialRef = useRef([]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Behaviour />
|
||||
{activeModule === "simulation" && (
|
||||
return (
|
||||
<>
|
||||
<PathCreation pathsGroupRef={pathsGroupRef} />
|
||||
<PathConnector pathsGroupRef={pathsGroupRef} />
|
||||
<ProcessContainer
|
||||
processes={processes}
|
||||
setProcesses={setProcesses}
|
||||
agvRef={agvRef}
|
||||
MaterialRef={MaterialRef}
|
||||
/>
|
||||
<Agv
|
||||
processes={processes}
|
||||
agvRef={agvRef}
|
||||
MaterialRef={MaterialRef}
|
||||
/>
|
||||
{activeModule === "simulation" && (
|
||||
<>
|
||||
<PathCreation pathsGroupRef={pathsGroupRef} />
|
||||
|
||||
<PathConnector pathsGroupRef={pathsGroupRef} />
|
||||
|
||||
<ProcessContainer
|
||||
processes={processes}
|
||||
setProcesses={setProcesses}
|
||||
agvRef={agvRef}
|
||||
MaterialRef={MaterialRef}
|
||||
armBots={armBots}
|
||||
setArmBots={setArmBots}
|
||||
/>
|
||||
|
||||
<Agv
|
||||
processes={processes}
|
||||
agvRef={agvRef}
|
||||
MaterialRef={MaterialRef}
|
||||
/>
|
||||
|
||||
</>
|
||||
)}
|
||||
<StaticMachine setArmBots={setArmBots} staticMachines={staticMachines} setStaticMachines={setStaticMachines} />
|
||||
<ArmBot armBots={armBots} setArmBots={setArmBots} setStaticMachines={setStaticMachines} />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
export default Simulation;
|
||||
|
||||
83
app/src/modules/simulation/staticMachine/staticMachine.tsx
Normal file
83
app/src/modules/simulation/staticMachine/staticMachine.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import React, { useEffect } from 'react'
|
||||
import * as SimulationTypes from '../../../types/simulationTypes';
|
||||
import { useSimulationStates } from '../../../store/store';
|
||||
import StaticMachineInstances from './staticMachineInstances';
|
||||
import { useResetButtonStore } from '../../../store/usePlayButtonStore';
|
||||
|
||||
interface ArmBotState {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
interface StaticMachineState {
|
||||
uuid: string;
|
||||
status: string;
|
||||
actions: { uuid: string; name: string; buffer: number; material: string; };
|
||||
machineTriggerId: string;
|
||||
connectedArmBot: string;
|
||||
}
|
||||
|
||||
type StaticMachineProps = {
|
||||
setArmBots: React.Dispatch<React.SetStateAction<ArmBotState[]>>;
|
||||
staticMachines: StaticMachineState[];
|
||||
setStaticMachines: React.Dispatch<React.SetStateAction<StaticMachineState[]>>;
|
||||
}
|
||||
|
||||
function StaticMachine({ setArmBots, staticMachines, setStaticMachines }: StaticMachineProps) {
|
||||
|
||||
const { simulationStates } = useSimulationStates();
|
||||
const { isReset } = useResetButtonStore();
|
||||
|
||||
useEffect(() => {
|
||||
const filtered = simulationStates.filter((s): s is SimulationTypes.StaticMachineEventsSchema => s.type === "StaticMachine");
|
||||
const initialStates: StaticMachineState[] = filtered
|
||||
.filter(machine => machine.points.connections.targets.length > 0)
|
||||
.map(machine => ({
|
||||
uuid: machine.modeluuid,
|
||||
status: "idle",
|
||||
actions: machine.points.actions,
|
||||
machineTriggerId: machine.points.triggers.uuid,
|
||||
connectedArmBot: machine.points.connections.targets[0].modelUUID
|
||||
}));
|
||||
setStaticMachines(initialStates);
|
||||
}, [simulationStates, isReset]);
|
||||
|
||||
const updateArmBotTriggerAndMachineStatus = (armBotUuid: string, triggerId: string, machineId: string) => {
|
||||
setArmBots((prevArmBots) => {
|
||||
return prevArmBots.map(bot => {
|
||||
if (bot.uuid === armBotUuid) {
|
||||
return { ...bot, triggerId: triggerId };
|
||||
}
|
||||
return bot;
|
||||
});
|
||||
});
|
||||
setStaticMachines((prevStaticMachines) => {
|
||||
return prevStaticMachines.map(machine => {
|
||||
if (machine.uuid === machineId) {
|
||||
return { ...machine, status: "idle" };
|
||||
} else {
|
||||
return machine;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{staticMachines.map((machine, index) => (
|
||||
<StaticMachineInstances key={index} machine={machine} updateArmBotTriggerAndMachineStatus={updateArmBotTriggerAndMachineStatus} />
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default StaticMachine;
|
||||
@@ -0,0 +1,33 @@
|
||||
import React, { useEffect } from 'react'
|
||||
import { useAnimationPlaySpeed } from '../../../store/usePlayButtonStore';
|
||||
|
||||
interface StaticMachineState {
|
||||
uuid: string;
|
||||
status: string;
|
||||
actions: { uuid: string; name: string; buffer: number; material: string; };
|
||||
machineTriggerId: string;
|
||||
connectedArmBot: string;
|
||||
}
|
||||
|
||||
type StaticMachineInstancesProps = {
|
||||
machine: StaticMachineState,
|
||||
updateArmBotTriggerAndMachineStatus: (armBotUuid: string, triggerId: string, machineId: string) => void;
|
||||
}
|
||||
|
||||
function StaticMachineInstances({ machine, updateArmBotTriggerAndMachineStatus }: StaticMachineInstancesProps) {
|
||||
const { speed } = useAnimationPlaySpeed();
|
||||
|
||||
useEffect(() => {
|
||||
if (machine.status === 'running') {
|
||||
setTimeout(() => {
|
||||
updateArmBotTriggerAndMachineStatus(machine.connectedArmBot, machine.machineTriggerId, machine.uuid);
|
||||
}, machine.actions.buffer * 1000 * speed);
|
||||
}
|
||||
}, [machine])
|
||||
|
||||
return (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
|
||||
export default StaticMachineInstances
|
||||
@@ -104,8 +104,8 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||
setShowLeftArrow(isOverflowing && canScrollLeft);
|
||||
setShowRightArrow(isOverflowing && canScrollRight);
|
||||
|
||||
console.log('canScrollRight: ', canScrollRight);
|
||||
console.log('isOverflowing: ', isOverflowing);
|
||||
// console.log('canScrollRight: ', canScrollRight);
|
||||
// console.log('isOverflowing: ', isOverflowing);
|
||||
|
||||
}
|
||||
}, []);
|
||||
|
||||
@@ -100,6 +100,8 @@ export const DraggableWidget = ({
|
||||
|
||||
const deleteSelectedChart = async () => {
|
||||
try {
|
||||
console.log("delete");
|
||||
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0];
|
||||
let deleteWidget = {
|
||||
@@ -109,7 +111,9 @@ export const DraggableWidget = ({
|
||||
};
|
||||
|
||||
if (visualizationSocket) {
|
||||
setSelectedChartId(null)
|
||||
visualizationSocket.emit("v2:viz-widget:delete", deleteWidget);
|
||||
console.log("delete widget",selectedChartId);
|
||||
}
|
||||
const updatedWidgets = selectedZone.widgets.filter(
|
||||
(w: Widget) => w.id !== widget.id
|
||||
@@ -120,7 +124,6 @@ export const DraggableWidget = ({
|
||||
widgets: updatedWidgets,
|
||||
}));
|
||||
setOpenKebabId(null);
|
||||
|
||||
// const response = await deleteWidgetApi(widget.id, organization);
|
||||
// if (response?.message === "Widget deleted successfully") {
|
||||
// const updatedWidgets = selectedZone.widgets.filter(
|
||||
@@ -175,6 +178,7 @@ export const DraggableWidget = ({
|
||||
|
||||
const duplicatedWidget: Widget = {
|
||||
...widget,
|
||||
title: name === '' ? widget.title : name,
|
||||
Data: {
|
||||
duration: duration,
|
||||
measurements: { ...measurements },
|
||||
@@ -187,6 +191,7 @@ export const DraggableWidget = ({
|
||||
zoneId: selectedZone.zoneId,
|
||||
widget: duplicatedWidget,
|
||||
};
|
||||
|
||||
if (visualizationSocket) {
|
||||
visualizationSocket.emit("v2:viz-widget:add", duplicateWidget);
|
||||
}
|
||||
@@ -306,7 +311,10 @@ export const DraggableWidget = ({
|
||||
: undefined,
|
||||
}}
|
||||
ref={chartWidget}
|
||||
onClick={() => setSelectedChartId(widget)}
|
||||
onClick={() => {setSelectedChartId(widget)
|
||||
console.log('click');
|
||||
|
||||
}}
|
||||
>
|
||||
{/* Kebab Icon */}
|
||||
<div className="icon kebab" onClick={handleKebabClick}>
|
||||
@@ -327,7 +335,10 @@ export const DraggableWidget = ({
|
||||
</div>
|
||||
<div className="label">Duplicate</div>
|
||||
</div>
|
||||
<div className="edit btn" onClick={deleteSelectedChart}>
|
||||
<div className="edit btn" onClick={(e)=>{
|
||||
e.stopPropagation()
|
||||
deleteSelectedChart();
|
||||
}}>
|
||||
<div className="icon">
|
||||
<DeleteIcon />
|
||||
</div>
|
||||
|
||||
@@ -520,37 +520,37 @@ const DroppedObjects: React.FC = () => {
|
||||
onPointerUp={handlePointerUp}
|
||||
className="floating-wrapper"
|
||||
>
|
||||
{zone.objects.map((obj, index) => {
|
||||
{zone?.objects?.map((obj, index) => {
|
||||
const topPosition =
|
||||
typeof obj.position.top === "number"
|
||||
? `calc(${obj.position.top}px + ${
|
||||
isPlaying && selectedZone.activeSides.includes("top")
|
||||
typeof obj?.position?.top === "number"
|
||||
? `calc(${obj?.position?.top}px + ${
|
||||
isPlaying && selectedZone?.activeSides?.includes("top")
|
||||
? `${heightMultiplier - 55}px`
|
||||
: "0px"
|
||||
})`
|
||||
: "auto";
|
||||
|
||||
const leftPosition =
|
||||
typeof obj.position.left === "number"
|
||||
? `calc(${obj.position.left}px + ${
|
||||
isPlaying && selectedZone.activeSides.includes("left")
|
||||
typeof obj?.position?.left === "number"
|
||||
? `calc(${obj?.position?.left}px + ${
|
||||
isPlaying && selectedZone?.activeSides?.includes("left")
|
||||
? `${widthMultiplier - 150}px`
|
||||
: "0px"
|
||||
})`
|
||||
: "auto";
|
||||
|
||||
const rightPosition =
|
||||
typeof obj.position.right === "number"
|
||||
? `calc(${obj.position.right}px + ${
|
||||
isPlaying && selectedZone.activeSides.includes("right")
|
||||
typeof obj?.position?.right === "number"
|
||||
? `calc(${obj?.position?.right}px + ${
|
||||
isPlaying && selectedZone?.activeSides?.includes("right")
|
||||
? `${widthMultiplier - 150}px`
|
||||
: "0px"
|
||||
})`
|
||||
: "auto";
|
||||
const bottomPosition =
|
||||
typeof obj.position.bottom === "number"
|
||||
? `calc(${obj.position.bottom}px + ${
|
||||
isPlaying && selectedZone.activeSides.includes("bottom")
|
||||
typeof obj?.position?.bottom === "number"
|
||||
? `calc(${obj?.position?.bottom}px + ${
|
||||
isPlaying && selectedZone?.activeSides?.includes("bottom")
|
||||
? `${heightMultiplier - 55}px`
|
||||
: "0px"
|
||||
})`
|
||||
@@ -558,7 +558,7 @@ const DroppedObjects: React.FC = () => {
|
||||
|
||||
return (
|
||||
<div
|
||||
key={`${zoneName}-${index}`}
|
||||
key={obj.id}
|
||||
className={`${obj.className} ${
|
||||
selectedChartId?.id === obj.id && "activeChart"
|
||||
} `}
|
||||
|
||||
@@ -26,7 +26,7 @@ import KeyPressListener from "../utils/shortcutkeys/handleShortcutKeys";
|
||||
|
||||
const Project: React.FC = () => {
|
||||
let navigate = useNavigate();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { activeModule, setActiveModule } = useModuleStore();
|
||||
const { loadingProgress } = useLoadingProgress();
|
||||
const { setUserName } = useUserName();
|
||||
const { setOrganization } = useOrganization();
|
||||
@@ -38,6 +38,7 @@ const Project: React.FC = () => {
|
||||
setFloorItems([]);
|
||||
setWallItems([]);
|
||||
setZones([]);
|
||||
setActiveModule('builder')
|
||||
const email = localStorage.getItem("email");
|
||||
if (email) {
|
||||
const Organization = email!.split("@")[1].split(".")[0];
|
||||
|
||||
@@ -1,500 +1,479 @@
|
||||
import * as THREE from "three";
|
||||
import * as Types from "../types/world/worldTypes";
|
||||
import * as SimulationTypes from "../types/simulationTypes";
|
||||
import { create } from "zustand";
|
||||
import { io } from "socket.io-client";
|
||||
|
||||
export const useSocketStore = create<any>((set: any, get: any) => ({
|
||||
socket: null,
|
||||
initializeSocket: (email: string, organization: string) => {
|
||||
const existingSocket = get().socket;
|
||||
if (existingSocket) {
|
||||
return;
|
||||
}
|
||||
socket: null,
|
||||
initializeSocket: (email: string, organization: string) => {
|
||||
const existingSocket = get().socket;
|
||||
if (existingSocket) {
|
||||
return;
|
||||
}
|
||||
|
||||
const socket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`,
|
||||
{
|
||||
reconnection: true,
|
||||
auth: { email, organization },
|
||||
}
|
||||
);
|
||||
const socket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`,
|
||||
{
|
||||
reconnection: true,
|
||||
auth: { email, organization },
|
||||
}
|
||||
);
|
||||
|
||||
const visualizationSocket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization`,
|
||||
{
|
||||
reconnection: true,
|
||||
auth: { email, organization },
|
||||
}
|
||||
);
|
||||
const visualizationSocket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization`,
|
||||
{
|
||||
reconnection: true,
|
||||
auth: { email, organization },
|
||||
}
|
||||
);
|
||||
|
||||
set({ socket, visualizationSocket });
|
||||
},
|
||||
disconnectSocket: () => {
|
||||
set((state: any) => {
|
||||
state.socket?.disconnect();
|
||||
state.visualizationSocket?.disconnect();
|
||||
return { socket: null };
|
||||
});
|
||||
},
|
||||
set({ socket, visualizationSocket });
|
||||
},
|
||||
disconnectSocket: () => {
|
||||
set((state: any) => {
|
||||
state.socket?.disconnect();
|
||||
state.visualizationSocket?.disconnect();
|
||||
return { socket: null };
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
||||
export const useLoadingProgress = create<{
|
||||
loadingProgress: number;
|
||||
setLoadingProgress: (x: number) => void;
|
||||
loadingProgress: number;
|
||||
setLoadingProgress: (x: number) => void;
|
||||
}>((set) => ({
|
||||
loadingProgress: 1,
|
||||
setLoadingProgress: (x: number) => set({ loadingProgress: x }),
|
||||
loadingProgress: 1,
|
||||
setLoadingProgress: (x: number) => set({ loadingProgress: x }),
|
||||
}));
|
||||
|
||||
export const useOrganization = create<any>((set: any) => ({
|
||||
organization: "",
|
||||
setOrganization: (x: any) => set(() => ({ organization: x })),
|
||||
organization: "",
|
||||
setOrganization: (x: any) => set(() => ({ organization: x })),
|
||||
}));
|
||||
|
||||
export const useToggleView = create<any>((set: any) => ({
|
||||
toggleView: false,
|
||||
setToggleView: (x: any) => set(() => ({ toggleView: x })),
|
||||
toggleView: false,
|
||||
setToggleView: (x: any) => set(() => ({ toggleView: x })),
|
||||
}));
|
||||
|
||||
export const useUpdateScene = create<any>((set: any) => ({
|
||||
updateScene: false,
|
||||
setUpdateScene: (x: any) => set(() => ({ updateScene: x })),
|
||||
updateScene: false,
|
||||
setUpdateScene: (x: any) => set(() => ({ updateScene: x })),
|
||||
}));
|
||||
|
||||
export const useWalls = create<any>((set: any) => ({
|
||||
walls: [],
|
||||
setWalls: (x: any) => set(() => ({ walls: x })),
|
||||
walls: [],
|
||||
setWalls: (x: any) => set(() => ({ walls: x })),
|
||||
}));
|
||||
|
||||
export const useZones = create<any>((set: any) => ({
|
||||
zones: [],
|
||||
setZones: (callback: any) =>
|
||||
set((state: any) => ({
|
||||
zones: typeof callback === "function" ? callback(state.zones) : callback,
|
||||
})),
|
||||
zones: [],
|
||||
setZones: (callback: any) =>
|
||||
set((state: any) => ({
|
||||
zones: typeof callback === "function" ? callback(state.zones) : callback,
|
||||
})),
|
||||
}));
|
||||
|
||||
interface ZonePointsState {
|
||||
zonePoints: THREE.Vector3[];
|
||||
setZonePoints: (points: THREE.Vector3[]) => void;
|
||||
zonePoints: THREE.Vector3[];
|
||||
setZonePoints: (points: THREE.Vector3[]) => void;
|
||||
}
|
||||
|
||||
export const useZonePoints = create<ZonePointsState>((set) => ({
|
||||
zonePoints: [],
|
||||
setZonePoints: (points) => set({ zonePoints: points }),
|
||||
zonePoints: [],
|
||||
setZonePoints: (points) => set({ zonePoints: points }),
|
||||
}));
|
||||
|
||||
export const useSelectedItem = create<any>((set: any) => ({
|
||||
selectedItem: { name: "", id: "" },
|
||||
setSelectedItem: (x: any) => set(() => ({ selectedItem: x })),
|
||||
selectedItem: { name: "", id: "" },
|
||||
setSelectedItem: (x: any) => set(() => ({ selectedItem: x })),
|
||||
}));
|
||||
|
||||
export const useSelectedAssets = create<any>((set: any) => ({
|
||||
selectedAssets: [],
|
||||
setSelectedAssets: (x: any) => set(() => ({ selectedAssets: x })),
|
||||
selectedAssets: [],
|
||||
setSelectedAssets: (x: any) => set(() => ({ selectedAssets: x })),
|
||||
}));
|
||||
|
||||
export const useLayers = create<any>((set: any) => ({
|
||||
Layers: 1,
|
||||
setLayers: (x: any) => set(() => ({ Layers: x })),
|
||||
Layers: 1,
|
||||
setLayers: (x: any) => set(() => ({ Layers: x })),
|
||||
}));
|
||||
|
||||
export const useCamPosition = create<any>((set: any) => ({
|
||||
camPosition: { x: undefined, y: undefined, z: undefined },
|
||||
setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }),
|
||||
camPosition: { x: undefined, y: undefined, z: undefined },
|
||||
setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }),
|
||||
}));
|
||||
|
||||
export const useMenuVisible = create<any>((set: any) => ({
|
||||
menuVisible: false,
|
||||
setMenuVisible: (x: any) => set(() => ({ menuVisible: x })),
|
||||
menuVisible: false,
|
||||
setMenuVisible: (x: any) => set(() => ({ menuVisible: x })),
|
||||
}));
|
||||
|
||||
export const useDeleteTool = create<any>((set: any) => ({
|
||||
deleteTool: false,
|
||||
setDeleteTool: (x: any) => set(() => ({ deleteTool: x })),
|
||||
deleteTool: false,
|
||||
setDeleteTool: (x: any) => set(() => ({ deleteTool: x })),
|
||||
}));
|
||||
|
||||
export const useToolMode = create<any>((set: any) => ({
|
||||
toolMode: null,
|
||||
setToolMode: (x: any) => set(() => ({ toolMode: x })),
|
||||
toolMode: null,
|
||||
setToolMode: (x: any) => set(() => ({ toolMode: x })),
|
||||
}));
|
||||
|
||||
export const useNewLines = create<any>((set: any) => ({
|
||||
newLines: [],
|
||||
setNewLines: (x: any) => set(() => ({ newLines: x })),
|
||||
newLines: [],
|
||||
setNewLines: (x: any) => set(() => ({ newLines: x })),
|
||||
}));
|
||||
|
||||
export const useDeletedLines = create<any>((set: any) => ({
|
||||
deletedLines: [],
|
||||
setDeletedLines: (x: any) => set(() => ({ deletedLines: x })),
|
||||
deletedLines: [],
|
||||
setDeletedLines: (x: any) => set(() => ({ deletedLines: x })),
|
||||
}));
|
||||
|
||||
export const useMovePoint = create<any>((set: any) => ({
|
||||
movePoint: false,
|
||||
setMovePoint: (x: any) => set(() => ({ movePoint: x })),
|
||||
movePoint: false,
|
||||
setMovePoint: (x: any) => set(() => ({ movePoint: x })),
|
||||
}));
|
||||
|
||||
export const useTransformMode = create<any>((set: any) => ({
|
||||
transformMode: null,
|
||||
setTransformMode: (x: any) => set(() => ({ transformMode: x })),
|
||||
transformMode: null,
|
||||
setTransformMode: (x: any) => set(() => ({ transformMode: x })),
|
||||
}));
|
||||
|
||||
export const useDeletePointOrLine = create<any>((set: any) => ({
|
||||
deletePointOrLine: false,
|
||||
setDeletePointOrLine: (x: any) => set(() => ({ deletePointOrLine: x })),
|
||||
deletePointOrLine: false,
|
||||
setDeletePointOrLine: (x: any) => set(() => ({ deletePointOrLine: x })),
|
||||
}));
|
||||
|
||||
export const useFloorItems = create<any>((set: any) => ({
|
||||
floorItems: null,
|
||||
setFloorItems: (callback: any) =>
|
||||
set((state: any) => ({
|
||||
floorItems:
|
||||
typeof callback === "function" ? callback(state.floorItems) : callback,
|
||||
})),
|
||||
floorItems: null,
|
||||
setFloorItems: (callback: any) =>
|
||||
set((state: any) => ({
|
||||
floorItems:
|
||||
typeof callback === "function" ? callback(state.floorItems) : callback,
|
||||
})),
|
||||
}));
|
||||
|
||||
export const useWallItems = create<any>((set: any) => ({
|
||||
wallItems: [],
|
||||
setWallItems: (callback: any) =>
|
||||
set((state: any) => ({
|
||||
wallItems:
|
||||
typeof callback === "function" ? callback(state.wallItems) : callback,
|
||||
})),
|
||||
wallItems: [],
|
||||
setWallItems: (callback: any) =>
|
||||
set((state: any) => ({
|
||||
wallItems:
|
||||
typeof callback === "function" ? callback(state.wallItems) : callback,
|
||||
})),
|
||||
}));
|
||||
|
||||
export const useSelectedWallItem = create<any>((set: any) => ({
|
||||
selectedWallItem: null,
|
||||
setSelectedWallItem: (x: any) => set(() => ({ selectedWallItem: x })),
|
||||
selectedWallItem: null,
|
||||
setSelectedWallItem: (x: any) => set(() => ({ selectedWallItem: x })),
|
||||
}));
|
||||
|
||||
export const useSelectedFloorItem = create<any>((set: any) => ({
|
||||
selectedFloorItem: null,
|
||||
setSelectedFloorItem: (x: any) => set(() => ({ selectedFloorItem: x })),
|
||||
selectedFloorItem: null,
|
||||
setSelectedFloorItem: (x: any) => set(() => ({ selectedFloorItem: x })),
|
||||
}));
|
||||
|
||||
export const useDeletableFloorItem = create<any>((set: any) => ({
|
||||
deletableFloorItem: null,
|
||||
setDeletableFloorItem: (x: any) => set(() => ({ deletableFloorItem: x })),
|
||||
deletableFloorItem: null,
|
||||
setDeletableFloorItem: (x: any) => set(() => ({ deletableFloorItem: x })),
|
||||
}));
|
||||
|
||||
export const useSetScale = create<any>((set: any) => ({
|
||||
scale: null,
|
||||
setScale: (x: any) => set(() => ({ scale: x })),
|
||||
scale: null,
|
||||
setScale: (x: any) => set(() => ({ scale: x })),
|
||||
}));
|
||||
|
||||
export const useRoofVisibility = create<any>((set: any) => ({
|
||||
roofVisibility: false,
|
||||
setRoofVisibility: (x: any) => set(() => ({ roofVisibility: x })),
|
||||
roofVisibility: false,
|
||||
setRoofVisibility: (x: any) => set(() => ({ roofVisibility: x })),
|
||||
}));
|
||||
|
||||
export const useWallVisibility = create<any>((set: any) => ({
|
||||
wallVisibility: false,
|
||||
setWallVisibility: (x: any) => set(() => ({ wallVisibility: x })),
|
||||
wallVisibility: false,
|
||||
setWallVisibility: (x: any) => set(() => ({ wallVisibility: x })),
|
||||
}));
|
||||
|
||||
export const useShadows = create<any>((set: any) => ({
|
||||
shadows: false,
|
||||
setShadows: (x: any) => set(() => ({ shadows: x })),
|
||||
shadows: false,
|
||||
setShadows: (x: any) => set(() => ({ shadows: x })),
|
||||
}));
|
||||
|
||||
export const useSunPosition = create<any>((set: any) => ({
|
||||
sunPosition: { x: undefined, y: undefined, z: undefined },
|
||||
setSunPosition: (newSuntPosition: any) =>
|
||||
set({ sunPosition: newSuntPosition }),
|
||||
sunPosition: { x: undefined, y: undefined, z: undefined },
|
||||
setSunPosition: (newSuntPosition: any) =>
|
||||
set({ sunPosition: newSuntPosition }),
|
||||
}));
|
||||
|
||||
export const useRemoveLayer = create<any>((set: any) => ({
|
||||
removeLayer: false,
|
||||
setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })),
|
||||
removeLayer: false,
|
||||
setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })),
|
||||
}));
|
||||
|
||||
export const useRemovedLayer = create<any>((set: any) => ({
|
||||
removedLayer: null,
|
||||
setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })),
|
||||
removedLayer: null,
|
||||
setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })),
|
||||
}));
|
||||
|
||||
export const useActiveLayer = create<any>((set: any) => ({
|
||||
activeLayer: 1,
|
||||
setActiveLayer: (x: any) => set({ activeLayer: x }),
|
||||
activeLayer: 1,
|
||||
setActiveLayer: (x: any) => set({ activeLayer: x }),
|
||||
}));
|
||||
|
||||
interface RefTextUpdateState {
|
||||
refTextupdate: number;
|
||||
setRefTextUpdate: (
|
||||
callback: (currentValue: number) => number | number
|
||||
) => void;
|
||||
refTextupdate: number;
|
||||
setRefTextUpdate: (
|
||||
callback: (currentValue: number) => number | number
|
||||
) => void;
|
||||
}
|
||||
|
||||
export const useRefTextUpdate = create<RefTextUpdateState>((set) => ({
|
||||
refTextupdate: -1000,
|
||||
setRefTextUpdate: (callback) =>
|
||||
set((state) => ({
|
||||
refTextupdate:
|
||||
typeof callback === "function"
|
||||
? callback(state.refTextupdate)
|
||||
: callback,
|
||||
})),
|
||||
refTextupdate: -1000,
|
||||
setRefTextUpdate: (callback) =>
|
||||
set((state) => ({
|
||||
refTextupdate:
|
||||
typeof callback === "function"
|
||||
? callback(state.refTextupdate)
|
||||
: callback,
|
||||
})),
|
||||
}));
|
||||
|
||||
export const useResetCamera = create<any>((set: any) => ({
|
||||
resetCamera: false,
|
||||
setResetCamera: (x: any) => set({ resetCamera: x }),
|
||||
resetCamera: false,
|
||||
setResetCamera: (x: any) => set({ resetCamera: x }),
|
||||
}));
|
||||
|
||||
export const useAddAction = create<any>((set: any) => ({
|
||||
addAction: null,
|
||||
setAddAction: (x: any) => set({ addAction: x }),
|
||||
addAction: null,
|
||||
setAddAction: (x: any) => set({ addAction: x }),
|
||||
}));
|
||||
|
||||
export const useActiveTool = create<any>((set: any) => ({
|
||||
activeTool: "cursor",
|
||||
setActiveTool: (x: any) => set({ activeTool: x }),
|
||||
activeTool: "cursor",
|
||||
setActiveTool: (x: any) => set({ activeTool: x }),
|
||||
}));
|
||||
|
||||
export const useActiveSubTool = create<any>((set: any) => ({
|
||||
activeSubTool: "cursor",
|
||||
setActiveSubTool: (x: any) => set({ activeSubTool: x }),
|
||||
activeSubTool: "cursor",
|
||||
setActiveSubTool: (x: any) => set({ activeSubTool: x }),
|
||||
}));
|
||||
|
||||
export const use2DUndoRedo = create<any>((set: any) => ({
|
||||
is2DUndoRedo: null,
|
||||
set2DUndoRedo: (x: any) => set({ is2DUndoRedo: x }),
|
||||
is2DUndoRedo: null,
|
||||
set2DUndoRedo: (x: any) => set({ is2DUndoRedo: x }),
|
||||
}));
|
||||
|
||||
export const useElevation = create<any>((set: any) => ({
|
||||
elevation: 45,
|
||||
setElevation: (x: any) => set({ elevation: x }),
|
||||
elevation: 45,
|
||||
setElevation: (x: any) => set({ elevation: x }),
|
||||
}));
|
||||
|
||||
export const useAzimuth = create<any>((set: any) => ({
|
||||
azimuth: -160,
|
||||
setAzimuth: (x: any) => set({ azimuth: x }),
|
||||
azimuth: -160,
|
||||
setAzimuth: (x: any) => set({ azimuth: x }),
|
||||
}));
|
||||
|
||||
export const useRenderDistance = create<any>((set: any) => ({
|
||||
renderDistance: 40,
|
||||
setRenderDistance: (x: any) => set({ renderDistance: x }),
|
||||
renderDistance: 40,
|
||||
setRenderDistance: (x: any) => set({ renderDistance: x }),
|
||||
}));
|
||||
|
||||
export const useCamMode = create<any>((set: any) => ({
|
||||
camMode: "ThirdPerson",
|
||||
setCamMode: (x: any) => set({ camMode: x }),
|
||||
camMode: "ThirdPerson",
|
||||
setCamMode: (x: any) => set({ camMode: x }),
|
||||
}));
|
||||
|
||||
export const useUserName = create<any>((set: any) => ({
|
||||
userName: "",
|
||||
setUserName: (x: any) => set({ userName: x }),
|
||||
userName: "",
|
||||
setUserName: (x: any) => set({ userName: x }),
|
||||
}));
|
||||
|
||||
export const useObjectPosition = create<any>((set: any) => ({
|
||||
objectPosition: { x: undefined, y: undefined, z: undefined },
|
||||
setObjectPosition: (newObjectPosition: any) =>
|
||||
set({ objectPosition: newObjectPosition }),
|
||||
objectPosition: { x: undefined, y: undefined, z: undefined },
|
||||
setObjectPosition: (newObjectPosition: any) =>
|
||||
set({ objectPosition: newObjectPosition }),
|
||||
}));
|
||||
|
||||
export const useObjectScale = create<any>((set: any) => ({
|
||||
objectScale: { x: undefined, y: undefined, z: undefined },
|
||||
setObjectScale: (newObjectScale: any) => set({ objectScale: newObjectScale }),
|
||||
objectScale: { x: undefined, y: undefined, z: undefined },
|
||||
setObjectScale: (newObjectScale: any) => set({ objectScale: newObjectScale }),
|
||||
}));
|
||||
|
||||
export const useObjectRotation = create<any>((set: any) => ({
|
||||
objectRotation: { x: undefined, y: undefined, z: undefined },
|
||||
setObjectRotation: (newObjectRotation: any) =>
|
||||
set({ objectRotation: newObjectRotation }),
|
||||
objectRotation: { x: undefined, y: undefined, z: undefined },
|
||||
setObjectRotation: (newObjectRotation: any) =>
|
||||
set({ objectRotation: newObjectRotation }),
|
||||
}));
|
||||
|
||||
export const useDrieTemp = create<any>((set: any) => ({
|
||||
drieTemp: undefined,
|
||||
setDrieTemp: (x: any) => set({ drieTemp: x }),
|
||||
drieTemp: undefined,
|
||||
setDrieTemp: (x: any) => set({ drieTemp: x }),
|
||||
}));
|
||||
|
||||
export const useActiveUsers = create<any>((set: any) => ({
|
||||
activeUsers: [],
|
||||
setActiveUsers: (callback: (prev: any[]) => any[] | any[]) =>
|
||||
set((state: { activeUsers: any[] }) => ({
|
||||
activeUsers:
|
||||
typeof callback === "function" ? callback(state.activeUsers) : callback,
|
||||
})),
|
||||
activeUsers: [],
|
||||
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) => ({
|
||||
drieUIValue: { touch: null, temperature: null, humidity: null },
|
||||
drieUIValue: { touch: null, temperature: null, humidity: null },
|
||||
|
||||
setDrieUIValue: (x: any) =>
|
||||
set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })),
|
||||
setDrieUIValue: (x: any) =>
|
||||
set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })),
|
||||
|
||||
setTouch: (value: any) =>
|
||||
set((state: any) => ({
|
||||
drieUIValue: { ...state.drieUIValue, touch: value },
|
||||
})),
|
||||
setTemperature: (value: any) =>
|
||||
set((state: any) => ({
|
||||
drieUIValue: { ...state.drieUIValue, temperature: value },
|
||||
})),
|
||||
setHumidity: (value: any) =>
|
||||
set((state: any) => ({
|
||||
drieUIValue: { ...state.drieUIValue, humidity: value },
|
||||
})),
|
||||
setTouch: (value: any) =>
|
||||
set((state: any) => ({
|
||||
drieUIValue: { ...state.drieUIValue, touch: value },
|
||||
})),
|
||||
setTemperature: (value: any) =>
|
||||
set((state: any) => ({
|
||||
drieUIValue: { ...state.drieUIValue, temperature: value },
|
||||
})),
|
||||
setHumidity: (value: any) =>
|
||||
set((state: any) => ({
|
||||
drieUIValue: { ...state.drieUIValue, humidity: value },
|
||||
})),
|
||||
}));
|
||||
|
||||
export const useDrawMaterialPath = create<any>((set: any) => ({
|
||||
drawMaterialPath: false,
|
||||
setDrawMaterialPath: (x: any) => set({ drawMaterialPath: x }),
|
||||
drawMaterialPath: false,
|
||||
setDrawMaterialPath: (x: any) => set({ drawMaterialPath: x }),
|
||||
}));
|
||||
|
||||
export const useSelectedActionSphere = create<any>((set: any) => ({
|
||||
selectedActionSphere: undefined,
|
||||
setSelectedActionSphere: (x: any) => set({ selectedActionSphere: x }),
|
||||
selectedActionSphere: undefined,
|
||||
setSelectedActionSphere: (x: any) => set({ selectedActionSphere: x }),
|
||||
}));
|
||||
|
||||
export const useSelectedPath = create<any>((set: any) => ({
|
||||
selectedPath: undefined,
|
||||
setSelectedPath: (x: any) => set({ selectedPath: x }),
|
||||
selectedPath: undefined,
|
||||
setSelectedPath: (x: any) => set({ selectedPath: x }),
|
||||
}));
|
||||
|
||||
interface SimulationPathsStore {
|
||||
simulationStates: (
|
||||
| Types.ConveyorEventsSchema
|
||||
| Types.VehicleEventsSchema
|
||||
| Types.StaticMachineEventsSchema
|
||||
| Types.ArmBotEventsSchema
|
||||
)[];
|
||||
setSimulationStates: (
|
||||
paths:
|
||||
| (
|
||||
| Types.ConveyorEventsSchema
|
||||
| Types.VehicleEventsSchema
|
||||
| Types.StaticMachineEventsSchema
|
||||
| Types.ArmBotEventsSchema
|
||||
)[]
|
||||
| ((
|
||||
prev: (
|
||||
| Types.ConveyorEventsSchema
|
||||
| Types.VehicleEventsSchema
|
||||
| Types.StaticMachineEventsSchema
|
||||
| Types.ArmBotEventsSchema
|
||||
)[]
|
||||
) => (
|
||||
| Types.ConveyorEventsSchema
|
||||
| Types.VehicleEventsSchema
|
||||
| Types.StaticMachineEventsSchema
|
||||
| Types.ArmBotEventsSchema
|
||||
)[])
|
||||
) => void;
|
||||
simulationStates: (SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[];
|
||||
setSimulationStates: (
|
||||
paths: (| SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[]
|
||||
| ((prev: (| SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[])
|
||||
=> (| SimulationTypes.ConveyorEventsSchema | SimulationTypes.VehicleEventsSchema | SimulationTypes.StaticMachineEventsSchema | SimulationTypes.ArmBotEventsSchema)[])
|
||||
) => void;
|
||||
}
|
||||
|
||||
export const useSimulationStates = create<SimulationPathsStore>((set) => ({
|
||||
simulationStates: [],
|
||||
setSimulationStates: (paths) =>
|
||||
set((state) => ({
|
||||
simulationStates:
|
||||
typeof paths === "function" ? paths(state.simulationStates) : paths,
|
||||
})),
|
||||
simulationStates: [],
|
||||
setSimulationStates: (paths) =>
|
||||
set((state) => ({
|
||||
simulationStates:
|
||||
typeof paths === "function" ? paths(state.simulationStates) : paths,
|
||||
})),
|
||||
}));
|
||||
|
||||
export const useNavMesh = create<any>((set: any) => ({
|
||||
navMesh: null,
|
||||
setNavMesh: (x: any) => set({ navMesh: x }),
|
||||
navMesh: null,
|
||||
setNavMesh: (x: any) => set({ navMesh: x }),
|
||||
}));
|
||||
|
||||
export const useIsConnecting = create<any>((set: any) => ({
|
||||
isConnecting: false,
|
||||
setIsConnecting: (x: any) => set({ isConnecting: x }),
|
||||
isConnecting: false,
|
||||
setIsConnecting: (x: any) => set({ isConnecting: x }),
|
||||
}));
|
||||
|
||||
export const useStartSimulation = create<any>((set: any) => ({
|
||||
startSimulation: false,
|
||||
setStartSimulation: (x: any) => set({ startSimulation: x }),
|
||||
startSimulation: false,
|
||||
setStartSimulation: (x: any) => set({ startSimulation: x }),
|
||||
}));
|
||||
|
||||
export const useEyeDropMode = create<any>((set: any) => ({
|
||||
eyeDropMode: false,
|
||||
setEyeDropMode: (x: any) => set({ eyeDropMode: x }),
|
||||
eyeDropMode: false,
|
||||
setEyeDropMode: (x: any) => set({ eyeDropMode: x }),
|
||||
}));
|
||||
|
||||
export const useEditingPoint = create<any>((set: any) => ({
|
||||
editingPoint: false,
|
||||
setEditingPoint: (x: any) => set({ editingPoint: x }),
|
||||
editingPoint: false,
|
||||
setEditingPoint: (x: any) => set({ editingPoint: x }),
|
||||
}));
|
||||
|
||||
export const usePreviewPosition = create<{
|
||||
previewPosition: { x: number; y: number } | null;
|
||||
setPreviewPosition: (position: { x: number; y: number } | null) => void;
|
||||
previewPosition: { x: number; y: number } | null;
|
||||
setPreviewPosition: (position: { x: number; y: number } | null) => void;
|
||||
}>((set) => ({
|
||||
previewPosition: null,
|
||||
setPreviewPosition: (position) => set({ previewPosition: position }),
|
||||
previewPosition: null,
|
||||
setPreviewPosition: (position) => set({ previewPosition: position }),
|
||||
}));
|
||||
|
||||
export const usezoneTarget = create<any>((set: any) => ({
|
||||
zoneTarget: [],
|
||||
setZoneTarget: (x: any) => set({ zoneTarget: x }),
|
||||
zoneTarget: [],
|
||||
setZoneTarget: (x: any) => set({ zoneTarget: x }),
|
||||
}));
|
||||
|
||||
export const usezonePosition = create<any>((set: any) => ({
|
||||
zonePosition: [],
|
||||
setZonePosition: (x: any) => set({ zonePosition: x }),
|
||||
zonePosition: [],
|
||||
setZonePosition: (x: any) => set({ zonePosition: x }),
|
||||
}));
|
||||
|
||||
interface EditPositionState {
|
||||
Edit: boolean;
|
||||
setEdit: (value: boolean) => void;
|
||||
Edit: boolean;
|
||||
setEdit: (value: boolean) => void;
|
||||
}
|
||||
|
||||
export const useEditPosition = create<EditPositionState>((set) => ({
|
||||
Edit: false,
|
||||
setEdit: (value) => set({ Edit: value }), // Properly updating the state
|
||||
Edit: false,
|
||||
setEdit: (value) => set({ Edit: value }), // Properly updating the state
|
||||
}));
|
||||
|
||||
export const useAsset3dWidget = create<any>((set: any) => ({
|
||||
widgetSelect: "",
|
||||
setWidgetSelect: (x: any) => set({ widgetSelect: x }),
|
||||
widgetSelect: "",
|
||||
setWidgetSelect: (x: any) => set({ widgetSelect: x }),
|
||||
}));
|
||||
|
||||
export const useWidgetSubOption = create<any>((set: any) => ({
|
||||
widgetSubOption: "2D",
|
||||
setWidgetSubOption: (x: any) => set({ widgetSubOption: x }),
|
||||
widgetSubOption: "2D",
|
||||
setWidgetSubOption: (x: any) => set({ widgetSubOption: x }),
|
||||
}));
|
||||
export const useLimitDistance = create<any>((set: any) => ({
|
||||
limitDistance: true,
|
||||
setLimitDistance: (x: any) => set({ limitDistance: x }),
|
||||
limitDistance: true,
|
||||
setLimitDistance: (x: any) => set({ limitDistance: x }),
|
||||
}));
|
||||
|
||||
export const useTileDistance = create<any>((set: any) => ({
|
||||
gridValue: { size: 300, divisions: 75 },
|
||||
planeValue: { height: 300, width: 300 },
|
||||
gridValue: { size: 300, divisions: 75 },
|
||||
planeValue: { height: 300, width: 300 },
|
||||
|
||||
setGridValue: (value: any) =>
|
||||
set((state: any) => ({
|
||||
gridValue: { ...state.gridValue, ...value },
|
||||
})),
|
||||
setGridValue: (value: any) =>
|
||||
set((state: any) => ({
|
||||
gridValue: { ...state.gridValue, ...value },
|
||||
})),
|
||||
|
||||
setPlaneValue: (value: any) =>
|
||||
set((state: any) => ({
|
||||
planeValue: { ...state.planeValue, ...value },
|
||||
})),
|
||||
setPlaneValue: (value: any) =>
|
||||
set((state: any) => ({
|
||||
planeValue: { ...state.planeValue, ...value },
|
||||
})),
|
||||
}));
|
||||
|
||||
export const usePlayAgv = create<any>((set, get) => ({
|
||||
PlayAgv: [],
|
||||
setPlayAgv: (updateFn: (prev: any[]) => any[]) =>
|
||||
set({ PlayAgv: updateFn(get().PlayAgv) }),
|
||||
PlayAgv: [],
|
||||
setPlayAgv: (updateFn: (prev: any[]) => any[]) =>
|
||||
set({ PlayAgv: updateFn(get().PlayAgv) }),
|
||||
}));
|
||||
// Define the Asset type
|
||||
type Asset = {
|
||||
id: string;
|
||||
name: string;
|
||||
position?: [number, number, number]; // Optional: 3D position
|
||||
rotation?: { x: number; y: number; z: number }; // Optional: Euler rotation
|
||||
id: string;
|
||||
name: string;
|
||||
position?: [number, number, number]; // Optional: 3D position
|
||||
rotation?: { x: number; y: number; z: number }; // Optional: Euler rotation
|
||||
};
|
||||
|
||||
// Zustand store type
|
||||
type ZoneAssetState = {
|
||||
zoneAssetId: Asset | null;
|
||||
setZoneAssetId: (asset: Asset | null) => void;
|
||||
zoneAssetId: Asset | null;
|
||||
setZoneAssetId: (asset: Asset | null) => void;
|
||||
};
|
||||
|
||||
// Zustand store
|
||||
export const useZoneAssetId = create<ZoneAssetState>((set) => ({
|
||||
zoneAssetId: null,
|
||||
setZoneAssetId: (asset) => set({ zoneAssetId: asset }),
|
||||
zoneAssetId: null,
|
||||
setZoneAssetId: (asset) => set({ zoneAssetId: asset }),
|
||||
}));
|
||||
|
||||
@@ -101,6 +101,7 @@ export const useDroppedObjectsStore = create<DroppedObjectsState>((set) => ({
|
||||
let visualizationSocket = socketState.visualizationSocket;
|
||||
let iotMeasurements = iotData.flotingMeasurements;
|
||||
let iotDuration = iotData.flotingDuration;
|
||||
let iotHeader = iotData.header
|
||||
|
||||
if (!zone) return;
|
||||
|
||||
@@ -117,6 +118,7 @@ export const useDroppedObjectsStore = create<DroppedObjectsState>((set) => ({
|
||||
measurements: iotMeasurements,
|
||||
duration: iotDuration,
|
||||
},
|
||||
header: iotHeader,
|
||||
id: `${originalObject.id}-copy-${Date.now()}`, // Unique ID
|
||||
position: {
|
||||
...originalObject.position,
|
||||
|
||||
@@ -56,6 +56,12 @@ input {
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.input-error {
|
||||
border: 1px solid #f65648 !important;
|
||||
outline: none !important;
|
||||
color: #f65648;
|
||||
}
|
||||
|
||||
.toggle-header-container {
|
||||
@include flex-center;
|
||||
padding: 6px 12px;
|
||||
@@ -344,7 +350,6 @@ input {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
|
||||
.loading {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
@@ -364,9 +369,7 @@ input {
|
||||
left: -50%;
|
||||
height: 100%;
|
||||
width: 50%;
|
||||
background: linear-gradient(to right,
|
||||
var(--accent-color),
|
||||
transparent);
|
||||
background: linear-gradient(to right, var(--accent-color), transparent);
|
||||
animation: loadingAnimation 1.2s linear infinite;
|
||||
border-radius: 4px;
|
||||
}
|
||||
@@ -381,8 +384,6 @@ input {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.dropdown-item {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
@@ -710,4 +711,4 @@ input {
|
||||
.multi-email-invite-input.active {
|
||||
border: 1px solid var(--accent-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
292
app/src/types/simulationTypes.d.ts
vendored
Normal file
292
app/src/types/simulationTypes.d.ts
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
|
||||
interface PathConnection {
|
||||
fromModelUUID: string;
|
||||
fromUUID: string;
|
||||
toConnections: {
|
||||
toModelUUID: string;
|
||||
toUUID: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
interface ConnectionStore {
|
||||
connections: PathConnection[];
|
||||
setConnections: (connections: PathConnection[]) => void;
|
||||
addConnection: (newConnection: PathConnection) => void;
|
||||
removeConnection: (fromUUID: string, toUUID: string) => void;
|
||||
}
|
||||
|
||||
interface ConveyorEventsSchema {
|
||||
modeluuid: string;
|
||||
modelName: string;
|
||||
type: "Conveyor";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: { uuid: string; name: string; type: string; material: string; delay: number | string; spawnInterval: number | string; isUsed: boolean; }[] | [];
|
||||
triggers: { uuid: string; name: string; type: string; isUsed: boolean; bufferTime: number; }[] | [];
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
}[];
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
speed: number | string;
|
||||
}
|
||||
|
||||
interface VehicleEventsSchema {
|
||||
modeluuid: string;
|
||||
modelName: string;
|
||||
type: "Vehicle";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: { uuid: string; name: string; type: string; start: { x: number; y: number } | {}; hitCount: number; end: { x: number; y: number } | {}; buffer: number; };
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
speed: number;
|
||||
isPlaying: boolean;
|
||||
};
|
||||
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
}
|
||||
|
||||
interface StaticMachineEventsSchema {
|
||||
modeluuid: string;
|
||||
modelName: string;
|
||||
type: "StaticMachine";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: { uuid: string; name: string; buffer: number; material: string; };
|
||||
triggers: { uuid: string; name: string; type: string };
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
};
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
}
|
||||
|
||||
interface ArmBotEventsSchema {
|
||||
modeluuid: string;
|
||||
modelName: string;
|
||||
type: "ArmBot";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
triggers: { uuid: string; name: string; type: string };
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
};
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
}
|
||||
|
||||
export type EventData = {
|
||||
modeluuid: string;
|
||||
modelname: string;
|
||||
position: [number, number, number];
|
||||
rotation: { x: number; y: number; z: number };
|
||||
modelfileID: string;
|
||||
isLocked: boolean;
|
||||
isVisible: boolean;
|
||||
eventData?:
|
||||
{
|
||||
type: "Conveyor";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: { uuid: string; name: string; type: string; material: string; delay: number | string; spawnInterval: number | string; isUsed: boolean; }[] | [];
|
||||
triggers: { uuid: string; name: string; type: string; isUsed: boolean; bufferTime: number; }[] | [];
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
}[];
|
||||
speed: number | string;
|
||||
}
|
||||
| {
|
||||
type: "Vehicle";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: { uuid: string; name: string; type: string; start: { x: number; y: number } | {}; hitCount: number; end: { x: number; y: number } | {}; buffer: number; };
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
speed: number;
|
||||
};
|
||||
}
|
||||
| {
|
||||
type: "StaticMachine";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: { uuid: string; name: string; buffer: number; material: string; };
|
||||
triggers: { uuid: string; name: string; type: string };
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
};
|
||||
}
|
||||
| {
|
||||
type: "ArmBot";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string; }[]; };
|
||||
triggers: { uuid: string; name: string; type: string };
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
interface AssetEventSchema {
|
||||
modelUuid: string;
|
||||
modelName: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
state: "idle" | "running" | "stopped" | "disabled" | "error";
|
||||
}
|
||||
|
||||
interface TriggerSchema {
|
||||
triggerUuid: string;
|
||||
triggerName: string;
|
||||
triggerType: "onComplete" | "onStart" | "onStop" | "delay" | "onError";
|
||||
delay: number;
|
||||
triggeredAsset: {
|
||||
triggeredModel: { modelName: string, modelUuid: string };
|
||||
triggeredAction: { actionName: string, actionUuid: string };
|
||||
} | null;
|
||||
}
|
||||
|
||||
interface TransferPointSchema {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: {
|
||||
actionUuid: string;
|
||||
actionName: string;
|
||||
actionType: "default" | "spawn" | "swap" | "despawn";
|
||||
material: string | "inherit";
|
||||
delay: number | "inherit";
|
||||
spawnInterval: number | "inherit";
|
||||
spawnCount: number | "inherit";
|
||||
triggers: TriggerSchema[] | [];
|
||||
}[];
|
||||
}
|
||||
|
||||
interface VehiclePointSchema {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: {
|
||||
actionUuid: string;
|
||||
actionName: string;
|
||||
actionType: "travel";
|
||||
material: string;
|
||||
unLoadDuration: number;
|
||||
loadCapacity: number;
|
||||
pickUpPoint: { x: number; y: number, z: number } | {};
|
||||
unLoadPoint: { x: number; y: number, z: number } | {};
|
||||
triggers: TriggerSchema[] | [];
|
||||
}[];
|
||||
}
|
||||
|
||||
interface RoboticArmPointSchema {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: {
|
||||
actionUuid: string;
|
||||
actionName: string;
|
||||
actionType: "pickAndPlace";
|
||||
process: { startPoint: string; endPoint: string };
|
||||
triggers: TriggerSchema[] | [];
|
||||
}[];
|
||||
}
|
||||
|
||||
interface MachinePointSchema {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: {
|
||||
actionUuid: string;
|
||||
actionName: string;
|
||||
actionType: "process";
|
||||
processTime: number;
|
||||
swapMaterial: string;
|
||||
triggers: TriggerSchema[] | [];
|
||||
}[];
|
||||
}
|
||||
|
||||
interface StoragePointSchema {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: {
|
||||
actionUuid: string;
|
||||
actionName: string;
|
||||
actionType: "storage";
|
||||
materials: { materialName: string; materialId: string; quantity: number }[];
|
||||
storageCapacity: number;
|
||||
}[];
|
||||
}
|
||||
|
||||
interface TransferEventSchema extends AssetEventSchema {
|
||||
type: "transfer";
|
||||
speed: number;
|
||||
points: TransferPointSchema[];
|
||||
}
|
||||
|
||||
interface VehicleSchemaEvent extends AssetEventSchema {
|
||||
type: "vehicle";
|
||||
speed: number;
|
||||
point: VehiclePointSchema;
|
||||
}
|
||||
|
||||
interface RoboticArmSchemaEvent extends AssetEventSchema {
|
||||
type: "roboticArm";
|
||||
speed: number;
|
||||
point: RoboticArmPointSchema;
|
||||
}
|
||||
|
||||
interface MachineSchemaEvent extends AssetEventSchema {
|
||||
type: "machine";
|
||||
point: MachinePointSchema;
|
||||
}
|
||||
|
||||
interface StorageSchemaEvent extends AssetEventSchema {
|
||||
type: "storageUnit";
|
||||
point: StoragePointSchema;
|
||||
}
|
||||
|
||||
type EventsSchema = TransferEventSchema | VehicleSchemaEvent | RoboticArmSchemaEvent | MachineSchemaEvent | StorageSchemaEvent | [];
|
||||
|
||||
type productsSchema = {
|
||||
productName: string;
|
||||
productId: string;
|
||||
eventsData: EventsSchema[];
|
||||
}[] | []
|
||||
339
app/src/types/world/worldTypes.d.ts
vendored
339
app/src/types/world/worldTypes.d.ts
vendored
@@ -47,9 +47,7 @@ export type Shape = THREE.Shape;
|
||||
export type IntersectionEvent = THREE.Intersection;
|
||||
|
||||
// Array type for intersections with objects in the scene
|
||||
export type IntersectsType = THREE.Intersection<
|
||||
THREE.Object3D<THREE.Object3DEventMap>
|
||||
>[];
|
||||
export type IntersectsType = THREE.Intersection<THREE.Object3D<THREE.Object3DEventMap>>[];
|
||||
|
||||
// Event type for mesh interactions
|
||||
export type MeshEvent = IntersectionEvent<MouseEvent>;
|
||||
@@ -107,9 +105,7 @@ export type NumberArray = number[];
|
||||
export type RefRaycaster = React.MutableRefObject<THREE.Raycaster>;
|
||||
|
||||
// Camera reference, supporting both perspective and basic cameras
|
||||
export type RefCamera = React.MutableRefObject<
|
||||
THREE.Camera | THREE.PerspectiveCamera
|
||||
>;
|
||||
export type RefCamera = React.MutableRefObject<THREE.Camera | THREE.PerspectiveCamera>;
|
||||
|
||||
/** Three.js Root State Management **/
|
||||
|
||||
@@ -134,11 +130,11 @@ export type Lines = Array<Line>;
|
||||
|
||||
// Defines a wall with its geometry, position, rotation, material, and layer information
|
||||
export type Wall = [
|
||||
THREE.ExtrudeGeometry,
|
||||
[number, number, number],
|
||||
[number, number, number],
|
||||
string,
|
||||
number
|
||||
THREE.ExtrudeGeometry,
|
||||
[number, number, number],
|
||||
[number, number, number],
|
||||
string,
|
||||
number
|
||||
];
|
||||
|
||||
// Collection of walls, useful in scene construction
|
||||
@@ -148,18 +144,10 @@ export type Walls = Array<Wall>;
|
||||
export type RefWalls = React.MutableRefObject<Walls>;
|
||||
|
||||
// Room type, containing coordinates and layer metadata for spatial management
|
||||
export type Rooms = Array<{
|
||||
coordinates: Array<{ position: THREE.Vector3; uuid: string }>;
|
||||
layer: number;
|
||||
}>;
|
||||
export type Rooms = Array<{ coordinates: Array<{ position: THREE.Vector3; uuid: string }>; layer: number; }>;
|
||||
|
||||
// Reference for room objects, enabling updates within React components
|
||||
export type RefRooms = React.MutableRefObject<
|
||||
Array<{
|
||||
coordinates: Array<{ position: THREE.Vector3; uuid: string }>;
|
||||
layer: number;
|
||||
}>
|
||||
>;
|
||||
export type RefRooms = React.MutableRefObject<Array<{ coordinates: Array<{ position: THREE.Vector3; uuid: string }>; layer: number; }>>;
|
||||
|
||||
// Reference for lines, supporting React-based state changes
|
||||
export type RefLines = React.MutableRefObject<Lines>;
|
||||
@@ -182,10 +170,10 @@ export type RefOnlyFloorLines = React.MutableRefObject<OnlyFloorLines>;
|
||||
|
||||
// Structure for representing GeoJSON lines, integrating external data sources
|
||||
export type GeoJsonLine = {
|
||||
line: any;
|
||||
uuids: [string, string];
|
||||
layer: number;
|
||||
type: string;
|
||||
line: any;
|
||||
uuids: [string, string];
|
||||
layer: number;
|
||||
type: string;
|
||||
};
|
||||
|
||||
/** State Management Types for React Components **/
|
||||
@@ -201,67 +189,59 @@ export type RefTubeGeometry = React.MutableRefObject<THREE.TubeGeometry | null>;
|
||||
|
||||
// Type for individual items placed on the floor, with positioning and rotation metadata
|
||||
export type FloorItemType = {
|
||||
modeluuid: string;
|
||||
modelname: string;
|
||||
position: [number, number, number];
|
||||
rotation: { x: number; y: number; z: number };
|
||||
modelfileID: string;
|
||||
isLocked: boolean;
|
||||
isVisible: boolean;
|
||||
modeluuid: string;
|
||||
modelname: string;
|
||||
position: [number, number, number];
|
||||
rotation: { x: number; y: number; z: number };
|
||||
modelfileID: string;
|
||||
isLocked: boolean;
|
||||
isVisible: boolean;
|
||||
};
|
||||
|
||||
// Array of floor items for managing multiple objects on the floor
|
||||
export type FloorItems = Array<FloorItemType>;
|
||||
|
||||
// Dispatch type for setting floor item state in React
|
||||
export type setFloorItemSetState = React.Dispatch<
|
||||
React.SetStateAction<FloorItems | null | undefined>
|
||||
>;
|
||||
export type setFloorItemSetState = React.Dispatch<React.SetStateAction<FloorItems | null | undefined>>;
|
||||
|
||||
/** Asset Configuration for Loading and Positioning **/
|
||||
|
||||
// Configuration for assets, allowing model URLs, scaling, positioning, and types
|
||||
interface AssetConfiguration {
|
||||
modelUrl: string;
|
||||
scale?: [number, number, number];
|
||||
csgscale?: [number, number, number];
|
||||
csgposition?: [number, number, number];
|
||||
positionY?: (intersectionPoint: { point: THREE.Vector3 }) => number;
|
||||
type?: "Fixed-Move" | "Free-Move";
|
||||
modelUrl: string;
|
||||
scale?: [number, number, number];
|
||||
csgscale?: [number, number, number];
|
||||
csgposition?: [number, number, number];
|
||||
positionY?: (intersectionPoint: { point: THREE.Vector3 }) => number;
|
||||
type?: "Fixed-Move" | "Free-Move";
|
||||
}
|
||||
|
||||
// Collection of asset configurations, keyed by unique identifiers
|
||||
export type AssetConfigurations = {
|
||||
[key: string]: AssetConfiguration;
|
||||
};
|
||||
export type AssetConfigurations = { [key: string]: AssetConfiguration; };
|
||||
|
||||
/** Wall Item Configuration **/
|
||||
|
||||
// Configuration for wall items, including model, scale, position, and rotation
|
||||
interface WallItem {
|
||||
type: "Fixed-Move" | "Free-Move" | undefined;
|
||||
model?: THREE.Group;
|
||||
modeluuid?: string;
|
||||
modelname?: string;
|
||||
scale?: [number, number, number];
|
||||
csgscale?: [number, number, number];
|
||||
csgposition?: [number, number, number];
|
||||
position?: [number, number, number];
|
||||
quaternion?: Types.QuaternionType;
|
||||
type: "Fixed-Move" | "Free-Move" | undefined;
|
||||
model?: THREE.Group;
|
||||
modeluuid?: string;
|
||||
modelname?: string;
|
||||
scale?: [number, number, number];
|
||||
csgscale?: [number, number, number];
|
||||
csgposition?: [number, number, number];
|
||||
position?: [number, number, number];
|
||||
quaternion?: Types.QuaternionType;
|
||||
}
|
||||
|
||||
// Collection of wall items, allowing for multiple items in a scene
|
||||
export type wallItems = Array<WallItem>;
|
||||
|
||||
// Dispatch for setting wall item state in React
|
||||
export type setWallItemSetState = React.Dispatch<
|
||||
React.SetStateAction<WallItem[]>
|
||||
>;
|
||||
export type setWallItemSetState = React.Dispatch<React.SetStateAction<WallItem[]>>;
|
||||
|
||||
// Dispatch for setting vector3 state in React
|
||||
export type setVector3State = React.Dispatch<
|
||||
React.SetStateAction<THREE.Vector3>
|
||||
>;
|
||||
export type setVector3State = React.Dispatch<React.SetStateAction<THREE.Vector3>>;
|
||||
|
||||
// Dispatch for setting euler state in React
|
||||
export type setEulerState = React.Dispatch<React.SetStateAction<THREE.Euler>>;
|
||||
@@ -274,245 +254,8 @@ export type RefWallItems = React.MutableRefObject<WallItem[]>;
|
||||
// State management for selecting, removing, and indexing wall items
|
||||
export type setRemoveLayerSetState = (layer: number | null) => void;
|
||||
export type setSelectedWallItemSetState = (item: THREE.Object3D | null) => void;
|
||||
export type setSelectedFloorItemSetState = (
|
||||
item: THREE.Object3D | null
|
||||
) => void;
|
||||
export type setSelectedFloorItemSetState = (item: THREE.Object3D | null) => void;
|
||||
export type setSelectedItemsIndexSetState = (index: number | null) => void;
|
||||
|
||||
export type RefCSM = React.MutableRefObject<CSM>;
|
||||
export type RefCSMHelper = React.MutableRefObject<CSMHelper>;
|
||||
|
||||
interface PathConnection {
|
||||
fromModelUUID: string;
|
||||
fromUUID: string;
|
||||
toConnections: {
|
||||
toModelUUID: string;
|
||||
toUUID: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
interface ConnectionStore {
|
||||
connections: PathConnection[];
|
||||
setConnections: (connections: PathConnection[]) => void;
|
||||
addConnection: (newConnection: PathConnection) => void;
|
||||
removeConnection: (fromUUID: string, toUUID: string) => void;
|
||||
}
|
||||
|
||||
interface ConveyorEventsSchema {
|
||||
modeluuid: string;
|
||||
modelName: string;
|
||||
type: "Conveyor";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions:
|
||||
| {
|
||||
uuid: string;
|
||||
name: string;
|
||||
type: string;
|
||||
material: string;
|
||||
delay: number | string;
|
||||
spawnInterval: number | string;
|
||||
isUsed: boolean;
|
||||
}[]
|
||||
| [];
|
||||
triggers:
|
||||
| {
|
||||
uuid: string;
|
||||
name: string;
|
||||
type: string;
|
||||
isUsed: boolean;
|
||||
bufferTime: number;
|
||||
}[]
|
||||
| [];
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
}[];
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
speed: number | string;
|
||||
}
|
||||
|
||||
interface VehicleEventsSchema {
|
||||
modeluuid: string;
|
||||
modelName: string;
|
||||
type: "Vehicle";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
actions: {
|
||||
uuid: string;
|
||||
name: string;
|
||||
type: string;
|
||||
start: { x: number; y: number } | {};
|
||||
hitCount: number;
|
||||
end: { x: number; y: number } | {};
|
||||
buffer: number;
|
||||
};
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
speed: number;
|
||||
isPlaying: boolean;
|
||||
};
|
||||
|
||||
position: [number, number, number];
|
||||
}
|
||||
|
||||
interface StaticMachineEventsSchema {
|
||||
modeluuid: string;
|
||||
modelName: string;
|
||||
type: "StaticMachine";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
actions: {
|
||||
uuid: string;
|
||||
name: string;
|
||||
buffer: number | string;
|
||||
material: string;
|
||||
isUsed: boolean;
|
||||
};
|
||||
triggers: { uuid: string; name: string; type: string };
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
};
|
||||
position: [number, number, number];
|
||||
}
|
||||
|
||||
interface ArmBotEventsSchema {
|
||||
modeluuid: string;
|
||||
modelName: string;
|
||||
type: "ArmBot";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
actions: {
|
||||
uuid: string;
|
||||
name: string;
|
||||
speed: number;
|
||||
processes: { triggerId: string; startPoint: string; endPoint: string }[];
|
||||
};
|
||||
triggers: { uuid: string; name: string; type: string };
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
};
|
||||
position: [number, number, number];
|
||||
}
|
||||
|
||||
export type EventData = {
|
||||
modeluuid: string;
|
||||
modelname: string;
|
||||
position: [number, number, number];
|
||||
rotation: { x: number; y: number; z: number };
|
||||
modelfileID: string;
|
||||
isLocked: boolean;
|
||||
isVisible: boolean;
|
||||
eventData?:
|
||||
| {
|
||||
type: "Conveyor";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions:
|
||||
| {
|
||||
uuid: string;
|
||||
name: string;
|
||||
type: string;
|
||||
material: string;
|
||||
delay: number | string;
|
||||
spawnInterval: number | string;
|
||||
isUsed: boolean;
|
||||
}[]
|
||||
| [];
|
||||
triggers:
|
||||
| {
|
||||
uuid: string;
|
||||
name: string;
|
||||
type: string;
|
||||
isUsed: boolean;
|
||||
bufferTime: number;
|
||||
}[]
|
||||
| [];
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
}[];
|
||||
speed: number | string;
|
||||
}
|
||||
| {
|
||||
type: "Vehicle";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: {
|
||||
uuid: string;
|
||||
name: string;
|
||||
type: string;
|
||||
start: { x: number; y: number } | {};
|
||||
hitCount: number;
|
||||
end: { x: number; y: number } | {};
|
||||
buffer: number;
|
||||
};
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
speed: number;
|
||||
};
|
||||
}
|
||||
| {
|
||||
type: "StaticMachine";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: {
|
||||
uuid: string;
|
||||
name: string;
|
||||
buffer: number;
|
||||
material: string;
|
||||
};
|
||||
triggers: { uuid: string; name: string; type: string };
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
};
|
||||
}
|
||||
| {
|
||||
type: "ArmBot";
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
actions: {
|
||||
uuid: string;
|
||||
name: string;
|
||||
speed: number;
|
||||
processes: {
|
||||
triggerId: string;
|
||||
startPoint: string;
|
||||
endPoint: string;
|
||||
}[];
|
||||
};
|
||||
triggers: { uuid: string; name: string; type: string };
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export type RefCSMHelper = React.MutableRefObject<CSMHelper>;
|
||||
Reference in New Issue
Block a user