From a7ec4720a4212b99516fc4f7b53ace589935b283 Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Thu, 27 Mar 2025 14:34:36 +0530 Subject: [PATCH] Refactor path connections structure and remove unused connection logic --- .../simulation/behaviour/behaviour.tsx | 8 +- .../modules/simulation/path/pathConnector.tsx | 203 ++++++++++++------ .../modules/simulation/path/pathCreation.tsx | 2 +- app/src/modules/simulation/simulation.tsx | 3 +- app/src/store/store.ts | 77 +------ 5 files changed, 146 insertions(+), 147 deletions(-) diff --git a/app/src/modules/simulation/behaviour/behaviour.tsx b/app/src/modules/simulation/behaviour/behaviour.tsx index 7ee46fb..d7a08af 100644 --- a/app/src/modules/simulation/behaviour/behaviour.tsx +++ b/app/src/modules/simulation/behaviour/behaviour.tsx @@ -12,7 +12,7 @@ interface Path { rotation: [number, number, number]; actions: { uuid: string; name: string; type: string; material: string; delay: number | string; spawnInterval: number | string; isUsed: boolean }[] | []; triggers: { uuid: string; name: string; type: string; isUsed: boolean }[] | []; - connections: { source: { pathUUID: string; pointUUID: string }; targets: { pathUUID: string; pointUUID: string }[] } | []; + connections: { source: { pathUUID: string; pointUUID: string }; targets: { pathUUID: string; pointUUID: string }[] }; }[]; pathPosition: [number, number, number]; pathRotation: [number, number, number]; @@ -45,7 +45,7 @@ function Behaviour({ setSimulationPaths }: { setSimulationPaths: any }) { rotation: [0, 0, 0], actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: false }], triggers: [], - connections: [], + connections: { source: { pathUUID: item.modeluuid, pointUUID: point1UUID }, targets: [] }, }, { uuid: middlePointUUID, @@ -53,7 +53,7 @@ function Behaviour({ setSimulationPaths }: { setSimulationPaths: any }) { rotation: [0, 0, 0], actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: false }], triggers: [], - connections: [], + connections: { source: { pathUUID: item.modeluuid, pointUUID: middlePointUUID }, targets: [] }, }, { uuid: point2UUID, @@ -61,7 +61,7 @@ function Behaviour({ setSimulationPaths }: { setSimulationPaths: any }) { rotation: [0, 0, 0], actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: false }], triggers: [], - connections: [], + connections: { source: { pathUUID: item.modeluuid, pointUUID: point2UUID }, targets: [] }, }, ], pathPosition: [...item.position], diff --git a/app/src/modules/simulation/path/pathConnector.tsx b/app/src/modules/simulation/path/pathConnector.tsx index 9766614..93172b7 100644 --- a/app/src/modules/simulation/path/pathConnector.tsx +++ b/app/src/modules/simulation/path/pathConnector.tsx @@ -2,21 +2,100 @@ import { useFrame, useThree } from '@react-three/fiber'; import React, { useEffect, useState } from 'react'; import * as THREE from 'three'; import { QuadraticBezierLine } from '@react-three/drei'; -import { useConnections, useIsConnecting, useSimulationPaths } from '../../../store/store'; +import { useIsConnecting, useSimulationPaths } from '../../../store/store'; import useModuleStore from '../../../store/useModuleStore'; function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject }) { const { activeModule } = useModuleStore(); const { gl, raycaster, scene, pointer, camera } = useThree(); - const { connections, setConnections, addConnection } = useConnections(); - const { isConnecting, setIsConnecting } = useIsConnecting(); + const { setIsConnecting } = useIsConnecting(); const { simulationPaths, setSimulationPaths } = useSimulationPaths(); - const [firstSelected, setFirstSelected] = useState<{ pathUUID: string; sphereUUID: string; position: THREE.Vector3; isCorner: boolean; } | null>(null); + const [firstSelected, setFirstSelected] = useState<{ + pathUUID: string; + sphereUUID: string; + position: THREE.Vector3; + isCorner: boolean; + } | null>(null); const [currentLine, setCurrentLine] = useState<{ start: THREE.Vector3, end: THREE.Vector3, mid: THREE.Vector3 } | null>(null); - const [hoveredSphere, setHoveredSphere] = useState<{ sphereUUID: string, position: THREE.Vector3 } | null>(null); const [helperlineColor, setHelperLineColor] = useState('red'); + const updatePathConnections = ( + fromPathUUID: string, + fromPointUUID: string, + toPathUUID: string, + toPointUUID: string + ) => { + const updatedPaths = simulationPaths.map(path => { + if (path.modeluuid === fromPathUUID) { + return { + ...path, + points: path.points.map(point => { + if (point.uuid === fromPointUUID) { + const newTarget = { + pathUUID: toPathUUID, + pointUUID: toPointUUID + }; + const existingTargets = point.connections.targets || []; + + if (!existingTargets.some(target => + target.pathUUID === newTarget.pathUUID && + target.pointUUID === newTarget.pointUUID + )) { + return { + ...point, + connections: { + ...point.connections, + targets: [...existingTargets, newTarget] + } + }; + } + } + return point; + }) + }; + } + else if (path.modeluuid === toPathUUID) { + return { + ...path, + points: path.points.map(point => { + if (point.uuid === toPointUUID) { + const reverseTarget = { + pathUUID: fromPathUUID, + pointUUID: fromPointUUID + }; + const existingTargets = point.connections.targets || []; + + if (!existingTargets.some(target => + target.pathUUID === reverseTarget.pathUUID && + target.pointUUID === reverseTarget.pointUUID + )) { + return { + ...point, + connections: { + ...point.connections, + targets: [...existingTargets, reverseTarget] + } + }; + } + } + return point; + }) + }; + } + return path; + }); + + setSimulationPaths(updatedPaths); + }; + + const handleAddConnection = (fromPathUUID: string, fromUUID: string, toPathUUID: string, toUUID: string) => { + updatePathConnections(fromPathUUID, fromUUID, toPathUUID, toUUID); + setFirstSelected(null); + setCurrentLine(null); + setIsConnecting(false); + }; + useEffect(() => { const canvasElement = gl.domElement; let drag = false; @@ -59,9 +138,12 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec ); if (pathUUID) { - const isAlreadyConnected = connections.some((connection) => - connection.fromUUID === sphereUUID || - connection.toConnections.some(conn => conn.toUUID === sphereUUID) + // Check if sphere is already connected + const isAlreadyConnected = simulationPaths.some(path => + path.points.some(point => + point.uuid === sphereUUID && + point.connections.targets.length > 0 + ) ); if (isAlreadyConnected) { @@ -89,16 +171,12 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec return; } - addConnection({ - fromPathUUID: firstSelected.pathUUID, - fromUUID: firstSelected.sphereUUID, - toConnections: [{ toPathUUID: pathUUID, toUUID: sphereUUID }] - }); - - setFirstSelected(null); - setCurrentLine(null); - setIsConnecting(false); - setHoveredSphere(null); + handleAddConnection( + firstSelected.pathUUID, + firstSelected.sphereUUID, + pathUUID, + sphereUUID + ); } } } @@ -106,7 +184,6 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec setFirstSelected(null); setCurrentLine(null); setIsConnecting(false); - setHoveredSphere(null); } }; @@ -119,7 +196,6 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec setFirstSelected(null); setCurrentLine(null); setIsConnecting(false); - setHoveredSphere(null); } return () => { @@ -128,7 +204,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec canvasElement.removeEventListener("mousemove", onMouseMove); canvasElement.removeEventListener("contextmenu", onContextMenu); }; - }, [camera, scene, raycaster, firstSelected, connections]); + }, [camera, scene, raycaster, firstSelected, simulationPaths]); useFrame(() => { if (firstSelected) { @@ -168,9 +244,11 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec sphereUUID === sphere.userData.path.points[sphere.userData.path.points.length - 1].uuid ); - const isAlreadyConnected = connections.some((connection) => - connection.fromUUID === sphereUUID || - connection.toConnections.some(conn => conn.toUUID === sphereUUID) + const isAlreadyConnected = simulationPaths.some(path => + path.points.some(point => + point.uuid === sphereUUID && + point.connections.targets.length > 0 + ) ); if ( @@ -186,10 +264,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec } if (snappedSphere) { - setHoveredSphere(snappedSphere); point = snappedSphere.position; - } else { - setHoveredSphere(null); } if (point) { @@ -224,50 +299,48 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec } }); - - useEffect(() => { - console.log('connections: ', connections); - }, [connections]); - + // Render connections from simulationPaths return ( <> - {connections.map((connection, index) => { - if (!pathsGroupRef.current) return; - const fromSphere = pathsGroupRef.current.getObjectByProperty('uuid', connection.fromUUID); - const toSphere = pathsGroupRef.current.getObjectByProperty('uuid', connection.toConnections[0].toUUID); + {simulationPaths.flatMap(path => + path.points.flatMap(point => + point.connections.targets.map((target, index) => { + const fromSphere = pathsGroupRef.current?.getObjectByProperty('uuid', point.uuid); + const toSphere = pathsGroupRef.current?.getObjectByProperty('uuid', target.pointUUID); - if (fromSphere && toSphere) { - const fromWorldPosition = new THREE.Vector3(); - const toWorldPosition = new THREE.Vector3(); - fromSphere.getWorldPosition(fromWorldPosition); - toSphere.getWorldPosition(toWorldPosition); + if (fromSphere && toSphere) { + const fromWorldPosition = new THREE.Vector3(); + const toWorldPosition = new THREE.Vector3(); + fromSphere.getWorldPosition(fromWorldPosition); + toSphere.getWorldPosition(toWorldPosition); - const distance = fromWorldPosition.distanceTo(toWorldPosition); - const heightFactor = Math.max(0.5, distance * 0.2); + const distance = fromWorldPosition.distanceTo(toWorldPosition); + const heightFactor = Math.max(0.5, distance * 0.2); - const midPoint = new THREE.Vector3( - (fromWorldPosition.x + toWorldPosition.x) / 2, - Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor, - (fromWorldPosition.z + toWorldPosition.z) / 2 - ); + const midPoint = new THREE.Vector3( + (fromWorldPosition.x + toWorldPosition.x) / 2, + Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor, + (fromWorldPosition.z + toWorldPosition.z) / 2 + ); - return ( - - ); - } - return null; - })} + return ( + + ); + } + return null; + }) + ) + )} {currentLine && ( ; const { simulationPaths, setSimulationPaths } = useSimulationPaths(); - const { connections, setConnections, addConnection, removeConnection } = useConnections(); const [processes, setProcesses] = useState([]); useEffect(() => { diff --git a/app/src/store/store.ts b/app/src/store/store.ts index 41b1f1b..6578761 100644 --- a/app/src/store/store.ts +++ b/app/src/store/store.ts @@ -307,7 +307,7 @@ interface Path { rotation: [number, number, number]; actions: { uuid: string; name: string; type: string; material: string; delay: number | string; spawnInterval: number | string; isUsed: boolean }[] | []; triggers: { uuid: string; name: string; type: string; isUsed: boolean }[] | []; - connections: { source: { pathUUID: string; pointUUID: string }; targets: { pathUUID: string; pointUUID: string }[] } | []; + connections: { source: { pathUUID: string; pointUUID: string }; targets: { pathUUID: string; pointUUID: string }[] }; }[]; pathPosition: [number, number, number]; pathRotation: [number, number, number]; @@ -321,80 +321,7 @@ interface SimulationPathsStore { export const useSimulationPaths = create((set) => ({ simulationPaths: [], - setSimulationPaths: (paths) => set({ simulationPaths: paths }), -})); - - -// interface Point { -// uuid: string; -// position: [number, number, number]; -// rotation: [number, number, number]; -// event: { -// uuid: string; -// type: string; -// material: string; -// delay: number | string; -// spawnInterval: number | string; -// isUsed: boolean; -// }; -// trigger: { -// uuid: string; -// type: string; -// isUsed: boolean; -// }; -// } - -// interface Process { -// processId: string; -// processName: string; -// points: Point[]; -// pathPosition: [number, number, number]; -// pathRotation: [number, number, number]; -// speed: number; -// isUsed: boolean; -// } - -// interface Path { -// modeluuid: string; -// processes: Process[]; -// } - -// interface SimulationPathsStore { -// simulationPaths: Path[]; -// setSimulationPaths: (paths: Path[]) => void; -// } - -// export const useSimulationPaths = create((set) => ({ -// simulationPaths: [], -// setSimulationPaths: (paths) => set({ simulationPaths: paths }), -// })); - - -export const useConnections = create((set) => ({ - connections: [], - - setConnections: (connections) => set({ connections }), - - addConnection: (newConnection) => - set((state) => ({ - connections: [...state.connections, newConnection], - })), - - removeConnection: (fromUUID, toUUID) => - set((state) => ({ - connections: state.connections - .map((connection) => - connection.fromUUID === fromUUID - ? { - ...connection, - toConnections: connection.toConnections.filter( - (to) => to.toUUID !== toUUID - ), - } - : connection - ) - .filter((connection) => connection.toConnections.length > 0), - })), + setSimulationPaths: (paths: Path[]) => set({ simulationPaths: paths }), })); export const useIsConnecting = create((set: any) => ({