refactor: remove console logs and enhance model userData structure
This commit is contained in:
parent
7b9695f006
commit
d29ee03c44
|
@ -101,7 +101,6 @@ const ProgressBarWidget = ({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
console.log(chartTypes, "chartTypes");
|
|
||||||
|
|
||||||
const Widgets2D = () => {
|
const Widgets2D = () => {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -10,6 +10,7 @@ import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||||
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
|
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
|
||||||
import { handleResize } from "../../../../functions/handleResizePannel";
|
import { handleResize } from "../../../../functions/handleResizePannel";
|
||||||
import {
|
import {
|
||||||
|
useFloorItems,
|
||||||
useSelectedActionSphere,
|
useSelectedActionSphere,
|
||||||
useSelectedPath,
|
useSelectedPath,
|
||||||
useSimulationPaths,
|
useSimulationPaths,
|
||||||
|
@ -17,11 +18,14 @@ import {
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import * as Types from "../../../../types/world/worldTypes";
|
import * as Types from "../../../../types/world/worldTypes";
|
||||||
import InputToggle from "../../../ui/inputs/InputToggle";
|
import InputToggle from "../../../ui/inputs/InputToggle";
|
||||||
|
import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
|
||||||
|
import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
|
||||||
|
|
||||||
const ConveyorMechanics: React.FC = () => {
|
const ConveyorMechanics: React.FC = () => {
|
||||||
const { selectedActionSphere } = useSelectedActionSphere();
|
const { selectedActionSphere } = useSelectedActionSphere();
|
||||||
const { selectedPath, setSelectedPath } = useSelectedPath();
|
const { selectedPath, setSelectedPath } = useSelectedPath();
|
||||||
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
|
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
|
||||||
|
const { floorItems, setFloorItems } = useFloorItems();
|
||||||
|
|
||||||
const actionsContainerRef = useRef<HTMLDivElement>(null);
|
const actionsContainerRef = useRef<HTMLDivElement>(null);
|
||||||
const triggersContainerRef = useRef<HTMLDivElement>(null);
|
const triggersContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
@ -36,6 +40,19 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
.find((point) => point.uuid === selectedActionSphere.point.uuid);
|
.find((point) => point.uuid === selectedActionSphere.point.uuid);
|
||||||
}, [selectedActionSphere, simulationPaths]);
|
}, [selectedActionSphere, simulationPaths]);
|
||||||
|
|
||||||
|
const updateBackend = async (updatedPath: Types.ConveyorEventsSchema | undefined) => {
|
||||||
|
if (!updatedPath) return;
|
||||||
|
// const email = localStorage.getItem("email");
|
||||||
|
// const organization = email ? email.split("@")[1].split(".")[0] : "";
|
||||||
|
// console.log('updatedPath: ', updatedPath);
|
||||||
|
// const a = await setEventApi(
|
||||||
|
// organization,
|
||||||
|
// updatedPath.modeluuid,
|
||||||
|
// updatedPath.points
|
||||||
|
// );
|
||||||
|
// console.log('a: ', a);
|
||||||
|
}
|
||||||
|
|
||||||
const handleAddAction = () => {
|
const handleAddAction = () => {
|
||||||
if (!selectedActionSphere) return;
|
if (!selectedActionSphere) return;
|
||||||
|
|
||||||
|
@ -65,6 +82,15 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
return path;
|
return path;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const updatedPath = updatedPaths.find(
|
||||||
|
(path): path is Types.ConveyorEventsSchema =>
|
||||||
|
path.type === "Conveyor" &&
|
||||||
|
path.points.some(
|
||||||
|
(point) => point.uuid === selectedActionSphere.point.uuid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -89,6 +115,15 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
: path
|
: path
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const updatedPath = updatedPaths.find(
|
||||||
|
(path): path is Types.ConveyorEventsSchema =>
|
||||||
|
path.type === "Conveyor" &&
|
||||||
|
path.points.some(
|
||||||
|
(point) => point.uuid === selectedActionSphere.point.uuid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -128,6 +163,15 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
: path
|
: path
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const updatedPath = updatedPaths.find(
|
||||||
|
(path): path is Types.ConveyorEventsSchema =>
|
||||||
|
path.type === "Conveyor" &&
|
||||||
|
path.points.some(
|
||||||
|
(point) => point.uuid === selectedActionSphere.point.uuid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
|
|
||||||
// Update the selected item to reflect changes
|
// Update the selected item to reflect changes
|
||||||
|
@ -174,6 +218,15 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
: path
|
: path
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const updatedPath = updatedPaths.find(
|
||||||
|
(path): path is Types.ConveyorEventsSchema =>
|
||||||
|
path.type === "Conveyor" &&
|
||||||
|
path.points.some(
|
||||||
|
(point) => point.uuid === selectedActionSphere.point.uuid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
|
|
||||||
// Update selected item if it's the current action
|
// Update selected item if it's the current action
|
||||||
|
@ -209,6 +262,15 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
: path
|
: path
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const updatedPath = updatedPaths.find(
|
||||||
|
(path): path is Types.ConveyorEventsSchema =>
|
||||||
|
path.type === "Conveyor" &&
|
||||||
|
path.points.some(
|
||||||
|
(point) => point.uuid === selectedActionSphere.point.uuid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -238,6 +300,15 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
: path
|
: path
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const updatedPath = updatedPaths.find(
|
||||||
|
(path): path is Types.ConveyorEventsSchema =>
|
||||||
|
path.type === "Conveyor" &&
|
||||||
|
path.points.some(
|
||||||
|
(point) => point.uuid === selectedActionSphere.point.uuid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -248,6 +319,15 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
path.modeluuid === selectedPath.path.modeluuid ? { ...path, speed } : path
|
path.modeluuid === selectedPath.path.modeluuid ? { ...path, speed } : path
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const updatedPath = updatedPaths.find(
|
||||||
|
(path): path is Types.ConveyorEventsSchema =>
|
||||||
|
path.type === "Conveyor" &&
|
||||||
|
path.points.some(
|
||||||
|
(point) => point.uuid === selectedActionSphere.point.uuid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
setSelectedPath({ ...selectedPath, path: { ...selectedPath.path, speed } });
|
setSelectedPath({ ...selectedPath, path: { ...selectedPath.path, speed } });
|
||||||
};
|
};
|
||||||
|
@ -278,6 +358,15 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
: path
|
: path
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const updatedPath = updatedPaths.find(
|
||||||
|
(path): path is Types.ConveyorEventsSchema =>
|
||||||
|
path.type === "Conveyor" &&
|
||||||
|
path.points.some(
|
||||||
|
(point) => point.uuid === selectedActionSphere.point.uuid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -302,6 +391,15 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
: path
|
: path
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const updatedPath = updatedPaths.find(
|
||||||
|
(path): path is Types.ConveyorEventsSchema =>
|
||||||
|
path.type === "Conveyor" &&
|
||||||
|
path.points.some(
|
||||||
|
(point) => point.uuid === selectedActionSphere.point.uuid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -328,6 +426,15 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
: path
|
: path
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const updatedPath = updatedPaths.find(
|
||||||
|
(path): path is Types.ConveyorEventsSchema =>
|
||||||
|
path.type === "Conveyor" &&
|
||||||
|
path.points.some(
|
||||||
|
(point) => point.uuid === selectedActionSphere.point.uuid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
|
|
||||||
// Ensure the selectedItem is updated immediately
|
// Ensure the selectedItem is updated immediately
|
||||||
|
@ -363,6 +470,15 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
: path
|
: path
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const updatedPath = updatedPaths.find(
|
||||||
|
(path): path is Types.ConveyorEventsSchema =>
|
||||||
|
path.type === "Conveyor" &&
|
||||||
|
path.points.some(
|
||||||
|
(point) => point.uuid === selectedActionSphere.point.uuid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
|
|
||||||
// Immediately update the selected item if it's the one being toggled
|
// Immediately update the selected item if it's the one being toggled
|
||||||
|
@ -400,6 +516,15 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
: path
|
: path
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const updatedPath = updatedPaths.find(
|
||||||
|
(path): path is Types.ConveyorEventsSchema =>
|
||||||
|
path.type === "Conveyor" &&
|
||||||
|
path.points.some(
|
||||||
|
(point) => point.uuid === selectedActionSphere.point.uuid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
|
|
||||||
// Immediately update the selected item if it's the one being toggled
|
// Immediately update the selected item if it's the one being toggled
|
||||||
|
@ -437,6 +562,15 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
: path
|
: path
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const updatedPath = updatedPaths.find(
|
||||||
|
(path): path is Types.ConveyorEventsSchema =>
|
||||||
|
path.type === "Conveyor" &&
|
||||||
|
path.points.some(
|
||||||
|
(point) => point.uuid === selectedActionSphere.point.uuid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
|
|
||||||
// Immediately update selectedItem if it's the currently selected trigger
|
// Immediately update selectedItem if it's the currently selected trigger
|
||||||
|
@ -493,8 +627,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
{selectedPoint?.actions.map((action) => (
|
{selectedPoint?.actions.map((action) => (
|
||||||
<div
|
<div
|
||||||
key={action.uuid}
|
key={action.uuid}
|
||||||
className={`list-item ${
|
className={`list-item ${selectedItem?.type === "action" &&
|
||||||
selectedItem?.type === "action" &&
|
|
||||||
selectedItem.item?.uuid === action.uuid
|
selectedItem.item?.uuid === action.uuid
|
||||||
? "active"
|
? "active"
|
||||||
: ""
|
: ""
|
||||||
|
@ -506,7 +639,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
setSelectedItem({ type: "action", item: action })
|
setSelectedItem({ type: "action", item: action })
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<input type="radio" name="action" id="action" defaultChecked={action.isUsed}/>
|
<input type="radio" name="action" id="action" defaultChecked={action.isUsed} />
|
||||||
<RenameInput value={action.name} />
|
<RenameInput value={action.name} />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -543,8 +676,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
{selectedPoint?.triggers.map((trigger) => (
|
{selectedPoint?.triggers.map((trigger) => (
|
||||||
<div
|
<div
|
||||||
key={trigger.uuid}
|
key={trigger.uuid}
|
||||||
className={`list-item ${
|
className={`list-item ${selectedItem?.type === "trigger" &&
|
||||||
selectedItem?.type === "trigger" &&
|
|
||||||
selectedItem.item?.uuid === trigger.uuid
|
selectedItem.item?.uuid === trigger.uuid
|
||||||
? "active"
|
? "active"
|
||||||
: ""
|
: ""
|
||||||
|
@ -588,8 +720,8 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
{selectedItem.type === "action" && (
|
{selectedItem.type === "action" && (
|
||||||
<>
|
<>
|
||||||
<InputToggle
|
<InputToggle
|
||||||
inputKey="enableTrigger"
|
inputKey="enableAction"
|
||||||
label="Enable Trigger"
|
label="Enable Action"
|
||||||
value={selectedItem.item.isUsed}
|
value={selectedItem.item.isUsed}
|
||||||
onClick={() => handleActionToggle(selectedItem.item.uuid)}
|
onClick={() => handleActionToggle(selectedItem.item.uuid)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -33,7 +33,7 @@ const GlobalProperties: React.FC = () => {
|
||||||
const { setPlaneValue, setGridValue, planeValue, gridValue } =
|
const { setPlaneValue, setGridValue, planeValue, gridValue } =
|
||||||
useTileDistance();
|
useTileDistance();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(gridValue, planeValue, "values");
|
// console.log(gridValue, planeValue, "values");
|
||||||
}, [gridValue, planeValue]);
|
}, [gridValue, planeValue]);
|
||||||
const { socket } = useSocketStore();
|
const { socket } = useSocketStore();
|
||||||
const { limitDistance, setLimitDistance } = useLimitDistance();
|
const { limitDistance, setLimitDistance } = useLimitDistance();
|
||||||
|
|
|
@ -24,6 +24,7 @@ async function addAssetModel(
|
||||||
socket: Socket<any>,
|
socket: Socket<any>,
|
||||||
selectedItem: any,
|
selectedItem: any,
|
||||||
setSelectedItem: any,
|
setSelectedItem: any,
|
||||||
|
setSimulationPaths: any,
|
||||||
plane: Types.RefMesh,
|
plane: Types.RefMesh,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
|
||||||
|
@ -64,7 +65,7 @@ async function addAssetModel(
|
||||||
const cachedModel = THREE.Cache.get(selectedItem.id);
|
const cachedModel = THREE.Cache.get(selectedItem.id);
|
||||||
if (cachedModel) {
|
if (cachedModel) {
|
||||||
// console.log(`[Cache] Fetching ${selectedItem.name}`);
|
// console.log(`[Cache] Fetching ${selectedItem.name}`);
|
||||||
handleModelLoad(cachedModel, intersectPoint!, selectedItem, itemsGroup, tempLoader, isTempLoader, setFloorItems, socket);
|
handleModelLoad(cachedModel, intersectPoint!, selectedItem, itemsGroup, tempLoader, isTempLoader, setFloorItems, setSimulationPaths, socket);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
const cachedModelBlob = await retrieveGLTF(selectedItem.id);
|
const cachedModelBlob = await retrieveGLTF(selectedItem.id);
|
||||||
|
@ -77,7 +78,7 @@ async function addAssetModel(
|
||||||
URL.revokeObjectURL(blobUrl);
|
URL.revokeObjectURL(blobUrl);
|
||||||
THREE.Cache.remove(blobUrl);
|
THREE.Cache.remove(blobUrl);
|
||||||
THREE.Cache.add(selectedItem.id, gltf);
|
THREE.Cache.add(selectedItem.id, gltf);
|
||||||
handleModelLoad(gltf, intersectPoint!, selectedItem, itemsGroup, tempLoader, isTempLoader, setFloorItems, socket);
|
handleModelLoad(gltf, intersectPoint!, selectedItem, itemsGroup, tempLoader, isTempLoader, setFloorItems, setSimulationPaths, socket);
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
TempLoader(intersectPoint!, isTempLoader, tempLoader, itemsGroup);
|
TempLoader(intersectPoint!, isTempLoader, tempLoader, itemsGroup);
|
||||||
|
@ -89,7 +90,7 @@ async function addAssetModel(
|
||||||
const modelBlob = await fetch(`${url_Backend_dwinzo}/api/v1/AssetFile/${selectedItem.id}`).then((res) => res.blob());
|
const modelBlob = await fetch(`${url_Backend_dwinzo}/api/v1/AssetFile/${selectedItem.id}`).then((res) => res.blob());
|
||||||
await storeGLTF(selectedItem.id, modelBlob);
|
await storeGLTF(selectedItem.id, modelBlob);
|
||||||
THREE.Cache.add(selectedItem.id, gltf);
|
THREE.Cache.add(selectedItem.id, gltf);
|
||||||
await handleModelLoad(gltf, intersectPoint!, selectedItem, itemsGroup, tempLoader, isTempLoader, setFloorItems, socket);
|
await handleModelLoad(gltf, intersectPoint!, selectedItem, itemsGroup, tempLoader, isTempLoader, setFloorItems, setSimulationPaths, socket);
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
TempLoader(intersectPoint!, isTempLoader, tempLoader, itemsGroup);
|
TempLoader(intersectPoint!, isTempLoader, tempLoader, itemsGroup);
|
||||||
|
@ -112,10 +113,11 @@ async function handleModelLoad(
|
||||||
tempLoader: Types.RefMesh,
|
tempLoader: Types.RefMesh,
|
||||||
isTempLoader: Types.RefBoolean,
|
isTempLoader: Types.RefBoolean,
|
||||||
setFloorItems: Types.setFloorItemSetState,
|
setFloorItems: Types.setFloorItemSetState,
|
||||||
|
setSimulationPaths: any,
|
||||||
socket: Socket<any>
|
socket: Socket<any>
|
||||||
) {
|
) {
|
||||||
const model = gltf.scene.clone();
|
const model = gltf.scene.clone();
|
||||||
model.userData = { name: selectedItem.name, modelId: selectedItem.id };
|
model.userData = { name: selectedItem.name, modelId: selectedItem.id, modeluuid: model.uuid };
|
||||||
model.position.set(intersectPoint!.x, 3 + intersectPoint!.y, intersectPoint!.z);
|
model.position.set(intersectPoint!.x, 3 + intersectPoint!.y, intersectPoint!.z);
|
||||||
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
|
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
|
||||||
|
|
||||||
|
@ -152,7 +154,7 @@ async function handleModelLoad(
|
||||||
if (res.type === "Conveyor") {
|
if (res.type === "Conveyor") {
|
||||||
const pointUUIDs = res.points.map(() => THREE.MathUtils.generateUUID());
|
const pointUUIDs = res.points.map(() => THREE.MathUtils.generateUUID());
|
||||||
|
|
||||||
const eventData: Extract<Types.FloorItemType['eventData'], { type: 'Conveyor' }> = {
|
const backendEventData: Extract<Types.FloorItemType['eventData'], { type: 'Conveyor' }> = {
|
||||||
type: 'Conveyor',
|
type: 'Conveyor',
|
||||||
points: res.points.map((point: any, index: number) => ({
|
points: res.points.map((point: any, index: number) => ({
|
||||||
uuid: pointUUIDs[index],
|
uuid: pointUUIDs[index],
|
||||||
|
@ -165,7 +167,7 @@ async function handleModelLoad(
|
||||||
material: 'Inherit',
|
material: 'Inherit',
|
||||||
delay: 'Inherit',
|
delay: 'Inherit',
|
||||||
spawnInterval: 'Inherit',
|
spawnInterval: 'Inherit',
|
||||||
isUsed: false
|
isUsed: true
|
||||||
}],
|
}],
|
||||||
triggers: [],
|
triggers: [],
|
||||||
connections: {
|
connections: {
|
||||||
|
@ -176,16 +178,6 @@ async function handleModelLoad(
|
||||||
speed: 'Inherit'
|
speed: 'Inherit'
|
||||||
};
|
};
|
||||||
|
|
||||||
// console.log('eventData: ', eventData);
|
|
||||||
newFloorItem.eventData = eventData;
|
|
||||||
}
|
|
||||||
|
|
||||||
setFloorItems((prevItems) => {
|
|
||||||
const updatedItems = [...(prevItems || []), newFloorItem];
|
|
||||||
localStorage.setItem("FloorItems", JSON.stringify(updatedItems));
|
|
||||||
return updatedItems;
|
|
||||||
});
|
|
||||||
|
|
||||||
// API
|
// API
|
||||||
|
|
||||||
// await setFloorItemApi(
|
// await setFloorItemApi(
|
||||||
|
@ -211,14 +203,69 @@ async function handleModelLoad(
|
||||||
rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
|
rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
|
||||||
isLocked: false,
|
isLocked: false,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
eventData: newFloorItem.eventData,
|
eventData: backendEventData,
|
||||||
socketId: socket.id
|
socketId: socket.id
|
||||||
};
|
};
|
||||||
console.log('data: ', data);
|
|
||||||
|
|
||||||
|
console.log('data: ', data);
|
||||||
|
setFloorItems((prevItems) => {
|
||||||
|
const updatedItems = [...(prevItems || []), newFloorItem];
|
||||||
|
localStorage.setItem("FloorItems", JSON.stringify(updatedItems));
|
||||||
|
return updatedItems;
|
||||||
|
});
|
||||||
|
|
||||||
|
const eventData: any = backendEventData;
|
||||||
|
eventData.modeluuid = newFloorItem.modeluuid;
|
||||||
|
eventData.modelName = newFloorItem.modelname;
|
||||||
|
eventData.position = newFloorItem.position;
|
||||||
|
eventData.rotation = [model.rotation.x, model.rotation.y, model.rotation.z];
|
||||||
|
|
||||||
|
setSimulationPaths((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => [
|
||||||
|
...(prevEvents || []),
|
||||||
|
eventData as Types.ConveyorEventsSchema | Types.VehicleEventsSchema
|
||||||
|
]);
|
||||||
|
|
||||||
socket.emit("v2:model-asset:add", data);
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// API
|
||||||
|
|
||||||
|
// await setFloorItemApi(
|
||||||
|
// organization,
|
||||||
|
// newFloorItem.modeluuid,
|
||||||
|
// newFloorItem.modelname,
|
||||||
|
// newFloorItem.modelfileID,
|
||||||
|
// newFloorItem.position,
|
||||||
|
// { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
|
||||||
|
// false,
|
||||||
|
// true
|
||||||
|
// );
|
||||||
|
|
||||||
|
// 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
|
||||||
|
};
|
||||||
|
|
||||||
|
setFloorItems((prevItems) => {
|
||||||
|
const updatedItems = [...(prevItems || []), newFloorItem];
|
||||||
|
localStorage.setItem("FloorItems", JSON.stringify(updatedItems));
|
||||||
|
return updatedItems;
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
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!"); } });
|
||||||
});
|
});
|
||||||
|
|
|
@ -121,7 +121,7 @@ export default async function assetManager(
|
||||||
|
|
||||||
const model = gltf;
|
const model = gltf;
|
||||||
model.uuid = item.modeluuid;
|
model.uuid = item.modeluuid;
|
||||||
model.userData = { name: item.modelname, modelId: item.modelfileID };
|
model.userData = { name: item.modelname, modelId: item.modelfileID, modeluuid: item.modeluuid };
|
||||||
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
|
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
|
||||||
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);
|
||||||
|
|
|
@ -10,6 +10,7 @@ async function DeleteFloorItems(
|
||||||
itemsGroup: Types.RefGroup,
|
itemsGroup: Types.RefGroup,
|
||||||
hoveredDeletableFloorItem: Types.RefMesh,
|
hoveredDeletableFloorItem: Types.RefMesh,
|
||||||
setFloorItems: Types.setFloorItemSetState,
|
setFloorItems: Types.setFloorItemSetState,
|
||||||
|
setSimulationPaths: any,
|
||||||
socket: Socket<any>
|
socket: Socket<any>
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
|
||||||
|
@ -74,6 +75,12 @@ async function DeleteFloorItems(
|
||||||
itemsGroup.current.remove(hoveredDeletableFloorItem.current);
|
itemsGroup.current.remove(hoveredDeletableFloorItem.current);
|
||||||
}
|
}
|
||||||
setFloorItems(updatedItems);
|
setFloorItems(updatedItems);
|
||||||
|
|
||||||
|
setSimulationPaths((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => {
|
||||||
|
const updatedEvents = (prevEvents || []).filter(event => event.modeluuid !== removedItem.modeluuid);
|
||||||
|
return updatedEvents;
|
||||||
|
});
|
||||||
|
|
||||||
toast.success("Model Removed!");
|
toast.success("Model Removed!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
useRenderDistance,
|
useRenderDistance,
|
||||||
useselectedFloorItem,
|
useselectedFloorItem,
|
||||||
useSelectedItem,
|
useSelectedItem,
|
||||||
|
useSimulationPaths,
|
||||||
useSocketStore,
|
useSocketStore,
|
||||||
useToggleView,
|
useToggleView,
|
||||||
useTransformMode,
|
useTransformMode,
|
||||||
|
@ -64,6 +65,7 @@ const FloorItemsGroup = ({
|
||||||
const { setselectedFloorItem } = useselectedFloorItem();
|
const { setselectedFloorItem } = useselectedFloorItem();
|
||||||
const { activeTool } = useActiveTool();
|
const { activeTool } = useActiveTool();
|
||||||
const { selectedItem, setSelectedItem } = useSelectedItem();
|
const { selectedItem, setSelectedItem } = useSelectedItem();
|
||||||
|
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
|
||||||
const { setLoadingProgress } = useLoadingProgress();
|
const { setLoadingProgress } = useLoadingProgress();
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
const { socket } = useSocketStore();
|
const { socket } = useSocketStore();
|
||||||
|
@ -96,6 +98,7 @@ const FloorItemsGroup = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
getFloorAssets(organization).then((data) => {
|
getFloorAssets(organization).then((data) => {
|
||||||
|
if (data.length > 0) {
|
||||||
const uniqueItems = (data as Types.FloorItems).filter(
|
const uniqueItems = (data as Types.FloorItems).filter(
|
||||||
(item, index, self) =>
|
(item, index, self) =>
|
||||||
index === self.findIndex((t) => t.modelfileID === item.modelfileID)
|
index === self.findIndex((t) => t.modelfileID === item.modelfileID)
|
||||||
|
@ -106,6 +109,12 @@ const FloorItemsGroup = ({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gltfLoaderWorker.postMessage({ floorItems: data });
|
gltfLoaderWorker.postMessage({ floorItems: data });
|
||||||
|
} else {
|
||||||
|
console.log('data: ', data);
|
||||||
|
gltfLoaderWorker.postMessage({ floorItems: [] });
|
||||||
|
loadInitialFloorItems(itemsGroup, setFloorItems, setSimulationPaths);
|
||||||
|
updateLoadingProgress(100);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
gltfLoaderWorker.onmessage = async (event) => {
|
gltfLoaderWorker.onmessage = async (event) => {
|
||||||
|
@ -122,7 +131,7 @@ const FloorItemsGroup = ({
|
||||||
updateLoadingProgress(progress);
|
updateLoadingProgress(progress);
|
||||||
|
|
||||||
if (loadedAssets === totalAssets) {
|
if (loadedAssets === totalAssets) {
|
||||||
loadInitialFloorItems(itemsGroup, setFloorItems);
|
loadInitialFloorItems(itemsGroup, setFloorItems, setSimulationPaths);
|
||||||
updateLoadingProgress(100);
|
updateLoadingProgress(100);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -240,6 +249,7 @@ const FloorItemsGroup = ({
|
||||||
itemsGroup,
|
itemsGroup,
|
||||||
hoveredDeletableFloorItem,
|
hoveredDeletableFloorItem,
|
||||||
setFloorItems,
|
setFloorItems,
|
||||||
|
setSimulationPaths,
|
||||||
socket
|
socket
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -365,6 +375,7 @@ const FloorItemsGroup = ({
|
||||||
socket,
|
socket,
|
||||||
selectedItem,
|
selectedItem,
|
||||||
setSelectedItem,
|
setSelectedItem,
|
||||||
|
setSimulationPaths,
|
||||||
plane
|
plane
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -408,7 +419,6 @@ const FloorItemsGroup = ({
|
||||||
activeModule,
|
activeModule,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {}, [floorItems]);
|
|
||||||
|
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
if (controls)
|
if (controls)
|
||||||
|
|
|
@ -105,7 +105,7 @@ export default function SocketResponses({
|
||||||
// console.log(`Getting ${data.data.modelname} from cache`);
|
// console.log(`Getting ${data.data.modelname} from cache`);
|
||||||
const model = cachedModel.scene.clone();
|
const model = cachedModel.scene.clone();
|
||||||
model.uuid = data.data.modeluuid;
|
model.uuid = data.data.modeluuid;
|
||||||
model.userData = { name: data.data.modelname, modelId: data.data.modelFileID };
|
model.userData = { name: data.data.modelname, modelId: data.data.modelFileID, modeluuid: data.data.modeluuid };
|
||||||
model.position.set(...data.data.position as [number, number, number]);
|
model.position.set(...data.data.position as [number, number, number]);
|
||||||
model.rotation.set(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z);
|
model.rotation.set(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z);
|
||||||
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
|
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
|
||||||
|
@ -183,7 +183,7 @@ export default function SocketResponses({
|
||||||
THREE.Cache.remove(url);
|
THREE.Cache.remove(url);
|
||||||
const model = gltf.scene;
|
const model = gltf.scene;
|
||||||
model.uuid = data.data.modeluuid;
|
model.uuid = data.data.modeluuid;
|
||||||
model.userData = { name: data.data.modelname, modelId: data.data.modelFileID };
|
model.userData = { name: data.data.modelname, modelId: data.data.modelFileID, modeluuid: data.data.modeluuid };
|
||||||
model.position.set(...data.data.position as [number, number, number]);
|
model.position.set(...data.data.position as [number, number, number]);
|
||||||
model.rotation.set(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z);
|
model.rotation.set(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z);
|
||||||
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
|
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
|
||||||
|
|
|
@ -11,7 +11,8 @@ import { getFloorAssets } from '../../../services/factoryBuilder/assest/floorAss
|
||||||
|
|
||||||
async function loadInitialFloorItems(
|
async function loadInitialFloorItems(
|
||||||
itemsGroup: Types.RefGroup,
|
itemsGroup: Types.RefGroup,
|
||||||
setFloorItems: Types.setFloorItemSetState
|
setFloorItems: Types.setFloorItemSetState,
|
||||||
|
setSimulationPaths: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => void
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!itemsGroup.current) return;
|
if (!itemsGroup.current) return;
|
||||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||||
|
@ -22,6 +23,8 @@ async function loadInitialFloorItems(
|
||||||
localStorage.setItem("FloorItems", JSON.stringify(items));
|
localStorage.setItem("FloorItems", JSON.stringify(items));
|
||||||
await initializeDB();
|
await initializeDB();
|
||||||
|
|
||||||
|
if (items.message === "floorItems not found") return;
|
||||||
|
|
||||||
if (items) {
|
if (items) {
|
||||||
const storedFloorItems: Types.FloorItems = items;
|
const storedFloorItems: Types.FloorItems = items;
|
||||||
const loader = new GLTFLoader();
|
const loader = new GLTFLoader();
|
||||||
|
@ -50,6 +53,7 @@ async function loadInitialFloorItems(
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const item of storedFloorItems) {
|
for (const item of storedFloorItems) {
|
||||||
|
console.log('item: ', item);
|
||||||
if (!item.modelfileID) return;
|
if (!item.modelfileID) return;
|
||||||
const itemPosition = new THREE.Vector3(item.position[0], item.position[1], item.position[2]);
|
const itemPosition = new THREE.Vector3(item.position[0], item.position[1], item.position[2]);
|
||||||
let storedPosition;
|
let storedPosition;
|
||||||
|
@ -68,7 +72,7 @@ async function loadInitialFloorItems(
|
||||||
const cachedModel = THREE.Cache.get(item.modelfileID!);
|
const cachedModel = THREE.Cache.get(item.modelfileID!);
|
||||||
if (cachedModel) {
|
if (cachedModel) {
|
||||||
// console.log(`[Cache] Fetching ${item.modelname}`);
|
// console.log(`[Cache] Fetching ${item.modelname}`);
|
||||||
processLoadedModel(cachedModel.scene.clone(), item, itemsGroup, setFloorItems);
|
processLoadedModel(cachedModel.scene.clone(), item, itemsGroup, setFloorItems, setSimulationPaths);
|
||||||
modelsLoaded++;
|
modelsLoaded++;
|
||||||
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve);
|
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve);
|
||||||
return;
|
return;
|
||||||
|
@ -85,7 +89,7 @@ async function loadInitialFloorItems(
|
||||||
URL.revokeObjectURL(blobUrl);
|
URL.revokeObjectURL(blobUrl);
|
||||||
THREE.Cache.remove(blobUrl);
|
THREE.Cache.remove(blobUrl);
|
||||||
THREE.Cache.add(item.modelfileID!, gltf);
|
THREE.Cache.add(item.modelfileID!, gltf);
|
||||||
processLoadedModel(gltf.scene.clone(), item, itemsGroup, setFloorItems);
|
processLoadedModel(gltf.scene.clone(), item, itemsGroup, setFloorItems, setSimulationPaths);
|
||||||
modelsLoaded++;
|
modelsLoaded++;
|
||||||
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve);
|
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve);
|
||||||
},
|
},
|
||||||
|
@ -108,7 +112,7 @@ async function loadInitialFloorItems(
|
||||||
const modelBlob = await fetch(modelUrl).then((res) => res.blob());
|
const modelBlob = await fetch(modelUrl).then((res) => res.blob());
|
||||||
await storeGLTF(item.modelfileID!, modelBlob);
|
await storeGLTF(item.modelfileID!, modelBlob);
|
||||||
THREE.Cache.add(item.modelfileID!, gltf);
|
THREE.Cache.add(item.modelfileID!, gltf);
|
||||||
processLoadedModel(gltf.scene.clone(), item, itemsGroup, setFloorItems);
|
processLoadedModel(gltf.scene.clone(), item, itemsGroup, setFloorItems, setSimulationPaths);
|
||||||
modelsLoaded++;
|
modelsLoaded++;
|
||||||
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve);
|
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve);
|
||||||
},
|
},
|
||||||
|
@ -121,34 +125,23 @@ async function loadInitialFloorItems(
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// console.log(`Item ${item.modelname} is not near`);
|
// console.log(`Item ${item.modelname} is not near`);
|
||||||
|
setFloorItems((prevItems) => [
|
||||||
|
...(prevItems || []),
|
||||||
|
{
|
||||||
|
modeluuid: item.modeluuid,
|
||||||
|
modelname: item.modelname,
|
||||||
|
position: item.position,
|
||||||
|
rotation: item.rotation,
|
||||||
|
modelfileID: item.modelfileID,
|
||||||
|
isLocked: item.isLocked,
|
||||||
|
isVisible: item.isVisible,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
if (item.eventData) {
|
if (item.eventData) {
|
||||||
setFloorItems((prevItems) => [
|
processEventData(item, setSimulationPaths);
|
||||||
...(prevItems || []),
|
|
||||||
{
|
|
||||||
modeluuid: item.modeluuid,
|
|
||||||
modelname: item.modelname,
|
|
||||||
position: item.position,
|
|
||||||
rotation: item.rotation,
|
|
||||||
modelfileID: item.modelfileID,
|
|
||||||
isLocked: item.isLocked,
|
|
||||||
isVisible: item.isVisible,
|
|
||||||
// eventData: item.eventData,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
} 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,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
modelsLoaded++;
|
modelsLoaded++;
|
||||||
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, () => { });
|
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, () => { });
|
||||||
}
|
}
|
||||||
|
@ -164,12 +157,13 @@ function processLoadedModel(
|
||||||
gltf: any,
|
gltf: any,
|
||||||
item: Types.FloorItemType,
|
item: Types.FloorItemType,
|
||||||
itemsGroup: Types.RefGroup,
|
itemsGroup: Types.RefGroup,
|
||||||
setFloorItems: Types.setFloorItemSetState
|
setFloorItems: Types.setFloorItemSetState,
|
||||||
|
setSimulationPaths: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => void
|
||||||
) {
|
) {
|
||||||
const model = gltf;
|
const model = gltf;
|
||||||
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 };
|
model.userData = { name: item.modelname, modelId: item.modelfileID, modeluuid: item.modeluuid };
|
||||||
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);
|
||||||
|
|
||||||
|
@ -186,21 +180,6 @@ function processLoadedModel(
|
||||||
|
|
||||||
itemsGroup?.current?.add(model);
|
itemsGroup?.current?.add(model);
|
||||||
|
|
||||||
if (item.eventData) {
|
|
||||||
setFloorItems((prevItems) => [
|
|
||||||
...(prevItems || []),
|
|
||||||
{
|
|
||||||
modeluuid: item.modeluuid,
|
|
||||||
modelname: item.modelname,
|
|
||||||
position: item.position,
|
|
||||||
rotation: item.rotation,
|
|
||||||
modelfileID: item.modelfileID,
|
|
||||||
isLocked: item.isLocked,
|
|
||||||
isVisible: item.isVisible,
|
|
||||||
// eventData: item.eventData,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
setFloorItems((prevItems) => [
|
setFloorItems((prevItems) => [
|
||||||
...(prevItems || []),
|
...(prevItems || []),
|
||||||
{
|
{
|
||||||
|
@ -213,12 +192,55 @@ function processLoadedModel(
|
||||||
isVisible: item.isVisible,
|
isVisible: item.isVisible,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
if (item.eventData || item.modelfileID === '67e3da19c2e8f37134526e6a') {
|
||||||
|
processEventData(item, setSimulationPaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
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' });
|
||||||
gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: 'power2.out' });
|
gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: 'power2.out' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function processEventData(item: Types.FloorItemType, setSimulationPaths: any) {
|
||||||
|
|
||||||
|
if (item.eventData?.type === 'Conveyor') {
|
||||||
|
|
||||||
|
const data: any = item.eventData;
|
||||||
|
data.modeluuid = item.modeluuid;
|
||||||
|
data.modelName = item.modelname;
|
||||||
|
data.position = item.position;
|
||||||
|
data.rotation = [item.rotation.x, item.rotation.y, item.rotation.z];
|
||||||
|
|
||||||
|
setSimulationPaths((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => [
|
||||||
|
...(prevEvents || []),
|
||||||
|
data as Types.ConveyorEventsSchema
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const pointUUID = THREE.MathUtils.generateUUID();
|
||||||
|
const pointPosition = new THREE.Vector3(0, 1.3, 0);
|
||||||
|
|
||||||
|
const newVehiclePath: Types.VehicleEventsSchema = {
|
||||||
|
modeluuid: item.modeluuid,
|
||||||
|
modelName: item.modelname,
|
||||||
|
type: 'Vehicle',
|
||||||
|
point: {
|
||||||
|
uuid: pointUUID,
|
||||||
|
position: [pointPosition.x, pointPosition.y, pointPosition.z],
|
||||||
|
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Start', start: {}, hitCount: 1, end: {}, buffer: 0 },
|
||||||
|
connections: { source: { pathUUID: item.modeluuid, pointUUID: pointUUID }, targets: [] },
|
||||||
|
speed: 2,
|
||||||
|
},
|
||||||
|
position: [...item.position],
|
||||||
|
};
|
||||||
|
|
||||||
|
setSimulationPaths((prevEvents: (Types.VehicleEventsSchema)[]) => [
|
||||||
|
...(prevEvents || []),
|
||||||
|
newVehiclePath as Types.VehicleEventsSchema
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function checkLoadingCompletion(
|
function checkLoadingCompletion(
|
||||||
modelsLoaded: number,
|
modelsLoaded: number,
|
||||||
modelsToLoad: number,
|
modelsToLoad: number,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { useEffect, useMemo } from "react";
|
import { useEffect, useMemo } 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, useSimulationPaths, useSocketStore, useToggleView } from "../../../../store/store";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
|
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
|
||||||
import * as Types from "../../../../types/world/worldTypes";
|
import * as Types from "../../../../types/world/worldTypes";
|
||||||
|
@ -10,6 +10,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||||
const { camera, controls, gl, scene, pointer, raycaster } = useThree();
|
const { camera, controls, gl, scene, pointer, raycaster } = useThree();
|
||||||
const { toggleView } = useToggleView();
|
const { toggleView } = useToggleView();
|
||||||
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
||||||
|
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
|
||||||
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
|
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
|
||||||
const { floorItems, setFloorItems } = useFloorItems();
|
const { floorItems, setFloorItems } = useFloorItems();
|
||||||
const { socket } = useSocketStore()
|
const { socket } = useSocketStore()
|
||||||
|
@ -150,8 +151,97 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||||
return updatedItems;
|
return updatedItems;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | undefined = simulationPaths.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||||
|
|
||||||
const email = localStorage.getItem("email");
|
const email = localStorage.getItem("email");
|
||||||
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
||||||
|
if (eventData) {
|
||||||
|
if (eventData.type === 'Conveyor' && eventData) {
|
||||||
|
const createConveyorPoint = (index: number) => {
|
||||||
|
const pointUUID = THREE.MathUtils.generateUUID();
|
||||||
|
const hasActions = (eventData as Types.ConveyorEventsSchema)?.points[index].actions.length > 0;
|
||||||
|
|
||||||
|
const defaultAction = {
|
||||||
|
uuid: THREE.MathUtils.generateUUID(),
|
||||||
|
name: 'Action 1',
|
||||||
|
type: 'Inherit',
|
||||||
|
material: 'Inherit',
|
||||||
|
delay: 'Inherit',
|
||||||
|
spawnInterval: 'Inherit',
|
||||||
|
isUsed: true
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
uuid: pointUUID,
|
||||||
|
position: (eventData as Types.ConveyorEventsSchema)?.points[index].position,
|
||||||
|
rotation: (eventData as Types.ConveyorEventsSchema)?.points[index].rotation,
|
||||||
|
actions: hasActions
|
||||||
|
? (eventData as Types.ConveyorEventsSchema)?.points[index].actions.map(action => ({
|
||||||
|
...action,
|
||||||
|
uuid: THREE.MathUtils.generateUUID()
|
||||||
|
}))
|
||||||
|
: [defaultAction],
|
||||||
|
triggers: (eventData as Types.ConveyorEventsSchema)?.points[index].triggers,
|
||||||
|
connections: {
|
||||||
|
source: { pathUUID: obj.uuid, pointUUID },
|
||||||
|
targets: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const backendEventData = {
|
||||||
|
type: 'Conveyor',
|
||||||
|
points: [
|
||||||
|
createConveyorPoint(0), // point1
|
||||||
|
createConveyorPoint(1), // middlePoint
|
||||||
|
createConveyorPoint(2) // point2
|
||||||
|
],
|
||||||
|
speed: (eventData as Types.ConveyorEventsSchema)?.speed
|
||||||
|
};
|
||||||
|
|
||||||
|
//REST
|
||||||
|
|
||||||
|
// await setFloorItemApi(
|
||||||
|
// organization,
|
||||||
|
// obj.uuid,
|
||||||
|
// obj.userData.name,
|
||||||
|
// [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||||
|
// { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
|
||||||
|
// obj.userData.modelId,
|
||||||
|
// false,
|
||||||
|
// true,
|
||||||
|
// backendEventData
|
||||||
|
// );
|
||||||
|
|
||||||
|
//SOCKET
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
organization,
|
||||||
|
modeluuid: newFloorItem.modeluuid,
|
||||||
|
modelname: newFloorItem.modelname,
|
||||||
|
modelfileID: newFloorItem.modelfileID,
|
||||||
|
position: newFloorItem.position,
|
||||||
|
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
|
||||||
|
isLocked: false,
|
||||||
|
isVisible: true,
|
||||||
|
eventData: backendEventData,
|
||||||
|
socketId: socket.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const newEventData: any = backendEventData;
|
||||||
|
newEventData.modeluuid = newFloorItem.modeluuid;
|
||||||
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
|
newEventData.position = newFloorItem.position;
|
||||||
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
|
setSimulationPaths((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => [
|
||||||
|
...(prevEvents || []),
|
||||||
|
newEventData as Types.ConveyorEventsSchema | Types.VehicleEventsSchema
|
||||||
|
]);
|
||||||
|
|
||||||
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
//REST
|
//REST
|
||||||
|
|
||||||
|
@ -182,6 +272,8 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||||
|
|
||||||
socket.emit("v2:model-asset:add", data);
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
itemsGroupRef.current.add(obj);
|
itemsGroupRef.current.add(obj);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { useEffect, useMemo } from "react";
|
import { useEffect, useMemo } 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, useSimulationPaths, useSocketStore, useToggleView } from "../../../../store/store";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
|
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
|
||||||
import * as Types from "../../../../types/world/worldTypes";
|
import * as Types from "../../../../types/world/worldTypes";
|
||||||
|
@ -10,11 +10,11 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||||
const { camera, controls, gl, scene, pointer, raycaster } = useThree();
|
const { camera, controls, gl, scene, pointer, raycaster } = useThree();
|
||||||
const { toggleView } = useToggleView();
|
const { toggleView } = useToggleView();
|
||||||
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
||||||
|
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
|
||||||
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
|
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
|
||||||
const { floorItems, setFloorItems } = useFloorItems();
|
const { floorItems, setFloorItems } = useFloorItems();
|
||||||
const { socket } = useSocketStore();
|
const { socket } = useSocketStore();
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!camera || !scene || toggleView) return;
|
if (!camera || !scene || toggleView) return;
|
||||||
const canvasElement = gl.domElement;
|
const canvasElement = gl.domElement;
|
||||||
|
@ -131,9 +131,99 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||||
return updatedItems;
|
return updatedItems;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | undefined = simulationPaths.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||||
|
|
||||||
const email = localStorage.getItem("email");
|
const email = localStorage.getItem("email");
|
||||||
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
||||||
|
|
||||||
|
if (eventData) {
|
||||||
|
if (eventData.type === 'Conveyor' && eventData) {
|
||||||
|
const createConveyorPoint = (index: number) => {
|
||||||
|
const pointUUID = THREE.MathUtils.generateUUID();
|
||||||
|
const hasActions = (eventData as Types.ConveyorEventsSchema)?.points[index].actions.length > 0;
|
||||||
|
|
||||||
|
const defaultAction = {
|
||||||
|
uuid: THREE.MathUtils.generateUUID(),
|
||||||
|
name: 'Action 1',
|
||||||
|
type: 'Inherit',
|
||||||
|
material: 'Inherit',
|
||||||
|
delay: 'Inherit',
|
||||||
|
spawnInterval: 'Inherit',
|
||||||
|
isUsed: true
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
uuid: pointUUID,
|
||||||
|
position: (eventData as Types.ConveyorEventsSchema)?.points[index].position,
|
||||||
|
rotation: (eventData as Types.ConveyorEventsSchema)?.points[index].rotation,
|
||||||
|
actions: hasActions
|
||||||
|
? (eventData as Types.ConveyorEventsSchema)?.points[index].actions.map(action => ({
|
||||||
|
...action,
|
||||||
|
uuid: THREE.MathUtils.generateUUID()
|
||||||
|
}))
|
||||||
|
: [defaultAction],
|
||||||
|
triggers: (eventData as Types.ConveyorEventsSchema)?.points[index].triggers,
|
||||||
|
connections: {
|
||||||
|
source: { pathUUID: obj.uuid, pointUUID },
|
||||||
|
targets: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const backendEventData = {
|
||||||
|
type: 'Conveyor',
|
||||||
|
points: [
|
||||||
|
createConveyorPoint(0), // point1
|
||||||
|
createConveyorPoint(1), // middlePoint
|
||||||
|
createConveyorPoint(2) // point2
|
||||||
|
],
|
||||||
|
speed: (eventData as Types.ConveyorEventsSchema)?.speed
|
||||||
|
};
|
||||||
|
|
||||||
|
//REST
|
||||||
|
|
||||||
|
// await setFloorItemApi(
|
||||||
|
// organization,
|
||||||
|
// obj.uuid,
|
||||||
|
// obj.userData.name,
|
||||||
|
// [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||||
|
// { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
|
||||||
|
// obj.userData.modelId,
|
||||||
|
// false,
|
||||||
|
// true,
|
||||||
|
// backendEventData
|
||||||
|
// );
|
||||||
|
|
||||||
|
//SOCKET
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
organization,
|
||||||
|
modeluuid: newFloorItem.modeluuid,
|
||||||
|
modelname: newFloorItem.modelname,
|
||||||
|
modelfileID: newFloorItem.modelfileID,
|
||||||
|
position: newFloorItem.position,
|
||||||
|
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
|
||||||
|
isLocked: false,
|
||||||
|
isVisible: true,
|
||||||
|
eventData: backendEventData,
|
||||||
|
socketId: socket.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const newEventData: any = backendEventData;
|
||||||
|
newEventData.modeluuid = newFloorItem.modeluuid;
|
||||||
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
|
newEventData.position = newFloorItem.position;
|
||||||
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
|
setSimulationPaths((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => [
|
||||||
|
...(prevEvents || []),
|
||||||
|
newEventData as Types.ConveyorEventsSchema | Types.VehicleEventsSchema
|
||||||
|
]);
|
||||||
|
|
||||||
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
//REST
|
//REST
|
||||||
|
|
||||||
// await setFloorItemApi(
|
// await setFloorItemApi(
|
||||||
|
@ -163,6 +253,8 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||||
|
|
||||||
socket.emit("v2:model-asset:add", data);
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
itemsGroupRef.current.add(obj);
|
itemsGroupRef.current.add(obj);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { useEffect, useMemo, useRef, useState } from "react";
|
import { useEffect, useMemo, useRef, useState } 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, useSimulationPaths, 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";
|
||||||
|
@ -12,6 +12,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||||
|
|
||||||
const { toggleView } = useToggleView();
|
const { toggleView } = useToggleView();
|
||||||
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
||||||
|
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
|
||||||
const { floorItems, setFloorItems } = useFloorItems();
|
const { floorItems, setFloorItems } = useFloorItems();
|
||||||
const { socket } = useSocketStore();
|
const { socket } = useSocketStore();
|
||||||
const itemsData = useRef<Types.FloorItems>([]);
|
const itemsData = useRef<Types.FloorItems>([]);
|
||||||
|
@ -179,9 +180,69 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||||
return updatedItems;
|
return updatedItems;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | undefined = simulationPaths.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||||
|
|
||||||
const email = localStorage.getItem("email");
|
const email = localStorage.getItem("email");
|
||||||
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
||||||
|
|
||||||
|
if (eventData) {
|
||||||
|
if (eventData.type === 'Conveyor' && eventData) {
|
||||||
|
|
||||||
|
const backendEventData = {
|
||||||
|
type: 'Conveyor',
|
||||||
|
points: eventData.points,
|
||||||
|
speed: (eventData as Types.ConveyorEventsSchema)?.speed
|
||||||
|
};
|
||||||
|
|
||||||
|
//REST
|
||||||
|
|
||||||
|
// await setFloorItemApi(
|
||||||
|
// organization,
|
||||||
|
// obj.uuid,
|
||||||
|
// obj.userData.name,
|
||||||
|
// [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||||
|
// { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
|
||||||
|
// obj.userData.modelId,
|
||||||
|
// false,
|
||||||
|
// true,
|
||||||
|
// backendEventData
|
||||||
|
// );
|
||||||
|
|
||||||
|
//SOCKET
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
organization,
|
||||||
|
modeluuid: newFloorItem.modeluuid,
|
||||||
|
modelname: newFloorItem.modelname,
|
||||||
|
modelfileID: newFloorItem.modelfileID,
|
||||||
|
position: newFloorItem.position,
|
||||||
|
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
|
||||||
|
isLocked: false,
|
||||||
|
isVisible: true,
|
||||||
|
eventData: backendEventData,
|
||||||
|
socketId: socket.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const newEventData: any = backendEventData;
|
||||||
|
newEventData.modeluuid = newFloorItem.modeluuid;
|
||||||
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
|
newEventData.position = newFloorItem.position;
|
||||||
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
|
setSimulationPaths((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => {
|
||||||
|
const updatedEvents = (prevEvents || []).map(event =>
|
||||||
|
event.modeluuid === newFloorItem.modeluuid
|
||||||
|
? { ...event, ...newEventData }
|
||||||
|
: event
|
||||||
|
);
|
||||||
|
return updatedEvents;
|
||||||
|
});
|
||||||
|
|
||||||
|
// socket.emit("v2:model-asset:add", data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
|
||||||
//REST
|
//REST
|
||||||
|
|
||||||
// await setFloorItemApi(
|
// await setFloorItemApi(
|
||||||
|
@ -211,6 +272,8 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||||
|
|
||||||
socket.emit("v2:model-asset:add", data);
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
itemsGroupRef.current.add(obj);
|
itemsGroupRef.current.add(obj);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { useEffect, useMemo, useRef, useState } from "react";
|
import { useEffect, useMemo, useRef, useState } 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, useSimulationPaths, 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";
|
||||||
|
@ -12,6 +12,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||||
|
|
||||||
const { toggleView } = useToggleView();
|
const { toggleView } = useToggleView();
|
||||||
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
||||||
|
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
|
||||||
const { floorItems, setFloorItems } = useFloorItems();
|
const { floorItems, setFloorItems } = useFloorItems();
|
||||||
const { socket } = useSocketStore();
|
const { socket } = useSocketStore();
|
||||||
const itemsData = useRef<Types.FloorItems>([]);
|
const itemsData = useRef<Types.FloorItems>([]);
|
||||||
|
@ -182,9 +183,69 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||||
return updatedItems;
|
return updatedItems;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | undefined = simulationPaths.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||||
|
|
||||||
const email = localStorage.getItem("email");
|
const email = localStorage.getItem("email");
|
||||||
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
||||||
|
|
||||||
|
if (eventData) {
|
||||||
|
if (eventData.type === 'Conveyor' && eventData) {
|
||||||
|
|
||||||
|
const backendEventData = {
|
||||||
|
type: 'Conveyor',
|
||||||
|
points: eventData.points,
|
||||||
|
speed: (eventData as Types.ConveyorEventsSchema)?.speed
|
||||||
|
};
|
||||||
|
|
||||||
|
//REST
|
||||||
|
|
||||||
|
// await setFloorItemApi(
|
||||||
|
// organization,
|
||||||
|
// obj.uuid,
|
||||||
|
// obj.userData.name,
|
||||||
|
// [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||||
|
// { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
|
||||||
|
// obj.userData.modelId,
|
||||||
|
// false,
|
||||||
|
// true,
|
||||||
|
// backendEventData
|
||||||
|
// );
|
||||||
|
|
||||||
|
//SOCKET
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
organization,
|
||||||
|
modeluuid: newFloorItem.modeluuid,
|
||||||
|
modelname: newFloorItem.modelname,
|
||||||
|
modelfileID: newFloorItem.modelfileID,
|
||||||
|
position: newFloorItem.position,
|
||||||
|
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
|
||||||
|
isLocked: false,
|
||||||
|
isVisible: true,
|
||||||
|
eventData: backendEventData,
|
||||||
|
socketId: socket.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const newEventData: any = backendEventData;
|
||||||
|
newEventData.modeluuid = newFloorItem.modeluuid;
|
||||||
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
|
newEventData.position = newFloorItem.position;
|
||||||
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
|
setSimulationPaths((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => {
|
||||||
|
const updatedEvents = (prevEvents || []).map(event =>
|
||||||
|
event.modeluuid === newFloorItem.modeluuid
|
||||||
|
? { ...event, ...newEventData }
|
||||||
|
: event
|
||||||
|
);
|
||||||
|
return updatedEvents;
|
||||||
|
});
|
||||||
|
|
||||||
|
// socket.emit("v2:model-asset:add", data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
|
||||||
//REST
|
//REST
|
||||||
|
|
||||||
// await setFloorItemApi(
|
// await setFloorItemApi(
|
||||||
|
@ -214,6 +275,8 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||||
|
|
||||||
socket.emit("v2:model-asset:add", data);
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
itemsGroupRef.current.add(obj);
|
itemsGroupRef.current.add(obj);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { SelectionBox } from "three/examples/jsm/interactive/SelectionBox";
|
import { SelectionBox } from "three/examples/jsm/interactive/SelectionBox";
|
||||||
import { SelectionHelper } from "./selectionHelper";
|
import { SelectionHelper } from "./selectionHelper";
|
||||||
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, useSimulationPaths, useSocketStore, useToggleView } from "../../../../store/store";
|
||||||
import BoundingBox from "./boundingBoxHelper";
|
import BoundingBox from "./boundingBoxHelper";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
// import { deleteFloorItem } from '../../../../services/factoryBuilder/assest/floorAsset/deleteFloorItemApi';
|
// import { deleteFloorItem } from '../../../../services/factoryBuilder/assest/floorAsset/deleteFloorItemApi';
|
||||||
|
@ -20,6 +20,7 @@ const SelectionControls: React.FC = () => {
|
||||||
const itemsGroupRef = useRef<THREE.Group | undefined>(undefined);
|
const itemsGroupRef = useRef<THREE.Group | undefined>(undefined);
|
||||||
const selectionGroup = useRef() as Types.RefGroup;
|
const selectionGroup = useRef() as Types.RefGroup;
|
||||||
const { toggleView } = useToggleView();
|
const { toggleView } = useToggleView();
|
||||||
|
const { setSimulationPaths } = useSimulationPaths();
|
||||||
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
||||||
const [movedObjects, setMovedObjects] = useState<THREE.Object3D[]>([]);
|
const [movedObjects, setMovedObjects] = useState<THREE.Object3D[]>([]);
|
||||||
const [rotatedObjects, setRotatedObjects] = useState<THREE.Object3D[]>([]);
|
const [rotatedObjects, setRotatedObjects] = useState<THREE.Object3D[]>([]);
|
||||||
|
@ -239,6 +240,11 @@ const SelectionControls: React.FC = () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setSimulationPaths((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => {
|
||||||
|
const updatedEvents = (prevEvents || []).filter(event => event.modeluuid !== selectedMesh.uuid);
|
||||||
|
return updatedEvents;
|
||||||
|
});
|
||||||
|
|
||||||
itemsGroupRef.current?.remove(selectedMesh);
|
itemsGroupRef.current?.remove(selectedMesh);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -93,13 +93,13 @@ export default function PostProcessing() {
|
||||||
<Outline
|
<Outline
|
||||||
selection={[selectedActionSphere.point]}
|
selection={[selectedActionSphere.point]}
|
||||||
selectionLayer={10}
|
selectionLayer={10}
|
||||||
width={750}
|
width={1000}
|
||||||
blendFunction={BlendFunction.ALPHA}
|
blendFunction={BlendFunction.ALPHA}
|
||||||
edgeStrength={15}
|
edgeStrength={10}
|
||||||
resolutionScale={2}
|
resolutionScale={2}
|
||||||
pulseSpeed={0}
|
pulseSpeed={0}
|
||||||
visibleEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
|
visibleEdgeColor={0x6f42c1}
|
||||||
hiddenEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
|
hiddenEdgeColor={0x6f42c1}
|
||||||
blur={true}
|
blur={true}
|
||||||
xRay={true}
|
xRay={true}
|
||||||
/>
|
/>
|
||||||
|
@ -108,9 +108,9 @@ export default function PostProcessing() {
|
||||||
<Outline
|
<Outline
|
||||||
selection={flattenChildren(selectedPath.group.children)}
|
selection={flattenChildren(selectedPath.group.children)}
|
||||||
selectionLayer={10}
|
selectionLayer={10}
|
||||||
width={750}
|
width={1000}
|
||||||
blendFunction={BlendFunction.ALPHA}
|
blendFunction={BlendFunction.ALPHA}
|
||||||
edgeStrength={15}
|
edgeStrength={10}
|
||||||
resolutionScale={2}
|
resolutionScale={2}
|
||||||
pulseSpeed={0}
|
pulseSpeed={0}
|
||||||
visibleEdgeColor={0x6f42c1}
|
visibleEdgeColor={0x6f42c1}
|
||||||
|
|
|
@ -10,76 +10,76 @@ function Behaviour() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const newPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[] = [];
|
const newPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[] = [];
|
||||||
|
|
||||||
floorItems.forEach((item: Types.FloorItemType) => {
|
// floorItems.forEach((item: Types.FloorItemType) => {
|
||||||
if (item.modelfileID === "672a090f80d91ac979f4d0bd") {
|
// if (item.modelfileID === "672a090f80d91ac979f4d0bd") {
|
||||||
console.log('item: ', item);
|
// const point1Position = new THREE.Vector3(0, 0.85, 2.2);
|
||||||
const point1Position = new THREE.Vector3(0, 0.85, 2.2);
|
// const middlePointPosition = new THREE.Vector3(0, 0.85, 0);
|
||||||
const middlePointPosition = new THREE.Vector3(0, 0.85, 0);
|
// const point2Position = new THREE.Vector3(0, 0.85, -2.2);
|
||||||
const point2Position = new THREE.Vector3(0, 0.85, -2.2);
|
|
||||||
|
|
||||||
const point1UUID = THREE.MathUtils.generateUUID();
|
// const point1UUID = THREE.MathUtils.generateUUID();
|
||||||
const middlePointUUID = THREE.MathUtils.generateUUID();
|
// const middlePointUUID = THREE.MathUtils.generateUUID();
|
||||||
const point2UUID = THREE.MathUtils.generateUUID();
|
// const point2UUID = THREE.MathUtils.generateUUID();
|
||||||
|
|
||||||
const newPath: Types.ConveyorEventsSchema = {
|
// const newPath: Types.ConveyorEventsSchema = {
|
||||||
modeluuid: item.modeluuid,
|
// modeluuid: item.modeluuid,
|
||||||
modelName: item.modelname,
|
// modelName: item.modelname,
|
||||||
type: 'Conveyor',
|
// type: 'Conveyor',
|
||||||
points: [
|
// points: [
|
||||||
{
|
// {
|
||||||
uuid: point1UUID,
|
// uuid: point1UUID,
|
||||||
position: [point1Position.x, point1Position.y, point1Position.z],
|
// position: [point1Position.x, point1Position.y, point1Position.z],
|
||||||
rotation: [0, 0, 0],
|
// rotation: [0, 0, 0],
|
||||||
actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: true }],
|
// actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: true }],
|
||||||
triggers: [],
|
// triggers: [],
|
||||||
connections: { source: { pathUUID: item.modeluuid, pointUUID: point1UUID }, targets: [] },
|
// connections: { source: { pathUUID: item.modeluuid, pointUUID: point1UUID }, targets: [] },
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
uuid: middlePointUUID,
|
// uuid: middlePointUUID,
|
||||||
position: [middlePointPosition.x, middlePointPosition.y, middlePointPosition.z],
|
// position: [middlePointPosition.x, middlePointPosition.y, middlePointPosition.z],
|
||||||
rotation: [0, 0, 0],
|
// rotation: [0, 0, 0],
|
||||||
actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: true }],
|
// actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: true }],
|
||||||
triggers: [],
|
// triggers: [],
|
||||||
connections: { source: { pathUUID: item.modeluuid, pointUUID: middlePointUUID }, targets: [] },
|
// connections: { source: { pathUUID: item.modeluuid, pointUUID: middlePointUUID }, targets: [] },
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
uuid: point2UUID,
|
// uuid: point2UUID,
|
||||||
position: [point2Position.x, point2Position.y, point2Position.z],
|
// position: [point2Position.x, point2Position.y, point2Position.z],
|
||||||
rotation: [0, 0, 0],
|
// rotation: [0, 0, 0],
|
||||||
actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: true }],
|
// actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: true }],
|
||||||
triggers: [],
|
// triggers: [],
|
||||||
connections: { source: { pathUUID: item.modeluuid, pointUUID: point2UUID }, targets: [] },
|
// connections: { source: { pathUUID: item.modeluuid, pointUUID: point2UUID }, targets: [] },
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
position: [...item.position],
|
// position: [...item.position],
|
||||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
// rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||||
speed: 'Inherit',
|
// speed: 'Inherit',
|
||||||
};
|
// };
|
||||||
|
|
||||||
newPaths.push(newPath);
|
// newPaths.push(newPath);
|
||||||
} else if (item.modelfileID === "67e3da19c2e8f37134526e6a") {
|
// } else if (item.modelfileID === "67e3da19c2e8f37134526e6a") {
|
||||||
const pointUUID = THREE.MathUtils.generateUUID();
|
// const pointUUID = THREE.MathUtils.generateUUID();
|
||||||
const pointPosition = new THREE.Vector3(0, 1.3, 0);
|
// const pointPosition = new THREE.Vector3(0, 1.3, 0);
|
||||||
|
|
||||||
const newVehiclePath: Types.VehicleEventsSchema = {
|
// const newVehiclePath: Types.VehicleEventsSchema = {
|
||||||
modeluuid: item.modeluuid,
|
// modeluuid: item.modeluuid,
|
||||||
modelName: item.modelname,
|
// modelName: item.modelname,
|
||||||
type: 'Vehicle',
|
// type: 'Vehicle',
|
||||||
point: {
|
// point: {
|
||||||
uuid: pointUUID,
|
// uuid: pointUUID,
|
||||||
position: [pointPosition.x, pointPosition.y, pointPosition.z],
|
// position: [pointPosition.x, pointPosition.y, pointPosition.z],
|
||||||
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Start', start: {}, hitCount: 1, end: {}, buffer: 0 },
|
// actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Start', start: {}, hitCount: 1, end: {}, buffer: 0 },
|
||||||
connections: { source: { pathUUID: item.modeluuid, pointUUID: pointUUID }, targets: [] },
|
// connections: { source: { pathUUID: item.modeluuid, pointUUID: pointUUID }, targets: [] },
|
||||||
speed: 2,
|
// speed: 2,
|
||||||
},
|
// },
|
||||||
position: [...item.position],
|
// position: [...item.position],
|
||||||
};
|
// };
|
||||||
|
|
||||||
newPaths.push(newVehiclePath);
|
// newPaths.push(newVehiclePath);
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
setSimulationPaths(newPaths);
|
// setSimulationPaths(newPaths);
|
||||||
|
// console.log('floorItems: ', floorItems);
|
||||||
}, [floorItems]);
|
}, [floorItems]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -69,7 +69,6 @@ const MAX_SPAWNED_OBJECTS = 20;
|
||||||
const ProcessAnimator: React.FC<{ processes: ProcessData[] }> = ({
|
const ProcessAnimator: React.FC<{ processes: ProcessData[] }> = ({
|
||||||
processes,
|
processes,
|
||||||
}) => {
|
}) => {
|
||||||
console.log("processes: ", processes);
|
|
||||||
const gltf = useLoader(GLTFLoader, boxGltb) as GLTF;
|
const gltf = useLoader(GLTFLoader, boxGltb) as GLTF;
|
||||||
const { isPlaying, setIsPlaying } = usePlayButtonStore();
|
const { isPlaying, setIsPlaying } = usePlayButtonStore();
|
||||||
|
|
||||||
|
@ -321,10 +320,10 @@ const ProcessAnimator: React.FC<{ processes: ProcessData[] }> = ({
|
||||||
spawnedObjectsRef.current.push(newObject);
|
spawnedObjectsRef.current.push(newObject);
|
||||||
|
|
||||||
// Clean up old objects if needed
|
// Clean up old objects if needed
|
||||||
console.log(
|
// console.log(
|
||||||
"spawnedObjectsRef.current.length: ",
|
// "spawnedObjectsRef.current.length: ",
|
||||||
spawnedObjectsRef.current.length
|
// spawnedObjectsRef.current.length
|
||||||
);
|
// );
|
||||||
if (spawnedObjectsRef.current.length > MAX_SPAWNED_OBJECTS) {
|
if (spawnedObjectsRef.current.length > MAX_SPAWNED_OBJECTS) {
|
||||||
const oldest = spawnedObjectsRef.current.shift();
|
const oldest = spawnedObjectsRef.current.shift();
|
||||||
if (oldest && groupRef.current.children.includes(oldest)) {
|
if (oldest && groupRef.current.children.includes(oldest)) {
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||||
|
|
||||||
|
export const setEventApi = async (
|
||||||
|
organization: string,
|
||||||
|
modeluuid: string,
|
||||||
|
eventData: any
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const body: any = { organization, modeluuid, eventData };
|
||||||
|
|
||||||
|
const response = await fetch(`${url_Backend_dwinzo}/api/v2/eventDataUpdate`, {
|
||||||
|
method: "PATCH",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Failed to set or update Floor Item");
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
throw new Error(error.message);
|
||||||
|
} else {
|
||||||
|
throw new Error("An unknown error occurred");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -30,7 +30,6 @@ export const setFloorItemApi = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
console.log('result: ', result);
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
|
|
|
@ -343,14 +343,21 @@ export const useSelectedPath = create<any>((set: any) => ({
|
||||||
interface SimulationPathsStore {
|
interface SimulationPathsStore {
|
||||||
simulationPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[];
|
simulationPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[];
|
||||||
setSimulationPaths: (
|
setSimulationPaths: (
|
||||||
paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]
|
paths:
|
||||||
|
| (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]
|
||||||
|
| ((prev: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]
|
||||||
|
) => (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[])
|
||||||
) => void;
|
) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useSimulationPaths = create<SimulationPathsStore>((set) => ({
|
export const useSimulationPaths = create<SimulationPathsStore>((set) => ({
|
||||||
simulationPaths: [],
|
simulationPaths: [],
|
||||||
setSimulationPaths: (paths) => set({ simulationPaths: paths }),
|
setSimulationPaths: (paths) =>
|
||||||
}));
|
set((state) => ({
|
||||||
|
simulationPaths:
|
||||||
|
typeof paths === "function" ? paths(state.simulationPaths) : paths,
|
||||||
|
})),
|
||||||
|
}))
|
||||||
|
|
||||||
export const useIsConnecting = create<any>((set: any) => ({
|
export const useIsConnecting = create<any>((set: any) => ({
|
||||||
isConnecting: false,
|
isConnecting: false,
|
||||||
|
|
Loading…
Reference in New Issue