Refactor asset model handling and event data management
- Removed redundant data structure in handleModelLoad function. - Introduced eventData object to encapsulate event-related information for different asset types (Conveyor, Vehicle, ArmBot, StaticMachine). - Updated socket emission to include complete data with eventData. - Enhanced copy-paste and duplication controls to maintain eventData integrity during object duplication. - Integrated event data updates in move and rotate controls to reflect changes in the simulation state. - Improved PointsCreator component to handle rotation for event groups. - Updated handleAddEventToProduct function to support event data management. - Enhanced product management to fetch existing products from the server and handle new product creation. - Added new types for eventData in worldTypes and simulationTypes for better type safety. - Refactored IndexedDB utility functions for cleaner code.
This commit is contained in:
@@ -62,7 +62,7 @@ function PointsCreator() {
|
||||
{events.map((event, i) => {
|
||||
if (event.type === 'transfer') {
|
||||
return (
|
||||
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||
<group key={i} position={[...event.position]} rotation={[...event.rotation]} >
|
||||
{event.points.map((point, j) => (
|
||||
<mesh
|
||||
name='Event-Sphere'
|
||||
@@ -78,6 +78,7 @@ function PointsCreator() {
|
||||
}}
|
||||
key={`${i}-${j}`}
|
||||
position={new THREE.Vector3(...point.position)}
|
||||
// rotation={new THREE.Euler(...point.rotation)}
|
||||
userData={{ modelUuid: event.modelUuid, pointUuid: point.uuid }}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
@@ -88,7 +89,7 @@ function PointsCreator() {
|
||||
);
|
||||
} else if (event.type === 'vehicle') {
|
||||
return (
|
||||
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||
<group key={i} position={[...event.position]} rotation={[...event.rotation]} >
|
||||
<mesh
|
||||
name='Event-Sphere'
|
||||
uuid={event.point.uuid}
|
||||
@@ -102,6 +103,7 @@ function PointsCreator() {
|
||||
setTransformMode(null);
|
||||
}}
|
||||
position={new THREE.Vector3(...event.point.position)}
|
||||
// rotation={new THREE.Euler(...event.point.rotation)}
|
||||
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
@@ -111,7 +113,7 @@ function PointsCreator() {
|
||||
);
|
||||
} else if (event.type === 'roboticArm') {
|
||||
return (
|
||||
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||
<group key={i} position={[...event.position]} rotation={[...event.rotation]} >
|
||||
<mesh
|
||||
name='Event-Sphere'
|
||||
uuid={event.point.uuid}
|
||||
@@ -125,6 +127,7 @@ function PointsCreator() {
|
||||
setTransformMode(null);
|
||||
}}
|
||||
position={new THREE.Vector3(...event.point.position)}
|
||||
// rotation={new THREE.Euler(...event.point.rotation)}
|
||||
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
@@ -134,7 +137,7 @@ function PointsCreator() {
|
||||
);
|
||||
} else if (event.type === 'machine') {
|
||||
return (
|
||||
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||
<group key={i} position={[...event.position]} rotation={[...event.rotation]} >
|
||||
<mesh
|
||||
name='Event-Sphere'
|
||||
uuid={event.point.uuid}
|
||||
@@ -148,6 +151,7 @@ function PointsCreator() {
|
||||
setTransformMode(null);
|
||||
}}
|
||||
position={new THREE.Vector3(...event.point.position)}
|
||||
// rotation={new THREE.Euler(...event.point.rotation)}
|
||||
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
|
||||
@@ -1,28 +1,38 @@
|
||||
import { upsertProductOrEventApi } from "../../../../../services/simulation/UpsertProductOrEventApi";
|
||||
|
||||
interface HandleAddEventToProductParams {
|
||||
selectedAsset: any; // Replace `any` with specific type if you have it
|
||||
addEvent: (productId: string, asset: any) => void;
|
||||
event: EventsSchema | undefined;
|
||||
addEvent: (productId: string, event: EventsSchema) => void;
|
||||
selectedProduct: {
|
||||
productId: string;
|
||||
productName: string;
|
||||
// Add other fields if needed
|
||||
};
|
||||
clearSelectedAsset: () => void;
|
||||
}
|
||||
clearSelectedAsset?: () => void;
|
||||
}
|
||||
|
||||
export const handleAddEventToProduct = ({
|
||||
selectedAsset,
|
||||
event,
|
||||
addEvent,
|
||||
selectedProduct,
|
||||
clearSelectedAsset,
|
||||
clearSelectedAsset
|
||||
}: HandleAddEventToProductParams) => {
|
||||
console.log('selectedProduct: ', selectedProduct);
|
||||
if (selectedAsset) {
|
||||
addEvent(selectedProduct.productId, selectedAsset);
|
||||
// upsertProductOrEventApi({
|
||||
// productName: selectedProduct.productName,
|
||||
// productId: selectedProduct.productId,
|
||||
// eventDatas: selectedAsset
|
||||
// });
|
||||
clearSelectedAsset();
|
||||
if (event && selectedProduct.productId) {
|
||||
addEvent(selectedProduct.productId, event);
|
||||
|
||||
const email = localStorage.getItem('email')
|
||||
const organization = (email!.split("@")[1]).split(".")[0];
|
||||
|
||||
upsertProductOrEventApi({
|
||||
productName: selectedProduct.productName,
|
||||
productId: selectedProduct.productId,
|
||||
organization: organization,
|
||||
eventDatas: event
|
||||
}).then((data) => {
|
||||
// console.log(data);
|
||||
})
|
||||
|
||||
if (clearSelectedAsset) {
|
||||
clearSelectedAsset();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -7,28 +7,27 @@ import { upsertProductOrEventApi } from '../../../services/simulation/UpsertProd
|
||||
import { getAllProductsApi } from '../../../services/simulation/getallProductsApi';
|
||||
|
||||
function Products() {
|
||||
const { products, addProduct } = useProductStore();
|
||||
const { products, addProduct, setProducts } = useProductStore();
|
||||
const { setSelectedProduct } = useSelectedProduct();
|
||||
|
||||
useEffect(() => {
|
||||
if (products.length === 0) {
|
||||
const id = THREE.MathUtils.generateUUID();
|
||||
const name = 'Product 1';
|
||||
addProduct(name, id);
|
||||
// upsertProductOrEventApi({ productName: name, productId: id }).then((data) => {
|
||||
// console.log('data: ', data);
|
||||
// });
|
||||
setSelectedProduct(id, name);
|
||||
}
|
||||
}, [products])
|
||||
const email = localStorage.getItem('email')
|
||||
const organization = (email!.split("@")[1]).split(".")[0];
|
||||
getAllProductsApi(organization).then((data) => {
|
||||
if (data.length === 0) {
|
||||
const id = THREE.MathUtils.generateUUID();
|
||||
const name = 'Product 1';
|
||||
addProduct(name, id);
|
||||
upsertProductOrEventApi({ productName: name, productId: id, organization: organization })
|
||||
setSelectedProduct(id, name);
|
||||
} else {
|
||||
setProducts(data);
|
||||
setSelectedProduct(data[0].productId, data[0].productName);
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
// const email = localStorage.getItem('email')
|
||||
// const organization = (email!.split("@")[1]).split(".")[0];
|
||||
// console.log(organization);
|
||||
// getAllProductsApi(organization).then((data) => {
|
||||
// console.log('data: ', data);
|
||||
// })
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
||||
@@ -19,11 +19,11 @@ function Simulation() {
|
||||
const { products } = useProductStore();
|
||||
|
||||
useEffect(() => {
|
||||
// console.log('events: ', events);
|
||||
console.log('events: ', events);
|
||||
}, [events])
|
||||
|
||||
useEffect(() => {
|
||||
// console.log('products: ', products);
|
||||
console.log('products: ', products);
|
||||
}, [products])
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,19 +1,85 @@
|
||||
import { useEffect } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
import { useSubModuleStore } from "../../../../store/useModuleStore";
|
||||
import { useSelectedAsset } from "../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../store/simulation/useProductStore";
|
||||
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
|
||||
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
|
||||
import { handleAddEventToProduct } from "../../events/points/functions/handleAddEventToProduct";
|
||||
|
||||
interface ConnectionLine {
|
||||
id: string;
|
||||
start: THREE.Vector3;
|
||||
end: THREE.Vector3;
|
||||
mid: THREE.Vector3;
|
||||
trigger: TriggerSchema;
|
||||
}
|
||||
|
||||
function TriggerConnector() {
|
||||
const { gl, raycaster, scene } = useThree();
|
||||
const { subModule } = useSubModuleStore();
|
||||
const { getPointByUuid, getIsEventInProduct } = useProductStore();
|
||||
const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, addEvent, getEventByModelUuid } = useProductStore();
|
||||
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
|
||||
useEffect(() => {
|
||||
const [firstSelectedPoint, setFirstSelectedPoint] = useState<{
|
||||
productId: string;
|
||||
modelUuid: string;
|
||||
pointUuid: string;
|
||||
actionUuid?: string;
|
||||
} | null>(null);
|
||||
|
||||
const [connections, setConnections] = useState<ConnectionLine[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const newConnections: ConnectionLine[] = [];
|
||||
|
||||
products.forEach(product => {
|
||||
product.eventDatas.forEach(event => {
|
||||
if ('points' in event) {
|
||||
event.points.forEach(point => {
|
||||
if ('action' in point && point.action?.triggers) {
|
||||
point.action.triggers.forEach(trigger => {
|
||||
if (trigger.triggeredAsset) {
|
||||
const targetPoint = getPointByUuid(
|
||||
product.productId,
|
||||
trigger.triggeredAsset.triggeredModel.modelUuid,
|
||||
trigger.triggeredAsset.triggeredPoint.pointUuid
|
||||
);
|
||||
|
||||
if (targetPoint) {
|
||||
const startPos = new THREE.Vector3(...point.position);
|
||||
const endPos = new THREE.Vector3(...targetPoint.position);
|
||||
const midPos = new THREE.Vector3()
|
||||
.addVectors(startPos, endPos)
|
||||
.multiplyScalar(0.5)
|
||||
.add(new THREE.Vector3(0, 2, 0));
|
||||
|
||||
newConnections.push({
|
||||
id: `${point.uuid}-${targetPoint.uuid}-${trigger.triggerUuid}`,
|
||||
start: startPos,
|
||||
end: endPos,
|
||||
mid: midPos,
|
||||
trigger
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
setConnections(newConnections);
|
||||
}, [products]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('connections: ', connections);
|
||||
}, connections)
|
||||
|
||||
useEffect(() => {
|
||||
const canvasElement = gl.domElement;
|
||||
|
||||
let drag = false;
|
||||
@@ -44,37 +110,114 @@ function TriggerConnector() {
|
||||
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;
|
||||
const intersects = raycaster.intersectObjects(scene.children, true);
|
||||
if (intersects.length === 0) return;
|
||||
|
||||
if (currentObject && currentObject.name === 'Event-Sphere') {
|
||||
const currentObject = intersects[0].object;
|
||||
if (!currentObject || currentObject.name !== 'Event-Sphere') return;
|
||||
|
||||
const isInProduct = getIsEventInProduct(
|
||||
selectedProduct.productId,
|
||||
currentObject.userData.modelUuid
|
||||
);
|
||||
const modelUuid = currentObject.userData.modelUuid;
|
||||
const pointUuid = currentObject.userData.pointUuid;
|
||||
|
||||
// You left Here
|
||||
if (selectedProduct && getIsEventInProduct(selectedProduct.productId, modelUuid)) {
|
||||
|
||||
if (isInProduct) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
modelUuid,
|
||||
pointUuid
|
||||
);
|
||||
|
||||
const event = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
currentObject.userData.modelUuid,
|
||||
currentObject.userData.pointUuid
|
||||
);
|
||||
console.log('event: ', event);
|
||||
} else {
|
||||
if (!point) return;
|
||||
|
||||
}
|
||||
let actionUuid: string | undefined;
|
||||
if ('action' in point && point.action) {
|
||||
actionUuid = point.action.actionUuid;
|
||||
} else if ('actions' in point && point.actions.length === 1) {
|
||||
actionUuid = point.actions[0].actionUuid;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!firstSelectedPoint) {
|
||||
setFirstSelectedPoint({
|
||||
productId: selectedProduct.productId,
|
||||
modelUuid,
|
||||
pointUuid,
|
||||
actionUuid
|
||||
});
|
||||
} else {
|
||||
const trigger: TriggerSchema = {
|
||||
triggerUuid: THREE.MathUtils.generateUUID(),
|
||||
triggerName: `Trigger ${firstSelectedPoint.pointUuid.slice(0, 4)} → ${pointUuid.slice(0, 4)}`,
|
||||
triggerType: "onComplete",
|
||||
delay: 0,
|
||||
triggeredAsset: {
|
||||
triggeredModel: {
|
||||
modelName: currentObject.parent?.parent?.name || 'Unknown',
|
||||
modelUuid: modelUuid
|
||||
},
|
||||
triggeredPoint: {
|
||||
pointName: currentObject.name,
|
||||
pointUuid: pointUuid
|
||||
},
|
||||
triggeredAction: actionUuid ? {
|
||||
actionName: getActionByUuid(selectedProduct.productId, actionUuid)?.actionName || 'Action',
|
||||
actionUuid: actionUuid
|
||||
} : null
|
||||
}
|
||||
};
|
||||
|
||||
if (firstSelectedPoint.actionUuid) {
|
||||
addTrigger(firstSelectedPoint.actionUuid, trigger);
|
||||
}
|
||||
setFirstSelectedPoint(null);
|
||||
}
|
||||
} else if (!getIsEventInProduct(selectedProduct.productId, modelUuid) && firstSelectedPoint) {
|
||||
handleAddEventToProduct({
|
||||
event: useEventsStore.getState().getEventByModelUuid(modelUuid),
|
||||
addEvent,
|
||||
selectedProduct,
|
||||
})
|
||||
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
modelUuid,
|
||||
pointUuid
|
||||
);
|
||||
|
||||
if (!point) return;
|
||||
|
||||
let actionUuid: string | undefined;
|
||||
if ('action' in point && point.action) {
|
||||
actionUuid = point.action.actionUuid;
|
||||
} else if ('actions' in point && point.actions.length === 1) {
|
||||
actionUuid = point.actions[0].actionUuid;
|
||||
}
|
||||
|
||||
const trigger: TriggerSchema = {
|
||||
triggerUuid: THREE.MathUtils.generateUUID(),
|
||||
triggerName: `Trigger ${firstSelectedPoint.pointUuid.slice(0, 4)} → ${pointUuid.slice(0, 4)}`,
|
||||
triggerType: "onComplete",
|
||||
delay: 0,
|
||||
triggeredAsset: {
|
||||
triggeredModel: {
|
||||
modelName: currentObject.parent?.parent?.name || 'Unknown',
|
||||
modelUuid: modelUuid
|
||||
},
|
||||
triggeredPoint: {
|
||||
pointName: currentObject.name,
|
||||
pointUuid: pointUuid
|
||||
},
|
||||
triggeredAction: actionUuid ? {
|
||||
actionName: getActionByUuid(selectedProduct.productId, actionUuid)?.actionName || 'Action',
|
||||
actionUuid: actionUuid
|
||||
} : null
|
||||
}
|
||||
};
|
||||
|
||||
if (firstSelectedPoint.actionUuid) {
|
||||
addTrigger(firstSelectedPoint.actionUuid, trigger);
|
||||
}
|
||||
setFirstSelectedPoint(null);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -92,12 +235,12 @@ function TriggerConnector() {
|
||||
canvasElement.removeEventListener('contextmenu', handleRightClick);
|
||||
};
|
||||
|
||||
}, [gl, subModule]);
|
||||
}, [gl, subModule, selectedProduct, firstSelectedPoint]);
|
||||
|
||||
return (
|
||||
<>
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default TriggerConnector
|
||||
export default TriggerConnector;
|
||||
Reference in New Issue
Block a user