Add MQTT URL to environment variables and refactor simulation components

This commit is contained in:
2025-03-28 19:10:49 +05:30
parent 813f620b4d
commit f46f29b88c
19 changed files with 1971 additions and 1164 deletions

View File

@@ -1,6 +1,7 @@
import { useFrame, useThree } from '@react-three/fiber';
import React, { useEffect, useState } from 'react';
import * as THREE from 'three';
import * as Types from '../../../types/world/worldTypes';
import { QuadraticBezierLine } from '@react-three/drei';
import { useIsConnecting, useSimulationPaths } from '../../../store/store';
import useModuleStore from '../../../store/useModuleStore';
@@ -27,61 +28,113 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
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]
}
if (path.type === 'Conveyor') {
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;
})
};
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;
})
};
}
}
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 || [];
else if (path.type === 'Vehicle') {
// Handle outgoing connections from Vehicle
if (path.modeluuid === fromPathUUID && path.point.uuid === fromPointUUID) {
const newTarget = {
pathUUID: toPathUUID,
pointUUID: toPointUUID
};
const existingTargets = path.point.connections.targets || [];
if (!existingTargets.some(target =>
target.pathUUID === reverseTarget.pathUUID &&
target.pointUUID === reverseTarget.pointUUID
)) {
return {
...point,
connections: {
...point.connections,
targets: [...existingTargets, reverseTarget]
}
};
if (!existingTargets.some(target =>
target.pathUUID === newTarget.pathUUID &&
target.pointUUID === newTarget.pointUUID
)) {
return {
...path,
point: {
...path.point,
connections: {
...path.point.connections,
targets: [...existingTargets, newTarget]
}
}
}
return point;
})
};
};
}
}
// Handle incoming connections to Vehicle
else if (path.modeluuid === toPathUUID && path.point.uuid === toPointUUID) {
const reverseTarget = {
pathUUID: fromPathUUID,
pointUUID: fromPointUUID
};
const existingTargets = path.point.connections.targets || [];
if (!existingTargets.some(target =>
target.pathUUID === reverseTarget.pathUUID &&
target.pointUUID === reverseTarget.pointUUID
)) {
return {
...path,
point: {
...path.point,
connections: {
...path.point.connections,
targets: [...existingTargets, reverseTarget]
}
}
};
}
}
}
return path;
});
@@ -126,25 +179,43 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
if (intersects.length > 0) {
const intersected = intersects[0].object;
if (intersected.name.includes("action-sphere")) {
if (intersected.name.includes("events-sphere")) {
const pathUUID = intersected.userData.path.modeluuid;
const sphereUUID = intersected.uuid;
const worldPosition = new THREE.Vector3();
intersected.getWorldPosition(worldPosition);
const 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
);
let isStartOrEnd = false;
if (intersected.userData.path.points) {
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;
}
if (pathUUID) {
// Check if sphere is already connected
const isAlreadyConnected = simulationPaths.some(path =>
path.points.some(point =>
point.uuid === sphereUUID &&
point.connections.targets.length > 0
)
);
const firstPath = simulationPaths.find(p => p.modeluuid === firstSelected?.pathUUID);
const secondPath = simulationPaths.find(p => p.modeluuid === pathUUID);
if (firstPath && secondPath && firstPath.type === 'Vehicle' && secondPath.type === 'Vehicle') {
console.log("Cannot connect two vehicle paths together");
return;
}
const isAlreadyConnected = simulationPaths.some(path => {
if (path.type === 'Conveyor') {
return path.points.some(point =>
point.uuid === sphereUUID &&
point.connections.targets.length > 0
);
} else if (path.type === 'Vehicle') {
return path.point.uuid === sphereUUID &&
path.point.connections.targets.length > 0;
}
return false;
});
if (isAlreadyConnected) {
console.log("Sphere is already connected. Ignoring.");
@@ -211,6 +282,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
raycaster.setFromCamera(pointer, camera);
const intersects = raycaster.intersectObjects(scene.children, true).filter((intersect) =>
!intersect.object.name.includes("Roof") &&
!intersect.object.name.includes("agv-collider") &&
!intersect.object.name.includes("MeasurementReference") &&
!intersect.object.userData.isPathObject &&
!(intersect.object.type === "GridHelper")
@@ -229,7 +301,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
}
const sphereIntersects = raycaster.intersectObjects(pathsGroupRef.current.children, true).filter((obj) =>
obj.object.name.includes("action-sphere")
obj.object.name.includes("events-sphere")
);
if (sphereIntersects.length > 0) {
@@ -237,27 +309,45 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
const sphereUUID = sphere.uuid;
const spherePosition = new THREE.Vector3();
sphere.getWorldPosition(spherePosition);
const pathUUID = sphere.userData.path.modeluuid;
const pathData = sphere.userData.path;
const pathUUID = pathData.modeluuid;
const isStartOrEnd = sphere.userData.path.points.length > 0 && (
sphereUUID === sphere.userData.path.points[0].uuid ||
sphereUUID === sphere.userData.path.points[sphere.userData.path.points.length - 1].uuid
);
const firstPath = simulationPaths.find(p => p.modeluuid === firstSelected.pathUUID);
const secondPath = simulationPaths.find(p => p.modeluuid === pathUUID);
const isVehicleToVehicle = firstPath?.type === 'Vehicle' && secondPath?.type === 'Vehicle';
const isAlreadyConnected = simulationPaths.some(path =>
path.points.some(point =>
point.uuid === sphereUUID &&
point.connections.targets.length > 0
)
);
const isConnectable = (pathData.type === 'Vehicle' ||
(pathData.points.length > 0 && (
sphereUUID === pathData.points[0].uuid ||
sphereUUID === pathData.points[pathData.points.length - 1].uuid
))) && !isVehicleToVehicle;
const isAlreadyConnected = simulationPaths.some(path => {
if (path.type === 'Conveyor') {
return path.points.some(point =>
point.uuid === sphereUUID &&
point.connections.targets.length > 0
);
} else if (path.type === 'Vehicle') {
return path.point.uuid === sphereUUID &&
path.point.connections.targets.length > 0;
}
return false;
});
if (
!isAlreadyConnected &&
!isVehicleToVehicle &&
firstSelected.sphereUUID !== sphereUUID &&
firstSelected.pathUUID !== pathUUID &&
(firstSelected.isCorner || isStartOrEnd)
(firstSelected.isCorner || isConnectable)
) {
snappedSphere = { sphereUUID, position: spherePosition, pathUUID, isCorner: isStartOrEnd };
snappedSphere = {
sphereUUID,
position: spherePosition,
pathUUID,
isCorner: isConnectable
};
} else {
isInvalidConnection = true;
}
@@ -281,8 +371,13 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
end: point,
mid: midPoint,
});
console.log({
start: firstSelected.position,
end: point,
mid: midPoint,
});
setIsConnecting(true);
// setIsConnecting(true);
if (sphereIntersects.length > 0) {
setHelperLineColor(isInvalidConnection ? 'red' : '#6cf542');
@@ -299,13 +394,53 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
}
});
// Render connections from simulationPaths
return (
<>
{simulationPaths.flatMap(path =>
path.points.flatMap(point =>
point.connections.targets.map((target, index) => {
const fromSphere = pathsGroupRef.current?.getObjectByProperty('uuid', point.uuid);
{simulationPaths.flatMap(path => {
if (path.type === 'Conveyor') {
return path.points.flatMap(point =>
point.connections.targets.map((target, index) => {
const targetPath = simulationPaths.find(p => p.modeluuid === target.pathUUID);
if (targetPath?.type === 'Vehicle') return null;
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);
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
);
return (
<QuadraticBezierLine
key={`${point.uuid}-${target.pointUUID}-${index}`}
start={fromWorldPosition.toArray()}
end={toWorldPosition.toArray()}
mid={midPoint.toArray()}
color="white"
lineWidth={4}
dashed
dashSize={0.75}
dashScale={20}
/>
);
}
return null;
})
);
} else if (path.type === 'Vehicle') {
return path.point.connections.targets.map((target, index) => {
const fromSphere = pathsGroupRef.current?.getObjectByProperty('uuid', path.point.uuid);
const toSphere = pathsGroupRef.current?.getObjectByProperty('uuid', target.pointUUID);
if (fromSphere && toSphere) {
@@ -325,22 +460,23 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
return (
<QuadraticBezierLine
key={`${point.uuid}-${target.pointUUID}-${index}`}
key={`${path.point.uuid}-${target.pointUUID}-${index}`}
start={fromWorldPosition.toArray()}
end={toWorldPosition.toArray()}
mid={midPoint.toArray()}
color="white"
color="orange"
lineWidth={4}
dashed
dashSize={1}
dashSize={0.75}
dashScale={20}
/>
);
}
return null;
})
)
)}
});
}
return [];
})}
{currentLine && (
<QuadraticBezierLine