v2-ui #71

Merged
Vishnu merged 21 commits from v2-ui into main 2025-04-30 12:57:05 +00:00
22 changed files with 1379 additions and 1209 deletions
Showing only changes of commit 882c81a385 - Show all commits

View File

@@ -1,6 +1,5 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { import {
useSelectedAsset,
useSelectedEventData, useSelectedEventData,
useSelectedEventSphere, useSelectedEventSphere,
useSelectedProduct, useSelectedProduct,
@@ -13,19 +12,17 @@ import MachineMechanics from "./mechanics/machineMechanics";
import StorageMechanics from "./mechanics/storageMechanics"; import StorageMechanics from "./mechanics/storageMechanics";
import { AddIcon } from "../../../../icons/ExportCommonIcons"; import { AddIcon } from "../../../../icons/ExportCommonIcons";
import { handleAddEventToProduct } from "../../../../../modules/simulation/events/points/functions/handleAddEventToProduct"; import { handleAddEventToProduct } from "../../../../../modules/simulation/events/points/functions/handleAddEventToProduct";
import { useEventsStore } from "../../../../../store/simulation/useEventsStore";
const EventProperties: React.FC = () => { const EventProperties: React.FC = () => {
const { selectedEventData } = useSelectedEventData(); const { selectedEventData } = useSelectedEventData();
const { getEventByModelUuid } = useProductStore(); const { getEventByModelUuid } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = useSelectedProduct();
const [currentEventData, setCurrentEventData] = useState<EventsSchema | null>( const [currentEventData, setCurrentEventData] = useState<EventsSchema | null>(null);
null
);
const [assetType, setAssetType] = useState<string | null>(null); const [assetType, setAssetType] = useState<string | null>(null);
const { products, addEvent } = useProductStore(); const { products, addEvent } = useProductStore();
const { selectedEventSphere } = useSelectedEventSphere(); const { selectedEventSphere } = useSelectedEventSphere();
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
useEffect(() => { useEffect(() => {
const event = getCurrentEventData(); const event = getCurrentEventData();
setCurrentEventData(event); setCurrentEventData(event);
@@ -96,17 +93,15 @@ const EventProperties: React.FC = () => {
{products.map((product) => ( {products.map((product) => (
<li key={product.productId}> <li key={product.productId}>
<button <button
onClick={() => onClick={() => {
if (selectedEventData) {
handleAddEventToProduct({ handleAddEventToProduct({
selectedAsset, event: useEventsStore.getState().getEventByModelUuid(selectedEventData?.data.modelUuid),
addEvent, addEvent,
selectedProduct: { selectedProduct,
productId: product.productId,
productName: product.productName,
},
clearSelectedAsset,
}) })
} }
}}
> >
<AddIcon /> <AddIcon />
{product.productName} {product.productName}
@@ -116,7 +111,8 @@ const EventProperties: React.FC = () => {
</ul> </ul>
</div> </div>
</div> </div>
)} )
}
{!selectedEventSphere && ( {!selectedEventSphere && (
<div className="no-event-selected"> <div className="no-event-selected">
<p> <p>
@@ -125,7 +121,7 @@ const EventProperties: React.FC = () => {
</p> </p>
</div> </div>
)} )}
</div> </div >
); );
}; };

View File

@@ -8,20 +8,13 @@ import SwapAction from "../actions/SwapAction";
import SpawnAction from "../actions/SpawnAction"; import SpawnAction from "../actions/SpawnAction";
import DefaultAction from "../actions/DefaultAction"; import DefaultAction from "../actions/DefaultAction";
import Trigger from "../trigger/Trigger"; import Trigger from "../trigger/Trigger";
import { import { useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore";
useSelectedEventData,
useSelectedProduct,
} from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import ActionsList from "../components/ActionsList"; import ActionsList from "../components/ActionsList";
function ConveyorMechanics() { function ConveyorMechanics() {
const [activeOption, setActiveOption] = useState< const [activeOption, setActiveOption] = useState<"default" | "spawn" | "swap" | "delay" | "despawn">("default");
"default" | "spawn" | "swap" | "delay" | "despawn" const [selectedPointData, setSelectedPointData] = useState<ConveyorPointSchema | undefined>();
>("default");
const [selectedPointData, setSelectedPointData] = useState<
ConveyorPointSchema | undefined
>();
const { selectedEventData } = useSelectedEventData(); const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, updateEvent, updateAction } = useProductStore(); const { getPointByUuid, updateEvent, updateAction } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = useSelectedProduct();
@@ -35,14 +28,7 @@ function ConveyorMechanics() {
) as ConveyorPointSchema | undefined; ) as ConveyorPointSchema | undefined;
if (point && "action" in point) { if (point && "action" in point) {
setSelectedPointData(point); setSelectedPointData(point);
setActiveOption( setActiveOption(point.action.actionType as | "default" | "spawn" | "swap" | "delay" | "despawn");
point.action.actionType as
| "default"
| "spawn"
| "swap"
| "delay"
| "despawn"
);
} }
} }
}, [selectedProduct, selectedEventData, getPointByUuid]); }, [selectedProduct, selectedEventData, getPointByUuid]);
@@ -56,12 +42,7 @@ function ConveyorMechanics() {
const handleActionTypeChange = (option: string) => { const handleActionTypeChange = (option: string) => {
if (!selectedEventData || !selectedPointData) return; if (!selectedEventData || !selectedPointData) return;
const validOption = option as const validOption = option as | "default" | "spawn" | "swap" | "delay" | "despawn";
| "default"
| "spawn"
| "swap"
| "delay"
| "despawn";
setActiveOption(validOption); setActiveOption(validOption);
updateAction(selectedPointData.action.actionUuid, { updateAction(selectedPointData.action.actionUuid, {
@@ -106,8 +87,7 @@ function ConveyorMechanics() {
}; };
// Get current values from store // Get current values from store
const currentSpeed = const currentSpeed = selectedEventData?.data.type === "transfer"
selectedEventData?.data.type === "transfer"
? selectedEventData.data.speed.toString() ? selectedEventData.data.speed.toString()
: "0.5"; : "0.5";
@@ -146,7 +126,7 @@ function ConveyorMechanics() {
defaultValue={"0.5"} defaultValue={"0.5"}
max={10} max={10}
activeOption="m/s" activeOption="m/s"
onClick={() => {}} onClick={() => { }}
onChange={handleSpeedChange} onChange={handleSpeedChange}
/> />
</div> </div>
@@ -167,11 +147,7 @@ function ConveyorMechanics() {
</div> </div>
<div className="selected-actions-list"> <div className="selected-actions-list">
<LabledDropdown <LabledDropdown
defaultOption={ defaultOption={selectedPointData ? selectedPointData.action.actionType : "default"}
selectedPointData
? selectedPointData.action.actionType
: "default"
}
options={availableActions.options} options={availableActions.options}
onSelect={handleActionTypeChange} onSelect={handleActionTypeChange}
/> />

View File

@@ -2,21 +2,14 @@ import { useEffect, useState } from "react";
import RenameInput from "../../../../../ui/inputs/RenameInput"; import RenameInput from "../../../../../ui/inputs/RenameInput";
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown"; import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import Trigger from "../trigger/Trigger"; import Trigger from "../trigger/Trigger";
import { import { useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore";
useSelectedEventData,
useSelectedProduct,
} from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import ProcessAction from "../actions/ProcessAction"; import ProcessAction from "../actions/ProcessAction";
import ActionsList from "../components/ActionsList"; import ActionsList from "../components/ActionsList";
function MachineMechanics() { function MachineMechanics() {
const [activeOption, setActiveOption] = useState<"default" | "process">( const [activeOption, setActiveOption] = useState<"default" | "process">("default");
"default" const [selectedPointData, setSelectedPointData] = useState<MachinePointSchema | undefined>();
);
const [selectedPointData, setSelectedPointData] = useState<
MachinePointSchema | undefined
>();
const { selectedEventData } = useSelectedEventData(); const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, updateAction } = useProductStore(); const { getPointByUuid, updateAction } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = useSelectedProduct();

View File

@@ -3,27 +3,18 @@ import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
import RenameInput from "../../../../../ui/inputs/RenameInput"; import RenameInput from "../../../../../ui/inputs/RenameInput";
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown"; import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import Trigger from "../trigger/Trigger"; import Trigger from "../trigger/Trigger";
import { import { useSelectedEventData, useSelectedProduct, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
useSelectedEventData,
useSelectedProduct,
useSelectedAction,
} from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import PickAndPlaceAction from "../actions/PickAndPlaceAction"; import PickAndPlaceAction from "../actions/PickAndPlaceAction";
import ActionsList from "../components/ActionsList"; import ActionsList from "../components/ActionsList";
function RoboticArmMechanics() { function RoboticArmMechanics() {
const [activeOption, setActiveOption] = useState<"default" | "pickAndPlace">( const [activeOption, setActiveOption] = useState<"default" | "pickAndPlace">("default");
"default" const [selectedPointData, setSelectedPointData] = useState<RoboticArmPointSchema | undefined>();
);
const [selectedPointData, setSelectedPointData] = useState<
RoboticArmPointSchema | undefined
>();
const { selectedEventData } = useSelectedEventData(); const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, updateEvent, updateAction } = useProductStore(); const { getPointByUuid, updateEvent, updateAction } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = useSelectedProduct();
const { selectedAction, setSelectedAction, clearSelectedAction } = const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
useSelectedAction();
useEffect(() => { useEffect(() => {
if (selectedEventData) { if (selectedEventData) {
@@ -34,9 +25,7 @@ function RoboticArmMechanics() {
) as RoboticArmPointSchema | undefined; ) as RoboticArmPointSchema | undefined;
if (point?.actions) { if (point?.actions) {
setSelectedPointData(point); setSelectedPointData(point);
setActiveOption( setActiveOption(point.actions[0].actionType as "default" | "pickAndPlace");
point.actions[0].actionType as "default" | "pickAndPlace"
);
if (point.actions.length > 0 && !selectedAction.actionId) { if (point.actions.length > 0 && !selectedAction.actionId) {
setSelectedAction( setSelectedAction(
point.actions[0].actionUuid, point.actions[0].actionUuid,
@@ -47,14 +36,7 @@ function RoboticArmMechanics() {
} else { } else {
clearSelectedAction(); clearSelectedAction();
} }
}, [ }, [clearSelectedAction, getPointByUuid, selectedAction.actionId, selectedEventData, selectedProduct, setSelectedAction,]);
clearSelectedAction,
getPointByUuid,
selectedAction.actionId,
selectedEventData,
selectedProduct,
setSelectedAction,
]);
const handleRenameAction = (newName: string) => { const handleRenameAction = (newName: string) => {
if (!selectedAction.actionId) return; if (!selectedAction.actionId) return;
@@ -62,9 +44,7 @@ function RoboticArmMechanics() {
if (selectedPointData) { if (selectedPointData) {
const updatedActions = selectedPointData.actions.map((action) => const updatedActions = selectedPointData.actions.map((action) =>
action.actionUuid === selectedAction.actionId action.actionUuid === selectedAction.actionId ? { ...action, actionName: newName } : action
? { ...action, actionName: newName }
: action
); );
setSelectedPointData({ setSelectedPointData({
...selectedPointData, ...selectedPointData,
@@ -87,10 +67,7 @@ function RoboticArmMechanics() {
updateAction(selectedAction.actionId, { updateAction(selectedAction.actionId, {
process: { process: {
startPoint: [x, y, z] as [number, number, number], startPoint: [x, y, z] as [number, number, number],
endPoint: endPoint: selectedPointData.actions.find((a) => a.actionUuid === selectedAction.actionId)?.process.endPoint || null,
selectedPointData.actions.find(
(a) => a.actionUuid === selectedAction.actionId
)?.process.endPoint || null,
}, },
}); });
}; };
@@ -101,10 +78,7 @@ function RoboticArmMechanics() {
updateAction(selectedAction.actionId, { updateAction(selectedAction.actionId, {
process: { process: {
startPoint: startPoint: selectedPointData.actions.find((a) => a.actionUuid === selectedAction.actionId)?.process.startPoint || null,
selectedPointData.actions.find(
(a) => a.actionUuid === selectedAction.actionId
)?.process.startPoint || null,
endPoint: [x, y, z] as [number, number, number], endPoint: [x, y, z] as [number, number, number],
}, },
}); });
@@ -115,14 +89,12 @@ function RoboticArmMechanics() {
options: ["pickAndPlace"], options: ["pickAndPlace"],
}; };
const currentSpeed = const currentSpeed = selectedEventData?.data.type === "roboticArm"
selectedEventData?.data.type === "roboticArm"
? selectedEventData.data.speed.toString() ? selectedEventData.data.speed.toString()
: "0.5"; : "0.5";
const currentAction = selectedPointData?.actions.find( const currentAction = selectedPointData?.actions.find((a) => a.actionUuid === selectedAction.actionId);
(a) => a.actionUuid === selectedAction.actionId
);
const currentPickPoint = currentAction?.process.startPoint const currentPickPoint = currentAction?.process.startPoint
? `${currentAction.process.startPoint[0]},${currentAction.process.startPoint[1]},${currentAction.process.startPoint[2]}` ? `${currentAction.process.startPoint[0]},${currentAction.process.startPoint[1]},${currentAction.process.startPoint[2]}`
: ""; : "";
@@ -145,7 +117,7 @@ function RoboticArmMechanics() {
defaultValue={"0.5"} defaultValue={"0.5"}
max={10} max={10}
activeOption="m/s" activeOption="m/s"
onClick={() => {}} onClick={() => { }}
onChange={handleSpeedChange} onChange={handleSpeedChange}
/> />
</div> </div>
@@ -170,7 +142,7 @@ function RoboticArmMechanics() {
<LabledDropdown <LabledDropdown
defaultOption={activeOption} defaultOption={activeOption}
options={availableActions.options} options={availableActions.options}
onSelect={() => {}} onSelect={() => { }}
disabled={true} disabled={true}
/> />
<PickAndPlaceAction <PickAndPlaceAction

View File

@@ -2,21 +2,14 @@ import { useEffect, useState } from "react";
import RenameInput from "../../../../../ui/inputs/RenameInput"; import RenameInput from "../../../../../ui/inputs/RenameInput";
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown"; import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import Trigger from "../trigger/Trigger"; import Trigger from "../trigger/Trigger";
import { import { useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore";
useSelectedEventData,
useSelectedProduct,
} from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import StorageAction from "../actions/StorageAction"; import StorageAction from "../actions/StorageAction";
import ActionsList from "../components/ActionsList"; import ActionsList from "../components/ActionsList";
function StorageMechanics() { function StorageMechanics() {
const [activeOption, setActiveOption] = useState< const [activeOption, setActiveOption] = useState<"default" | "store" | "spawn">("default");
"default" | "store" | "spawn" const [selectedPointData, setSelectedPointData] = useState<StoragePointSchema | undefined>();
>("default");
const [selectedPointData, setSelectedPointData] = useState<
StoragePointSchema | undefined
>();
const { selectedEventData } = useSelectedEventData(); const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, updateAction } = useProductStore(); const { getPointByUuid, updateAction } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = useSelectedProduct();

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useRef } from "react"; import React, { useRef } from "react";
import { import {
AddIcon, AddIcon,
ArrowIcon, ArrowIcon,
@@ -15,8 +15,9 @@ import { useProductStore } from "../../../../store/simulation/useProductStore";
import { generateUUID } from "three/src/math/MathUtils"; import { generateUUID } from "three/src/math/MathUtils";
import RenderOverlay from "../../../templates/Overlay"; import RenderOverlay from "../../../templates/Overlay";
import EditWidgetOption from "../../../ui/menu/EditWidgetOption"; import EditWidgetOption from "../../../ui/menu/EditWidgetOption";
import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi";
import { handleAddEventToProduct } from "../../../../modules/simulation/events/points/functions/handleAddEventToProduct"; import { handleAddEventToProduct } from "../../../../modules/simulation/events/points/functions/handleAddEventToProduct";
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
import { deleteEventDataApi } from "../../../../services/simulation/deleteEventDataApi";
interface Event { interface Event {
pathName: string; pathName: string;
@@ -36,15 +37,9 @@ const List: React.FC<ListProps> = ({ val }) => {
const Simulations: React.FC = () => { const Simulations: React.FC = () => {
const productsContainerRef = useRef<HTMLDivElement>(null); const productsContainerRef = useRef<HTMLDivElement>(null);
const { const { products, addProduct, removeProduct, renameProduct, addEvent, removeEvent, } = useProductStore();
products,
addProduct,
removeProduct,
renameProduct,
addEvent,
removeEvent,
} = useProductStore();
const { selectedProduct, setSelectedProduct } = useSelectedProduct(); const { selectedProduct, setSelectedProduct } = useSelectedProduct();
const { getEventByModelUuid } = useEventsStore();
const { selectedAsset, clearSelectedAsset } = useSelectedAsset(); const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
const handleAddProduct = () => { const handleAddProduct = () => {
@@ -84,6 +79,13 @@ const Simulations: React.FC = () => {
const handleRemoveEventFromProduct = () => { const handleRemoveEventFromProduct = () => {
if (selectedAsset) { if (selectedAsset) {
const email = localStorage.getItem('email')
const organization = (email!.split("@")[1]).split(".")[0];
deleteEventDataApi({
productId: selectedProduct.productId,
modelUuid: selectedAsset.modelUuid,
organization: organization
});
removeEvent(selectedProduct.productId, selectedAsset.modelUuid); removeEvent(selectedProduct.productId, selectedAsset.modelUuid);
clearSelectedAsset(); clearSelectedAsset();
} }
@@ -93,8 +95,7 @@ const Simulations: React.FC = () => {
(product) => product.productId === selectedProduct.productId (product) => product.productId === selectedProduct.productId
); );
const events: Event[] = const events: Event[] = selectedProductData?.eventDatas.map((event) => ({
selectedProductData?.eventDatas.map((event) => ({
pathName: event.modelName, pathName: event.modelName,
})) || []; })) || [];
@@ -118,8 +119,7 @@ const Simulations: React.FC = () => {
{products.map((product, index) => ( {products.map((product, index) => (
<div <div
key={product.productId} key={product.productId}
className={`list-item ${ className={`list-item ${selectedProduct.productId === product.productId
selectedProduct.productId === product.productId
? "active" ? "active"
: "" : ""
}`} }`}
@@ -197,10 +197,10 @@ const Simulations: React.FC = () => {
onClick={(option) => { onClick={(option) => {
if (option === "Add to Product") { if (option === "Add to Product") {
handleAddEventToProduct({ handleAddEventToProduct({
selectedAsset, event: getEventByModelUuid(selectedAsset.modelUuid),
addEvent, addEvent,
selectedProduct, selectedProduct,
clearSelectedAsset, clearSelectedAsset
}); });
} else { } else {
handleRemoveEventFromProduct(); handleRemoveEventFromProduct();

View File

@@ -156,7 +156,7 @@ function processLoadedModel(
const model = gltf.clone(); const model = gltf.clone();
model.uuid = item.modeluuid; model.uuid = item.modeluuid;
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap); model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
model.userData = { name: item.modelname, modelId: item.modelfileID, modeluuid: item.modeluuid }; model.userData = { name: item.modelname, modelId: item.modelfileID, modeluuid: item.modeluuid, eventData: item.eventData };
model.position.set(...item.position); model.position.set(...item.position);
model.rotation.set(item.rotation.x, item.rotation.y, item.rotation.z); model.rotation.set(item.rotation.x, item.rotation.y, item.rotation.z);
@@ -170,9 +170,9 @@ function processLoadedModel(
} }
}); });
itemsGroup?.current?.add(model); itemsGroup?.current?.add(model);
if (item.eventData) {
setFloorItems((prevItems) => [ setFloorItems((prevItems) => [
...(prevItems || []), ...(prevItems || []),
{ {
@@ -183,18 +183,11 @@ function processLoadedModel(
modelfileID: item.modelfileID, modelfileID: item.modelfileID,
isLocked: item.isLocked, isLocked: item.isLocked,
isVisible: item.isVisible, isVisible: item.isVisible,
eventData: item.eventData,
}, },
]); ]);
if (item.modelfileID === "a1ee92554935007b10b3eb05") { if (item.eventData.type === "vehicle") {
const data = PointsCalculator(
'Vehicle',
gltf.clone(),
new THREE.Vector3(...model.rotation)
);
if (!data || !data.points) return;
const vehicleEvent: VehicleEventSchema = { const vehicleEvent: VehicleEventSchema = {
modelUuid: item.modeluuid, modelUuid: item.modeluuid,
modelName: item.modelname, modelName: item.modelname,
@@ -204,9 +197,9 @@ function processLoadedModel(
type: "vehicle", type: "vehicle",
speed: 1, speed: 1,
point: { point: {
uuid: THREE.MathUtils.generateUUID(), uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
position: [data.points[0].x, data.points[0].y, data.points[0].z], position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
rotation: [0, 0, 0], rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
action: { action: {
actionUuid: THREE.MathUtils.generateUUID(), actionUuid: THREE.MathUtils.generateUUID(),
actionName: "Vehicle Action", actionName: "Vehicle Action",
@@ -220,15 +213,7 @@ function processLoadedModel(
} }
}; };
addEvent(vehicleEvent); addEvent(vehicleEvent);
} else if (item.modelfileID === "7dc04e36882e4debbc1a8e3d") { } else if (item.eventData.type === "Conveyor") {
const data = PointsCalculator(
'Conveyor',
gltf.clone(),
new THREE.Vector3(...model.rotation)
);
if (!data || !data.points) return;
const ConveyorEvent: ConveyorEventSchema = { const ConveyorEvent: ConveyorEventSchema = {
modelUuid: item.modeluuid, modelUuid: item.modeluuid,
modelName: item.modelname, modelName: item.modelname,
@@ -237,10 +222,10 @@ function processLoadedModel(
state: "idle", state: "idle",
type: "transfer", type: "transfer",
speed: 1, speed: 1,
points: data.points.map((point: THREE.Vector3, index: number) => ({ points: item.eventData.points?.map((point: any, index: number) => ({
uuid: THREE.MathUtils.generateUUID(), uuid: point.uuid || THREE.MathUtils.generateUUID(),
position: [point.x, point.y, point.z], position: [point.position[0], point.position[1], point.position[2]],
rotation: [0, 0, 0], rotation: [point.rotation[0], point.rotation[1], point.rotation[2]],
action: { action: {
actionUuid: THREE.MathUtils.generateUUID(), actionUuid: THREE.MathUtils.generateUUID(),
actionName: `Action ${index + 1}`, actionName: `Action ${index + 1}`,
@@ -251,117 +236,10 @@ function processLoadedModel(
spawnCount: 1, spawnCount: 1,
triggers: [] triggers: []
} }
})) })) || [],
}; };
addEvent(ConveyorEvent); addEvent(ConveyorEvent);
} else if (item.modelfileID === "7dc04e36882e4debbc1a8e3d") { } else if (item.eventData.type === "StaticMachine") {
// 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 = { const machineEvent: MachineEventSchema = {
modelUuid: item.modeluuid, modelUuid: item.modeluuid,
modelName: item.modelname, modelName: item.modelname,
@@ -370,9 +248,9 @@ function processLoadedModel(
state: "idle", state: "idle",
type: "machine", type: "machine",
point: { point: {
uuid: THREE.MathUtils.generateUUID(), uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
position: [data.points[0].x, data.points[0].y, data.points[0].z], position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
rotation: [0, 0, 0], rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
action: { action: {
actionUuid: THREE.MathUtils.generateUUID(), actionUuid: THREE.MathUtils.generateUUID(),
actionName: "Process Action", actionName: "Process Action",
@@ -384,15 +262,7 @@ function processLoadedModel(
} }
}; };
addEvent(machineEvent); addEvent(machineEvent);
} else if (item.modelfileID === "52e6681fbb743a890d96c914") { } else if (item.eventData.type === "ArmBot") {
const data = PointsCalculator(
'ArmBot',
gltf.clone(),
new THREE.Vector3(...model.rotation)
);
if (!data || !data.points) return;
const roboticArmEvent: RoboticArmEventSchema = { const roboticArmEvent: RoboticArmEventSchema = {
modelUuid: item.modeluuid, modelUuid: item.modeluuid,
modelName: item.modelname, modelName: item.modelname,
@@ -402,9 +272,9 @@ function processLoadedModel(
type: "roboticArm", type: "roboticArm",
speed: 1, speed: 1,
point: { point: {
uuid: THREE.MathUtils.generateUUID(), uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
position: [data.points[0].x, data.points[0].y, data.points[0].z], position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
rotation: [0, 0, 0], rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
actions: [ actions: [
{ {
actionUuid: THREE.MathUtils.generateUUID(), actionUuid: THREE.MathUtils.generateUUID(),
@@ -420,6 +290,21 @@ function processLoadedModel(
} }
}; };
addEvent(roboticArmEvent); addEvent(roboticArmEvent);
}
} else {
setFloorItems((prevItems) => [
...(prevItems || []),
{
modeluuid: item.modeluuid,
modelname: item.modelname,
position: item.position,
rotation: item.rotation,
modelfileID: item.modelfileID,
isLocked: item.isLocked,
isVisible: item.isVisible,
},
]);
} }
gsap.to(model.position, { y: item.position[1], duration: 1.5, ease: 'power2.out' }); gsap.to(model.position, { y: item.position[1], duration: 1.5, ease: 'power2.out' });

View File

@@ -164,18 +164,6 @@ async function handleModelLoad(
// SOCKET // SOCKET
const data = {
organization,
modeluuid: newFloorItem.modeluuid,
modelname: newFloorItem.modelname,
modelfileID: newFloorItem.modelfileID,
position: newFloorItem.position,
rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
isLocked: false,
isVisible: true,
socketId: socket.id
};
if (selectedItem.type) { if (selectedItem.type) {
const data = PointsCalculator( const data = PointsCalculator(
selectedItem.type, selectedItem.type,
@@ -185,6 +173,10 @@ async function handleModelLoad(
if (!data || !data.points) return; if (!data || !data.points) return;
const eventData: any = {
type: selectedItem.type,
};
if (selectedItem.type === "Conveyor") { if (selectedItem.type === "Conveyor") {
const ConveyorEvent: ConveyorEventSchema = { const ConveyorEvent: ConveyorEventSchema = {
modelUuid: newFloorItem.modeluuid, modelUuid: newFloorItem.modeluuid,
@@ -209,8 +201,14 @@ async function handleModelLoad(
triggers: [] triggers: []
} }
})) }))
} };
addEvent(ConveyorEvent); addEvent(ConveyorEvent);
eventData.points = ConveyorEvent.points.map(point => ({
uuid: point.uuid,
position: point.position,
rotation: point.rotation
}));
} else if (selectedItem.type === "Vehicle") { } else if (selectedItem.type === "Vehicle") {
const vehicleEvent: VehicleEventSchema = { const vehicleEvent: VehicleEventSchema = {
modelUuid: newFloorItem.modeluuid, modelUuid: newFloorItem.modeluuid,
@@ -237,6 +235,12 @@ async function handleModelLoad(
} }
}; };
addEvent(vehicleEvent); addEvent(vehicleEvent);
eventData.point = {
uuid: vehicleEvent.point.uuid,
position: vehicleEvent.point.position,
rotation: vehicleEvent.point.rotation
};
} else if (selectedItem.type === "ArmBot") { } else if (selectedItem.type === "ArmBot") {
const roboticArmEvent: RoboticArmEventSchema = { const roboticArmEvent: RoboticArmEventSchema = {
modelUuid: newFloorItem.modeluuid, modelUuid: newFloorItem.modeluuid,
@@ -265,6 +269,13 @@ async function handleModelLoad(
} }
}; };
addEvent(roboticArmEvent); addEvent(roboticArmEvent);
console.log('roboticArmEvent: ', roboticArmEvent);
eventData.point = {
uuid: roboticArmEvent.point.uuid,
position: roboticArmEvent.point.position,
rotation: roboticArmEvent.point.rotation
};
} else if (selectedItem.type === "StaticMachine") { } else if (selectedItem.type === "StaticMachine") {
const machineEvent: MachineEventSchema = { const machineEvent: MachineEventSchema = {
modelUuid: newFloorItem.modeluuid, modelUuid: newFloorItem.modeluuid,
@@ -288,8 +299,53 @@ async function handleModelLoad(
} }
}; };
addEvent(machineEvent); addEvent(machineEvent);
eventData.point = {
uuid: machineEvent.point.uuid,
position: machineEvent.point.position,
rotation: machineEvent.point.rotation
};
} }
}
const completeData = {
organization,
modeluuid: newFloorItem.modeluuid,
modelname: newFloorItem.modelname,
modelfileID: newFloorItem.modelfileID,
position: newFloorItem.position,
rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
isLocked: false,
isVisible: true,
socketId: socket.id,
eventData: eventData
};
model.userData.eventData = eventData;
newFloorItem.eventData = eventData;
setFloorItems((prevItems) => {
const updatedItems = [...(prevItems || []), newFloorItem];
localStorage.setItem("FloorItems", JSON.stringify(updatedItems));
return updatedItems;
});
socket.emit("v2:model-asset:add", completeData);
gsap.to(model.position, { y: newFloorItem.position[1], duration: 1.5, ease: "power2.out" });
gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: "power2.out", onComplete: () => { toast.success("Model Added!"); } });
} else {
const data = {
organization,
modeluuid: newFloorItem.modeluuid,
modelname: newFloorItem.modelname,
modelfileID: newFloorItem.modelfileID,
position: newFloorItem.position,
rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
isLocked: false,
isVisible: true,
socketId: socket.id
};
setFloorItems((prevItems) => { setFloorItems((prevItems) => {
const updatedItems = [...(prevItems || []), newFloorItem]; const updatedItems = [...(prevItems || []), newFloorItem];
@@ -301,6 +357,7 @@ async function handleModelLoad(
gsap.to(model.position, { y: newFloorItem.position[1], duration: 1.5, ease: "power2.out" }); gsap.to(model.position, { y: newFloorItem.position[1], duration: 1.5, ease: "power2.out" });
gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: "power2.out", onComplete: () => { toast.success("Model Added!"); } }); gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: "power2.out", onComplete: () => { toast.success("Model Added!"); } });
}
} }
export default addAssetModel; export default addAssetModel;

View File

@@ -65,6 +65,7 @@ const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject
}; };
getFloorAssets(organization).then((data) => { getFloorAssets(organization).then((data) => {
console.log('data: ', data);
if (data.length > 0) { if (data.length > 0) {
const uniqueItems = (data as Types.FloorItems).filter((item, index, self) => index === self.findIndex((t) => t.modelfileID === item.modelfileID)); const uniqueItems = (data as Types.FloorItems).filter((item, index, self) => index === self.findIndex((t) => t.modelfileID === item.modelfileID));
totalAssets = uniqueItems.length; totalAssets = uniqueItems.length;

View File

@@ -137,6 +137,38 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
if (itemsGroupRef.current) { if (itemsGroupRef.current) {
let updatedEventData = null;
if (obj.userData.eventData) {
updatedEventData = JSON.parse(JSON.stringify(obj.userData.eventData));
updatedEventData.modelUuid = THREE.MathUtils.generateUUID();
if (updatedEventData.type === "Conveyor" && updatedEventData.points) {
updatedEventData.points = updatedEventData.points.map((point: any) => ({
...point,
uuid: THREE.MathUtils.generateUUID()
}));
}
else if (updatedEventData.type === "Vehicle" && updatedEventData.point) {
updatedEventData.point = {
...updatedEventData.point,
uuid: THREE.MathUtils.generateUUID()
};
}
else if (updatedEventData.type === "ArmBot" && updatedEventData.point) {
updatedEventData.point = {
...updatedEventData.point,
uuid: THREE.MathUtils.generateUUID()
};
}
else if (updatedEventData.type === "StaticMachine" && updatedEventData.point) {
updatedEventData.point = {
...updatedEventData.point,
uuid: THREE.MathUtils.generateUUID()
};
}
}
const newFloorItem: Types.FloorItemType = { const newFloorItem: Types.FloorItemType = {
modeluuid: obj.uuid, modeluuid: obj.uuid,
modelname: obj.userData.name, modelname: obj.userData.name,
@@ -144,7 +176,8 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
position: [worldPosition.x, worldPosition.y, worldPosition.z], position: [worldPosition.x, worldPosition.y, worldPosition.z],
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z, }, rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z, },
isLocked: false, isLocked: false,
isVisible: true isVisible: true,
eventData: updatedEventData
}; };
setFloorItems((prevItems: Types.FloorItems) => { setFloorItems((prevItems: Types.FloorItems) => {
@@ -181,11 +214,18 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
isLocked: false, isLocked: false,
isVisible: true, isVisible: true,
socketId: socket.id, socketId: socket.id,
eventData: updatedEventData
}; };
socket.emit("v2:model-asset:add", data); socket.emit("v2:model-asset:add", data);
obj.userData.modeluuid = newFloorItem.modeluuid; obj.userData = {
name: newFloorItem.modelname,
modelId: newFloorItem.modelfileID,
modeluuid: newFloorItem.modeluuid,
eventData: updatedEventData
};
itemsGroupRef.current.add(obj); itemsGroupRef.current.add(obj);
} }
}); });
@@ -205,7 +245,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
setSelectedAssets([]); setSelectedAssets([]);
} }
return null; // No visible output, but the component handles copy-paste functionality return null;
}; };
export default CopyPasteControls; export default CopyPasteControls;

View File

@@ -115,6 +115,38 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
if (itemsGroupRef.current) { if (itemsGroupRef.current) {
let updatedEventData = null;
if (obj.userData.eventData) {
updatedEventData = JSON.parse(JSON.stringify(obj.userData.eventData));
updatedEventData.modelUuid = THREE.MathUtils.generateUUID();
if (updatedEventData.type === "Conveyor" && updatedEventData.points) {
updatedEventData.points = updatedEventData.points.map((point: any) => ({
...point,
uuid: THREE.MathUtils.generateUUID()
}));
}
else if (updatedEventData.type === "Vehicle" && updatedEventData.point) {
updatedEventData.point = {
...updatedEventData.point,
uuid: THREE.MathUtils.generateUUID()
};
}
else if (updatedEventData.type === "ArmBot" && updatedEventData.point) {
updatedEventData.point = {
...updatedEventData.point,
uuid: THREE.MathUtils.generateUUID()
};
}
else if (updatedEventData.type === "StaticMachine" && updatedEventData.point) {
updatedEventData.point = {
...updatedEventData.point,
uuid: THREE.MathUtils.generateUUID()
};
}
}
const newFloorItem: Types.FloorItemType = { const newFloorItem: Types.FloorItemType = {
modeluuid: obj.uuid, modeluuid: obj.uuid,
modelname: obj.userData.name, modelname: obj.userData.name,
@@ -122,7 +154,8 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
position: [worldPosition.x, worldPosition.y, worldPosition.z], position: [worldPosition.x, worldPosition.y, worldPosition.z],
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z, }, rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z, },
isLocked: false, isLocked: false,
isVisible: true isVisible: true,
eventData: updatedEventData
}; };
setFloorItems((prevItems: Types.FloorItems) => { setFloorItems((prevItems: Types.FloorItems) => {
@@ -159,11 +192,18 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
isLocked: false, isLocked: false,
isVisible: true, isVisible: true,
socketId: socket.id, socketId: socket.id,
eventData: updatedEventData
}; };
socket.emit("v2:model-asset:add", data); socket.emit("v2:model-asset:add", data);
obj.userData.modeluuid = newFloorItem.modeluuid; obj.userData = {
name: newFloorItem.modelname,
modelId: newFloorItem.modelfileID,
modeluuid: newFloorItem.modeluuid,
eventData: updatedEventData
};
itemsGroupRef.current.add(obj); itemsGroupRef.current.add(obj);
} }
}); });
@@ -183,7 +223,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
setSelectedAssets([]); setSelectedAssets([]);
} }
return null; // This component does not render any UI return null;
}; };
export default DuplicationControls; export default DuplicationControls;

View File

@@ -1,11 +1,14 @@
import * as THREE from "three"; import * as THREE from "three";
import { useEffect, useMemo, useRef, useState } from "react"; import { useEffect, useMemo, useRef } from "react";
import { useFrame, useThree } from "@react-three/fiber"; import { useFrame, useThree } from "@react-three/fiber";
import { useFloorItems, useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/store"; import { useFloorItems, useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/store";
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; // import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import * as Types from "../../../../types/world/worldTypes"; import * as Types from "../../../../types/world/worldTypes";
import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys"; import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys";
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
import { useProductStore } from "../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, rotatedObjects, setRotatedObjects, boundingBoxRef }: any) { function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, rotatedObjects, setRotatedObjects, boundingBoxRef }: any) {
const { camera, controls, gl, scene, pointer, raycaster } = useThree(); const { camera, controls, gl, scene, pointer, raycaster } = useThree();
@@ -176,6 +179,24 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
isVisible: true isVisible: true
}; };
if (obj.userData.eventData) {
const eventData = useEventsStore.getState().getEventByModelUuid(obj.userData.modeluuid);
const productData = useProductStore.getState().getEventByModelUuid(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modeluuid);
if (eventData) {
useEventsStore.getState().updateEvent(obj.userData.modeluuid, {
position: [worldPosition.x, worldPosition.y, worldPosition.z],
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
})
}
if (productData) {
useProductStore.getState().updateEvent(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modeluuid, {
position: [worldPosition.x, worldPosition.y, worldPosition.z],
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
})
}
}
setFloorItems((prevItems: Types.FloorItems) => { setFloorItems((prevItems: Types.FloorItems) => {
const updatedItems = [...(prevItems || []), newFloorItem]; const updatedItems = [...(prevItems || []), newFloorItem];
localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); localStorage.setItem("FloorItems", JSON.stringify(updatedItems));
@@ -234,7 +255,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
setSelectedAssets([]); setSelectedAssets([]);
} }
return null; // No need to return anything, as this component is used for its side effects return null;
} }
export default MoveControls export default MoveControls

View File

@@ -1,11 +1,13 @@
import * as THREE from "three"; import * as THREE from "three";
import { useEffect, useMemo, useRef, useState } from "react"; import { useEffect, useMemo, useRef } from "react";
import { useFrame, useThree } from "@react-three/fiber"; import { useFrame, useThree } from "@react-three/fiber";
import { useFloorItems, useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/store"; import { useFloorItems, useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/store";
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; // import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import * as Types from "../../../../types/world/worldTypes"; import * as Types from "../../../../types/world/worldTypes";
import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; import { useEventsStore } from "../../../../store/simulation/useEventsStore";
import { useProductStore } from "../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, boundingBoxRef }: any) { function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, boundingBoxRef }: any) {
const { camera, controls, gl, scene, pointer, raycaster } = useThree(); const { camera, controls, gl, scene, pointer, raycaster } = useThree();
@@ -177,6 +179,24 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
isVisible: true isVisible: true
}; };
if (obj.userData.eventData) {
const eventData = useEventsStore.getState().getEventByModelUuid(obj.userData.modeluuid);
const productData = useProductStore.getState().getEventByModelUuid(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modeluuid);
if (eventData) {
useEventsStore.getState().updateEvent(obj.userData.modeluuid, {
position: [worldPosition.x, worldPosition.y, worldPosition.z],
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
})
}
if (productData) {
useProductStore.getState().updateEvent(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modeluuid, {
position: [worldPosition.x, worldPosition.y, worldPosition.z],
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
})
}
}
setFloorItems((prevItems: Types.FloorItems) => { setFloorItems((prevItems: Types.FloorItems) => {
const updatedItems = [...(prevItems || []), newFloorItem]; const updatedItems = [...(prevItems || []), newFloorItem];
localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); localStorage.setItem("FloorItems", JSON.stringify(updatedItems));
@@ -235,7 +255,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
setSelectedAssets([]); setSelectedAssets([]);
} }
return null; // No need to return anything, as this component is used for its side effects return null;
} }
export default RotateControls export default RotateControls

View File

@@ -62,7 +62,7 @@ function PointsCreator() {
{events.map((event, i) => { {events.map((event, i) => {
if (event.type === 'transfer') { if (event.type === 'transfer') {
return ( return (
<group key={i} position={new THREE.Vector3(...event.position)}> <group key={i} position={[...event.position]} rotation={[...event.rotation]} >
{event.points.map((point, j) => ( {event.points.map((point, j) => (
<mesh <mesh
name='Event-Sphere' name='Event-Sphere'
@@ -78,6 +78,7 @@ function PointsCreator() {
}} }}
key={`${i}-${j}`} key={`${i}-${j}`}
position={new THREE.Vector3(...point.position)} position={new THREE.Vector3(...point.position)}
// rotation={new THREE.Euler(...point.rotation)}
userData={{ modelUuid: event.modelUuid, pointUuid: point.uuid }} userData={{ modelUuid: event.modelUuid, pointUuid: point.uuid }}
> >
<sphereGeometry args={[0.1, 16, 16]} /> <sphereGeometry args={[0.1, 16, 16]} />
@@ -88,7 +89,7 @@ function PointsCreator() {
); );
} else if (event.type === 'vehicle') { } else if (event.type === 'vehicle') {
return ( return (
<group key={i} position={new THREE.Vector3(...event.position)}> <group key={i} position={[...event.position]} rotation={[...event.rotation]} >
<mesh <mesh
name='Event-Sphere' name='Event-Sphere'
uuid={event.point.uuid} uuid={event.point.uuid}
@@ -102,6 +103,7 @@ function PointsCreator() {
setTransformMode(null); setTransformMode(null);
}} }}
position={new THREE.Vector3(...event.point.position)} position={new THREE.Vector3(...event.point.position)}
// rotation={new THREE.Euler(...event.point.rotation)}
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }} userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
> >
<sphereGeometry args={[0.1, 16, 16]} /> <sphereGeometry args={[0.1, 16, 16]} />
@@ -111,7 +113,7 @@ function PointsCreator() {
); );
} else if (event.type === 'roboticArm') { } else if (event.type === 'roboticArm') {
return ( return (
<group key={i} position={new THREE.Vector3(...event.position)}> <group key={i} position={[...event.position]} rotation={[...event.rotation]} >
<mesh <mesh
name='Event-Sphere' name='Event-Sphere'
uuid={event.point.uuid} uuid={event.point.uuid}
@@ -125,6 +127,7 @@ function PointsCreator() {
setTransformMode(null); setTransformMode(null);
}} }}
position={new THREE.Vector3(...event.point.position)} position={new THREE.Vector3(...event.point.position)}
// rotation={new THREE.Euler(...event.point.rotation)}
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }} userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
> >
<sphereGeometry args={[0.1, 16, 16]} /> <sphereGeometry args={[0.1, 16, 16]} />
@@ -134,7 +137,7 @@ function PointsCreator() {
); );
} else if (event.type === 'machine') { } else if (event.type === 'machine') {
return ( return (
<group key={i} position={new THREE.Vector3(...event.position)}> <group key={i} position={[...event.position]} rotation={[...event.rotation]} >
<mesh <mesh
name='Event-Sphere' name='Event-Sphere'
uuid={event.point.uuid} uuid={event.point.uuid}
@@ -148,6 +151,7 @@ function PointsCreator() {
setTransformMode(null); setTransformMode(null);
}} }}
position={new THREE.Vector3(...event.point.position)} position={new THREE.Vector3(...event.point.position)}
// rotation={new THREE.Euler(...event.point.rotation)}
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }} userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
> >
<sphereGeometry args={[0.1, 16, 16]} /> <sphereGeometry args={[0.1, 16, 16]} />

View File

@@ -1,28 +1,38 @@
import { upsertProductOrEventApi } from "../../../../../services/simulation/UpsertProductOrEventApi";
interface HandleAddEventToProductParams { interface HandleAddEventToProductParams {
selectedAsset: any; // Replace `any` with specific type if you have it event: EventsSchema | undefined;
addEvent: (productId: string, asset: any) => void; addEvent: (productId: string, event: EventsSchema) => void;
selectedProduct: { selectedProduct: {
productId: string; productId: string;
productName: string; productName: string;
// Add other fields if needed }
}; clearSelectedAsset?: () => void;
clearSelectedAsset: () => void;
} }
export const handleAddEventToProduct = ({ export const handleAddEventToProduct = ({
selectedAsset, event,
addEvent, addEvent,
selectedProduct, selectedProduct,
clearSelectedAsset, clearSelectedAsset
}: HandleAddEventToProductParams) => { }: HandleAddEventToProductParams) => {
console.log('selectedProduct: ', selectedProduct); if (event && selectedProduct.productId) {
if (selectedAsset) { addEvent(selectedProduct.productId, event);
addEvent(selectedProduct.productId, selectedAsset);
// upsertProductOrEventApi({ const email = localStorage.getItem('email')
// productName: selectedProduct.productName, const organization = (email!.split("@")[1]).split(".")[0];
// productId: selectedProduct.productId,
// eventDatas: selectedAsset upsertProductOrEventApi({
// }); productName: selectedProduct.productName,
productId: selectedProduct.productId,
organization: organization,
eventDatas: event
}).then((data) => {
// console.log(data);
})
if (clearSelectedAsset) {
clearSelectedAsset(); clearSelectedAsset();
} }
}
}; };

View File

@@ -7,28 +7,27 @@ import { upsertProductOrEventApi } from '../../../services/simulation/UpsertProd
import { getAllProductsApi } from '../../../services/simulation/getallProductsApi'; import { getAllProductsApi } from '../../../services/simulation/getallProductsApi';
function Products() { function Products() {
const { products, addProduct } = useProductStore(); const { products, addProduct, setProducts } = useProductStore();
const { setSelectedProduct } = useSelectedProduct(); const { setSelectedProduct } = useSelectedProduct();
useEffect(() => { useEffect(() => {
if (products.length === 0) { 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 id = THREE.MathUtils.generateUUID();
const name = 'Product 1'; const name = 'Product 1';
addProduct(name, id); addProduct(name, id);
// upsertProductOrEventApi({ productName: name, productId: id }).then((data) => { upsertProductOrEventApi({ productName: name, productId: id, organization: organization })
// console.log('data: ', data);
// });
setSelectedProduct(id, name); setSelectedProduct(id, name);
} else {
setProducts(data);
setSelectedProduct(data[0].productId, data[0].productName);
} }
}, [products]) })
}, [])
useEffect(() => { 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 ( return (

View File

@@ -19,11 +19,11 @@ function Simulation() {
const { products } = useProductStore(); const { products } = useProductStore();
useEffect(() => { useEffect(() => {
// console.log('events: ', events); console.log('events: ', events);
}, [events]) }, [events])
useEffect(() => { useEffect(() => {
// console.log('products: ', products); console.log('products: ', products);
}, [products]) }, [products])
return ( return (

View File

@@ -1,19 +1,85 @@
import { useEffect } from "react"; import { useEffect, useRef, useState } from "react";
import { useThree } from "@react-three/fiber"; import { useThree } from "@react-three/fiber";
import * as THREE from "three";
import { useSubModuleStore } from "../../../../store/useModuleStore"; import { useSubModuleStore } from "../../../../store/useModuleStore";
import { useSelectedAsset } from "../../../../store/simulation/useSimulationStore"; import { useSelectedAsset } from "../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../store/simulation/useProductStore";
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore"; 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() { function TriggerConnector() {
const { gl, raycaster, scene } = useThree(); const { gl, raycaster, scene } = useThree();
const { subModule } = useSubModuleStore(); const { subModule } = useSubModuleStore();
const { getPointByUuid, getIsEventInProduct } = useProductStore(); const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, addEvent, getEventByModelUuid } = useProductStore();
const { selectedAsset, clearSelectedAsset } = useSelectedAsset(); const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
const { selectedProduct } = useSelectedProduct(); 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; const canvasElement = gl.domElement;
let drag = false; let drag = false;
@@ -44,37 +110,114 @@ function TriggerConnector() {
const handleRightClick = (evt: MouseEvent) => { const handleRightClick = (evt: MouseEvent) => {
if (drag) return; if (drag) return;
evt.preventDefault(); evt.preventDefault();
const canvasElement = gl.domElement;
if (!canvasElement) return;
let intersects = raycaster.intersectObjects(scene.children, true); const 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) { if (intersects.length === 0) return;
let currentObject = intersects[0].object;
if (currentObject && currentObject.name === 'Event-Sphere') { const currentObject = intersects[0].object;
if (!currentObject || currentObject.name !== 'Event-Sphere') return;
const isInProduct = getIsEventInProduct( const modelUuid = currentObject.userData.modelUuid;
const pointUuid = currentObject.userData.pointUuid;
if (selectedProduct && getIsEventInProduct(selectedProduct.productId, modelUuid)) {
const point = getPointByUuid(
selectedProduct.productId, selectedProduct.productId,
currentObject.userData.modelUuid modelUuid,
pointUuid
); );
// You left Here if (!point) return;
if (isInProduct) { 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 event = getPointByUuid( 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, selectedProduct.productId,
currentObject.userData.modelUuid, modelUuid,
currentObject.userData.pointUuid 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 { 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); canvasElement.removeEventListener('contextmenu', handleRightClick);
}; };
}, [gl, subModule]); }, [gl, subModule, selectedProduct, firstSelectedPoint]);
return ( return (
<> <>
</> </>
) );
} }
export default TriggerConnector export default TriggerConnector;

View File

@@ -6,6 +6,7 @@ type ProductsStore = {
// Product-level actions // Product-level actions
addProduct: (productName: string, productId: string) => void; addProduct: (productName: string, productId: string) => void;
setProducts: (products: productsSchema) => void;
removeProduct: (productId: string) => void; removeProduct: (productId: string) => void;
updateProduct: (productId: string, updates: Partial<{ productName: string; eventDatas: EventsSchema[] }>) => void; updateProduct: (productId: string, updates: Partial<{ productName: string; eventDatas: EventsSchema[] }>) => void;
@@ -78,6 +79,12 @@ export const useProductStore = create<ProductsStore>()(
}); });
}, },
setProducts: (products) => {
set((state) => {
state.products = products;
});
},
removeProduct: (productId) => { removeProduct: (productId) => {
set((state) => { set((state) => {
state.products = state.products.filter(p => p.productId !== productId); state.products = state.products.filter(p => p.productId !== productId);

View File

@@ -14,7 +14,7 @@ interface TriggerSchema {
triggeredAsset: { triggeredAsset: {
triggeredModel: { modelName: string, modelUuid: string }; triggeredModel: { modelName: string, modelUuid: string };
triggeredPoint: { pointName: string, pointUuid: string }; triggeredPoint: { pointName: string, pointUuid: string };
triggeredAction: { actionName: string, actionUuid: string }; triggeredAction: { actionName: string, actionUuid: string } | null;
} | null; } | null;
} }

View File

@@ -196,6 +196,19 @@ export type FloorItemType = {
modelfileID: string; modelfileID: string;
isLocked: boolean; isLocked: boolean;
isVisible: boolean; isVisible: boolean;
eventData?: {
type: string;
point?: {
uuid: string;
position: [number, number, number];
rotation: [number, number, number];
}
points?: {
uuid: string;
position: [number, number, number];
rotation: [number, number, number];
}[];
}
}; };
// Array of floor items for managing multiple objects on the floor // Array of floor items for managing multiple objects on the floor