added backend connection for conveyor and vehicle mechanics

This commit is contained in:
2025-04-04 16:57:18 +05:30
parent e1892b0b00
commit cf6946750b
24 changed files with 595 additions and 280 deletions

View File

@@ -5,12 +5,14 @@ import * as Types from '../../../types/world/worldTypes';
import { QuadraticBezierLine } from '@react-three/drei';
import { useIsConnecting, useSimulationPaths } from '../../../store/store';
import useModuleStore from '../../../store/useModuleStore';
import { usePlayButtonStore } from '../../../store/usePlayButtonStore';
function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject<THREE.Group> }) {
const { activeModule } = useModuleStore();
const { gl, raycaster, scene, pointer, camera } = useThree();
const { setIsConnecting } = useIsConnecting();
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
const { isPlaying } = usePlayButtonStore();
const [firstSelected, setFirstSelected] = useState<{
pathUUID: string;
@@ -89,12 +91,12 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
// In the updatePathConnections function, modify the Vehicle handling section:
else if (path.type === 'Vehicle') {
// Handle outgoing connections from Vehicle
if (path.modeluuid === fromPathUUID && path.point.uuid === fromPointUUID) {
if (path.modeluuid === fromPathUUID && path.points.uuid === fromPointUUID) {
const newTarget = {
pathUUID: toPathUUID,
pointUUID: toPointUUID
};
const existingTargets = path.point.connections.targets || [];
const existingTargets = path.points.connections.targets || [];
// Check if target is a Conveyor
const toPath = simulationPaths.find(p => p.modeluuid === toPathUUID);
@@ -115,10 +117,10 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
)) {
return {
...path,
point: {
...path.point,
points: {
...path.points,
connections: {
...path.point.connections,
...path.points.connections,
targets: [...existingTargets, newTarget]
}
}
@@ -126,12 +128,12 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
}
}
// Handle incoming connections to Vehicle
else if (path.modeluuid === toPathUUID && path.point.uuid === toPointUUID) {
else if (path.modeluuid === toPathUUID && path.points.uuid === toPointUUID) {
const reverseTarget = {
pathUUID: fromPathUUID,
pointUUID: fromPointUUID
};
const existingTargets = path.point.connections.targets || [];
const existingTargets = path.points.connections.targets || [];
// Check if source is a Conveyor
const fromPath = simulationPaths.find(p => p.modeluuid === fromPathUUID);
@@ -152,10 +154,10 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
)) {
return {
...path,
point: {
...path.point,
points: {
...path.points,
connections: {
...path.point.connections,
...path.points.connections,
targets: [...existingTargets, reverseTarget]
}
}
@@ -215,13 +217,13 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
let isStartOrEnd = false;
if (intersected.userData.path.points) {
if (intersected.userData.path.points && intersected.userData.path.points.length > 1) {
isStartOrEnd = intersected.userData.path.points.length > 0 && (
sphereUUID === intersected.userData.path.points[0].uuid ||
sphereUUID === intersected.userData.path.points[intersected.userData.path.points.length - 1].uuid
);
} else if (intersected.userData.path.point) {
isStartOrEnd = sphereUUID === intersected.userData.path.point.uuid;
} else if (intersected.userData.path.points) {
isStartOrEnd = sphereUUID === intersected.userData.path.points.uuid;
}
if (pathUUID) {
@@ -253,7 +255,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
t.pathUUID === pathUUID && t.pointUUID === sphereUUID
);
} else if (path.type === 'Vehicle') {
return path.point.connections.targets.some(t =>
return path.points.connections.targets.some(t =>
t.pathUUID === pathUUID && t.pointUUID === sphereUUID
);
}
@@ -269,7 +271,8 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
// For Vehicles, check if they're already connected to anything
if (intersected.userData.path.type === 'Vehicle') {
const vehicleConnections = intersected.userData.path.point.connections.targets.length;
console.log('intersected: ', intersected);
const vehicleConnections = intersected.userData.path.points.connections.targets.length;
if (vehicleConnections >= 1) {
console.log("Vehicle can only have one connection");
return;
@@ -418,7 +421,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
t.pathUUID === pathUUID && t.pointUUID === sphereUUID
);
} else if (path.type === 'Vehicle') {
return path.point.connections.targets.some(t =>
return path.points.connections.targets.some(t =>
t.pathUUID === pathUUID && t.pointUUID === sphereUUID
);
}
@@ -440,7 +443,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
// Check vehicle connection rules
const isVehicleAtMaxConnections = pathData.type === 'Vehicle' &&
pathData.point.connections.targets.length >= 1;
pathData.points.connections.targets.length >= 1;
const isVehicleConnectingToNonConveyor =
(firstPath?.type === 'Vehicle' && secondPath?.type !== 'Conveyor') ||
(secondPath?.type === 'Vehicle' && firstPath?.type !== 'Conveyor');
@@ -501,7 +504,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
});
return (
<>
<group name='simulationConnectionGroup' visible={!isPlaying} >
{simulationPaths.flatMap(path => {
if (path.type === 'Conveyor') {
return path.points.flatMap(point =>
@@ -545,8 +548,8 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
})
);
} else if (path.type === 'Vehicle') {
return path.point.connections.targets.map((target, index) => {
const fromSphere = pathsGroupRef.current?.getObjectByProperty('uuid', path.point.uuid);
return path.points.connections.targets.map((target, index) => {
const fromSphere = pathsGroupRef.current?.getObjectByProperty('uuid', path.points.uuid);
const toSphere = pathsGroupRef.current?.getObjectByProperty('uuid', target.pointUUID);
if (fromSphere && toSphere) {
@@ -566,7 +569,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
return (
<QuadraticBezierLine
key={`${path.point.uuid}-${target.pointUUID}-${index}`}
key={`${path.points.uuid}-${target.pointUUID}-${index}`}
start={fromWorldPosition.toArray()}
end={toWorldPosition.toArray()}
mid={midPoint.toArray()}
@@ -596,7 +599,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
dashScale={20}
/>
)}
</>
</group>
);
}

View File

@@ -15,6 +15,7 @@ import {
import { useFrame, useThree } from "@react-three/fiber";
import { useSubModuleStore } from "../../../store/useModuleStore";
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
import { setEventApi } from "../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
function PathCreation({
pathsGroupRef,
@@ -24,16 +25,12 @@ function PathCreation({
const { isPlaying } = usePlayButtonStore();
const { renderDistance } = useRenderDistance();
const { setSubModule } = useSubModuleStore();
const { setSelectedActionSphere, selectedActionSphere } =
useSelectedActionSphere();
const { setSelectedActionSphere, selectedActionSphere } = useSelectedActionSphere();
const { eyeDropMode, setEyeDropMode } = useEyeDropMode();
const { editingPoint, setEditingPoint } = useEditingPoint();
const { previewPosition, setPreviewPosition } = usePreviewPosition();
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 { simulationPaths, setSimulationPaths } = useSimulationPaths();
const { isConnecting } = useIsConnecting();
@@ -42,9 +39,7 @@ function PathCreation({
const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({});
const isMovingRef = useRef(false);
const transformRef = useRef<any>(null);
const [transformMode, setTransformMode] = useState<
"translate" | "rotate" | null
>(null);
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
useEffect(() => {
setTransformMode(null);
@@ -81,20 +76,20 @@ function PathCreation({
return {
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
point.uuid === selectedActionSphere.points.uuid
? {
...point,
position: [
selectedActionSphere.point.position.x,
selectedActionSphere.point.position.y,
selectedActionSphere.point.position.z,
],
rotation: [
selectedActionSphere.point.rotation.x,
selectedActionSphere.point.rotation.y,
selectedActionSphere.point.rotation.z,
],
}
...point,
position: [
selectedActionSphere.points.position.x,
selectedActionSphere.points.position.y,
selectedActionSphere.points.position.z,
],
rotation: [
selectedActionSphere.points.rotation.x,
selectedActionSphere.points.rotation.y,
selectedActionSphere.points.rotation.z,
],
}
: point
),
};
@@ -161,26 +156,37 @@ function PathCreation({
};
}, [eyeDropMode, editingPoint, previewPosition]);
const updateBackend = async (updatedPath: Types.VehicleEventsSchema | undefined) => {
if (!updatedPath) return;
const email = localStorage.getItem("email");
const organization = email ? email.split("@")[1].split(".")[0] : "";
await setEventApi(
organization,
updatedPath.modeluuid,
{ type: "Vehicle", points: updatedPath.points }
);
}
const handlePointUpdate = (
pointType: "start" | "end",
x: number,
z: number
) => {
if (!selectedActionSphere?.point?.uuid) return;
if (!selectedActionSphere?.points?.uuid) return;
const updatedPaths = simulationPaths.map((path) => {
if (
path.type === "Vehicle" &&
path.point.uuid === selectedActionSphere.point.uuid
path.points.uuid === selectedActionSphere.points.uuid
) {
return {
...path,
point: {
...path.point,
points: {
...path.points,
actions: {
...path.point.actions,
...path.points.actions,
[pointType]: {
...path.point.actions[pointType],
...path.points.actions[pointType],
x: x,
y: z,
},
@@ -191,6 +197,13 @@ function PathCreation({
return path;
});
const updatedPath = updatedPaths.find(
(path): path is Types.VehicleEventsSchema =>
path.type === "Vehicle" &&
path.points.uuid === selectedActionSphere.points.uuid
);
updateBackend(updatedPath);
setSimulationPaths(updatedPaths);
};
@@ -239,12 +252,12 @@ function PathCreation({
e.stopPropagation();
setSelectedActionSphere({
path,
point: sphereRefs.current[point.uuid],
points: sphereRefs.current[point.uuid],
});
setSubModule("mechanics");
setSelectedPath(null);
}}
userData={{ point, path }}
userData={{ points, path }}
onPointerMissed={() => {
if (eyeDropMode) return;
setSubModule("properties");
@@ -256,8 +269,8 @@ function PathCreation({
index === 0
? "orange"
: index === path.points.length - 1
? "blue"
: "green"
? "blue"
: "green"
}
/>
</Sphere>
@@ -318,23 +331,23 @@ function PathCreation({
}}
>
<Sphere
key={path.point.uuid}
uuid={path.point.uuid}
position={path.point.position}
key={path.points.uuid}
uuid={path.points.uuid}
position={path.points.position}
args={[0.15, 32, 32]}
name="events-sphere"
ref={(el) => (sphereRefs.current[path.point.uuid] = el!)}
ref={(el) => (sphereRefs.current[path.points.uuid] = el!)}
onClick={(e) => {
if (isConnecting || eyeDropMode) return;
e.stopPropagation();
setSelectedActionSphere({
path,
point: sphereRefs.current[path.point.uuid],
points: sphereRefs.current[path.points.uuid],
});
setSubModule("mechanics");
setSelectedPath(null);
}}
userData={{ point: path.point, path }}
userData={{ points: path.points, path }}
onPointerMissed={() => {
if (eyeDropMode) return;
setSubModule("properties");
@@ -352,7 +365,7 @@ function PathCreation({
{selectedActionSphere && transformMode && (
<TransformControls
ref={transformRef}
object={selectedActionSphere.point}
object={selectedActionSphere.points}
mode={transformMode}
onMouseUp={updateSimulationPaths}
/>