Merge remote-tracking branch 'origin/dev-storageunit-refactor' into main-demo
This commit is contained in:
85
app/package-lock.json
generated
85
app/package-lock.json
generated
@@ -38,6 +38,7 @@
|
||||
"mqtt": "^5.10.4",
|
||||
"postprocessing": "^6.36.4",
|
||||
"prompt-sync": "^4.2.0",
|
||||
"r3f-perf": "^7.2.3",
|
||||
"react": "^18.3.1",
|
||||
"react-chartjs-2": "^5.3.0",
|
||||
"react-dom": "^18.3.1",
|
||||
@@ -3371,6 +3372,15 @@
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-icons": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.2.tgz",
|
||||
"integrity": "sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc"
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-id": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.0.tgz",
|
||||
@@ -7073,6 +7083,23 @@
|
||||
"react": ">= 16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@utsubo/events": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@utsubo/events/-/events-0.1.7.tgz",
|
||||
"integrity": "sha512-WB/GEj/0h27Bz8rJ0+CBtNz5mLT79ne1OjB7PUM4n0qLBqEDwm6yBzZC3j6tasHjlBPJDYZiBVIA1glaMlgZ5g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"eventemitter3": "^4.0.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@webassemblyjs/ast": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
|
||||
@@ -17894,6 +17921,64 @@
|
||||
"integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/r3f-perf": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/r3f-perf/-/r3f-perf-7.2.3.tgz",
|
||||
"integrity": "sha512-4+P/N/bnO9D8nzdm3suL/NjPZK/HHdjwpvajhi8j7eB41i2ECN6lX9RXiKSpHzpsDi2ui1tBj6q7/sz5opoqXw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@react-three/drei": "^9.103.0",
|
||||
"@stitches/react": "^1.2.8",
|
||||
"@utsubo/events": "^0.1.7",
|
||||
"zustand": "~4.5.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@react-three/fiber": ">=8.0",
|
||||
"react": ">=18.0",
|
||||
"react-dom": ">=18.0",
|
||||
"three": ">=0.133"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@react-three/fiber": {
|
||||
"optional": true
|
||||
},
|
||||
"dom": {
|
||||
"optional": true
|
||||
},
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/r3f-perf/node_modules/zustand": {
|
||||
"version": "4.5.7",
|
||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz",
|
||||
"integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"use-sync-external-store": "^1.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": ">=16.8",
|
||||
"immer": ">=9.0.6",
|
||||
"react": ">=16.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"immer": {
|
||||
"optional": true
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/raf": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
"mqtt": "^5.10.4",
|
||||
"postprocessing": "^6.36.4",
|
||||
"prompt-sync": "^4.2.0",
|
||||
"r3f-perf": "^7.2.3",
|
||||
"react": "^18.3.1",
|
||||
"react-chartjs-2": "^5.3.0",
|
||||
"react-dom": "^18.3.1",
|
||||
|
||||
@@ -3,53 +3,51 @@ import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
|
||||
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
|
||||
|
||||
interface StorageActionProps {
|
||||
type: "store" | "spawn" | "default";
|
||||
value: string;
|
||||
maxCapacity: string;
|
||||
spawnedCount: string;
|
||||
min: number;
|
||||
max?: number;
|
||||
defaultValue: string;
|
||||
maxCapacityDefault: string;
|
||||
spawnedCountCefault: string;
|
||||
currentMaterialType: string;
|
||||
handleCapacityChange: (value: string) => void;
|
||||
handleSpawnCountChange: (value: string) => void;
|
||||
handleMaterialTypeChange: (value: string) => void;
|
||||
}
|
||||
|
||||
const StorageAction: React.FC<StorageActionProps> = ({ type, value, min, max, defaultValue, currentMaterialType, handleCapacityChange, handleMaterialTypeChange }) => {
|
||||
const StorageAction: React.FC<StorageActionProps> = ({ maxCapacity, spawnedCount, min, max, maxCapacityDefault, spawnedCountCefault, currentMaterialType, handleCapacityChange, handleSpawnCountChange, handleMaterialTypeChange }) => {
|
||||
return (
|
||||
<>
|
||||
{type === 'store' &&
|
||||
<InputWithDropDown
|
||||
label="Storage Capacity"
|
||||
value={value}
|
||||
min={min}
|
||||
step={1}
|
||||
max={max}
|
||||
defaultValue={defaultValue}
|
||||
activeOption="unit"
|
||||
onClick={() => { }}
|
||||
onChange={handleCapacityChange}
|
||||
/>
|
||||
}
|
||||
{type === 'spawn' &&
|
||||
<>
|
||||
<InputWithDropDown
|
||||
label="Spawn Capacity"
|
||||
value={value}
|
||||
min={min}
|
||||
step={1}
|
||||
max={max}
|
||||
defaultValue={defaultValue}
|
||||
activeOption="unit"
|
||||
onClick={() => { }}
|
||||
onChange={handleCapacityChange}
|
||||
/>
|
||||
<LabledDropdown
|
||||
label={"Material Type"}
|
||||
defaultOption={currentMaterialType}
|
||||
options={["Default material", "Material 1", "Material 2", "Material 3"]}
|
||||
onSelect={handleMaterialTypeChange}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
<InputWithDropDown
|
||||
key={'Storage Capacity'}
|
||||
label="Storage Capacity"
|
||||
value={maxCapacity}
|
||||
min={min}
|
||||
step={1}
|
||||
max={max}
|
||||
defaultValue={maxCapacityDefault}
|
||||
activeOption="unit"
|
||||
onClick={() => { }}
|
||||
onChange={handleCapacityChange}
|
||||
/>
|
||||
<InputWithDropDown
|
||||
key={"Spawn Count"}
|
||||
label="Spawn Count"
|
||||
value={spawnedCount}
|
||||
min={min}
|
||||
step={1}
|
||||
max={max}
|
||||
defaultValue={spawnedCountCefault}
|
||||
activeOption="unit"
|
||||
onClick={() => { }}
|
||||
onChange={handleSpawnCountChange}
|
||||
/>
|
||||
<LabledDropdown
|
||||
label={"Material Type"}
|
||||
defaultOption={currentMaterialType}
|
||||
options={["Default material", "Material 1", "Material 2", "Material 3"]}
|
||||
onSelect={handleMaterialTypeChange}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -125,26 +125,6 @@ function ConveyorMechanics() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedPointData) return;
|
||||
|
||||
setActionName(newName);
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{ actionName: newName }
|
||||
);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSpawnCountChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
|
||||
|
||||
@@ -62,36 +62,6 @@ function CraneMechanics() {
|
||||
});
|
||||
};
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedAction.actionId || !selectedPointData) return;
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
{ actionName: newName }
|
||||
);
|
||||
|
||||
const updatedActions = selectedPointData.actions.map(action =>
|
||||
action.actionUuid === selectedAction.actionId
|
||||
? { ...action, actionName: newName }
|
||||
: action
|
||||
);
|
||||
|
||||
setSelectedPointData({
|
||||
...selectedPointData,
|
||||
actions: updatedActions,
|
||||
});
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddAction = () => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
|
||||
|
||||
@@ -142,7 +142,6 @@ function HumanMechanics() {
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
const updatedEvent = {
|
||||
...selectedEventData.data,
|
||||
speed: numericValue
|
||||
} as HumanEventSchema;
|
||||
|
||||
|
||||
@@ -71,36 +71,6 @@ function RoboticArmMechanics() {
|
||||
});
|
||||
};
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedAction.actionId || !selectedPointData) return;
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
{ actionName: newName }
|
||||
);
|
||||
|
||||
const updatedActions = selectedPointData.actions.map(action =>
|
||||
action.actionUuid === selectedAction.actionId
|
||||
? { ...action, actionName: newName }
|
||||
: action
|
||||
);
|
||||
|
||||
setSelectedPointData({
|
||||
...selectedPointData,
|
||||
actions: updatedActions,
|
||||
});
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSpeedChange = (value: string) => {
|
||||
if (!selectedEventData) return;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { MathUtils } from "three";
|
||||
import RenameInput from "../../../../../ui/inputs/RenameInput";
|
||||
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
|
||||
import Trigger from "../trigger/Trigger";
|
||||
@@ -6,58 +7,85 @@ import StorageAction from "../actions/StorageAction";
|
||||
import ActionsList from "../components/ActionsList";
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useSelectedAction, useSelectedEventData } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import * as THREE from 'three';
|
||||
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
|
||||
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||
|
||||
function StorageMechanics() {
|
||||
const [activeOption, setActiveOption] = useState<"default" | "store" | "spawn">("default");
|
||||
const [activeOption, setActiveOption] = useState<"store" | "spawn">("store");
|
||||
const [currentCapacity, setCurrentCapacity] = useState("1");
|
||||
const [spawnedCount, setSpawnedCount] = useState("0");
|
||||
const [spawnedMaterial, setSpawnedMaterial] = useState("Default material");
|
||||
const [selectedPointData, setSelectedPointData] = useState<StoragePointSchema | undefined>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { productStore } = useSceneContext();
|
||||
const { getPointByUuid, updateAction } = productStore();
|
||||
const { getPointByUuid, updateAction, updateEvent, getEventByModelUuid, getActionByUuid, addAction, removeAction } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { setSelectedAction, clearSelectedAction } = useSelectedAction();
|
||||
const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
const updateSelectedPointData = () => {
|
||||
if (selectedEventData && selectedProduct) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData?.data.modelUuid,
|
||||
selectedEventData?.selectedPoint
|
||||
) as StoragePointSchema | undefined;
|
||||
if (point && "action" in point) {
|
||||
setSelectedPointData(point);
|
||||
const uiOption = point.action.actionType === "retrieve" ? "spawn" : point.action.actionType;
|
||||
setActiveOption(uiOption as "store" | "spawn");
|
||||
setSelectedAction(point.action.actionUuid, point.action.actionName);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
if (selectedEventData && selectedEventData.data.type === "storageUnit") {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData?.data.modelUuid,
|
||||
selectedEventData?.selectedPoint
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as StoragePointSchema | undefined;
|
||||
if (point && "action" in point) {
|
||||
|
||||
if (point?.actions?.length) {
|
||||
setSelectedPointData(point);
|
||||
const uiOption = point.action.actionType === "retrieve" ? "spawn" : point.action.actionType;
|
||||
setActiveOption(uiOption as "store" | "spawn");
|
||||
setSelectedAction(point.action.actionUuid, point.action.actionName);
|
||||
const firstAction = point.actions[0];
|
||||
|
||||
const eventData = getEventByModelUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid
|
||||
) as StorageEventSchema | undefined;
|
||||
|
||||
setCurrentCapacity(eventData?.storageCapacity?.toString() || "1");
|
||||
setSpawnedCount(eventData?.storageCount?.toString() || "0");
|
||||
setSpawnedMaterial(eventData?.materialType?.toString() || "Default material");
|
||||
|
||||
const actionUuid = selectedAction.actionId || firstAction.actionUuid;
|
||||
const newCurrentAction = getActionByUuid(selectedProduct.productUuid, actionUuid);
|
||||
|
||||
if (newCurrentAction) {
|
||||
const uiOption = newCurrentAction.actionType === "retrieve" ? "spawn" : "store";
|
||||
setActiveOption(uiOption);
|
||||
setSelectedAction(newCurrentAction.actionUuid, newCurrentAction.actionName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
clearSelectedAction();
|
||||
}
|
||||
}, [selectedProduct, selectedEventData]);
|
||||
}, [selectedEventData, selectedProduct]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData && selectedEventData.data.type === "storageUnit" && selectedAction.actionId) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as StoragePointSchema | undefined;
|
||||
|
||||
const actionUuid = selectedAction.actionId || point?.actions[0].actionUuid || '';
|
||||
|
||||
const newCurrentAction = getActionByUuid(selectedProduct.productUuid, actionUuid);
|
||||
|
||||
if (newCurrentAction && (newCurrentAction.actionType === 'store' || newCurrentAction.actionType === 'retrieve')) {
|
||||
if (!selectedAction.actionId) {
|
||||
setSelectedAction(newCurrentAction.actionUuid, newCurrentAction.actionName);
|
||||
}
|
||||
const uiOption = newCurrentAction.actionType === "retrieve" ? "spawn" : "store";
|
||||
setActiveOption(uiOption);
|
||||
} else {
|
||||
clearSelectedAction();
|
||||
}
|
||||
}
|
||||
}, [selectedAction, selectedProduct, selectedEventData]);
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
@@ -75,48 +103,63 @@ function StorageMechanics() {
|
||||
}
|
||||
|
||||
const handleActionTypeChange = (option: string) => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
const internalOption = actionTypeMap[option as keyof typeof actionTypeMap] as "store" | "retrieve";
|
||||
if (!selectedAction.actionId || !selectedPointData) return;
|
||||
|
||||
const internalOption = option === "spawn" ? "retrieve" : "store";
|
||||
|
||||
const updatedAction = {
|
||||
actionType: internalOption as "store" | "retrieve"
|
||||
};
|
||||
|
||||
const updatedActions = selectedPointData.actions.map(action =>
|
||||
action.actionUuid === selectedAction.actionId ? {
|
||||
...action,
|
||||
actionType: updatedAction.actionType
|
||||
} : action
|
||||
);
|
||||
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
updatedAction
|
||||
);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
}
|
||||
|
||||
setSelectedPointData(updatedPoint);
|
||||
setActiveOption(option as "store" | "spawn");
|
||||
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, {
|
||||
actionType: internalOption,
|
||||
});
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateSelectedPointData();
|
||||
}
|
||||
};
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedPointData) return;
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, { actionName: newName });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateSelectedPointData();
|
||||
}
|
||||
};
|
||||
|
||||
const handleCapacityChange = (value: string) => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
const newCapacity = parseInt(value);
|
||||
if (!selectedEventData) return;
|
||||
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, {
|
||||
storageCapacity: newCapacity,
|
||||
});
|
||||
const numericValue = parseInt(value);
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
const updatedEvent = {
|
||||
storageCapacity: numericValue
|
||||
} as StorageEventSchema;
|
||||
|
||||
const currentCount = parseInt(spawnedCount);
|
||||
if (currentCount > numericValue) {
|
||||
updatedEvent.storageCount = numericValue;
|
||||
setSpawnedCount(numericValue.toString());
|
||||
}
|
||||
|
||||
const event = updateEvent(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
updatedEvent
|
||||
);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
@@ -125,25 +168,54 @@ function StorageMechanics() {
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateSelectedPointData();
|
||||
}
|
||||
|
||||
setCurrentCapacity(value);
|
||||
};
|
||||
|
||||
const createNewMaterial = (materialType: string): { materialType: string; materialId: string } | null => {
|
||||
if (!selectedEventData || !selectedPointData) return null;
|
||||
const materialId = THREE.MathUtils.generateUUID();
|
||||
return {
|
||||
materialType,
|
||||
materialId
|
||||
};
|
||||
const handleSpawnCountChange = (value: string) => {
|
||||
if (!selectedEventData) return;
|
||||
|
||||
const numericValue = parseInt(value);
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
const maxCapacity = parseInt(currentCapacity);
|
||||
if (numericValue > maxCapacity) return;
|
||||
|
||||
const updatedEvent = {
|
||||
storageCount: numericValue
|
||||
} as StorageEventSchema;
|
||||
|
||||
const event = updateEvent(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
updatedEvent
|
||||
);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
}
|
||||
|
||||
setSpawnedCount(value);
|
||||
};
|
||||
|
||||
const handleMaterialTypeChange = (value: string) => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
if (!selectedEventData) return;
|
||||
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, {
|
||||
materialType: value,
|
||||
});
|
||||
const updatedEvent = {
|
||||
materialType: value
|
||||
} as StorageEventSchema;
|
||||
|
||||
const event = updateEvent(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
updatedEvent
|
||||
);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
@@ -152,70 +224,114 @@ function StorageMechanics() {
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateSelectedPointData();
|
||||
}
|
||||
|
||||
setSpawnedMaterial(value);
|
||||
};
|
||||
|
||||
const currentActionName = useMemo(() =>
|
||||
selectedPointData ? selectedPointData.action.actionName : "Action Name",
|
||||
[selectedPointData]
|
||||
);
|
||||
const handleAddAction = () => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
|
||||
const currentCapacity = useMemo(() =>
|
||||
selectedPointData ? selectedPointData.action.storageCapacity.toString() : "0",
|
||||
[selectedPointData]
|
||||
);
|
||||
const newAction: StorageAction = {
|
||||
actionUuid: MathUtils.generateUUID(),
|
||||
actionName: `Action ${selectedPointData.actions.length + 1}`,
|
||||
actionType: "store",
|
||||
triggers: [],
|
||||
};
|
||||
|
||||
const currentMaterialType = useMemo(() =>
|
||||
selectedPointData?.action.materialType || "Default material",
|
||||
[selectedPointData]
|
||||
);
|
||||
const updatedActions = [...(selectedPointData.actions || []), newAction];
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const availableActions = {
|
||||
defaultOption: "store",
|
||||
options: ["store", "spawn"],
|
||||
const event = addAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint,
|
||||
newAction
|
||||
);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
}
|
||||
|
||||
setSelectedPointData(updatedPoint);
|
||||
setSelectedAction(newAction.actionUuid, newAction.actionName);
|
||||
};
|
||||
|
||||
const actionTypeMap = {
|
||||
spawn: "retrieve",
|
||||
store: "store"
|
||||
const handleDeleteAction = (actionUuid: string) => {
|
||||
if (!selectedPointData || !actionUuid) return;
|
||||
|
||||
const updatedActions = selectedPointData.actions.filter(action => action.actionUuid !== actionUuid);
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const event = removeAction(
|
||||
selectedProduct.productUuid,
|
||||
actionUuid
|
||||
);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
}
|
||||
|
||||
setSelectedPointData(updatedPoint);
|
||||
|
||||
const index = selectedPointData.actions.findIndex((a) => a.actionUuid === selectedAction.actionId);
|
||||
const nextAction = updatedPoint.actions[index] || updatedPoint.actions[index - 1];
|
||||
if (nextAction) {
|
||||
setSelectedAction(nextAction.actionUuid, nextAction.actionName);
|
||||
} else {
|
||||
clearSelectedAction();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{selectedEventData && (
|
||||
<section>
|
||||
<ActionsList
|
||||
selectedPointData={selectedPointData}
|
||||
/>
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={currentActionName}
|
||||
canEdit={false}
|
||||
/>
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={activeOption}
|
||||
options={availableActions.options}
|
||||
onSelect={handleActionTypeChange}
|
||||
/>
|
||||
<StorageAction
|
||||
type={activeOption}
|
||||
value={currentCapacity}
|
||||
defaultValue="0"
|
||||
min={0}
|
||||
currentMaterialType={currentMaterialType}
|
||||
handleCapacityChange={handleCapacityChange}
|
||||
handleMaterialTypeChange={handleMaterialTypeChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger selectedPointData={selectedPointData as any} type={'StorageUnit'} />
|
||||
</div>
|
||||
</section>
|
||||
{selectedEventData && selectedEventData.data.type === "storageUnit" && (
|
||||
<>
|
||||
<section>
|
||||
<StorageAction
|
||||
maxCapacity={currentCapacity}
|
||||
spawnedCount={spawnedCount}
|
||||
maxCapacityDefault="0"
|
||||
spawnedCountCefault="0"
|
||||
min={0}
|
||||
currentMaterialType={spawnedMaterial}
|
||||
handleCapacityChange={handleCapacityChange}
|
||||
handleSpawnCountChange={handleSpawnCountChange}
|
||||
handleMaterialTypeChange={handleMaterialTypeChange}
|
||||
/>
|
||||
</section>
|
||||
<section>
|
||||
<ActionsList
|
||||
selectedPointData={selectedPointData}
|
||||
multipleAction={true}
|
||||
handleAddAction={handleAddAction}
|
||||
handleDeleteAction={handleDeleteAction}
|
||||
/>
|
||||
|
||||
{selectedAction.actionId && (
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={selectedAction.actionName || ""}
|
||||
canEdit={false}
|
||||
/>
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
label="Action Type"
|
||||
defaultOption={activeOption}
|
||||
options={["store", "spawn"]}
|
||||
onSelect={handleActionTypeChange}
|
||||
disabled={false}
|
||||
/>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger selectedPointData={selectedPointData as any} type={'StorageUnit'} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -119,26 +119,6 @@ function VehicleMechanics() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedPointData) return;
|
||||
|
||||
setActionName(newName);
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{ actionName: newName }
|
||||
);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleLoadCapacityChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||
|
||||
type TriggerProps = {
|
||||
selectedPointData?: PointsScheme | undefined;
|
||||
type?: "Conveyor" | "Vehicle" | "RoboticArm" | "Machine" | "StorageUnit" | "Human";
|
||||
type?: "Conveyor" | "Vehicle" | "RoboticArm" | "Machine" | "StorageUnit" | "Human" | "Crane";
|
||||
};
|
||||
|
||||
const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
@@ -36,9 +36,9 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
|
||||
let actionUuid: string | undefined;
|
||||
|
||||
if (type === "Conveyor" || type === "Vehicle" || type === "Machine" || type === "StorageUnit") {
|
||||
actionUuid = (selectedPointData as | ConveyorPointSchema | VehiclePointSchema | MachinePointSchema | StoragePointSchema).action?.actionUuid;
|
||||
} else if ((type === "RoboticArm" || type === "Human") && selectedAction.actionId) {
|
||||
if (type === "Conveyor" || type === "Vehicle" || type === "Machine") {
|
||||
actionUuid = (selectedPointData as | ConveyorPointSchema | VehiclePointSchema | MachinePointSchema).action?.actionUuid;
|
||||
} else if ((type === "RoboticArm" || type === "Human" || type === "StorageUnit" || type === 'Crane') && selectedAction.actionId) {
|
||||
actionUuid = selectedAction.actionId;
|
||||
}
|
||||
|
||||
|
||||
@@ -232,18 +232,22 @@ function AssetsGroup({ plane }: { readonly plane: RefMesh }) {
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "storageUnit",
|
||||
storageCapacity: 10,
|
||||
storageCount: 10,
|
||||
materialType: "Default material",
|
||||
subType: item.eventData.subType || '',
|
||||
point: {
|
||||
uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
|
||||
position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
|
||||
rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Action 1",
|
||||
actionType: "store",
|
||||
storageCapacity: 10,
|
||||
triggers: []
|
||||
}
|
||||
actions: [
|
||||
{
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Action 1",
|
||||
actionType: "store",
|
||||
triggers: []
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
addEvent(storageEvent);
|
||||
|
||||
@@ -345,18 +345,22 @@ async function handleModelLoad(
|
||||
rotation: newFloorItem.rotation,
|
||||
state: "idle",
|
||||
type: "storageUnit",
|
||||
storageCapacity: 10,
|
||||
storageCount: 10,
|
||||
materialType: "Default material",
|
||||
subType: selectedItem.subType || '',
|
||||
point: {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [data.points[0].x, data.points[0].y, data.points[0].z],
|
||||
rotation: [0, 0, 0],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Action 1",
|
||||
actionType: "store",
|
||||
storageCapacity: 10,
|
||||
triggers: [],
|
||||
},
|
||||
actions: [
|
||||
{
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Action 1",
|
||||
actionType: "store",
|
||||
triggers: [],
|
||||
}
|
||||
],
|
||||
},
|
||||
};
|
||||
addEvent(storageEvent);
|
||||
|
||||
@@ -386,18 +386,22 @@ const CopyPasteControls3D = ({
|
||||
rotation: [newFloorItem.rotation.x, newFloorItem.rotation.y, newFloorItem.rotation.z],
|
||||
state: "idle",
|
||||
type: "storageUnit",
|
||||
storageCapacity: 10,
|
||||
storageCount: 10,
|
||||
materialType: "Default material",
|
||||
subType: pastedAsset.userData.eventData.subType || '',
|
||||
point: {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [updatedEventData.point.position[0], updatedEventData.point.position[1], updatedEventData.point.position[2]],
|
||||
rotation: [updatedEventData.point.rotation[0], updatedEventData.point.rotation[1], updatedEventData.point.rotation[2]],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Action 1",
|
||||
actionType: "store",
|
||||
storageCapacity: 10,
|
||||
triggers: []
|
||||
}
|
||||
actions: [
|
||||
{
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Action 1",
|
||||
actionType: "store",
|
||||
triggers: []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
addEvent(storageEvent);
|
||||
|
||||
@@ -453,18 +453,22 @@ const DuplicationControls3D = ({
|
||||
rotation: [newFloorItem.rotation.x, newFloorItem.rotation.y, newFloorItem.rotation.z],
|
||||
state: "idle",
|
||||
type: "storageUnit",
|
||||
storageCapacity: 10,
|
||||
storageCount: 10,
|
||||
materialType: "Default material",
|
||||
subType: duplicatedAsset.userData.eventData.subType || '',
|
||||
point: {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [updatedEventData.point.position[0], updatedEventData.point.position[1], updatedEventData.point.position[2]],
|
||||
rotation: [updatedEventData.point.rotation[0], updatedEventData.point.rotation[1], updatedEventData.point.rotation[2]],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Action 1",
|
||||
actionType: "store",
|
||||
storageCapacity: 10,
|
||||
triggers: []
|
||||
}
|
||||
actions: [
|
||||
{
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Action 1",
|
||||
actionType: "store",
|
||||
triggers: []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
addEvent(storageEvent);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Stats } from "@react-three/drei";
|
||||
import { detectModifierKeys } from "../../../utils/shortcutkeys/detectModifierKeys";
|
||||
|
||||
import { Perf } from 'r3f-perf';
|
||||
|
||||
export default function StatsHelper() {
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
@@ -18,5 +19,5 @@ export default function StatsHelper() {
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, []);
|
||||
|
||||
return visible ? <Stats className="stats" /> : null;
|
||||
return visible ? <Perf position="bottom-left" className="scene-performance-stats"/> : null;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import { getAllProjects } from "../../services/dashboard/getAllProjects";
|
||||
import { getUserData } from "../../functions/getUserData";
|
||||
import { useLoadingProgress, useSocketStore } from "../../store/builder/store";
|
||||
import { Color, SRGBColorSpace } from "three";
|
||||
import StatsHelper from "./helpers/StatsHelper";
|
||||
|
||||
export default function Scene({ layout }: { readonly layout: "Main Layout" | "Comparison Layout"; }) {
|
||||
const map = useMemo(() => [
|
||||
@@ -72,7 +71,6 @@ export default function Scene({ layout }: { readonly layout: "Main Layout" | "Co
|
||||
<Builder />
|
||||
<Simulation />
|
||||
<Visualization />
|
||||
<StatsHelper />
|
||||
</Canvas>
|
||||
</KeyboardControls>
|
||||
);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import Sun from '../environment/sky'
|
||||
import Shadows from '../environment/shadow'
|
||||
import PostProcessing from '../postProcessing/postProcessing'
|
||||
import StatsHelper from '../helpers/StatsHelper';
|
||||
import Controls from '../controls/controls';
|
||||
import { AdaptiveDpr, AdaptiveEvents, Environment } from '@react-three/drei'
|
||||
|
||||
import background from "../../../assets/textures/hdr/mudroadpuresky2k.hdr";
|
||||
// import { Perf } from 'r3f-perf';
|
||||
|
||||
function Setup() {
|
||||
return (
|
||||
@@ -18,12 +18,12 @@ function Setup() {
|
||||
|
||||
<PostProcessing />
|
||||
|
||||
{/* <Perf position="bottom-left" className="scene-performance-stats"/> */}
|
||||
|
||||
{/* <MovingClouds /> */}
|
||||
|
||||
<Environment files={background} environmentIntensity={1.5} />
|
||||
|
||||
<StatsHelper />
|
||||
|
||||
<AdaptiveEvents />
|
||||
|
||||
<AdaptiveDpr pixelated />
|
||||
|
||||
47
app/src/modules/scene/tools/autoRotate.tsx
Normal file
47
app/src/modules/scene/tools/autoRotate.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useThree, useFrame } from '@react-three/fiber'
|
||||
import type CameraControlsImpl from 'camera-controls'
|
||||
|
||||
export default function AutoRotate() {
|
||||
const { gl, controls } = useThree()
|
||||
const [isIdle, setIsIdle] = useState(false)
|
||||
const idleTimeout = useRef<NodeJS.Timeout | null>(null)
|
||||
const lastInteractionTime = useRef(Date.now())
|
||||
|
||||
const cameraControls = controls as CameraControlsImpl | null
|
||||
|
||||
const resetIdleTimer = () => {
|
||||
lastInteractionTime.current = Date.now()
|
||||
if (isIdle) setIsIdle(false)
|
||||
if (idleTimeout.current) clearTimeout(idleTimeout.current)
|
||||
idleTimeout.current = setTimeout(() => {
|
||||
setIsIdle(true)
|
||||
}, 30_000)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const dom = gl.domElement
|
||||
const listener = () => resetIdleTimer()
|
||||
|
||||
dom.addEventListener('pointerdown', listener)
|
||||
dom.addEventListener('wheel', listener)
|
||||
window.addEventListener('keydown', listener)
|
||||
|
||||
resetIdleTimer()
|
||||
|
||||
return () => {
|
||||
dom.removeEventListener('pointerdown', listener)
|
||||
dom.removeEventListener('wheel', listener)
|
||||
window.removeEventListener('keydown', listener)
|
||||
}
|
||||
}, [gl])
|
||||
|
||||
useFrame((_, delta) => {
|
||||
if (isIdle && cameraControls) {
|
||||
cameraControls.rotate(delta * 0.1, 0, true)
|
||||
cameraControls.update(delta)
|
||||
}
|
||||
})
|
||||
|
||||
return null
|
||||
}
|
||||
@@ -44,35 +44,29 @@ export function useRetrieveHandler() {
|
||||
if (!modelUuid || !pointUuid) return null;
|
||||
const currentTime = performance.now();
|
||||
|
||||
if (action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid &&
|
||||
action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid &&
|
||||
action.triggers[0]?.triggeredAsset?.triggeredAction?.actionUuid
|
||||
) {
|
||||
const newMaterial: MaterialSchema = {
|
||||
materialId: materialId,
|
||||
materialName: `${materialType}-${Date.now()}`,
|
||||
materialType: materialType,
|
||||
isActive: false,
|
||||
isVisible: false,
|
||||
isPaused: false,
|
||||
isRendered: true,
|
||||
startTime: currentTime,
|
||||
previous: {
|
||||
modelUuid: modelUuid,
|
||||
pointUuid: pointUuid,
|
||||
actionUuid: action.actionUuid
|
||||
},
|
||||
current: {
|
||||
modelUuid: modelUuid,
|
||||
pointUuid: pointUuid,
|
||||
actionUuid: action.actionUuid
|
||||
},
|
||||
};
|
||||
const newMaterial: MaterialSchema = {
|
||||
materialId: materialId,
|
||||
materialName: `${materialType}-${Date.now()}`,
|
||||
materialType: materialType,
|
||||
isActive: false,
|
||||
isVisible: false,
|
||||
isPaused: false,
|
||||
isRendered: true,
|
||||
startTime: currentTime,
|
||||
previous: {
|
||||
modelUuid: modelUuid,
|
||||
pointUuid: pointUuid,
|
||||
actionUuid: action.actionUuid
|
||||
},
|
||||
current: {
|
||||
modelUuid: modelUuid,
|
||||
pointUuid: pointUuid,
|
||||
actionUuid: action.actionUuid
|
||||
},
|
||||
};
|
||||
|
||||
addMaterial(newMaterial);
|
||||
return newMaterial;
|
||||
}
|
||||
return null;
|
||||
addMaterial(newMaterial);
|
||||
return newMaterial;
|
||||
}, [addMaterial, getModelUuidByActionUuid, getPointUuidByActionUuid, selectedProduct.productUuid]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -112,12 +106,16 @@ export function useRetrieveHandler() {
|
||||
getModelUuidByActionUuid(selectedProduct.productUuid, retrieval.action.actionUuid) ?? ''
|
||||
);
|
||||
|
||||
if (!storageUnit || storageUnit.currentLoad <= 0) {
|
||||
if (!storageUnit) {
|
||||
completedActions.push(actionUuid);
|
||||
hasChanges = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (storageUnit.currentLoad <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (retrieval.action.triggers.length === 0 || !retrieval.action.triggers[0]?.triggeredAsset) {
|
||||
return;
|
||||
}
|
||||
@@ -171,8 +169,9 @@ export function useRetrieveHandler() {
|
||||
if (retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, retrieval.action.triggers[0]?.triggeredAsset.triggeredAction.actionUuid);
|
||||
if (action && action.triggers.length > 0 && action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid) {
|
||||
const model = getEventByModelUuid(selectedProduct.productUuid, action.triggers[0]?.triggeredAsset.triggeredModel.modelUuid);
|
||||
if (model) {
|
||||
const model = getEventByModelUuid(selectedProduct.productUuid, action?.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid || '');
|
||||
const triggeredAction = getActionByUuid(selectedProduct.productUuid, action?.triggers[0]?.triggeredAsset?.triggeredAction?.actionUuid || '');
|
||||
if (model && triggeredAction) {
|
||||
if (model.type === 'vehicle') {
|
||||
const vehicle = getVehicleById(model.modelUuid);
|
||||
if (vehicle && !vehicle.isActive && vehicle.state === 'idle' && vehicle.isPicking && vehicle.currentLoad < vehicle.point.action.loadCapacity) {
|
||||
@@ -180,7 +179,7 @@ export function useRetrieveHandler() {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageUnit.point.action
|
||||
triggeredAction as StorageAction
|
||||
);
|
||||
if (material) {
|
||||
|
||||
@@ -193,11 +192,11 @@ export function useRetrieveHandler() {
|
||||
retrieveLogStatus(material.materialName, `is being picked by ${armBot?.modelName}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (triggeredAction) {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageUnit.point.action
|
||||
triggeredAction as StorageAction
|
||||
);
|
||||
if (material) {
|
||||
|
||||
@@ -271,10 +270,15 @@ export function useRetrieveHandler() {
|
||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||
if (lastMaterial) {
|
||||
if (vehicle?.currentLoad < vehicle.point.action.loadCapacity) {
|
||||
const triggeredAction = getActionByUuid(
|
||||
selectedProduct.productUuid,
|
||||
retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid || ''
|
||||
);
|
||||
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageUnit.point.action
|
||||
triggeredAction as StorageAction
|
||||
);
|
||||
|
||||
if (material) {
|
||||
@@ -322,6 +326,12 @@ export function useRetrieveHandler() {
|
||||
const triggeredModel = action.triggers[0]?.triggeredAsset?.triggeredModel?.modelUuid
|
||||
? getEventByModelUuid(selectedProduct.productUuid, action.triggers[0].triggeredAsset.triggeredModel.modelUuid)
|
||||
: null;
|
||||
|
||||
const triggeredAction = getActionByUuid(
|
||||
selectedProduct.productUuid,
|
||||
action.triggers[0]?.triggeredAsset?.triggeredAction?.actionUuid || ''
|
||||
);
|
||||
|
||||
if (triggeredModel?.type === 'vehicle') {
|
||||
const model = getVehicleById(triggeredModel.modelUuid);
|
||||
if (model && !model.isActive && model.state === 'idle' && model.isPicking && model.currentLoad < model.point.action.loadCapacity) {
|
||||
@@ -333,7 +343,7 @@ export function useRetrieveHandler() {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageUnit.point.action
|
||||
triggeredAction as StorageAction
|
||||
);
|
||||
if (material) {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
@@ -359,7 +369,7 @@ export function useRetrieveHandler() {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageUnit.point.action
|
||||
triggeredAction as StorageAction
|
||||
);
|
||||
if (material) {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
@@ -385,7 +395,7 @@ export function useRetrieveHandler() {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageUnit.point.action
|
||||
triggeredAction as StorageAction
|
||||
);
|
||||
if (material) {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
@@ -417,7 +427,7 @@ export function useRetrieveHandler() {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageUnit.point.action
|
||||
triggeredAction as StorageAction
|
||||
);
|
||||
if (material) {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
@@ -438,7 +448,7 @@ export function useRetrieveHandler() {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageUnit.point.action
|
||||
triggeredAction as StorageAction
|
||||
);
|
||||
if (material) {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
@@ -484,10 +494,15 @@ export function useRetrieveHandler() {
|
||||
|
||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||
if (lastMaterial) {
|
||||
const triggeredAction = getActionByUuid(
|
||||
selectedProduct.productUuid,
|
||||
action?.triggers[0]?.triggeredAsset?.triggeredAction?.actionUuid || ''
|
||||
);
|
||||
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageUnit.point.action
|
||||
triggeredAction as StorageAction
|
||||
);
|
||||
if (material) {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
|
||||
@@ -56,7 +56,6 @@ function PillarJibAnimator({
|
||||
if (crane.currentPhase === 'init-pickup') {
|
||||
if (crane.currentMaterials.length > 0) {
|
||||
const materials = scene.getObjectsByProperty('uuid', crane.currentMaterials[0].materialId);
|
||||
console.log('materials: ', materials);
|
||||
const material = materials.find((material) => material.visible === true);
|
||||
if (material) {
|
||||
const materialWorld = new THREE.Vector3();
|
||||
|
||||
@@ -35,17 +35,15 @@ function PillarJibInstance({ crane }: { crane: CraneStatus }) {
|
||||
if (!crane.isActive && crane.currentPhase === 'init' && crane.currentMaterials.length > 0 && action.maxPickUpCount <= crane.currentMaterials.length) {
|
||||
setCurrentPhase(crane.modelUuid, 'init-pickup');
|
||||
} else if (crane.currentPhase === 'picking' && crane.currentMaterials.length > 0 && action.maxPickUpCount <= crane.currentMaterials.length && !crane.isCarrying) {
|
||||
if (action.triggers.length > 0) {
|
||||
if (humanAsset?.animationState?.current === "working_standing" && humanAsset?.animationState?.isCompleted && humanId && humanAction && humanAction.actionType === 'operator') {
|
||||
setCurrentAnimation(humanId, 'idle', true, true, true);
|
||||
setIsCaryying(crane.modelUuid, true);
|
||||
setCurrentPhase(crane.modelUuid, 'pickup-drop');
|
||||
} else {
|
||||
setCurrentPhaseHuman(humanId, 'hooking');
|
||||
setHumanActive(humanId, true);
|
||||
setHumanState(humanId, 'running');
|
||||
setCurrentAnimation(humanId, 'working_standing', true, false, false);
|
||||
}
|
||||
if (humanAsset?.animationState?.current === "working_standing" && humanAsset?.animationState?.isCompleted && humanId && humanAction && humanAction.actionType === 'operator') {
|
||||
setCurrentAnimation(humanId, 'idle', true, true, true);
|
||||
setIsCaryying(crane.modelUuid, true);
|
||||
setCurrentPhase(crane.modelUuid, 'pickup-drop');
|
||||
} else {
|
||||
setCurrentPhaseHuman(humanId, 'hooking');
|
||||
setHumanActive(humanId, true);
|
||||
setHumanState(humanId, 'running');
|
||||
setCurrentAnimation(humanId, 'working_standing', true, false, false);
|
||||
}
|
||||
} else if (crane.currentPhase === 'dropping' && crane.currentMaterials.length > 0 && action.maxPickUpCount <= crane.currentMaterials.length && crane.isCarrying && human.currentPhase === 'hooking') {
|
||||
setCurrentPhaseHuman(humanId, 'loadPoint-unloadPoint');
|
||||
|
||||
@@ -144,8 +144,8 @@ function TriggerConnector() {
|
||||
// Handle StorageUnit point
|
||||
else if (event.type === "storageUnit" && 'point' in event) {
|
||||
const point = event.point;
|
||||
if (point.action?.triggers) {
|
||||
point.action.triggers.forEach(trigger => {
|
||||
point.actions?.forEach(action => {
|
||||
action.triggers?.forEach(trigger => {
|
||||
if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint) {
|
||||
newConnections.push({
|
||||
id: `${point.uuid}-${trigger.triggeredAsset.triggeredPoint.pointUuid}-${trigger.triggerUuid}`,
|
||||
@@ -155,7 +155,7 @@ function TriggerConnector() {
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
// Handle Human point
|
||||
else if (event.type === "human" && 'point' in event) {
|
||||
|
||||
@@ -126,9 +126,11 @@ function OperatorInstance({ human }: { human: HumanStatus }) {
|
||||
humanStatus(human.modelUuid, 'Started from loadPoint, heading to unloadPoint');
|
||||
}
|
||||
} else if (human.state === 'idle' && human.currentPhase === 'unhooking') {
|
||||
setHumanState(human.modelUuid, 'running');
|
||||
setHumanActive(human.modelUuid, true);
|
||||
setCurrentAnimation(human.modelUuid, 'working_standing', true, false, false);
|
||||
setTimeout(() => {
|
||||
setHumanState(human.modelUuid, 'running');
|
||||
setHumanActive(human.modelUuid, true);
|
||||
setCurrentAnimation(human.modelUuid, 'working_standing', true, false, false);
|
||||
}, 1)
|
||||
}
|
||||
} else {
|
||||
reset()
|
||||
|
||||
@@ -108,7 +108,7 @@ function WorkerInstance({ human }: { human: HumanStatus }) {
|
||||
if (!human.isActive && human.state === 'idle' && human.currentPhase === 'init') {
|
||||
const humanMesh = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||
if (!humanMesh) return;
|
||||
|
||||
|
||||
const toPickupPath = computePath(humanMesh.position.toArray(), action?.pickUpPoint?.position || [0, 0, 0]);
|
||||
|
||||
setPath(toPickupPath);
|
||||
@@ -233,15 +233,13 @@ function WorkerInstance({ human }: { human: HumanStatus }) {
|
||||
|
||||
const checkAnimation = () => {
|
||||
if (humanAsset?.animationState?.isCompleted) {
|
||||
if (model.point.action.actionType === 'store') {
|
||||
loopMaterialDropToStorage(
|
||||
human.modelUuid,
|
||||
human.currentLoad,
|
||||
model.modelUuid,
|
||||
model.point.action.storageCapacity,
|
||||
(action as HumanAction)
|
||||
);
|
||||
}
|
||||
loopMaterialDropToStorage(
|
||||
human.modelUuid,
|
||||
human.currentLoad,
|
||||
model.modelUuid,
|
||||
model.storageCapacity,
|
||||
(action as HumanAction)
|
||||
);
|
||||
} else {
|
||||
requestAnimationFrame(checkAnimation);
|
||||
}
|
||||
|
||||
@@ -136,15 +136,14 @@ function Products() {
|
||||
if (event.type === 'storageUnit') {
|
||||
addStorageUnit(selectedProduct.productUuid, event);
|
||||
|
||||
if (event.point.action.actionType === 'retrieve') {
|
||||
const storageAction = event.point.action;
|
||||
const materials = Array.from({ length: storageAction.storageCapacity }, () => ({
|
||||
materialType: storageAction.materialType || 'Default material',
|
||||
if (event.storageCount > 0) {
|
||||
const materials = Array.from({ length: event.storageCount }, () => ({
|
||||
materialType: event.materialType || 'Default material',
|
||||
materialId: THREE.MathUtils.generateUUID()
|
||||
}));
|
||||
|
||||
setCurrentMaterials(event.modelUuid, materials);
|
||||
updateCurrentLoad(event.modelUuid, storageAction.storageCapacity);
|
||||
updateCurrentLoad(event.modelUuid, event.storageCount);
|
||||
} else {
|
||||
setCurrentMaterials(event.modelUuid, []);
|
||||
updateCurrentLoad(event.modelUuid, 0);
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { extractTriggersFromPoint } from "./extractTriggersFromPoint";
|
||||
|
||||
export function determineExecutionOrder(products: productsSchema): PointsScheme[] {
|
||||
export function determineExecutionOrder(products: productsSchema): Action[] {
|
||||
// Create maps for all events and points
|
||||
const eventMap = new Map<string, EventsSchema>();
|
||||
const pointMap = new Map<string, PointsScheme>();
|
||||
const allPoints: PointsScheme[] = [];
|
||||
const spawnActions: Action[] = [];
|
||||
|
||||
// First pass: collect all points
|
||||
// First pass: collect all points and identify spawn actions
|
||||
products.forEach(product => {
|
||||
product.eventDatas.forEach(event => {
|
||||
eventMap.set(event.modelUuid, event);
|
||||
@@ -15,6 +16,11 @@ export function determineExecutionOrder(products: productsSchema): PointsScheme[
|
||||
event.points.forEach(point => {
|
||||
pointMap.set(point.uuid, point);
|
||||
allPoints.push(point);
|
||||
|
||||
// Check for spawn actions in conveyors
|
||||
if (point.action.actionType === 'spawn') {
|
||||
spawnActions.push(point.action);
|
||||
}
|
||||
});
|
||||
} else if (event.type === 'vehicle' ||
|
||||
event.type === 'machine' ||
|
||||
@@ -25,6 +31,16 @@ export function determineExecutionOrder(products: productsSchema): PointsScheme[
|
||||
) {
|
||||
pointMap.set(event.point.uuid, event.point);
|
||||
allPoints.push(event.point);
|
||||
|
||||
// Check for spawn actions in storage units and other types
|
||||
if (event.type === 'storageUnit') {
|
||||
const storagePoint = event.point as StoragePointSchema;
|
||||
storagePoint.actions.forEach(action => {
|
||||
if (action.actionType === 'retrieve') {
|
||||
spawnActions.push(action);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -33,11 +49,19 @@ export function determineExecutionOrder(products: productsSchema): PointsScheme[
|
||||
const graph = new Map<string, string[]>();
|
||||
const reverseGraph = new Map<string, string[]>();
|
||||
const allTriggeredPoints = new Set<string>();
|
||||
const actionMap = new Map<string, Action>(); // Map point UUID to its primary action
|
||||
|
||||
allPoints.forEach(point => {
|
||||
const triggers = extractTriggersFromPoint(point);
|
||||
const dependencies: string[] = [];
|
||||
|
||||
// Store the primary action for this point
|
||||
if ('action' in point) {
|
||||
actionMap.set(point.uuid, point.action);
|
||||
} else if ('actions' in point && point.actions.length > 0) {
|
||||
actionMap.set(point.uuid, point.actions[0]); // Use first action as primary
|
||||
}
|
||||
|
||||
triggers.forEach(trigger => {
|
||||
const targetUuid = trigger.triggeredAsset?.triggeredPoint?.pointUuid;
|
||||
if (targetUuid && pointMap.has(targetUuid)) {
|
||||
@@ -58,15 +82,12 @@ export function determineExecutionOrder(products: productsSchema): PointsScheme[
|
||||
const rootPoints = allPoints
|
||||
.filter(point => !allTriggeredPoints.has(point.uuid))
|
||||
.filter(point => {
|
||||
// Only include roots that actually have triggers pointing FROM them
|
||||
const triggers = extractTriggersFromPoint(point);
|
||||
return triggers.some(t => t.triggeredAsset?.triggeredPoint?.pointUuid);
|
||||
});
|
||||
|
||||
// If no root points found but we have triggered points, find the earliest triggers
|
||||
if (rootPoints.length === 0 && allTriggeredPoints.size > 0) {
|
||||
// This handles cases where we have circular dependencies
|
||||
// but still want to include the triggered points
|
||||
const minTriggerCount = Math.min(
|
||||
...Array.from(allTriggeredPoints)
|
||||
.map(uuid => (graph.get(uuid) || []).length)
|
||||
@@ -105,11 +126,18 @@ export function determineExecutionOrder(products: productsSchema): PointsScheme[
|
||||
// Start processing from root points
|
||||
rootPoints.forEach(root => visit(root.uuid));
|
||||
|
||||
// Convert UUIDs back to points and filter out untriggered points
|
||||
const triggeredPoints = order
|
||||
.map(uuid => pointMap.get(uuid)!)
|
||||
.filter(point => allTriggeredPoints.has(point.uuid) ||
|
||||
rootPoints.some(root => root.uuid === point.uuid));
|
||||
// Convert UUIDs back to actions
|
||||
const triggeredActions = order
|
||||
.map(uuid => actionMap.get(uuid))
|
||||
.filter((action): action is Action => action !== undefined);
|
||||
|
||||
return triggeredPoints;
|
||||
// Combine triggered actions with ALL spawn actions
|
||||
const allExecutionActions = [...triggeredActions, ...spawnActions];
|
||||
|
||||
// Remove duplicate actions while preserving order
|
||||
const uniqueActions = allExecutionActions.filter((action, index, array) =>
|
||||
array.findIndex(a => a.actionUuid === action.actionUuid) === index
|
||||
);
|
||||
|
||||
return uniqueActions;
|
||||
}
|
||||
@@ -21,12 +21,13 @@ function Simulator() {
|
||||
if (!product) return;
|
||||
|
||||
const executionOrder = determineExecutionOrder([product]);
|
||||
executionOrder.forEach(point => {
|
||||
const action = 'actions' in point ? point.actions[0] : point.action;
|
||||
|
||||
executionOrder.forEach(action => {
|
||||
handleAction(action);
|
||||
});
|
||||
}, [products, isPlaying, isReset, selectedProduct]);
|
||||
|
||||
|
||||
return (
|
||||
|
||||
<>
|
||||
|
||||
@@ -106,6 +106,7 @@ export function useTriggerHandler() {
|
||||
|
||||
// Handle current action using Event Manager
|
||||
addVehicleToMonitor(vehicle.modelUuid, () => {
|
||||
setIsVisible(materialId, false);
|
||||
handleAction(action, materialId);
|
||||
})
|
||||
}
|
||||
@@ -392,7 +393,7 @@ export function useTriggerHandler() {
|
||||
}
|
||||
}
|
||||
} else if (toEvent?.type === 'crane') {
|
||||
// Transfer to Human
|
||||
// Transfer to Crane
|
||||
if (materialId && trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) {
|
||||
const material = getMaterialById(materialId);
|
||||
if (material) {
|
||||
@@ -575,7 +576,7 @@ export function useTriggerHandler() {
|
||||
|
||||
if (action && storageUnit) {
|
||||
|
||||
if (storageUnit.currentLoad < storageUnit.point.action.storageCapacity) {
|
||||
if (storageUnit.currentLoad < storageUnit.storageCapacity) {
|
||||
|
||||
// Handle current action from vehicle
|
||||
handleAction(action, materialId);
|
||||
@@ -622,7 +623,7 @@ export function useTriggerHandler() {
|
||||
}
|
||||
}
|
||||
} else if (toEvent?.type === 'crane') {
|
||||
// Vehicle to Human
|
||||
// Vehicle to Crane
|
||||
if (materialId && trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) {
|
||||
const material = getMaterialById(materialId);
|
||||
if (material) {
|
||||
@@ -1135,7 +1136,7 @@ export function useTriggerHandler() {
|
||||
|
||||
if (action && storageUnit) {
|
||||
|
||||
if (storageUnit.currentLoad < storageUnit.point.action.storageCapacity) {
|
||||
if (storageUnit.currentLoad < storageUnit.storageCapacity) {
|
||||
|
||||
// Handle current action from vehicle
|
||||
handleAction(action, materialId);
|
||||
@@ -1782,7 +1783,7 @@ export function useTriggerHandler() {
|
||||
|
||||
if (action && storageUnit) {
|
||||
|
||||
if (storageUnit.currentLoad < storageUnit.point.action.storageCapacity) {
|
||||
if (storageUnit.currentLoad < storageUnit.storageCapacity) {
|
||||
|
||||
// Handle current action from vehicle
|
||||
handleAction(action, materialId);
|
||||
@@ -1801,25 +1802,25 @@ export function useTriggerHandler() {
|
||||
}
|
||||
} else if (fromEvent?.type === 'crane') {
|
||||
if (toEvent?.type === 'transfer') {
|
||||
// Crane Unit to Transfer
|
||||
// Crane to Transfer
|
||||
|
||||
} else if (toEvent?.type === 'vehicle') {
|
||||
// Crane Unit to Vehicle
|
||||
// Crane to Vehicle
|
||||
|
||||
} else if (toEvent?.type === 'machine') {
|
||||
// Crane Unit to Machine
|
||||
// Crane to Machine
|
||||
|
||||
} else if (toEvent?.type === 'roboticArm') {
|
||||
// Crane Unit to Robotic Arm
|
||||
// Crane to Robotic Arm
|
||||
|
||||
} else if (toEvent?.type === 'storageUnit') {
|
||||
// Crane Unit to Storage Unit
|
||||
// Crane to Storage Unit
|
||||
|
||||
} else if (toEvent?.type === 'human') {
|
||||
// Crane Unit to Human
|
||||
// Crane to Human
|
||||
|
||||
} else if (toEvent?.type === 'crane') {
|
||||
// Crane Unit to Human
|
||||
// Crane to Human
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ const StorageContentUi: React.FC<StorageContentUiProps> = ({ storageUnit }) => {
|
||||
status={storageUnit.state}
|
||||
count={storageUnit.currentLoad}
|
||||
enableStatue={false}
|
||||
totalCapacity={storageUnit.point.action.storageCapacity}
|
||||
totalCapacity={storageUnit.storageCapacity}
|
||||
/>
|
||||
</Html>
|
||||
);
|
||||
|
||||
@@ -378,8 +378,10 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
|
||||
const human = getHumanById(humanId);
|
||||
const humanAction = human?.point.actions.find((action) => action.actionUuid === humanActionId);
|
||||
if (human && human.currentAction?.actionUuid !== humanActionId && human.currentLoad < (humanAction?.loadCapacity || 0)) {
|
||||
addCurrentAction(humanId, humanActionId);
|
||||
if (human && human.currentLoad < (humanAction?.loadCapacity || 0)) {
|
||||
if (human.currentAction?.actionUuid !== humanActionId) {
|
||||
addCurrentAction(humanId, humanActionId);
|
||||
}
|
||||
setTimeout(() => {
|
||||
unloadLoop();
|
||||
}, 500)
|
||||
@@ -388,16 +390,14 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
|
||||
function handleMaterialDropToStorageUnit(model: StorageEventSchema) {
|
||||
if (model) {
|
||||
if (model.point.action.actionType === 'store') {
|
||||
loopMaterialDropToStorage(
|
||||
agvDetail.modelUuid,
|
||||
agvDetail.currentLoad,
|
||||
agvDetail.point.action.unLoadDuration,
|
||||
model.modelUuid,
|
||||
model.point.action.storageCapacity,
|
||||
agvDetail.point.action
|
||||
);
|
||||
}
|
||||
loopMaterialDropToStorage(
|
||||
agvDetail.modelUuid,
|
||||
agvDetail.currentLoad,
|
||||
agvDetail.point.action.unLoadDuration,
|
||||
model.modelUuid,
|
||||
model.storageCapacity,
|
||||
agvDetail.point.action
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,13 @@ export const createMaterialStore = () => {
|
||||
addMaterial: (material) => {
|
||||
let updatedMaterial: MaterialSchema | undefined;
|
||||
set((state) => {
|
||||
const existingIndex = state.materials.findIndex(m => m.materialId === material.materialId);
|
||||
if (existingIndex !== -1) {
|
||||
state.materials.splice(existingIndex, 1);
|
||||
}
|
||||
|
||||
state.materials.push(material);
|
||||
updatedMaterial = JSON.parse(JSON.stringify(material));
|
||||
});
|
||||
return updatedMaterial;
|
||||
},
|
||||
|
||||
@@ -205,7 +205,7 @@ export const createStorageUnitStore = () => {
|
||||
|
||||
getFullStorageUnits: () => {
|
||||
return get().storageUnits.filter(
|
||||
s => s.currentLoad >= s.point.action.storageCapacity
|
||||
s => s.currentLoad >= s.storageCapacity
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
8
app/src/types/simulationTypes.d.ts
vendored
8
app/src/types/simulationTypes.d.ts
vendored
@@ -90,8 +90,6 @@ interface StorageAction {
|
||||
actionUuid: string;
|
||||
actionName: string;
|
||||
actionType: "store" | "retrieve";
|
||||
materialType?: string;
|
||||
storageCapacity: number;
|
||||
triggers: TriggerSchema[];
|
||||
}
|
||||
|
||||
@@ -155,7 +153,7 @@ interface StoragePointSchema {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
action: StorageAction;
|
||||
actions: StorageAction[];
|
||||
}
|
||||
|
||||
interface HumanPointSchema {
|
||||
@@ -207,6 +205,9 @@ interface MachineEventSchema extends AssetEventSchema {
|
||||
interface StorageEventSchema extends AssetEventSchema {
|
||||
type: "storageUnit";
|
||||
subType: string;
|
||||
storageCapacity: number;
|
||||
storageCount: number;
|
||||
materialType: string;
|
||||
point: StoragePointSchema;
|
||||
}
|
||||
|
||||
@@ -455,7 +456,6 @@ type ConveyorPoints = NormalConveyor | YJunctionConveyor | CurvedConveyor;
|
||||
|
||||
// Crane Constraints
|
||||
|
||||
|
||||
type PillarJibCrane = {
|
||||
trolleySpeed: number;
|
||||
hookSpeed: number;
|
||||
|
||||
Reference in New Issue
Block a user