Add MQTT URL to environment variables and refactor simulation components
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user