merged with orgin/v2
This commit is contained in:
@@ -8,10 +8,12 @@ import * as Types from "../../../types/world/worldTypes";
|
||||
import { initializeDB, retrieveGLTF, storeGLTF } from '../../../utils/indexDB/idbUtils';
|
||||
import { getCamera } from '../../../services/factoryBuilder/camera/getCameraApi';
|
||||
import { getFloorAssets } from '../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi';
|
||||
import PointsCalculator from '../../simulation/events/points/functions/pointsCalculator';
|
||||
|
||||
async function loadInitialFloorItems(
|
||||
itemsGroup: Types.RefGroup,
|
||||
setFloorItems: Types.setFloorItemSetState,
|
||||
addEvent: (event: EventsSchema) => void,
|
||||
): Promise<void> {
|
||||
if (!itemsGroup.current) return;
|
||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||
@@ -70,7 +72,7 @@ async function loadInitialFloorItems(
|
||||
const cachedModel = THREE.Cache.get(item.modelfileID!);
|
||||
if (cachedModel) {
|
||||
// console.log(`[Cache] Fetching ${item.modelname}`);
|
||||
processLoadedModel(cachedModel.scene.clone(), item, itemsGroup, setFloorItems);
|
||||
processLoadedModel(cachedModel.scene.clone(), item, itemsGroup, setFloorItems, addEvent);
|
||||
modelsLoaded++;
|
||||
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve);
|
||||
return;
|
||||
@@ -85,7 +87,7 @@ async function loadInitialFloorItems(
|
||||
URL.revokeObjectURL(blobUrl);
|
||||
THREE.Cache.remove(blobUrl);
|
||||
THREE.Cache.add(item.modelfileID!, gltf);
|
||||
processLoadedModel(gltf.scene.clone(), item, itemsGroup, setFloorItems);
|
||||
processLoadedModel(gltf.scene.clone(), item, itemsGroup, setFloorItems, addEvent);
|
||||
modelsLoaded++;
|
||||
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve);
|
||||
},
|
||||
@@ -106,7 +108,7 @@ async function loadInitialFloorItems(
|
||||
const modelBlob = await fetch(modelUrl).then((res) => res.blob());
|
||||
await storeGLTF(item.modelfileID!, modelBlob);
|
||||
THREE.Cache.add(item.modelfileID!, gltf);
|
||||
processLoadedModel(gltf.scene.clone(), item, itemsGroup, setFloorItems);
|
||||
processLoadedModel(gltf.scene.clone(), item, itemsGroup, setFloorItems, addEvent);
|
||||
modelsLoaded++;
|
||||
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve);
|
||||
},
|
||||
@@ -148,8 +150,9 @@ function processLoadedModel(
|
||||
item: Types.FloorItemType,
|
||||
itemsGroup: Types.RefGroup,
|
||||
setFloorItems: Types.setFloorItemSetState,
|
||||
addEvent: (event: EventsSchema) => void,
|
||||
) {
|
||||
const model = gltf;
|
||||
const model = gltf.clone();
|
||||
model.uuid = item.modeluuid;
|
||||
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
|
||||
model.userData = { name: item.modelname, modelId: item.modelfileID, modeluuid: item.modeluuid };
|
||||
@@ -182,6 +185,243 @@ function processLoadedModel(
|
||||
},
|
||||
]);
|
||||
|
||||
if (item.modelfileID === "a1ee92554935007b10b3eb05") {
|
||||
const data = PointsCalculator(
|
||||
'Vehicle',
|
||||
gltf.clone(),
|
||||
new THREE.Vector3(...model.rotation)
|
||||
);
|
||||
|
||||
if (!data || !data.points) return;
|
||||
|
||||
const vehicleEvent: VehicleEventSchema = {
|
||||
modelUuid: item.modeluuid,
|
||||
modelName: item.modelname,
|
||||
position: item.position,
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "vehicle",
|
||||
speed: 1,
|
||||
point: {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [data.points[0].x, data.points[0].y, data.points[0].z],
|
||||
rotation: [0, 0, 0],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Vehicle Action",
|
||||
actionType: "travel",
|
||||
material: null,
|
||||
unLoadDuration: 5,
|
||||
loadCapacity: 10,
|
||||
pickUpPoint: null,
|
||||
unLoadPoint: null,
|
||||
triggers: []
|
||||
}
|
||||
}
|
||||
};
|
||||
addEvent(vehicleEvent);
|
||||
} else if (item.modelfileID === "7dc04e36882e4debbc1a8e3d") {
|
||||
const data = PointsCalculator(
|
||||
'Conveyor',
|
||||
gltf.clone(),
|
||||
new THREE.Vector3(...model.rotation)
|
||||
);
|
||||
|
||||
if (!data || !data.points) return;
|
||||
|
||||
const ConveyorEvent: ConveyorEventSchema = {
|
||||
modelUuid: item.modeluuid,
|
||||
modelName: item.modelname,
|
||||
position: item.position,
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "transfer",
|
||||
speed: 1,
|
||||
points: data.points.map((point: THREE.Vector3, index: number) => ({
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [point.x, point.y, point.z],
|
||||
rotation: [0, 0, 0],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: `Action ${index + 1}`,
|
||||
actionType: 'default',
|
||||
material: 'Default material',
|
||||
delay: 0,
|
||||
spawnInterval: 5,
|
||||
spawnCount: 1,
|
||||
triggers: []
|
||||
}
|
||||
}))
|
||||
};
|
||||
addEvent(ConveyorEvent);
|
||||
} else if (item.modelfileID === "7dc04e36882e4debbc1a8e3d") {
|
||||
// const data = PointsCalculator(
|
||||
// 'Conveyor',
|
||||
// gltf.clone(),
|
||||
// new THREE.Vector3(...model.rotation)
|
||||
// );
|
||||
|
||||
// if (!data || !data.points) return;
|
||||
|
||||
// const points: ConveyorPointSchema[] = data.points.map((point: THREE.Vector3, index: number) => {
|
||||
// const actionUuid = THREE.MathUtils.generateUUID();
|
||||
// return {
|
||||
// uuid: THREE.MathUtils.generateUUID(),
|
||||
// position: [point.x, point.y, point.z],
|
||||
// rotation: [0, 0, 0],
|
||||
// action: {
|
||||
// actionUuid,
|
||||
// actionName: `Action ${index}`,
|
||||
// actionType: 'default',
|
||||
// material: 'inherit',
|
||||
// delay: 0,
|
||||
// spawnInterval: 5,
|
||||
// spawnCount: 1,
|
||||
// triggers: []
|
||||
// }
|
||||
// };
|
||||
// });
|
||||
|
||||
// points.forEach((point, index) => {
|
||||
// if (index < points.length - 1) {
|
||||
// const nextPoint = points[index + 1];
|
||||
// point.action.triggers.push({
|
||||
// triggerUuid: THREE.MathUtils.generateUUID(),
|
||||
// triggerName: `Trigger 1`,
|
||||
// triggerType: "onComplete",
|
||||
// delay: 0,
|
||||
// triggeredAsset: {
|
||||
// triggeredModel: {
|
||||
// modelName: item.modelname,
|
||||
// modelUuid: item.modeluuid
|
||||
// },
|
||||
// triggeredPoint: {
|
||||
// pointName: `Point ${index + 1}`,
|
||||
// pointUuid: nextPoint.uuid
|
||||
// },
|
||||
// triggeredAction: {
|
||||
// actionName: nextPoint.action.actionName,
|
||||
// actionUuid: nextPoint.action.actionUuid
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
|
||||
// const ConveyorEvent: ConveyorEventSchema = {
|
||||
// modelUuid: item.modeluuid,
|
||||
// modelName: item.modelname,
|
||||
// position: item.position,
|
||||
// rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
// state: "idle",
|
||||
// type: "transfer",
|
||||
// speed: 1,
|
||||
// points
|
||||
// };
|
||||
// addEvent(ConveyorEvent);
|
||||
} else if (item.modelfileID === "7dc04e36882e4debbc1a8e3d") {
|
||||
const data = PointsCalculator(
|
||||
'Conveyor',
|
||||
gltf.clone(),
|
||||
new THREE.Vector3(...model.rotation)
|
||||
);
|
||||
|
||||
if (!data || !data.points) return;
|
||||
|
||||
const ConveyorEvent: ConveyorEventSchema = {
|
||||
modelUuid: item.modeluuid,
|
||||
modelName: item.modelname,
|
||||
position: item.position,
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "transfer",
|
||||
speed: 1,
|
||||
points: data.points.map((point: THREE.Vector3, index: number) => ({
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [point.x, point.y, point.z],
|
||||
rotation: [0, 0, 0],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: `Action ${index}`,
|
||||
actionType: 'default',
|
||||
material: 'inherit',
|
||||
delay: 0,
|
||||
spawnInterval: 5,
|
||||
spawnCount: 1,
|
||||
triggers: []
|
||||
}
|
||||
}))
|
||||
};
|
||||
addEvent(ConveyorEvent);
|
||||
} else if (item.modelfileID === "29dee78715ad5b853f5c346d") {
|
||||
const data = PointsCalculator(
|
||||
'StaticMachine',
|
||||
gltf.clone(),
|
||||
new THREE.Vector3(...model.rotation)
|
||||
);
|
||||
|
||||
if (!data || !data.points) return;
|
||||
|
||||
const machineEvent: MachineEventSchema = {
|
||||
modelUuid: item.modeluuid,
|
||||
modelName: item.modelname,
|
||||
position: item.position,
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "machine",
|
||||
point: {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [data.points[0].x, data.points[0].y, data.points[0].z],
|
||||
rotation: [0, 0, 0],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Process Action",
|
||||
actionType: "process",
|
||||
processTime: 10,
|
||||
swapMaterial: "material-id",
|
||||
triggers: []
|
||||
}
|
||||
}
|
||||
};
|
||||
addEvent(machineEvent);
|
||||
} else if (item.modelfileID === "52e6681fbb743a890d96c914") {
|
||||
const data = PointsCalculator(
|
||||
'ArmBot',
|
||||
gltf.clone(),
|
||||
new THREE.Vector3(...model.rotation)
|
||||
);
|
||||
|
||||
if (!data || !data.points) return;
|
||||
|
||||
const roboticArmEvent: RoboticArmEventSchema = {
|
||||
modelUuid: item.modeluuid,
|
||||
modelName: item.modelname,
|
||||
position: item.position,
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "roboticArm",
|
||||
speed: 1,
|
||||
point: {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [data.points[0].x, data.points[0].y, data.points[0].z],
|
||||
rotation: [0, 0, 0],
|
||||
actions: [
|
||||
{
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Pick and Place",
|
||||
actionType: "pickAndPlace",
|
||||
process: {
|
||||
startPoint: [0, 0, 0],
|
||||
endPoint: [0, 0, 0]
|
||||
},
|
||||
triggers: []
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
addEvent(roboticArmEvent);
|
||||
}
|
||||
|
||||
gsap.to(model.position, { y: item.position[1], duration: 1.5, ease: 'power2.out' });
|
||||
gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: 'power2.out' });
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ import Ground from "../scene/environment/ground";
|
||||
// import ZoneGroup from "../groups/zoneGroup1";
|
||||
import { findEnvironment } from "../../services/factoryBuilder/environment/findEnvironment";
|
||||
import Layer2DVisibility from "./geomentries/layers/layer2DVisibility";
|
||||
import DrieHtmlTemp from "..//visualization/mqttTemp/drieHtmlTemp";
|
||||
import DrieHtmlTemp from "../visualization/mqttTemp/drieHtmlTemp";
|
||||
import ZoneGroup from "./groups/zoneGroup";
|
||||
import useModuleStore from "../../store/useModuleStore";
|
||||
import MeasurementTool from "../scene/tools/measurementTool";
|
||||
|
||||
@@ -10,7 +10,7 @@ import { retrieveGLTF, storeGLTF } from '../../../../utils/indexDB/idbUtils';
|
||||
import { Socket } from 'socket.io-client';
|
||||
import * as CONSTANTS from '../../../../types/world/worldConstants';
|
||||
import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
|
||||
import PointsCalculator from '../../../simulation/events/points/pointsCalculator';
|
||||
import PointsCalculator from '../../../simulation/events/points/functions/pointsCalculator';
|
||||
|
||||
async function addAssetModel(
|
||||
raycaster: THREE.Raycaster,
|
||||
@@ -184,24 +184,9 @@ async function handleModelLoad(
|
||||
);
|
||||
|
||||
if (!data || !data.points) return;
|
||||
console.log('data: ', data);
|
||||
|
||||
const createMarker = (point: THREE.Vector3) => {
|
||||
const sphere = new THREE.SphereGeometry(0.1, 15);
|
||||
const material = new THREE.MeshStandardMaterial();
|
||||
const mesh = new THREE.Mesh(sphere, material);
|
||||
mesh.position.copy(point);
|
||||
return mesh;
|
||||
};
|
||||
|
||||
if (data.points && data.points.length > 0) {
|
||||
data.points.forEach((Point) => {
|
||||
model.add(createMarker(Point));
|
||||
});
|
||||
}
|
||||
|
||||
if (selectedItem.type === "Conveyor") {
|
||||
const event: ConveyorEventSchema = {
|
||||
const ConveyorEvent: ConveyorEventSchema = {
|
||||
modelUuid: newFloorItem.modeluuid,
|
||||
modelName: newFloorItem.modelname,
|
||||
position: newFloorItem.position,
|
||||
@@ -225,7 +210,85 @@ async function handleModelLoad(
|
||||
}
|
||||
}))
|
||||
}
|
||||
addEvent(event);
|
||||
addEvent(ConveyorEvent);
|
||||
} else if (selectedItem.type === "Vehicle") {
|
||||
const vehicleEvent: VehicleEventSchema = {
|
||||
modelUuid: newFloorItem.modeluuid,
|
||||
modelName: newFloorItem.modelname,
|
||||
position: newFloorItem.position,
|
||||
rotation: [newFloorItem.rotation.x, newFloorItem.rotation.y, newFloorItem.rotation.z],
|
||||
state: "idle",
|
||||
type: "vehicle",
|
||||
speed: 1,
|
||||
point: {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [data.points[0].x, data.points[0].y, data.points[0].z],
|
||||
rotation: [0, 0, 0],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Vehicle Action",
|
||||
actionType: "travel",
|
||||
material: null,
|
||||
unLoadDuration: 5,
|
||||
loadCapacity: 10,
|
||||
pickUpPoint: null,
|
||||
unLoadPoint: null,
|
||||
triggers: []
|
||||
}
|
||||
}
|
||||
};
|
||||
addEvent(vehicleEvent);
|
||||
} else if (selectedItem.type === "ArmBot") {
|
||||
const roboticArmEvent: RoboticArmEventSchema = {
|
||||
modelUuid: newFloorItem.modeluuid,
|
||||
modelName: newFloorItem.modelname,
|
||||
position: newFloorItem.position,
|
||||
rotation: [newFloorItem.rotation.x, newFloorItem.rotation.y, newFloorItem.rotation.z],
|
||||
state: "idle",
|
||||
type: "roboticArm",
|
||||
speed: 1,
|
||||
point: {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [data.points[0].x, data.points[0].y, data.points[0].z],
|
||||
rotation: [0, 0, 0],
|
||||
actions: [
|
||||
{
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Pick and Place",
|
||||
actionType: "pickAndPlace",
|
||||
process: {
|
||||
startPoint: [0, 0, 0],
|
||||
endPoint: [0, 0, 0]
|
||||
},
|
||||
triggers: []
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
addEvent(roboticArmEvent);
|
||||
} else if (selectedItem.type === "StaticMachine") {
|
||||
const machineEvent: MachineEventSchema = {
|
||||
modelUuid: newFloorItem.modeluuid,
|
||||
modelName: newFloorItem.modelname,
|
||||
position: newFloorItem.position,
|
||||
rotation: [newFloorItem.rotation.x, newFloorItem.rotation.y, newFloorItem.rotation.z],
|
||||
state: "idle",
|
||||
type: "machine",
|
||||
point: {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [data.points[0].x, data.points[0].y, data.points[0].z],
|
||||
rotation: [0, 0, 0],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Process Action",
|
||||
actionType: "process",
|
||||
processTime: 10,
|
||||
swapMaterial: "material-id",
|
||||
triggers: []
|
||||
}
|
||||
}
|
||||
};
|
||||
addEvent(machineEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ import addAssetModel from "../geomentries/assets/addAssetModel";
|
||||
import { getFloorAssets } from "../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi";
|
||||
import useModuleStore from "../../../store/useModuleStore";
|
||||
// import { retrieveGLTF } from "../../../utils/indexDB/idbUtils";
|
||||
|
||||
import { useEventsStore } from "../../../store/simulation/useEventsStore";
|
||||
|
||||
const assetManagerWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/assetManagerWorker.js", import.meta.url));
|
||||
const gltfLoaderWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js", import.meta.url));
|
||||
|
||||
@@ -75,7 +75,7 @@ const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject
|
||||
gltfLoaderWorker.postMessage({ floorItems: data });
|
||||
} else {
|
||||
gltfLoaderWorker.postMessage({ floorItems: [] });
|
||||
loadInitialFloorItems(itemsGroup, setFloorItems);
|
||||
loadInitialFloorItems(itemsGroup, setFloorItems, addEvent);
|
||||
updateLoadingProgress(100);
|
||||
}
|
||||
});
|
||||
@@ -94,7 +94,7 @@ const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject
|
||||
updateLoadingProgress(progress);
|
||||
|
||||
if (loadedAssets === totalAssets) {
|
||||
loadInitialFloorItems(itemsGroup, setFloorItems);
|
||||
loadInitialFloorItems(itemsGroup, setFloorItems, addEvent);
|
||||
updateLoadingProgress(100);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,90 +2,107 @@ import * as THREE from "three";
|
||||
import { EffectComposer, N8AO, Outline } from "@react-three/postprocessing";
|
||||
import { BlendFunction } from "postprocessing";
|
||||
import {
|
||||
useDeletableFloorItem,
|
||||
useSelectedWallItem,
|
||||
useSelectedFloorItem,
|
||||
useDeletableFloorItem,
|
||||
useSelectedWallItem,
|
||||
useSelectedFloorItem,
|
||||
} from "../../../store/store";
|
||||
import * as Types from "../../../types/world/worldTypes";
|
||||
import * as CONSTANTS from "../../../types/world/worldConstants";
|
||||
import { useEffect } from "react";
|
||||
import { useSelectedEventSphere } from "../../../store/simulation/useSimulationStore";
|
||||
|
||||
export default function PostProcessing() {
|
||||
const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem();
|
||||
const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
|
||||
const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem();
|
||||
const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem();
|
||||
const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
|
||||
const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem();
|
||||
const { selectedEventSphere } = useSelectedEventSphere();
|
||||
|
||||
function flattenChildren(children: any[]) {
|
||||
const allChildren: any[] = [];
|
||||
children.forEach((child) => {
|
||||
allChildren.push(child);
|
||||
if (child.children && child.children.length > 0) {
|
||||
allChildren.push(...flattenChildren(child.children));
|
||||
}
|
||||
});
|
||||
return allChildren;
|
||||
}
|
||||
function flattenChildren(children: any[]) {
|
||||
const allChildren: any[] = [];
|
||||
children.forEach((child) => {
|
||||
allChildren.push(child);
|
||||
if (child.children && child.children.length > 0) {
|
||||
allChildren.push(...flattenChildren(child.children));
|
||||
}
|
||||
});
|
||||
return allChildren;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<EffectComposer autoClear={false}>
|
||||
<N8AO
|
||||
color="black"
|
||||
aoRadius={20}
|
||||
intensity={7}
|
||||
distanceFalloff={4}
|
||||
aoSamples={32}
|
||||
denoiseRadius={6}
|
||||
denoiseSamples={16}
|
||||
/>
|
||||
{deletableFloorItem && (
|
||||
<Outline
|
||||
selection={flattenChildren(deletableFloorItem.children)}
|
||||
selectionLayer={10}
|
||||
width={3000}
|
||||
blendFunction={BlendFunction.ALPHA}
|
||||
edgeStrength={5}
|
||||
resolutionScale={2}
|
||||
pulseSpeed={0}
|
||||
visibleEdgeColor={CONSTANTS.outlineConfig.assetDeleteColor}
|
||||
hiddenEdgeColor={CONSTANTS.outlineConfig.assetDeleteColor}
|
||||
blur={true}
|
||||
xRay={true}
|
||||
/>
|
||||
)}
|
||||
{selectedWallItem && (
|
||||
<Outline
|
||||
selection={selectedWallItem.children[1].children[0].children.filter(
|
||||
(child: Types.Mesh) => child.name !== "CSG_REF"
|
||||
)}
|
||||
selectionLayer={10}
|
||||
width={3000}
|
||||
blendFunction={BlendFunction.ALPHA}
|
||||
edgeStrength={5}
|
||||
resolutionScale={2}
|
||||
pulseSpeed={0}
|
||||
visibleEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
|
||||
hiddenEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
|
||||
blur={true}
|
||||
xRay={true}
|
||||
/>
|
||||
)}
|
||||
{selectedFloorItem && (
|
||||
<Outline
|
||||
selection={flattenChildren(selectedFloorItem.children)}
|
||||
selectionLayer={10}
|
||||
width={3000}
|
||||
blendFunction={BlendFunction.ALPHA}
|
||||
edgeStrength={5}
|
||||
resolutionScale={2}
|
||||
pulseSpeed={0}
|
||||
visibleEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
|
||||
hiddenEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
|
||||
blur={true}
|
||||
xRay={true}
|
||||
/>
|
||||
)}
|
||||
</EffectComposer>
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<EffectComposer autoClear={false}>
|
||||
<N8AO
|
||||
color="black"
|
||||
aoRadius={20}
|
||||
intensity={7}
|
||||
distanceFalloff={4}
|
||||
aoSamples={32}
|
||||
denoiseRadius={6}
|
||||
denoiseSamples={16}
|
||||
/>
|
||||
{deletableFloorItem && (
|
||||
<Outline
|
||||
selection={flattenChildren(deletableFloorItem.children)}
|
||||
selectionLayer={10}
|
||||
width={3000}
|
||||
blendFunction={BlendFunction.ALPHA}
|
||||
edgeStrength={5}
|
||||
resolutionScale={2}
|
||||
pulseSpeed={0}
|
||||
visibleEdgeColor={CONSTANTS.outlineConfig.assetDeleteColor}
|
||||
hiddenEdgeColor={CONSTANTS.outlineConfig.assetDeleteColor}
|
||||
blur={true}
|
||||
xRay={true}
|
||||
/>
|
||||
)}
|
||||
{selectedWallItem && (
|
||||
<Outline
|
||||
selection={selectedWallItem.children[1].children[0].children.filter(
|
||||
(child: Types.Mesh) => child.name !== "CSG_REF"
|
||||
)}
|
||||
selectionLayer={10}
|
||||
width={3000}
|
||||
blendFunction={BlendFunction.ALPHA}
|
||||
edgeStrength={5}
|
||||
resolutionScale={2}
|
||||
pulseSpeed={0}
|
||||
visibleEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
|
||||
hiddenEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
|
||||
blur={true}
|
||||
xRay={true}
|
||||
/>
|
||||
)}
|
||||
{selectedFloorItem && (
|
||||
<Outline
|
||||
selection={flattenChildren(selectedFloorItem.children)}
|
||||
selectionLayer={10}
|
||||
width={3000}
|
||||
blendFunction={BlendFunction.ALPHA}
|
||||
edgeStrength={5}
|
||||
resolutionScale={2}
|
||||
pulseSpeed={0}
|
||||
visibleEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
|
||||
hiddenEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
|
||||
blur={true}
|
||||
xRay={true}
|
||||
/>
|
||||
)}
|
||||
{selectedEventSphere && (
|
||||
<Outline
|
||||
selection={[selectedEventSphere]}
|
||||
selectionLayer={10}
|
||||
width={1000}
|
||||
blendFunction={BlendFunction.ALPHA}
|
||||
edgeStrength={10}
|
||||
resolutionScale={2}
|
||||
pulseSpeed={0}
|
||||
visibleEdgeColor={0x6f42c1}
|
||||
hiddenEdgeColor={0x6f42c1}
|
||||
blur={true}
|
||||
xRay={true}
|
||||
/>
|
||||
)}
|
||||
</EffectComposer>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
14
app/src/modules/simulation/conveyor/conveyor.tsx
Normal file
14
app/src/modules/simulation/conveyor/conveyor.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react'
|
||||
import ConveyorInstances from './instances/conveyorInstances'
|
||||
|
||||
function Conveyor() {
|
||||
return (
|
||||
<>
|
||||
|
||||
<ConveyorInstances />
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Conveyor
|
||||
@@ -0,0 +1,10 @@
|
||||
import React from 'react'
|
||||
|
||||
function ConveyorInstance() {
|
||||
return (
|
||||
<>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default ConveyorInstance
|
||||
@@ -0,0 +1,14 @@
|
||||
import React from 'react'
|
||||
import ConveyorInstance from './conveyorInstance/conveyorInstance'
|
||||
|
||||
function ConveyorInstances() {
|
||||
return (
|
||||
<>
|
||||
|
||||
<ConveyorInstance />
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default ConveyorInstances
|
||||
@@ -0,0 +1,169 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import * as THREE from 'three';
|
||||
import { useEventsStore } from '../../../../../store/simulation/useEventsStore';
|
||||
import useModuleStore from '../../../../../store/useModuleStore';
|
||||
import { TransformControls } from '@react-three/drei';
|
||||
import { detectModifierKeys } from '../../../../../utils/shortcutkeys/detectModifierKeys';
|
||||
import { useSelectedEventSphere, useSelectedEventData } from '../../../../../store/simulation/useSimulationStore';
|
||||
|
||||
function PointsCreator() {
|
||||
const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore();
|
||||
const { activeModule } = useModuleStore();
|
||||
const transformRef = useRef<any>(null);
|
||||
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
|
||||
const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({});
|
||||
const { selectedEventSphere, setSelectedEventSphere, clearSelectedEventSphere } = useSelectedEventSphere();
|
||||
const { setSelectedEventData, clearSelectedEventData } = useSelectedEventData();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventSphere) {
|
||||
const eventData = getEventByModelUuid(selectedEventSphere.userData.modelUuid);
|
||||
if (eventData) {
|
||||
setSelectedEventData(
|
||||
eventData,
|
||||
selectedEventSphere.userData.pointUuid
|
||||
);
|
||||
} else {
|
||||
clearSelectedEventData();
|
||||
}
|
||||
} else {
|
||||
clearSelectedEventData();
|
||||
}
|
||||
}, [selectedEventSphere]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
const keyCombination = detectModifierKeys(e);
|
||||
if (!selectedEventSphere) return;
|
||||
if (keyCombination === "G") {
|
||||
setTransformMode((prev) => (prev === "translate" ? null : "translate"));
|
||||
}
|
||||
if (keyCombination === "R") {
|
||||
setTransformMode((prev) => (prev === "rotate" ? null : "rotate"));
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, [selectedEventSphere]);
|
||||
|
||||
const updatePointToState = (selectedEventSphere: THREE.Mesh) => {
|
||||
let point = JSON.parse(JSON.stringify(getPointByUuid(selectedEventSphere.userData.modelUuid, selectedEventSphere.userData.pointUuid)));
|
||||
if (point) {
|
||||
point.position = [selectedEventSphere.position.x, selectedEventSphere.position.y, selectedEventSphere.position.z];
|
||||
updatePoint(selectedEventSphere.userData.modelUuid, selectedEventSphere.userData.pointUuid, point)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{activeModule === 'simulation' &&
|
||||
<>
|
||||
<group name='EventPointsGroup' >
|
||||
{events.map((event, i) => {
|
||||
if (event.type === 'transfer') {
|
||||
return (
|
||||
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||
{event.points.map((point, j) => (
|
||||
<mesh
|
||||
uuid={point.uuid}
|
||||
ref={(el) => (sphereRefs.current[point.uuid] = el!)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setSelectedEventSphere(sphereRefs.current[point.uuid]);
|
||||
}}
|
||||
onPointerMissed={() => {
|
||||
clearSelectedEventSphere();
|
||||
setTransformMode(null);
|
||||
}}
|
||||
key={`${i}-${j}`}
|
||||
position={new THREE.Vector3(...point.position)}
|
||||
userData={{ modelUuid: event.modelUuid, pointUuid: point.uuid }}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
<meshStandardMaterial color="orange" />
|
||||
</mesh>
|
||||
))}
|
||||
</group>
|
||||
);
|
||||
} else if (event.type === 'vehicle') {
|
||||
return (
|
||||
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||
<mesh
|
||||
uuid={event.point.uuid}
|
||||
ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setSelectedEventSphere(sphereRefs.current[event.point.uuid]);
|
||||
}}
|
||||
onPointerMissed={() => {
|
||||
clearSelectedEventSphere();
|
||||
setTransformMode(null);
|
||||
}}
|
||||
position={new THREE.Vector3(...event.point.position)}
|
||||
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
<meshStandardMaterial color="blue" />
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
} else if (event.type === 'roboticArm') {
|
||||
return (
|
||||
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||
<mesh
|
||||
uuid={event.point.uuid}
|
||||
ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setSelectedEventSphere(sphereRefs.current[event.point.uuid]);
|
||||
}}
|
||||
onPointerMissed={() => {
|
||||
clearSelectedEventSphere();
|
||||
setTransformMode(null);
|
||||
}}
|
||||
position={new THREE.Vector3(...event.point.position)}
|
||||
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
<meshStandardMaterial color="green" />
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
} else if (event.type === 'machine') {
|
||||
return (
|
||||
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||
<mesh
|
||||
uuid={event.point.uuid}
|
||||
ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setSelectedEventSphere(sphereRefs.current[event.point.uuid]);
|
||||
}}
|
||||
onPointerMissed={() => {
|
||||
clearSelectedEventSphere();
|
||||
setTransformMode(null);
|
||||
}}
|
||||
position={new THREE.Vector3(...event.point.position)}
|
||||
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
<meshStandardMaterial color="purple" />
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
</group>
|
||||
{(selectedEventSphere && transformMode) &&
|
||||
<TransformControls ref={transformRef} object={selectedEventSphere} mode={transformMode} onMouseUp={(e) => { updatePointToState(selectedEventSphere) }} />
|
||||
}
|
||||
</>
|
||||
}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default PointsCreator;
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as THREE from 'three';
|
||||
import { Group } from '../../../../types/world/worldTypes';
|
||||
import { Group } from '../../../../../types/world/worldTypes';
|
||||
|
||||
function PointsCalculator(
|
||||
type: string,
|
||||
12
app/src/modules/simulation/events/points/points.tsx
Normal file
12
app/src/modules/simulation/events/points/points.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from 'react'
|
||||
import PointsCreator from './creator/pointsCreator'
|
||||
|
||||
function Points() {
|
||||
return (
|
||||
<>
|
||||
<PointsCreator />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Points
|
||||
@@ -0,0 +1,10 @@
|
||||
import React from 'react'
|
||||
|
||||
function MachineInstance() {
|
||||
return (
|
||||
<>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default MachineInstance
|
||||
@@ -0,0 +1,14 @@
|
||||
import React from 'react'
|
||||
import MachineInstance from './machineInstance/machineInstance'
|
||||
|
||||
function MachineInstances() {
|
||||
return (
|
||||
<>
|
||||
|
||||
<MachineInstance />
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default MachineInstances
|
||||
14
app/src/modules/simulation/machine/machine.tsx
Normal file
14
app/src/modules/simulation/machine/machine.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react'
|
||||
import MachineInstances from './instances/machineInstances'
|
||||
|
||||
function Machine() {
|
||||
return (
|
||||
<>
|
||||
|
||||
<MachineInstances />
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Machine
|
||||
@@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
|
||||
function MaterialAnimator() {
|
||||
return (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
|
||||
export default MaterialAnimator
|
||||
@@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
|
||||
function MaterialInstance() {
|
||||
return (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
|
||||
export default MaterialInstance
|
||||
@@ -0,0 +1,17 @@
|
||||
import React from 'react'
|
||||
import MaterialInstance from './instance/materialInstance'
|
||||
import MaterialAnimator from './animator/materialAnimator'
|
||||
|
||||
function MaterialInstances() {
|
||||
return (
|
||||
<>
|
||||
|
||||
<MaterialInstance />
|
||||
|
||||
<MaterialAnimator />
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default MaterialInstances
|
||||
14
app/src/modules/simulation/materials/materials.tsx
Normal file
14
app/src/modules/simulation/materials/materials.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react'
|
||||
import MaterialInstances from './instances/materialInstances'
|
||||
|
||||
function Materials() {
|
||||
return (
|
||||
<>
|
||||
|
||||
<MaterialInstances />
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Materials
|
||||
25
app/src/modules/simulation/products/products.tsx
Normal file
25
app/src/modules/simulation/products/products.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React, { useEffect } from 'react'
|
||||
import { useProductStore } from '../../../store/simulation/useProductStore'
|
||||
import * as THREE from 'three';
|
||||
import { useSelectedProduct } from '../../../store/simulation/useSimulationStore';
|
||||
|
||||
function Products() {
|
||||
const { products, addProduct } = useProductStore();
|
||||
const { setSelectedProduct } = useSelectedProduct();
|
||||
|
||||
useEffect(() => {
|
||||
if (products.length === 0) {
|
||||
const id = THREE.MathUtils.generateUUID();
|
||||
const name = 'Product 1';
|
||||
addProduct(name, id);
|
||||
setSelectedProduct(id, name);
|
||||
}
|
||||
}, [products])
|
||||
|
||||
return (
|
||||
<>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Products
|
||||
@@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
|
||||
function RoboticArmAnimator({ armUuid, HandleCallback, currentPhase }: any) {
|
||||
return (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
|
||||
export default RoboticArmAnimator;
|
||||
@@ -0,0 +1,61 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import IKInstance from '../ikInstance/ikInstance';
|
||||
import RoboticArmAnimator from '../animator/roboticArmAnimator';
|
||||
import { usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||
import { useArmBotStore } from '../../../../../store/simulation/useArmBotStore';
|
||||
|
||||
function RoboticArmInstance({ armBot }: any) {
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const [currentPhase, setCurrentPhase] = useState<(string)>("init");
|
||||
// console.log('currentPhase: ', currentPhase);
|
||||
const { armBots, addArmBot, addCurrentAction } = useArmBotStore();
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
// console.log('isPlaying: ', isPlaying);
|
||||
if (isPlaying) {
|
||||
//Moving armBot from initial point to rest position.
|
||||
|
||||
if (armBot?.isActive && armBot?.state == "idle" && currentPhase == "init") {
|
||||
addCurrentAction(armBot.modelUuid, 'action-001');
|
||||
setCurrentPhase("moving-to-rest");
|
||||
|
||||
}
|
||||
//Waiting for trigger.
|
||||
if (!armBot?.isActive && armBot?.state == "idle" && currentPhase == "moving-to-rest") {
|
||||
setCurrentPhase("rest");
|
||||
}
|
||||
// Moving armBot from rest position to pick up point.
|
||||
if (!armBot?.isActive && armBot?.state == "idle" && currentPhase == "rest") {
|
||||
|
||||
}
|
||||
//Moving arm from start point to end point.
|
||||
if (armBot?.isActive && armBot?.state == "running " && currentPhase == "rest-to-start ") {
|
||||
|
||||
}
|
||||
//Moving arm from end point to idle.
|
||||
if (armBot?.isActive && armBot?.state == "running" && currentPhase == "end-to-start") {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}, [currentPhase, armBot, isPlaying])
|
||||
|
||||
const HandleCallback = () => {
|
||||
if (armBot.isActive && armBot.state == "idle" && currentPhase == "init") {
|
||||
addCurrentAction('armbot-xyz-001', 'action-001');
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
<IKInstance />
|
||||
<RoboticArmAnimator armUuid={armBot?.modelUuid} HandleCallback={HandleCallback} currentPhase={currentPhase} />
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default RoboticArmInstance;
|
||||
@@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
|
||||
function IKInstance() {
|
||||
return (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
|
||||
export default IKInstance;
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react'
|
||||
import RoboticArmInstance from './armInstance/roboticArmInstance';
|
||||
import { useArmBotStore } from '../../../../store/simulation/useArmBotStore';
|
||||
|
||||
function RoboticArmInstances() {
|
||||
const { armBots } = useArmBotStore();
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
{armBots?.map((robot) => (
|
||||
<RoboticArmInstance key={robot.modelUuid} armdetals={robot} />
|
||||
))}
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default RoboticArmInstances;
|
||||
103
app/src/modules/simulation/roboticArm/roboticArm.tsx
Normal file
103
app/src/modules/simulation/roboticArm/roboticArm.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
import { useEffect } from "react";
|
||||
import RoboticArmInstances from "./instances/roboticArmInstances";
|
||||
import { useArmBotStore } from "../../../store/simulation/useArmBotStore";
|
||||
|
||||
function RoboticArm() {
|
||||
const { armBots, addArmBot, addCurrentAction } = useArmBotStore();
|
||||
|
||||
const armBotStatusSample: RoboticArmEventSchema[] = [
|
||||
{
|
||||
state: "idle",
|
||||
// currentAction: {
|
||||
// actionUuid: "action-001",
|
||||
// actionName: "Pick Component",
|
||||
// },
|
||||
modelUuid: "armbot-xyz-001",
|
||||
modelName: "ArmBot-X200",
|
||||
position: [0, 0, 0],
|
||||
rotation: [91.94347308985614, 0, 6.742905194869091],
|
||||
type: "roboticArm",
|
||||
speed: 1.5,
|
||||
point: {
|
||||
uuid: "point-123",
|
||||
position: [0, 1.5, 0],
|
||||
rotation: [0, 0, 0],
|
||||
actions: [
|
||||
{
|
||||
actionUuid: "action-001",
|
||||
actionName: "Pick Component",
|
||||
actionType: "pickAndPlace",
|
||||
process: {
|
||||
startPoint: [1.2, 0.3, 0.5],
|
||||
endPoint: [-0.8, 1.1, 0.7],
|
||||
},
|
||||
triggers: [
|
||||
{
|
||||
triggerUuid: "trigger-001",
|
||||
triggerName: "Start Trigger",
|
||||
triggerType: "onStart",
|
||||
delay: 0,
|
||||
triggeredAsset: {
|
||||
triggeredModel: {
|
||||
modelName: "Conveyor A1",
|
||||
modelUuid: "conveyor-01",
|
||||
},
|
||||
triggeredPoint: {
|
||||
pointName: "Start Point",
|
||||
pointUuid: "conveyor-01-point-001",
|
||||
},
|
||||
triggeredAction: {
|
||||
actionName: "Move Forward",
|
||||
actionUuid: "conveyor-action-01",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
triggerUuid: "trigger-002",
|
||||
triggerName: "Complete Trigger",
|
||||
triggerType: "onComplete",
|
||||
delay: 0,
|
||||
triggeredAsset: {
|
||||
triggeredModel: {
|
||||
modelName: "StaticMachine B2",
|
||||
modelUuid: "machine-02",
|
||||
},
|
||||
triggeredPoint: {
|
||||
pointName: "Receive Point",
|
||||
pointUuid: "machine-02-point-001",
|
||||
},
|
||||
triggeredAction: {
|
||||
actionName: "Process Part",
|
||||
actionUuid: "machine-action-01",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
addArmBot('123', armBotStatusSample[0]);
|
||||
// addCurrentAction('armbot-xyz-001', 'action-001');
|
||||
}, []);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
// console.log('armBots: ', armBots);
|
||||
}, [armBots]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
<RoboticArmInstances />
|
||||
|
||||
<></>
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default RoboticArm;
|
||||
@@ -2,13 +2,24 @@ import React, { useEffect } from 'react';
|
||||
import { useEventsStore } from '../../store/simulation/useEventsStore';
|
||||
import { useProductStore } from '../../store/simulation/useProductStore';
|
||||
import Vehicles from './vehicle/vehicles';
|
||||
import Points from './events/points/points';
|
||||
import Conveyor from './conveyor/conveyor';
|
||||
import RoboticArm from './roboticArm/roboticArm';
|
||||
import Materials from './materials/materials';
|
||||
import Machine from './machine/machine';
|
||||
import StorageUnit from './storageUnit/storageUnit';
|
||||
import Simulator from './simulator/simulator';
|
||||
import Products from './products/products';
|
||||
import Trigger from './triggers/trigger';
|
||||
import useModuleStore from '../../store/useModuleStore';
|
||||
|
||||
function Simulation() {
|
||||
const { activeModule } = useModuleStore();
|
||||
const { events } = useEventsStore();
|
||||
const { products } = useProductStore();
|
||||
|
||||
useEffect(() => {
|
||||
console.log('events: ', events);
|
||||
// console.log('events: ', events);
|
||||
}, [events])
|
||||
|
||||
useEffect(() => {
|
||||
@@ -17,9 +28,37 @@ function Simulation() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Vehicles />
|
||||
|
||||
{activeModule === 'simulation' &&
|
||||
|
||||
<>
|
||||
|
||||
<Points />
|
||||
|
||||
<Products />
|
||||
|
||||
<Materials />
|
||||
|
||||
<Trigger />
|
||||
|
||||
<Conveyor />
|
||||
|
||||
<Vehicles />
|
||||
|
||||
<RoboticArm />
|
||||
|
||||
<Machine />
|
||||
|
||||
<StorageUnit />
|
||||
|
||||
<Simulator />
|
||||
|
||||
</>
|
||||
|
||||
}
|
||||
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default Simulation
|
||||
export default Simulation;
|
||||
|
||||
11
app/src/modules/simulation/simulator/simulator.tsx
Normal file
11
app/src/modules/simulation/simulator/simulator.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from 'react'
|
||||
|
||||
function Simulator() {
|
||||
return (
|
||||
<>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Simulator
|
||||
@@ -0,0 +1,10 @@
|
||||
import React from 'react'
|
||||
|
||||
function storageUnitInstance() {
|
||||
return (
|
||||
<>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default storageUnitInstance
|
||||
@@ -0,0 +1,14 @@
|
||||
import React from 'react'
|
||||
import StorageUnitInstance from './storageUnitInstance/storageUnitInstance'
|
||||
|
||||
function StorageUnitInstances() {
|
||||
return (
|
||||
<>
|
||||
|
||||
<StorageUnitInstance />
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default StorageUnitInstances
|
||||
14
app/src/modules/simulation/storageUnit/storageUnit.tsx
Normal file
14
app/src/modules/simulation/storageUnit/storageUnit.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react'
|
||||
import StorageUnitInstances from './instances/storageUnitInstances'
|
||||
|
||||
function StorageUnit() {
|
||||
return (
|
||||
<>
|
||||
|
||||
<StorageUnitInstances />
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default StorageUnit
|
||||
@@ -0,0 +1,126 @@
|
||||
import { useThree } from '@react-three/fiber'
|
||||
import React, { useEffect } from 'react'
|
||||
import { Object3D } from 'three';
|
||||
import { useSubModuleStore } from '../../../../store/useModuleStore';
|
||||
import { useLeftData, useTopData } from '../../../../store/visualization/useZone3DWidgetStore';
|
||||
import { useEventsStore } from '../../../../store/simulation/useEventsStore';
|
||||
import { useProductStore } from '../../../../store/simulation/useProductStore';
|
||||
import { useSelectedProduct } from '../../../../store/simulation/useSimulationStore';
|
||||
import { useSelectedAsset } from '../../../../store/simulation/useSimulationStore';
|
||||
|
||||
function TriggerConnector() {
|
||||
const { gl, raycaster, scene } = useThree();
|
||||
const { subModule } = useSubModuleStore();
|
||||
const { setTop } = useTopData();
|
||||
const { setLeft } = useLeftData();
|
||||
const { getIsEventInProduct } = useProductStore();
|
||||
const { getEventByModelUuid } = useEventsStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const { selectedAsset, setSelectedAsset, clearSelectedAsset } = useSelectedAsset();
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
const canvasElement = gl.domElement;
|
||||
|
||||
let drag = false;
|
||||
let isRightMouseDown = false;
|
||||
|
||||
const onMouseDown = (evt: MouseEvent) => {
|
||||
if (selectedAsset) {
|
||||
clearSelectedAsset();
|
||||
}
|
||||
if (evt.button === 2) {
|
||||
isRightMouseDown = true;
|
||||
drag = false;
|
||||
}
|
||||
};
|
||||
|
||||
const onMouseUp = (evt: MouseEvent) => {
|
||||
if (evt.button === 2) {
|
||||
isRightMouseDown = false;
|
||||
}
|
||||
}
|
||||
|
||||
const onMouseMove = () => {
|
||||
if (isRightMouseDown) {
|
||||
drag = true;
|
||||
}
|
||||
};
|
||||
|
||||
const handleRightClick = (evt: MouseEvent) => {
|
||||
if (drag) return;
|
||||
evt.preventDefault();
|
||||
const canvasElement = gl.domElement;
|
||||
if (!canvasElement) return;
|
||||
|
||||
let intersects = raycaster.intersectObjects(scene.children, true);
|
||||
if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) {
|
||||
let currentObject = intersects[0].object;
|
||||
|
||||
while (currentObject) {
|
||||
if (currentObject.name === "Scene") {
|
||||
break;
|
||||
}
|
||||
currentObject = currentObject.parent as Object3D;
|
||||
}
|
||||
if (currentObject) {
|
||||
const isInProduct = getIsEventInProduct(selectedProduct.productId, currentObject.uuid);
|
||||
|
||||
if (isInProduct) {
|
||||
const event = getEventByModelUuid(currentObject.uuid);
|
||||
if (event) {
|
||||
setSelectedAsset(event)
|
||||
const canvasRect = canvasElement.getBoundingClientRect();
|
||||
const relativeX = evt.clientX - canvasRect.left;
|
||||
const relativeY = evt.clientY - canvasRect.top;
|
||||
|
||||
setTop(relativeY);
|
||||
setLeft(relativeX);
|
||||
} else {
|
||||
clearSelectedAsset()
|
||||
}
|
||||
} else {
|
||||
const event = getEventByModelUuid(currentObject.uuid);
|
||||
if (event) {
|
||||
setSelectedAsset(event)
|
||||
const canvasRect = canvasElement.getBoundingClientRect();
|
||||
const relativeX = evt.clientX - canvasRect.left;
|
||||
const relativeY = evt.clientY - canvasRect.top;
|
||||
|
||||
setTop(relativeY);
|
||||
setLeft(relativeX);
|
||||
} else {
|
||||
clearSelectedAsset()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
clearSelectedAsset()
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
if (subModule === 'simulations') {
|
||||
canvasElement.addEventListener("mousedown", onMouseDown);
|
||||
canvasElement.addEventListener("mouseup", onMouseUp);
|
||||
canvasElement.addEventListener("mousemove", onMouseMove);
|
||||
canvasElement.addEventListener('contextmenu', handleRightClick);
|
||||
}
|
||||
|
||||
return () => {
|
||||
canvasElement.removeEventListener("mousedown", onMouseDown);
|
||||
canvasElement.removeEventListener("mouseup", onMouseUp);
|
||||
canvasElement.removeEventListener("mousemove", onMouseMove);
|
||||
canvasElement.removeEventListener('contextmenu', handleRightClick);
|
||||
};
|
||||
|
||||
}, [gl, subModule, selectedProduct, selectedAsset]);
|
||||
|
||||
return (
|
||||
<>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default TriggerConnector
|
||||
14
app/src/modules/simulation/triggers/trigger.tsx
Normal file
14
app/src/modules/simulation/triggers/trigger.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react'
|
||||
import TriggerConnector from './connector/triggerConnector'
|
||||
|
||||
function Trigger() {
|
||||
return (
|
||||
<>
|
||||
|
||||
<TriggerConnector />
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Trigger
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useFrame, useThree } from '@react-three/fiber';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useFloorItems } from '../../../../../store/store';
|
||||
import * as THREE from 'three';
|
||||
import { Line } from '@react-three/drei';
|
||||
@@ -15,7 +15,7 @@ interface VehicleAnimatorProps {
|
||||
}
|
||||
|
||||
function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetail }: VehicleAnimatorProps) {
|
||||
const { updateVehicleLoad, vehicles } = useVehicleStore();
|
||||
const { decrementVehicleLoad, vehicles } = useVehicleStore();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
const { speed } = useAnimationPlaySpeed();
|
||||
const { isReset } = useResetButtonStore();
|
||||
@@ -132,30 +132,23 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
|
||||
const unLoadDuration = agvDetail.point.action.unLoadDuration;
|
||||
const droppedMaterial = agvDetail.currentLoad;
|
||||
fixedInterval = (unLoadDuration / droppedMaterial) * 1000;
|
||||
if (!isPaused) {
|
||||
step(droppedMaterial);
|
||||
} else {
|
||||
pausedTime = performance.now();
|
||||
step(droppedMaterial);
|
||||
}
|
||||
startTime = performance.now();
|
||||
step(droppedMaterial);
|
||||
}
|
||||
|
||||
function step(droppedMaterial: number) {
|
||||
if (!isPaused) {
|
||||
const elapsedTime = performance.now() - startTime;
|
||||
|
||||
if (elapsedTime >= fixedInterval) {
|
||||
console.log('fixedInterval: ', fixedInterval);
|
||||
console.log('elapsedTime: ', elapsedTime);
|
||||
let droppedMat = droppedMaterial - 1;
|
||||
decrementVehicleLoad(agvDetail.modelUuid, 1);
|
||||
if (droppedMat === 0) return;
|
||||
startTime = performance.now();
|
||||
const elapsedTime = performance.now() - startTime - pausedTime;
|
||||
if (elapsedTime >= fixedInterval) {
|
||||
let droppedMat = droppedMaterial - 1;
|
||||
updateVehicleLoad(agvDetail.modelUuid, droppedMat);
|
||||
if (droppedMat === 0) return;
|
||||
startTime = performance.now();
|
||||
pausedTime = 0;
|
||||
requestAnimationFrame(() => step(droppedMat));
|
||||
} else {
|
||||
requestAnimationFrame(() => step(droppedMaterial));
|
||||
}
|
||||
requestAnimationFrame(() => step(droppedMat));
|
||||
} else {
|
||||
requestAnimationFrame(() => firstFrame);
|
||||
requestAnimationFrame(() => step(droppedMaterial));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore
|
||||
function VehicleInstance({ agvDetail }: any) {
|
||||
const { navMesh } = useNavMesh();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { vehicles, setVehicleActive, setVehicleState, updateVehicleLoad } = useVehicleStore();
|
||||
const { vehicles, setVehicleActive, setVehicleState, incrementVehicleLoad } = useVehicleStore();
|
||||
const [currentPhase, setCurrentPhase] = useState<string>('stationed');
|
||||
const [path, setPath] = useState<[number, number, number][]>([]);
|
||||
|
||||
@@ -50,8 +50,9 @@ function VehicleInstance({ agvDetail }: any) {
|
||||
agvDetail.state === 'idle' &&
|
||||
currentPhase === 'picking'
|
||||
) {
|
||||
|
||||
setTimeout(() => {
|
||||
updateVehicleLoad(agvDetail.modelUuid, 2);
|
||||
incrementVehicleLoad(agvDetail.modelUuid, 2);
|
||||
}, 5000);
|
||||
|
||||
if (agvDetail.currentLoad === agvDetail.point.action.loadCapacity) {
|
||||
|
||||
@@ -17,7 +17,7 @@ export default function PolygonGenerator({
|
||||
useEffect(() => {
|
||||
let allLines = arrayLinesToObject(lines.current);
|
||||
const wallLines = allLines?.filter((line) => line?.type === "WallLine");
|
||||
const aisleLines = allLines?.filter((line) => line?.type === "AisleLine");
|
||||
const aisleLines = allLines?.filter((line) => line?.type === "AisleLine")
|
||||
|
||||
const wallPoints = wallLines
|
||||
.map((pair) => pair?.line.map((vals) => vals.position))
|
||||
@@ -39,9 +39,10 @@ export default function PolygonGenerator({
|
||||
);
|
||||
|
||||
const polygons = turf.polygonize(turf.featureCollection(lineFeatures));
|
||||
|
||||
renderWallGeometry(wallPoints);
|
||||
|
||||
if (polygons.features.length > 1) {
|
||||
if (polygons.features.length > 0) {
|
||||
polygons.features.forEach((feature) => {
|
||||
if (feature.geometry.type === "Polygon") {
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ function Vehicles() {
|
||||
|
||||
useEffect(() => {
|
||||
addVehicle('123', vehicleStatusSample[0]);
|
||||
addVehicle('123', vehicleStatusSample[1]);
|
||||
// addVehicle('123', vehicleStatusSample[1]);
|
||||
// addVehicle('123', vehicleStatusSample[2]);
|
||||
}, [])
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ const RealTimeVisulization: React.FC = () => {
|
||||
{}
|
||||
);
|
||||
setZonesData(formattedData);
|
||||
} catch (error) {}
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
GetZoneData();
|
||||
@@ -362,6 +362,10 @@ const RealTimeVisulization: React.FC = () => {
|
||||
"RotateY",
|
||||
"Delete",
|
||||
]}
|
||||
onClick={(e) => {
|
||||
setRightSelect(e);
|
||||
setEditWidgetOptions(false);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user