feat: Enhance simulation state management to include StaticMachineEventsSchema

- Updated various modules to accommodate StaticMachineEventsSchema in simulation states.
- Modified event handling in addAssetModel, deleteFloorItems, and loadInitialFloorItems to support new event types.
- Adjusted type definitions in worldTypes.d.ts to define StaticMachineEventsSchema.
- Refactored path management in processCreator and simulation to handle new event types.
- Ensured compatibility in selection and manipulation controls for StaticMachine events.
- Removed bug that made the other assets not droppable
This commit is contained in:
2025-04-05 14:33:25 +05:30
parent c89129e4ce
commit 1cc877aee1
15 changed files with 412 additions and 377 deletions

View File

@@ -219,7 +219,7 @@ async function handleModelLoad(
eventData.position = newFloorItem.position; eventData.position = newFloorItem.position;
eventData.rotation = [model.rotation.x, model.rotation.y, model.rotation.z]; eventData.rotation = [model.rotation.x, model.rotation.y, model.rotation.z];
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => [ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
...(prevEvents || []), ...(prevEvents || []),
eventData as Types.ConveyorEventsSchema eventData as Types.ConveyorEventsSchema
]); ]);
@@ -235,7 +235,7 @@ async function handleModelLoad(
points: { points: {
uuid: pointUUID, uuid: pointUUID,
position: res.points.position as [number, number, number], position: res.points.position as [number, number, number],
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Start', start: {}, hitCount: 1, end: {}, buffer: 0 }, actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: '', start: {}, hitCount: 1, end: {}, buffer: 0 },
connections: { source: { modelUUID: model.uuid, pointUUID: pointUUID }, targets: [] }, connections: { source: { modelUUID: model.uuid, pointUUID: pointUUID }, targets: [] },
speed: 2, speed: 2,
} }
@@ -281,13 +281,50 @@ async function handleModelLoad(
return updatedItems; return updatedItems;
}); });
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => [ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
...(prevEvents || []), ...(prevEvents || []),
eventData as Types.VehicleEventsSchema eventData as Types.VehicleEventsSchema
]); ]);
socket.emit("v2:model-asset:add", data); socket.emit("v2:model-asset:add", data);
} else {
// API
// await setFloorItemApi(
// organization,
// newFloorItem.modeluuid,
// newFloorItem.modelname,
// newFloorItem.modelfileID,
// newFloorItem.position,
// { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
// false,
// true,
// );
// SOCKET
const data = {
organization,
modeluuid: newFloorItem.modeluuid,
modelname: newFloorItem.modelname,
modelfileID: newFloorItem.modelfileID,
position: newFloorItem.position,
rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
isLocked: false,
isVisible: true,
socketId: socket.id
};
setFloorItems((prevItems) => {
const updatedItems = [...(prevItems || []), newFloorItem];
localStorage.setItem("FloorItems", JSON.stringify(updatedItems));
return updatedItems;
});
socket.emit("v2:model-asset:add", data);
} }
gsap.to(model.position, { y: newFloorItem.position[1], duration: 1.5, ease: "power2.out" }); gsap.to(model.position, { y: newFloorItem.position[1], duration: 1.5, ease: "power2.out" });

View File

@@ -76,7 +76,7 @@ async function DeleteFloorItems(
} }
setFloorItems(updatedItems); setFloorItems(updatedItems);
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => { setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
const updatedEvents = (prevEvents || []).filter(event => event.modeluuid !== removedItem.modeluuid); const updatedEvents = (prevEvents || []).filter(event => event.modeluuid !== removedItem.modeluuid);
return updatedEvents; return updatedEvents;
}); });

View File

@@ -12,7 +12,7 @@ import { getFloorAssets } from '../../../services/factoryBuilder/assest/floorAss
async function loadInitialFloorItems( async function loadInitialFloorItems(
itemsGroup: Types.RefGroup, itemsGroup: Types.RefGroup,
setFloorItems: Types.setFloorItemSetState, setFloorItems: Types.setFloorItemSetState,
setSimulationStates: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => void setSimulationStates: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => void
): Promise<void> { ): Promise<void> {
if (!itemsGroup.current) return; if (!itemsGroup.current) return;
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`; let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
@@ -137,7 +137,7 @@ async function loadInitialFloorItems(
}, },
]); ]);
if (item.eventData) { if (item.eventData || item.modelfileID === '67e3db95c2e8f37134526fb2') {
processEventData(item, setSimulationStates); processEventData(item, setSimulationStates);
} }
@@ -157,7 +157,7 @@ function processLoadedModel(
item: Types.EventData, item: Types.EventData,
itemsGroup: Types.RefGroup, itemsGroup: Types.RefGroup,
setFloorItems: Types.setFloorItemSetState, setFloorItems: Types.setFloorItemSetState,
setSimulationStates: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => void setSimulationStates: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => void
) { ) {
const model = gltf; const model = gltf;
model.uuid = item.modeluuid; model.uuid = item.modeluuid;
@@ -192,7 +192,7 @@ function processLoadedModel(
}, },
]); ]);
if (item.eventData) { if (item.eventData || item.modelfileID === '67e3db95c2e8f37134526fb2') {
processEventData(item, setSimulationStates); processEventData(item, setSimulationStates);
} }
@@ -210,7 +210,7 @@ function processEventData(item: Types.EventData, setSimulationStates: any) {
data.position = item.position; data.position = item.position;
data.rotation = [item.rotation.x, item.rotation.y, item.rotation.z]; data.rotation = [item.rotation.x, item.rotation.y, item.rotation.z];
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => [ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
...(prevEvents || []), ...(prevEvents || []),
data as Types.ConveyorEventsSchema data as Types.ConveyorEventsSchema
]); ]);
@@ -222,11 +222,37 @@ function processEventData(item: Types.EventData, setSimulationStates: any) {
data.modelName = item.modelname; data.modelName = item.modelname;
data.position = item.position; data.position = item.position;
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => [ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
...(prevEvents || []), ...(prevEvents || []),
data as Types.VehicleEventsSchema data as Types.VehicleEventsSchema
]); ]);
} else if (item.modelfileID === '67e3db95c2e8f37134526fb2') {
const pointUUID = THREE.MathUtils.generateUUID();
const pointPosition = new THREE.Vector3(0, 1.75, 0);
const staticMachine: Types.StaticMachineEventsSchema = {
modeluuid: item.modeluuid,
modelName: item.modelname,
type: "StaticMachine",
points: {
uuid: pointUUID,
position: [pointPosition.x, pointPosition.y, pointPosition.z],
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', buffer: 'Inherit', material: 'Inherit', isUsed: false },
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
connections: { source: { modelUUID: item.modeluuid, pointUUID: pointUUID }, targets: [] },
},
position: item.position
};
console.log(staticMachine);
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
...(prevEvents || []),
staticMachine as Types.StaticMachineEventsSchema
]);
} }
} }

View File

@@ -151,7 +151,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
return updatedItems; return updatedItems;
}); });
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid); let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
const email = localStorage.getItem("email"); const email = localStorage.getItem("email");
const organization = email ? email.split("@")[1].split(".")[0] : "default"; const organization = email ? email.split("@")[1].split(".")[0] : "default";
@@ -234,7 +234,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
newEventData.position = newFloorItem.position; newEventData.position = newFloorItem.position;
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => [ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
...(prevEvents || []), ...(prevEvents || []),
newEventData as Types.ConveyorEventsSchema newEventData as Types.ConveyorEventsSchema
]); ]);
@@ -314,7 +314,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
newEventData.modelName = newFloorItem.modelname; newEventData.modelName = newFloorItem.modelname;
newEventData.position = newFloorItem.position; newEventData.position = newFloorItem.position;
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => [ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
...(prevEvents || []), ...(prevEvents || []),
newEventData as Types.VehicleEventsSchema newEventData as Types.VehicleEventsSchema
]); ]);

View File

@@ -132,7 +132,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
return updatedItems; return updatedItems;
}); });
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid); let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
const email = localStorage.getItem("email"); const email = localStorage.getItem("email");
const organization = email ? email.split("@")[1].split(".")[0] : "default"; const organization = email ? email.split("@")[1].split(".")[0] : "default";
@@ -216,7 +216,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
newEventData.position = newFloorItem.position; newEventData.position = newFloorItem.position;
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => [ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
...(prevEvents || []), ...(prevEvents || []),
newEventData as Types.ConveyorEventsSchema newEventData as Types.ConveyorEventsSchema
]); ]);
@@ -295,7 +295,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
newEventData.modelName = newFloorItem.modelname; newEventData.modelName = newFloorItem.modelname;
newEventData.position = newFloorItem.position; newEventData.position = newFloorItem.position;
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => [ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
...(prevEvents || []), ...(prevEvents || []),
newEventData as Types.VehicleEventsSchema newEventData as Types.VehicleEventsSchema
]); ]);

View File

@@ -180,7 +180,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
return updatedItems; return updatedItems;
}); });
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid); let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
const email = localStorage.getItem("email"); const email = localStorage.getItem("email");
const organization = email ? email.split("@")[1].split(".")[0] : "default"; const organization = email ? email.split("@")[1].split(".")[0] : "default";
@@ -229,7 +229,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
newEventData.position = newFloorItem.position; newEventData.position = newFloorItem.position;
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => { setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
const updatedEvents = (prevEvents || []).map(event => const updatedEvents = (prevEvents || []).map(event =>
event.modeluuid === newFloorItem.modeluuid event.modeluuid === newFloorItem.modeluuid
? { ...event, ...newEventData } ? { ...event, ...newEventData }
@@ -280,7 +280,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
newEventData.modelName = newFloorItem.modelname; newEventData.modelName = newFloorItem.modelname;
newEventData.position = newFloorItem.position; newEventData.position = newFloorItem.position;
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => { setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
const updatedEvents = (prevEvents || []).map(event => const updatedEvents = (prevEvents || []).map(event =>
event.modeluuid === newFloorItem.modeluuid event.modeluuid === newFloorItem.modeluuid
? { ...event, ...newEventData } ? { ...event, ...newEventData }

View File

@@ -184,7 +184,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
return updatedItems; return updatedItems;
}); });
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid); let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
const email = localStorage.getItem("email"); const email = localStorage.getItem("email");
const organization = email ? email.split("@")[1].split(".")[0] : "default"; const organization = email ? email.split("@")[1].split(".")[0] : "default";
@@ -233,7 +233,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
newEventData.position = newFloorItem.position; newEventData.position = newFloorItem.position;
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z]; newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => { setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
const updatedEvents = (prevEvents || []).map(event => const updatedEvents = (prevEvents || []).map(event =>
event.modeluuid === newFloorItem.modeluuid event.modeluuid === newFloorItem.modeluuid
? { ...event, ...newEventData } ? { ...event, ...newEventData }
@@ -285,7 +285,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
newEventData.modelName = newFloorItem.modelname; newEventData.modelName = newFloorItem.modelname;
newEventData.position = newFloorItem.position; newEventData.position = newFloorItem.position;
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => { setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
const updatedEvents = (prevEvents || []).map(event => const updatedEvents = (prevEvents || []).map(event =>
event.modeluuid === newFloorItem.modeluuid event.modeluuid === newFloorItem.modeluuid
? { ...event, ...newEventData } ? { ...event, ...newEventData }

View File

@@ -240,7 +240,7 @@ const SelectionControls: React.FC = () => {
} }
}); });
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => { setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
const updatedEvents = (prevEvents || []).filter(event => event.modeluuid !== selectedMesh.uuid); const updatedEvents = (prevEvents || []).filter(event => event.modeluuid !== selectedMesh.uuid);
return updatedEvents; return updatedEvents;
}); });

View File

@@ -8,7 +8,7 @@ function Behaviour() {
const { floorItems } = useFloorItems(); const { floorItems } = useFloorItems();
useEffect(() => { useEffect(() => {
const newPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[] = []; const newPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[] = [];
// floorItems.forEach((item: Types.FloorItemType) => { // floorItems.forEach((item: Types.FloorItemType) => {
// if (item.modelfileID === "672a090f80d91ac979f4d0bd") { // if (item.modelfileID === "672a090f80d91ac979f4d0bd") {

View File

@@ -180,7 +180,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
updateBackend(updatedPathDetails); updateBackend(updatedPathDetails);
}; };
const updateBackend = async (updatedPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => { const updateBackend = async (updatedPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
if (updatedPaths.length === 0) return; if (updatedPaths.length === 0) return;
const email = localStorage.getItem("email"); const email = localStorage.getItem("email");
const organization = email ? email.split("@")[1].split(".")[0] : ""; const organization = email ? email.split("@")[1].split(".")[0] : "";

View File

@@ -3,386 +3,340 @@ import * as Types from "../../../types/world/worldTypes";
import { useRef, useState, useEffect, useMemo } from "react"; import { useRef, useState, useEffect, useMemo } from "react";
import { Sphere, TransformControls } from "@react-three/drei"; import { Sphere, TransformControls } from "@react-three/drei";
import { import {
useEditingPoint, useEditingPoint,
useEyeDropMode, useEyeDropMode,
useIsConnecting, useIsConnecting,
usePreviewPosition, usePreviewPosition,
useRenderDistance, useRenderDistance,
useSelectedActionSphere, useSelectedActionSphere,
useSelectedPath, useSelectedPath,
useSimulationStates, useSimulationStates,
} from "../../../store/store"; } from "../../../store/store";
import { useFrame, useThree } from "@react-three/fiber"; import { useFrame, useThree } from "@react-three/fiber";
import { useSubModuleStore } from "../../../store/useModuleStore"; import { useSubModuleStore } from "../../../store/useModuleStore";
import { usePlayButtonStore } from "../../../store/usePlayButtonStore"; import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
import { setEventApi } from "../../../services/factoryBuilder/assest/floorAsset/setEventsApt"; import { setEventApi } from "../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
function PathCreation({ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObject<THREE.Group>; }) {
pathsGroupRef, const { isPlaying } = usePlayButtonStore();
}: { const { renderDistance } = useRenderDistance();
pathsGroupRef: React.MutableRefObject<THREE.Group>; const { setSubModule } = useSubModuleStore();
}) { const { setSelectedActionSphere, selectedActionSphere } = useSelectedActionSphere();
const { isPlaying } = usePlayButtonStore(); const { eyeDropMode, setEyeDropMode } = useEyeDropMode();
const { renderDistance } = useRenderDistance(); const { editingPoint, setEditingPoint } = useEditingPoint();
const { setSubModule } = useSubModuleStore(); const { previewPosition, setPreviewPosition } = usePreviewPosition();
const { setSelectedActionSphere, selectedActionSphere } = useSelectedActionSphere(); const { raycaster, camera, pointer, gl } = useThree();
const { eyeDropMode, setEyeDropMode } = useEyeDropMode(); const { setSelectedPath } = useSelectedPath();
const { editingPoint, setEditingPoint } = useEditingPoint(); const { simulationStates, setSimulationStates } = useSimulationStates();
const { previewPosition, setPreviewPosition } = usePreviewPosition(); const { isConnecting } = useIsConnecting();
const { raycaster, camera, pointer, gl } = useThree(); const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
const { setSelectedPath } = useSelectedPath();
const { simulationStates, setSimulationStates } = useSimulationStates();
const { isConnecting } = useIsConnecting();
const groupRefs = useRef<{ [key: string]: THREE.Group }>({}); const groupRefs = useRef<{ [key: string]: THREE.Group }>({});
const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({}); const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({});
const isMovingRef = useRef(false); const isMovingRef = useRef(false);
const transformRef = useRef<any>(null); const transformRef = useRef<any>(null);
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null); const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
useEffect(() => { useEffect(() => {
setTransformMode(null); setTransformMode(null);
const handleKeyDown = (e: KeyboardEvent) => { const handleKeyDown = (e: KeyboardEvent) => {
if (!selectedActionSphere) return; if (!selectedActionSphere) return;
if (e.key === "g") { if (e.key === "g") {
setTransformMode((prev) => (prev === "translate" ? null : "translate")); setTransformMode((prev) => (prev === "translate" ? null : "translate"));
} }
if (e.key === "r") { if (e.key === "r") {
setTransformMode((prev) => (prev === "rotate" ? null : "rotate")); setTransformMode((prev) => (prev === "rotate" ? null : "rotate"));
} }
}; };
window.addEventListener("keydown", handleKeyDown); window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown);
}, [selectedActionSphere]); }, [selectedActionSphere]);
useFrame(() => { useFrame(() => {
Object.values(groupRefs.current).forEach((group) => { Object.values(groupRefs.current).forEach((group) => {
if (group) { if (group) {
const distance = new THREE.Vector3( const distance = new THREE.Vector3(
...group.position.toArray() ...group.position.toArray()
).distanceTo(camera.position); ).distanceTo(camera.position);
group.visible = ((distance <= renderDistance) && !isPlaying); group.visible = ((distance <= renderDistance) && !isPlaying);
} }
}); });
}); });
const updateSimulationPaths = () => { const updateSimulationPaths = () => {
if (!selectedActionSphere) return; if (!selectedActionSphere) return;
const updatedPaths = simulationStates.map((path) => { const updatedPaths = simulationStates.map((path) => {
if (path.type === "Conveyor") { if (path.type === "Conveyor") {
return { return {
...path, ...path,
points: path.points.map((point) => points: path.points.map((point) =>
point.uuid === selectedActionSphere.points.uuid point.uuid === selectedActionSphere.points.uuid
? { ? {
...point, ...point,
position: [ position: [
selectedActionSphere.points.position.x, selectedActionSphere.points.position.x,
selectedActionSphere.points.position.y, selectedActionSphere.points.position.y,
selectedActionSphere.points.position.z, selectedActionSphere.points.position.z,
], ],
rotation: [ rotation: [
selectedActionSphere.points.rotation.x, selectedActionSphere.points.rotation.x,
selectedActionSphere.points.rotation.y, selectedActionSphere.points.rotation.y,
selectedActionSphere.points.rotation.z, selectedActionSphere.points.rotation.z,
], ],
} }
: point : point
), ),
}; };
} else { } else {
return path; return path;
} }
}) as Types.ConveyorEventsSchema[]; }) as Types.ConveyorEventsSchema[];
const updatedPath = updatedPaths.find( const updatedPath = updatedPaths.find(
(path) => (path) => path.type === "Conveyor" && path.points.some((point) => point.uuid === selectedActionSphere.points.uuid)
path.type === "Conveyor" && );
path.points.some(
(point) => point.uuid === selectedActionSphere.points.uuid
)
);
// console.log("Updated Path:", updatedPath); // console.log("Updated Path:", updatedPath);
setSimulationStates(updatedPaths); setSimulationStates(updatedPaths);
}; };
useFrame(() => { useFrame(() => {
if (eyeDropMode) { if (eyeDropMode) {
raycaster.setFromCamera(pointer, camera); raycaster.setFromCamera(pointer, camera);
const intersectionPoint = new THREE.Vector3(); const intersectionPoint = new THREE.Vector3();
const point = raycaster.ray.intersectPlane(plane, intersectionPoint); const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
if (point) { if (point) {
setPreviewPosition({ x: point.x, y: point.z }); setPreviewPosition({ x: point.x, y: point.z });
} }
} else { } else {
setPreviewPosition(null); setPreviewPosition(null);
} }
}); });
useEffect(() => { useEffect(() => {
if (!camera) return; if (!camera) return;
const canvasElement = gl.domElement; const canvasElement = gl.domElement;
canvasElement.tabIndex = 0; canvasElement.tabIndex = 0;
const onPointerDown = () => { const onPointerDown = () => {
isMovingRef.current = false; isMovingRef.current = false;
}; };
const onPointerMove = () => { const onPointerMove = () => {
isMovingRef.current = true; isMovingRef.current = true;
}; };
const onPointerUp = (event: PointerEvent) => { const onPointerUp = (event: PointerEvent) => {
if ( if (
!isMovingRef.current && !isMovingRef.current &&
eyeDropMode && eyeDropMode &&
event.button === 0 && event.button === 0 &&
previewPosition previewPosition
) { ) {
event.preventDefault(); event.preventDefault();
if (editingPoint) { if (editingPoint) {
handlePointUpdate(editingPoint, previewPosition.x, previewPosition.y); handlePointUpdate(editingPoint, previewPosition.x, previewPosition.y);
setEditingPoint(null); setEditingPoint(null);
setEyeDropMode(false); setEyeDropMode(false);
} }
} }
}; };
if (eyeDropMode) { if (eyeDropMode) {
canvasElement.addEventListener("pointerdown", onPointerDown); canvasElement.addEventListener("pointerdown", onPointerDown);
canvasElement.addEventListener("pointermove", onPointerMove); canvasElement.addEventListener("pointermove", onPointerMove);
canvasElement.addEventListener("pointerup", onPointerUp); canvasElement.addEventListener("pointerup", onPointerUp);
} }
return () => { return () => {
canvasElement.removeEventListener("pointerdown", onPointerDown); canvasElement.removeEventListener("pointerdown", onPointerDown);
canvasElement.removeEventListener("pointermove", onPointerMove); canvasElement.removeEventListener("pointermove", onPointerMove);
canvasElement.removeEventListener("pointerup", onPointerUp); canvasElement.removeEventListener("pointerup", onPointerUp);
}; };
}, [eyeDropMode, editingPoint, previewPosition]); }, [eyeDropMode, editingPoint, previewPosition]);
const updateBackend = async (updatedPath: Types.VehicleEventsSchema | undefined) => { const updateBackend = async (updatedPath: Types.VehicleEventsSchema | undefined) => {
if (!updatedPath) return; if (!updatedPath) return;
const email = localStorage.getItem("email"); const email = localStorage.getItem("email");
const organization = email ? email.split("@")[1].split(".")[0] : ""; const organization = email ? email.split("@")[1].split(".")[0] : "";
await setEventApi( await setEventApi(
organization, organization,
updatedPath.modeluuid, updatedPath.modeluuid,
{ type: "Vehicle", points: updatedPath.points } { type: "Vehicle", points: updatedPath.points }
); );
} }
const handlePointUpdate = ( const handlePointUpdate = (pointType: "start" | "end", x: number, z: number) => {
pointType: "start" | "end", if (!selectedActionSphere?.points?.uuid) return;
x: number, const updatedPaths = simulationStates.map((path) => {
z: number
) => {
if (!selectedActionSphere?.points?.uuid) return;
const updatedPaths = simulationStates.map((path) => {
if ( if (path.type === "Vehicle" && path.points.uuid === selectedActionSphere.points.uuid) {
path.type === "Vehicle" && return {
path.points.uuid === selectedActionSphere.points.uuid ...path,
) { points: {
return { ...path.points,
...path, actions: {
points: { ...path.points.actions,
...path.points, [pointType]: { ...path.points.actions[pointType], x: x, y: z, },
actions: { },
...path.points.actions, },
[pointType]: { };
...path.points.actions[pointType], }
x: x, return path;
y: z, });
},
},
},
};
}
return path;
});
const updatedPath = updatedPaths.find( const updatedPath = updatedPaths.find((path): path is Types.VehicleEventsSchema => path.type === "Vehicle" && path.points.uuid === selectedActionSphere.points.uuid);
(path): path is Types.VehicleEventsSchema => updateBackend(updatedPath);
path.type === "Vehicle" &&
path.points.uuid === selectedActionSphere.points.uuid
);
updateBackend(updatedPath);
setSimulationStates(updatedPaths); setSimulationStates(updatedPaths);
}; };
return ( return (
<group visible={!isPlaying} name="simulation-simulationStates-group" ref={pathsGroupRef}> <group visible={!isPlaying} name="simulation-simulationStates-group" ref={pathsGroupRef}>
{simulationStates.map((path) => { {simulationStates.map((path) => {
if (path.type === "Conveyor") { if (path.type === "Conveyor") {
const points = path.points.map( const points = path.points.map(
(point) => new THREE.Vector3(...point.position) (point) => new THREE.Vector3(...point.position)
); );
return ( return (
<group <group
name={`${path.modeluuid}-event-path`} name={`${path.modeluuid}-${path.type}-path`}
key={path.modeluuid} key={path.modeluuid}
ref={(el) => (groupRefs.current[path.modeluuid] = el!)} ref={(el) => (groupRefs.current[path.modeluuid] = el!)}
position={path.position} position={path.position}
rotation={path.rotation} rotation={path.rotation}
onClick={(e) => { onClick={(e) => {
if (isConnecting || eyeDropMode) return; if (isConnecting || eyeDropMode) return;
e.stopPropagation(); e.stopPropagation();
setSelectedPath({ setSelectedPath({
path, path,
group: groupRefs.current[path.modeluuid], group: groupRefs.current[path.modeluuid],
}); });
setSelectedActionSphere(null); setSelectedActionSphere(null);
setTransformMode(null); setTransformMode(null);
setSubModule("mechanics"); setSubModule("mechanics");
}} }}
onPointerMissed={() => { onPointerMissed={() => {
if (eyeDropMode) return; if (eyeDropMode) return;
setSelectedPath(null); setSelectedPath(null);
setSubModule("properties"); setSubModule("properties");
}} }}
> >
{path.points.map((point, index) => ( {path.points.map((point, index) => (
<Sphere <Sphere
key={point.uuid} key={point.uuid}
uuid={point.uuid} uuid={point.uuid}
position={point.position} position={point.position}
args={[0.15, 32, 32]} args={[0.15, 32, 32]}
name="events-sphere" name="events-sphere"
ref={(el) => (sphereRefs.current[point.uuid] = el!)} ref={(el) => (sphereRefs.current[point.uuid] = el!)}
onClick={(e) => { onClick={(e) => {
if (isConnecting || eyeDropMode) return; if (isConnecting || eyeDropMode) return;
e.stopPropagation(); e.stopPropagation();
setSelectedActionSphere({ setSelectedActionSphere({
path, path,
points: sphereRefs.current[point.uuid], points: sphereRefs.current[point.uuid],
}); });
setSubModule("mechanics"); setSubModule("mechanics");
setSelectedPath(null); setSelectedPath(null);
}} }}
userData={{ points, path }} userData={{ points, path }}
onPointerMissed={() => { onPointerMissed={() => {
if (eyeDropMode) return; if (eyeDropMode) return;
setSubModule("properties"); setSubModule("properties");
setSelectedActionSphere(null); setSelectedActionSphere(null);
}} }}
> >
<meshStandardMaterial <meshStandardMaterial
color={ color={index === 0 ? "orange" : index === path.points.length - 1 ? "blue" : "green"}
index === 0 />
? "orange" </Sphere>
: index === path.points.length - 1 ))}
? "blue"
: "green"
}
/>
</Sphere>
))}
{points.slice(0, -1).map((point, index) => { {points.slice(0, -1).map((point, index) => {
const nextPoint = points[index + 1]; const nextPoint = points[index + 1];
const segmentCurve = new THREE.CatmullRomCurve3([ const segmentCurve = new THREE.CatmullRomCurve3([point, nextPoint,]);
point, const tubeGeometry = new THREE.TubeGeometry(segmentCurve, 20, 0.1, 16, false);
nextPoint,
]);
const tubeGeometry = new THREE.TubeGeometry(
segmentCurve,
20,
0.1,
16,
false
);
return ( return (
<mesh <mesh name="event-connection-tube" key={`tube-${index}`} geometry={tubeGeometry}>
name="event-connection-tube" <meshStandardMaterial transparent opacity={0.9} color="red" />
key={`tube-${index}`} </mesh>
geometry={tubeGeometry} );
> })}
<meshStandardMaterial </group>
transparent );
opacity={0.9} } else if (path.type === "Vehicle" || path.type === "StaticMachine") {
color="red" return (
/> <group
</mesh> name={`${path.modeluuid}-${path.type}-path`}
); key={path.modeluuid}
})} ref={(el) => (groupRefs.current[path.modeluuid] = el!)}
</group> position={path.position}
); onClick={(e) => {
} else if (path.type === "Vehicle") { if (isConnecting || eyeDropMode) return;
return ( e.stopPropagation();
<group setSelectedPath({
name={`${path.modeluuid}-vehicle-path`} path,
key={path.modeluuid} group: groupRefs.current[path.modeluuid],
ref={(el) => (groupRefs.current[path.modeluuid] = el!)} });
position={path.position} setSelectedActionSphere(null);
onClick={(e) => { setTransformMode(null);
if (isConnecting || eyeDropMode) return; setSubModule("mechanics");
e.stopPropagation(); }}
setSelectedPath({ onPointerMissed={() => {
path, if (eyeDropMode) return;
group: groupRefs.current[path.modeluuid], setSelectedPath(null);
}); setSubModule("properties");
setSelectedActionSphere(null); }}
setTransformMode(null); >
setSubModule("mechanics"); <Sphere
}} key={path.points.uuid}
onPointerMissed={() => { uuid={path.points.uuid}
if (eyeDropMode) return; position={path.points.position}
setSelectedPath(null); args={[0.15, 32, 32]}
setSubModule("properties"); name="events-sphere"
}} ref={(el) => (sphereRefs.current[path.points.uuid] = el!)}
> onClick={(e) => {
<Sphere if (isConnecting || eyeDropMode) return;
key={path.points.uuid} e.stopPropagation();
uuid={path.points.uuid} setSelectedActionSphere({
position={path.points.position} path,
args={[0.15, 32, 32]} points: sphereRefs.current[path.points.uuid],
name="events-sphere" });
ref={(el) => (sphereRefs.current[path.points.uuid] = el!)} setSubModule("mechanics");
onClick={(e) => { setSelectedPath(null);
if (isConnecting || eyeDropMode) return; }}
e.stopPropagation(); userData={{ points: path.points, path }}
setSelectedActionSphere({ onPointerMissed={() => {
path, if (eyeDropMode) return;
points: sphereRefs.current[path.points.uuid], setSubModule("properties");
}); setSelectedActionSphere(null);
setSubModule("mechanics"); }}
setSelectedPath(null); >
}} <meshStandardMaterial color="purple" />
userData={{ points: path.points, path }} </Sphere>
onPointerMissed={() => { </group>
if (eyeDropMode) return; );
setSubModule("properties"); }
setSelectedActionSphere(null); return null;
}} })}
>
<meshStandardMaterial color="purple" />
</Sphere>
</group>
);
}
return null;
})}
{selectedActionSphere && transformMode && ( {selectedActionSphere && transformMode && (
<TransformControls <TransformControls
ref={transformRef} ref={transformRef}
object={selectedActionSphere.points} object={selectedActionSphere.points}
mode={transformMode} mode={transformMode}
onMouseUp={updateSimulationPaths} onMouseUp={updateSimulationPaths}
/> />
)} )}
</group> </group>
); );
} }
export default PathCreation; export default PathCreation;

View File

@@ -433,6 +433,7 @@ export interface PathPoint {
} }
export interface SimulationPath { export interface SimulationPath {
type: string;
modeluuid: string; modeluuid: string;
points: PathPoint[]; points: PathPoint[];
pathPosition: [number, number, number]; pathPosition: [number, number, number];
@@ -464,6 +465,7 @@ function convertToSimulationPath(
if (path.type === "Conveyor") { if (path.type === "Conveyor") {
return { return {
type: path.type,
modeluuid, modeluuid,
points: path.points.map((point) => ({ points: path.points.map((point) => ({
uuid: point.uuid, uuid: point.uuid,
@@ -483,6 +485,7 @@ function convertToSimulationPath(
}; };
} else { } else {
return { return {
type: path.type,
modeluuid, modeluuid,
points: [ points: [
{ {
@@ -614,6 +617,7 @@ export function useProcessCreation() {
const [processes, setProcesses] = useState<Process[]>([]); const [processes, setProcesses] = useState<Process[]>([]);
const hasSpawnAction = useCallback((path: SimulationPath): boolean => { const hasSpawnAction = useCallback((path: SimulationPath): boolean => {
if (path.type !== "Conveyor") return false;
return path.points.some((point) => return path.points.some((point) =>
point.actions.some((action) => action.type.toLowerCase() === "spawn") point.actions.some((action) => action.type.toLowerCase() === "spawn")
); );

View File

@@ -19,7 +19,7 @@ function Simulation() {
const [processes, setProcesses] = useState([]); const [processes, setProcesses] = useState([]);
useEffect(() => { useEffect(() => {
// console.log('simulationStates: ', simulationStates); console.log('simulationStates: ', simulationStates);
}, [simulationStates]); }, [simulationStates]);
// useEffect(() => { // useEffect(() => {

View File

@@ -341,12 +341,12 @@ export const useSelectedPath = create<any>((set: any) => ({
})); }));
interface SimulationPathsStore { interface SimulationPathsStore {
simulationStates: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]; simulationStates: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[];
setSimulationStates: ( setSimulationStates: (
paths: paths:
| (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[] | (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]
| ((prev: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[] | ((prev: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]
) => (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) ) => (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[])
) => void; ) => void;
} }

View File

@@ -317,6 +317,20 @@ interface VehicleEventsSchema {
position: [number, number, number]; 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: { pathUUID: string; pointUUID: string }[] };
};
position: [number, number, number];
}
export type EventData = { export type EventData = {
modeluuid: string; modeluuid: string;
modelname: string; modelname: string;