Merge remote-tracking branch 'origin/feature/agv-edit' into main-demo
This commit is contained in:
47
app/package-lock.json
generated
47
app/package-lock.json
generated
@@ -2026,7 +2026,7 @@
|
|||||||
"version": "0.8.1",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/trace-mapping": "0.3.9"
|
"@jridgewell/trace-mapping": "0.3.9"
|
||||||
},
|
},
|
||||||
@@ -2038,7 +2038,7 @@
|
|||||||
"version": "0.3.9",
|
"version": "0.3.9",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/resolve-uri": "^3.0.3",
|
"@jridgewell/resolve-uri": "^3.0.3",
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||||
@@ -4180,6 +4180,25 @@
|
|||||||
"url": "https://github.com/sponsors/gregberge"
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@testing-library/dom": {
|
||||||
|
"version": "10.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
|
||||||
|
"integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/code-frame": "^7.10.4",
|
||||||
|
"@babel/runtime": "^7.12.5",
|
||||||
|
"@types/aria-query": "^5.0.1",
|
||||||
|
"aria-query": "5.3.0",
|
||||||
|
"chalk": "^4.1.0",
|
||||||
|
"dom-accessibility-api": "^0.5.9",
|
||||||
|
"lz-string": "^1.5.0",
|
||||||
|
"pretty-format": "^27.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@testing-library/jest-dom": {
|
"node_modules/@testing-library/jest-dom": {
|
||||||
"version": "5.17.0",
|
"version": "5.17.0",
|
||||||
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
|
||||||
@@ -4291,25 +4310,25 @@
|
|||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
||||||
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
|
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@tsconfig/node12": {
|
"node_modules/@tsconfig/node12": {
|
||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@tsconfig/node14": {
|
"node_modules/@tsconfig/node14": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@tsconfig/node16": {
|
"node_modules/@tsconfig/node16": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
||||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@turf/along": {
|
"node_modules/@turf/along": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
@@ -9063,7 +9082,7 @@
|
|||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/cross-env": {
|
"node_modules/cross-env": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
@@ -9940,7 +9959,7 @@
|
|||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.3.1"
|
"node": ">=0.3.1"
|
||||||
}
|
}
|
||||||
@@ -15324,7 +15343,7 @@
|
|||||||
"version": "1.3.6",
|
"version": "1.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/makeerror": {
|
"node_modules/makeerror": {
|
||||||
"version": "1.0.12",
|
"version": "1.0.12",
|
||||||
@@ -20801,7 +20820,7 @@
|
|||||||
"version": "10.9.2",
|
"version": "10.9.2",
|
||||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||||
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cspotcode/source-map-support": "^0.8.0",
|
"@cspotcode/source-map-support": "^0.8.0",
|
||||||
"@tsconfig/node10": "^1.0.7",
|
"@tsconfig/node10": "^1.0.7",
|
||||||
@@ -20844,7 +20863,7 @@
|
|||||||
"version": "8.3.4",
|
"version": "8.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
|
||||||
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
|
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": "^8.11.0"
|
"acorn": "^8.11.0"
|
||||||
},
|
},
|
||||||
@@ -20856,7 +20875,7 @@
|
|||||||
"version": "4.1.3",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/tsconfig-paths": {
|
"node_modules/tsconfig-paths": {
|
||||||
"version": "3.15.0",
|
"version": "3.15.0",
|
||||||
@@ -21352,7 +21371,7 @@
|
|||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/v8-to-istanbul": {
|
"node_modules/v8-to-istanbul": {
|
||||||
"version": "8.1.1",
|
"version": "8.1.1",
|
||||||
@@ -22411,7 +22430,7 @@
|
|||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,9 +38,11 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
|
|||||||
|
|
||||||
const handleCreateNewProject = async () => {
|
const handleCreateNewProject = async () => {
|
||||||
const token = localStorage.getItem("token");
|
const token = localStorage.getItem("token");
|
||||||
|
const refreshToken = localStorage.getItem("refreshToken")
|
||||||
|
console.log('refreshToken: ', refreshToken);
|
||||||
try {
|
try {
|
||||||
const projectId = generateProjectId();
|
const projectId = generateProjectId();
|
||||||
useSocketStore.getState().initializeSocket(email, organization, token);
|
useSocketStore.getState().initializeSocket(email, organization, token, refreshToken);
|
||||||
|
|
||||||
//API for creating new Project
|
//API for creating new Project
|
||||||
// const project = await createProject(
|
// const project = await createProject(
|
||||||
@@ -56,7 +58,8 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
|
|||||||
organization: organization,
|
organization: organization,
|
||||||
projectUuid: projectId,
|
projectUuid: projectId,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log('projectSocket: ', projectSocket);
|
||||||
if (projectSocket) {
|
if (projectSocket) {
|
||||||
const handleResponse = (data: any) => {
|
const handleResponse = (data: any) => {
|
||||||
if (data.message === "Project created successfully") {
|
if (data.message === "Project created successfully") {
|
||||||
|
|||||||
@@ -12,13 +12,17 @@ import { zoneCameraUpdate } from "../../../../services/visulization/zone/zoneCam
|
|||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { getUserData } from "../../../../functions/getUserData";
|
import { getUserData } from "../../../../functions/getUserData";
|
||||||
import { useVersionContext } from "../../../../modules/builder/version/versionContext";
|
import { useVersionContext } from "../../../../modules/builder/version/versionContext";
|
||||||
|
import { useSceneContext } from "../../../../modules/scene/sceneContext";
|
||||||
|
|
||||||
const ZoneProperties: React.FC = () => {
|
const ZoneProperties: React.FC = () => {
|
||||||
const { Edit, setEdit } = useEditPosition();
|
const { Edit, setEdit } = useEditPosition();
|
||||||
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||||
const { zonePosition, setZonePosition } = usezonePosition();
|
const { zonePosition, setZonePosition } = usezonePosition();
|
||||||
const { zoneTarget, setZoneTarget } = usezoneTarget();
|
const { zoneTarget, setZoneTarget } = usezoneTarget();
|
||||||
const { zones, setZones } = useZones();
|
// const { zones, setZones } = useZones();
|
||||||
|
const { assetStore, zoneStore } = useSceneContext();
|
||||||
|
const { zones, setZoneName } = zoneStore()
|
||||||
|
|
||||||
const { projectId } = useParams();
|
const { projectId } = useParams();
|
||||||
const { userName, userId, organization, email } = getUserData();
|
const { userName, userId, organization, email } = getUserData();
|
||||||
const { selectedVersionStore } = useVersionContext();
|
const { selectedVersionStore } = useVersionContext();
|
||||||
@@ -34,10 +38,11 @@ const ZoneProperties: React.FC = () => {
|
|||||||
|
|
||||||
let zonesdata = {
|
let zonesdata = {
|
||||||
zoneUuid: selectedZone.zoneUuid,
|
zoneUuid: selectedZone.zoneUuid,
|
||||||
viewPortposition: zonePosition,
|
viewPortPosition: zonePosition,
|
||||||
viewPortCenter: zoneTarget,
|
viewPortTarget: zoneTarget,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
let response = await zoneCameraUpdate(zonesdata, organization, projectId, selectedVersion?.versionId || "");
|
let response = await zoneCameraUpdate(zonesdata, organization, projectId, selectedVersion?.versionId || "");
|
||||||
// console.log('response: ', response);
|
// console.log('response: ', response);
|
||||||
if (response.message === "zone updated") {
|
if (response.message === "zone updated") {
|
||||||
@@ -63,13 +68,14 @@ const ZoneProperties: React.FC = () => {
|
|||||||
let response = await zoneCameraUpdate(zonesdata, organization, projectId, selectedVersion?.versionId || "");
|
let response = await zoneCameraUpdate(zonesdata, organization, projectId, selectedVersion?.versionId || "");
|
||||||
if (response.message === "zone updated") {
|
if (response.message === "zone updated") {
|
||||||
setSelectedZone((prev) => ({ ...prev, zoneName: newName }));
|
setSelectedZone((prev) => ({ ...prev, zoneName: newName }));
|
||||||
setZones((prevZones: any[]) =>
|
setZoneName(selectedZone.zoneUuid, newName)
|
||||||
prevZones.map((zone) =>
|
// setZones((prevZones: any[]) =>
|
||||||
zone.zoneUuid === selectedZone.zoneUuid
|
// prevZones.map((zone) =>
|
||||||
? { ...zone, zoneName: newName }
|
// zone.zoneUuid === selectedZone.zoneUuid
|
||||||
: zone
|
// ? { ...zone, zoneName: newName }
|
||||||
)
|
// : zone
|
||||||
);
|
// )
|
||||||
|
// );
|
||||||
} else {
|
} else {
|
||||||
// console.log(response?.message);
|
// console.log(response?.message);
|
||||||
}
|
}
|
||||||
@@ -81,6 +87,7 @@ const ZoneProperties: React.FC = () => {
|
|||||||
setSelectedZone((prev) => ({ ...prev, [key]: newValue }));
|
setSelectedZone((prev) => ({ ...prev, [key]: newValue }));
|
||||||
}
|
}
|
||||||
const checkZoneNameDuplicate = (name: string) => {
|
const checkZoneNameDuplicate = (name: string) => {
|
||||||
|
console.log('zones: ', zones);
|
||||||
return zones.some(
|
return zones.some(
|
||||||
(zone: any) =>
|
(zone: any) =>
|
||||||
zone.zoneName?.trim().toLowerCase() === name?.trim().toLowerCase() &&
|
zone.zoneName?.trim().toLowerCase() === name?.trim().toLowerCase() &&
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ const EventProperties: React.FC = () => {
|
|||||||
const { selectedVersionStore } = useVersionContext();
|
const { selectedVersionStore } = useVersionContext();
|
||||||
const { selectedVersion } = selectedVersionStore();
|
const { selectedVersion } = selectedVersionStore();
|
||||||
const { projectId } = useParams();
|
const { projectId } = useParams();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const event = getCurrentEventData();
|
const event = getCurrentEventData();
|
||||||
setCurrentEventData(event);
|
setCurrentEventData(event);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { useProductContext } from "../../../../../../modules/simulation/products
|
|||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
|
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
|
||||||
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||||
|
import { useSelectedPath } from "../../../../../../store/builder/store";
|
||||||
|
|
||||||
function VehicleMechanics() {
|
function VehicleMechanics() {
|
||||||
const [activeOption, setActiveOption] = useState<"default" | "travel">("default");
|
const [activeOption, setActiveOption] = useState<"default" | "travel">("default");
|
||||||
@@ -27,6 +28,7 @@ function VehicleMechanics() {
|
|||||||
const { selectedVersionStore } = useVersionContext();
|
const { selectedVersionStore } = useVersionContext();
|
||||||
const { selectedVersion } = selectedVersionStore();
|
const { selectedVersion } = selectedVersionStore();
|
||||||
const { projectId } = useParams();
|
const { projectId } = useParams();
|
||||||
|
const { selectedPath, setSelectedPath } = useSelectedPath();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedEventData && selectedEventData.data.type === "vehicle") {
|
if (selectedEventData && selectedEventData.data.type === "vehicle") {
|
||||||
@@ -282,9 +284,34 @@ function VehicleMechanics() {
|
|||||||
type={"Vehicle"}
|
type={"Vehicle"}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div style={{ display: "flex", gap: "10px", flexDirection: "column", alignItems: "center" }}>
|
||||||
|
<button style={{
|
||||||
|
backgroundColor: "#6f42c1",
|
||||||
|
color: "#f3f3fd",
|
||||||
|
borderRadius: "15px",
|
||||||
|
height: "30px",
|
||||||
|
width: "150px",
|
||||||
|
border: "none",
|
||||||
|
cursor: "pointer",
|
||||||
|
padding: "0 5px",
|
||||||
|
|
||||||
|
}} onClick={() => setSelectedPath("auto")}>Auto Generate Path</button>
|
||||||
|
<button style={{
|
||||||
|
backgroundColor: "#6f42c1",
|
||||||
|
color: "#f3f3fd",
|
||||||
|
borderRadius: "15px",
|
||||||
|
height: "30px",
|
||||||
|
width: "150px",
|
||||||
|
border: "none",
|
||||||
|
cursor: "pointer",
|
||||||
|
padding: "0 5px",
|
||||||
|
|
||||||
|
}} onClick={() => setSelectedPath("manual")}>Create Path</button>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</>
|
</>
|
||||||
)}
|
)
|
||||||
|
}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,16 +44,19 @@ const DropDownList: React.FC<DropDownListProps> = ({
|
|||||||
remove,
|
remove,
|
||||||
}) => {
|
}) => {
|
||||||
const [isOpen, setIsOpen] = useState<boolean>(defaultOpen);
|
const [isOpen, setIsOpen] = useState<boolean>(defaultOpen);
|
||||||
const { zones } = useZones();
|
// const { zones } = useZones();
|
||||||
|
|
||||||
const handleToggle = () => {
|
const handleToggle = () => {
|
||||||
setIsOpen((prev) => !prev); // Toggle the state
|
setIsOpen((prev) => !prev); // Toggle the state
|
||||||
};
|
};
|
||||||
|
|
||||||
const [zoneDataList, setZoneDataList] = useState<ZoneData[]>([]);
|
const [zoneDataList, setZoneDataList] = useState<ZoneData[]>([]);
|
||||||
const { assetStore } = useSceneContext();
|
// const { assetStore } = useSceneContext();
|
||||||
|
const { assetStore, zoneStore } = useSceneContext();
|
||||||
const { assets } = assetStore();
|
const { assets } = assetStore();
|
||||||
|
const { zones } = zoneStore()
|
||||||
|
|
||||||
|
|
||||||
const isPointInsidePolygon = (
|
const isPointInsidePolygon = (
|
||||||
point: [number, number],
|
point: [number, number],
|
||||||
polygon: [number, number][]
|
polygon: [number, number][]
|
||||||
@@ -76,7 +79,7 @@ const DropDownList: React.FC<DropDownListProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const updatedZoneList: ZoneData[] = zones?.map((zone: Zone) => {
|
const updatedZoneList: ZoneData[] = zones?.map((zone: any) => {
|
||||||
const polygon2D = zone.points.map((p: [number, number, number]) => [
|
const polygon2D = zone.points.map((p: [number, number, number]) => [
|
||||||
p[0],
|
p[0],
|
||||||
p[2],
|
p[2],
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
|||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||||
const { zoneAssetId, setZoneAssetId } = useZoneAssetId();
|
const { zoneAssetId, setZoneAssetId } = useZoneAssetId();
|
||||||
const { zones, setZones } = useZones();
|
|
||||||
const { setSubModule } = useSubModuleStore();
|
const { setSubModule } = useSubModuleStore();
|
||||||
const [expandedZones, setExpandedZones] = useState<Record<string, boolean>>({});
|
const [expandedZones, setExpandedZones] = useState<Record<string, boolean>>({});
|
||||||
const { projectId } = useParams();
|
const { projectId } = useParams();
|
||||||
@@ -55,6 +55,8 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
|||||||
const { organization } = getUserData();
|
const { organization } = getUserData();
|
||||||
const { selectedVersionStore } = useVersionContext();
|
const { selectedVersionStore } = useVersionContext();
|
||||||
const { selectedVersion } = selectedVersionStore();
|
const { selectedVersion } = selectedVersionStore();
|
||||||
|
const { zoneStore } = useSceneContext();
|
||||||
|
const { zones, setZoneName } = zoneStore()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
useSelectedZoneStore.getState().setSelectedZone({
|
useSelectedZoneStore.getState().setSelectedZone({
|
||||||
@@ -92,8 +94,8 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
|||||||
lockedPanels: response?.lockedPanels ?? [],
|
lockedPanels: response?.lockedPanels ?? [],
|
||||||
widgets: response?.widgets ?? [],
|
widgets: response?.widgets ?? [],
|
||||||
zoneUuid: response?.zoneUuid,
|
zoneUuid: response?.zoneUuid,
|
||||||
zoneViewPortTarget: response?.viewPortCenter ?? [],
|
zoneViewPortTarget: response?.viewPortTarget ?? [],
|
||||||
zoneViewPortPosition: response?.viewPortposition ?? [],
|
zoneViewPortPosition: response?.viewPortPosition ?? [],
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
echo.error("Failed to select zone");
|
echo.error("Failed to select zone");
|
||||||
@@ -123,13 +125,14 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
|||||||
const response = await zoneCameraUpdate(zonesdata, organization, projectId, selectedVersion?.versionId || "");
|
const response = await zoneCameraUpdate(zonesdata, organization, projectId, selectedVersion?.versionId || "");
|
||||||
if (response.message === "zone updated") {
|
if (response.message === "zone updated") {
|
||||||
setSelectedZone((prev) => ({ ...prev, zoneName: newName }));
|
setSelectedZone((prev) => ({ ...prev, zoneName: newName }));
|
||||||
setZones((prevZones: any[]) =>
|
setZoneName(selectedZone.zoneUuid, newName)
|
||||||
prevZones.map((zone) =>
|
// setZones((prevZones: any[]) =>
|
||||||
zone.zoneUuid === selectedZone.zoneUuid
|
// prevZones.map((zone) =>
|
||||||
? { ...zone, zoneName: newName }
|
// zone.zoneUuid === selectedZone.zoneUuid
|
||||||
: zone
|
// ? { ...zone, zoneName: newName }
|
||||||
)
|
// : zone
|
||||||
);
|
// )
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
useToolMode,
|
useToolMode,
|
||||||
useRenderDistance,
|
useRenderDistance,
|
||||||
useLimitDistance,
|
useLimitDistance,
|
||||||
|
useLoadingProgress,
|
||||||
} from "../../store/builder/store";
|
} from "../../store/builder/store";
|
||||||
|
|
||||||
////////// 3D Function Imports //////////
|
////////// 3D Function Imports //////////
|
||||||
@@ -56,6 +57,7 @@ export default function Builder() {
|
|||||||
const { projectId } = useParams();
|
const { projectId } = useParams();
|
||||||
const { setHoveredPoint, setHoveredLine } = useBuilderStore();
|
const { setHoveredPoint, setHoveredLine } = useBuilderStore();
|
||||||
const { userId, organization } = getUserData();
|
const { userId, organization } = getUserData();
|
||||||
|
const { loadingProgress } = useLoadingProgress();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!toggleView) {
|
if (!toggleView) {
|
||||||
@@ -115,8 +117,7 @@ export default function Builder() {
|
|||||||
|
|
||||||
<CalculateAreaGroup />
|
<CalculateAreaGroup />
|
||||||
|
|
||||||
<NavMesh />
|
{loadingProgress == 0 && <NavMesh />}
|
||||||
|
|
||||||
<DxfFile />
|
<DxfFile />
|
||||||
|
|
||||||
<LayoutImage />
|
<LayoutImage />
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ function ZoneCreator() {
|
|||||||
const { activeLayer } = useActiveLayer();
|
const { activeLayer } = useActiveLayer();
|
||||||
const { socket } = useSocketStore();
|
const { socket } = useSocketStore();
|
||||||
const { zoneStore } = useSceneContext();
|
const { zoneStore } = useSceneContext();
|
||||||
const { addZone, getZonePointById, getZoneByPoints } = zoneStore();
|
const { zones, addZone, getZonePointById, getZoneByPoints } = zoneStore();
|
||||||
const drag = useRef(false);
|
const drag = useRef(false);
|
||||||
const isLeftMouseDown = useRef(false);
|
const isLeftMouseDown = useRef(false);
|
||||||
const { selectedVersionStore } = useVersionContext();
|
const { selectedVersionStore } = useVersionContext();
|
||||||
@@ -32,6 +32,7 @@ function ZoneCreator() {
|
|||||||
const [isCreating, setIsCreating] = useState(false);
|
const [isCreating, setIsCreating] = useState(false);
|
||||||
const { zoneColor, zoneHeight, snappedPosition, snappedPoint, setSnappedPoint, setSnappedPosition } = useBuilderStore();
|
const { zoneColor, zoneHeight, snappedPosition, snappedPoint, setSnappedPoint, setSnappedPosition } = useBuilderStore();
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const canvasElement = gl.domElement;
|
const canvasElement = gl.domElement;
|
||||||
|
|
||||||
@@ -92,7 +93,7 @@ function ZoneCreator() {
|
|||||||
if (tempPoints.length > 2 && isCreating && snappedPoint && snappedPoint.pointUuid === tempPoints[0].pointUuid) {
|
if (tempPoints.length > 2 && isCreating && snappedPoint && snappedPoint.pointUuid === tempPoints[0].pointUuid) {
|
||||||
const zone: Zone = {
|
const zone: Zone = {
|
||||||
zoneUuid: THREE.MathUtils.generateUUID(),
|
zoneUuid: THREE.MathUtils.generateUUID(),
|
||||||
zoneName: "Zone",
|
zoneName: `Zone `,
|
||||||
points: tempPoints,
|
points: tempPoints,
|
||||||
zoneColor,
|
zoneColor,
|
||||||
zoneHeight,
|
zoneHeight,
|
||||||
|
|||||||
@@ -0,0 +1,328 @@
|
|||||||
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
import * as THREE from 'three';
|
||||||
|
import { Canvas, useThree, useFrame, ThreeEvent } from '@react-three/fiber';
|
||||||
|
import { Line, OrbitControls } from '@react-three/drei';
|
||||||
|
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||||
|
import { useActiveTool, useSelectedPath } from '../../../../../store/builder/store';
|
||||||
|
|
||||||
|
interface InteractivePointsProps {
|
||||||
|
agvUuid: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default function InteractivePoints({ agvUuid }: InteractivePointsProps) {
|
||||||
|
const { gl, scene, raycaster } = useThree();
|
||||||
|
const [points, setPoints] = useState<[number, number, number][]>([]);
|
||||||
|
const { isPaused } = usePauseButtonStore();
|
||||||
|
const { isPlaying } = usePlayButtonStore();
|
||||||
|
const { speed } = useAnimationPlaySpeed();
|
||||||
|
const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0)); // XZ plane
|
||||||
|
const progressRef = useRef<number>(0);
|
||||||
|
const { selectedPath } = useSelectedPath();
|
||||||
|
const lastTimeRef = useRef(performance.now());
|
||||||
|
const [isAnyDragging, setIsAnyDragging] = useState<string>("");
|
||||||
|
const { activeTool } = useActiveTool();
|
||||||
|
const hasClicked = useRef(false);
|
||||||
|
|
||||||
|
useFrame(() => {
|
||||||
|
if (!isPlaying) return
|
||||||
|
const now = performance.now();
|
||||||
|
const delta = (now - lastTimeRef.current) / 1000;
|
||||||
|
lastTimeRef.current = now;
|
||||||
|
|
||||||
|
const object = scene.getObjectByProperty('uuid', agvUuid);
|
||||||
|
if (!object || points.length < 2) return;
|
||||||
|
if (isPaused) return;
|
||||||
|
|
||||||
|
let totalDistance = 0;
|
||||||
|
const distances = [];
|
||||||
|
let accumulatedDistance = 0;
|
||||||
|
let index = 0;
|
||||||
|
const rotationSpeed = 1;
|
||||||
|
|
||||||
|
for (let i = 0; i < points.length - 1; i++) {
|
||||||
|
const start = new THREE.Vector3(...points[i]);
|
||||||
|
const end = new THREE.Vector3(...points[i + 1]);
|
||||||
|
const segmentDistance = start.distanceTo(end);
|
||||||
|
distances.push(segmentDistance);
|
||||||
|
totalDistance += segmentDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (index < distances.length && progressRef.current > accumulatedDistance + distances[index]) {
|
||||||
|
accumulatedDistance += distances[index];
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < distances.length) {
|
||||||
|
const start = new THREE.Vector3(...points[index]);
|
||||||
|
const end = new THREE.Vector3(...points[index + 1]);
|
||||||
|
const segmentDistance = distances[index];
|
||||||
|
|
||||||
|
const currentDirection = new THREE.Vector3().subVectors(end, start).normalize();
|
||||||
|
const targetAngle = Math.atan2(currentDirection.x, currentDirection.z);
|
||||||
|
const currentAngle = object.rotation.y;
|
||||||
|
|
||||||
|
let angleDifference = targetAngle - currentAngle;
|
||||||
|
if (angleDifference > Math.PI) angleDifference -= 2 * Math.PI;
|
||||||
|
if (angleDifference < -Math.PI) angleDifference += 2 * Math.PI;
|
||||||
|
|
||||||
|
const maxRotationStep = (rotationSpeed * speed * 2) * delta;
|
||||||
|
object.rotation.y += Math.sign(angleDifference) * Math.min(Math.abs(angleDifference), maxRotationStep);
|
||||||
|
const isAligned = Math.abs(angleDifference) < 0.01;
|
||||||
|
|
||||||
|
if (isAligned) {
|
||||||
|
progressRef.current += delta * (speed * 2);
|
||||||
|
const t = (progressRef.current - accumulatedDistance) / segmentDistance;
|
||||||
|
const position = start.clone().lerp(end, t);
|
||||||
|
object.position.copy(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const downPosition = useRef<{ x: number; y: number } | null>(null);
|
||||||
|
|
||||||
|
const handleMouseDown = useCallback((e: MouseEvent) => {
|
||||||
|
hasClicked.current = false;
|
||||||
|
downPosition.current = { x: e.clientX, y: e.clientY };
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleClick = useCallback((e: MouseEvent) => {
|
||||||
|
if (hasClicked.current) return;
|
||||||
|
hasClicked.current = true;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!downPosition.current ||
|
||||||
|
Math.abs(downPosition.current.x - e.clientX) > 2 ||
|
||||||
|
Math.abs(downPosition.current.y - e.clientY) > 2
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const intersection = new THREE.Vector3();
|
||||||
|
if (raycaster.ray.intersectPlane(plane.current, intersection) && activeTool !== "pen") {
|
||||||
|
const pointArray = intersection.toArray() as [number, number, number];
|
||||||
|
|
||||||
|
// ✅ Check if this point already exists
|
||||||
|
const alreadyExists = points.some((p) =>
|
||||||
|
Math.abs(p[0] - pointArray[0]) < 0.01 &&
|
||||||
|
Math.abs(p[1] - pointArray[1]) < 0.01 &&
|
||||||
|
Math.abs(p[2] - pointArray[2]) < 0.01
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!alreadyExists) {
|
||||||
|
console.log("pointArray: ", pointArray);
|
||||||
|
setPoints((prev) => [...prev, pointArray]);
|
||||||
|
console.log("points created");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [activeTool, raycaster, points]);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isPlaying) return;
|
||||||
|
const domElement = gl.domElement;
|
||||||
|
|
||||||
|
domElement.addEventListener('mousedown', handleMouseDown);
|
||||||
|
domElement.addEventListener('mouseup', handleClick);
|
||||||
|
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
domElement.removeEventListener('mousedown', handleMouseDown);
|
||||||
|
domElement.removeEventListener('mouseup', handleClick);
|
||||||
|
;
|
||||||
|
};
|
||||||
|
}, [isPlaying, handleClick, handleMouseDown]);
|
||||||
|
|
||||||
|
|
||||||
|
const updatePoint = (index: number, pos: THREE.Vector3) => {
|
||||||
|
const updated = [...points];
|
||||||
|
updated[index] = pos.toArray() as [number, number, number];
|
||||||
|
setPoints(updated);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{selectedPath === "manual" &&
|
||||||
|
<group>
|
||||||
|
{points.length > 0 && (
|
||||||
|
<group >
|
||||||
|
{points.map((pos, i) =>
|
||||||
|
(<React.Fragment key={i}>
|
||||||
|
<DraggableSphere
|
||||||
|
key={i}
|
||||||
|
index={i}
|
||||||
|
position={new THREE.Vector3(...pos)}
|
||||||
|
onMove={updatePoint}
|
||||||
|
isAnyDragging={isAnyDragging}
|
||||||
|
setIsAnyDragging={setIsAnyDragging}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</React.Fragment>)
|
||||||
|
|
||||||
|
|
||||||
|
)}
|
||||||
|
</group >
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{points && (
|
||||||
|
points.map((pos, i) => {
|
||||||
|
if (i < points.length - 1) {
|
||||||
|
return (
|
||||||
|
<DraggableLineSegment
|
||||||
|
key={i}
|
||||||
|
index={i}
|
||||||
|
start={new THREE.Vector3(...points[i])}
|
||||||
|
end={new THREE.Vector3(...points[i + 1])}
|
||||||
|
updatePoints={(i0, p0, i1, p1) => {
|
||||||
|
const updated = [...points];
|
||||||
|
updated[i0] = p0.toArray() as [number, number, number];
|
||||||
|
updated[i1] = p1.toArray() as [number, number, number];
|
||||||
|
setPoints(updated);
|
||||||
|
}}
|
||||||
|
isAnyDragging={isAnyDragging}
|
||||||
|
setIsAnyDragging={setIsAnyDragging}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
)}
|
||||||
|
</group>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function DraggableSphere({
|
||||||
|
index,
|
||||||
|
position,
|
||||||
|
onMove,
|
||||||
|
isAnyDragging,
|
||||||
|
setIsAnyDragging,
|
||||||
|
}: {
|
||||||
|
index: number;
|
||||||
|
position: THREE.Vector3;
|
||||||
|
onMove: (index: number, pos: THREE.Vector3) => void;
|
||||||
|
isAnyDragging: string;
|
||||||
|
setIsAnyDragging: (val: string) => void;
|
||||||
|
}) {
|
||||||
|
const meshRef = useRef<THREE.Mesh>(null);
|
||||||
|
const { gl, controls, raycaster } = useThree();
|
||||||
|
const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
|
||||||
|
const { activeTool } = useActiveTool();
|
||||||
|
|
||||||
|
const onPointerDown = (e: ThreeEvent<PointerEvent>) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
if (activeTool !== 'pen') return;
|
||||||
|
setIsAnyDragging("point");
|
||||||
|
gl.domElement.style.cursor = 'grabbing';
|
||||||
|
if (controls) (controls as any).enabled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPointerMove = (e: ThreeEvent<PointerEvent>) => {
|
||||||
|
if (isAnyDragging !== "point" || activeTool !== 'pen') return;
|
||||||
|
|
||||||
|
const intersect = new THREE.Vector3();
|
||||||
|
if (raycaster.ray.intersectPlane(plane, intersect)) {
|
||||||
|
meshRef.current!.position.copy(intersect);
|
||||||
|
onMove(index, intersect);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPointerUp = () => {
|
||||||
|
if (activeTool !== 'pen') return;
|
||||||
|
setIsAnyDragging("");
|
||||||
|
gl.domElement.style.cursor = 'default';
|
||||||
|
if (controls) (controls as any).enabled = true;
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
gl.domElement.addEventListener("pointerup", onPointerUp);
|
||||||
|
return (() => {
|
||||||
|
gl.domElement.removeEventListener("pointerup", onPointerUp);
|
||||||
|
})
|
||||||
|
}, [activeTool])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<mesh
|
||||||
|
ref={meshRef}
|
||||||
|
position={position}
|
||||||
|
onPointerDown={onPointerDown}
|
||||||
|
onPointerMove={onPointerMove}
|
||||||
|
onPointerUp={onPointerUp}
|
||||||
|
onPointerMissed={onPointerUp}
|
||||||
|
>
|
||||||
|
<sphereGeometry args={[0.2, 16, 16]} />
|
||||||
|
<meshStandardMaterial color="red" />
|
||||||
|
</mesh>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function DraggableLineSegment({
|
||||||
|
index,
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
updatePoints,
|
||||||
|
isAnyDragging,
|
||||||
|
setIsAnyDragging,
|
||||||
|
}: {
|
||||||
|
index: number;
|
||||||
|
start: THREE.Vector3;
|
||||||
|
end: THREE.Vector3;
|
||||||
|
updatePoints: (i0: number, p0: THREE.Vector3, i1: number, p1: THREE.Vector3) => void;
|
||||||
|
isAnyDragging: string;
|
||||||
|
setIsAnyDragging: (val: string) => void;
|
||||||
|
}) {
|
||||||
|
const { gl, raycaster, controls } = useThree();
|
||||||
|
const { activeTool } = useActiveTool();
|
||||||
|
const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
|
||||||
|
const dragStart = useRef<THREE.Vector3 | null>(null);
|
||||||
|
|
||||||
|
const onPointerDown = () => {
|
||||||
|
if (activeTool !== 'pen' || isAnyDragging) return;
|
||||||
|
setIsAnyDragging("line");
|
||||||
|
gl.domElement.style.cursor = 'grabbing';
|
||||||
|
if (controls) (controls as any).enabled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPointerMove = (e: ThreeEvent<PointerEvent>) => {
|
||||||
|
if (isAnyDragging !== "line" || activeTool !== 'pen') return;
|
||||||
|
|
||||||
|
const intersect = new THREE.Vector3();
|
||||||
|
if (raycaster.ray.intersectPlane(plane, intersect)) {
|
||||||
|
if (!dragStart.current) dragStart.current = intersect.clone();
|
||||||
|
const offset = new THREE.Vector3().subVectors(intersect, dragStart.current);
|
||||||
|
const newStart = start.clone().add(offset);
|
||||||
|
const newEnd = end.clone().add(offset);
|
||||||
|
updatePoints(index, newStart, index + 1, newEnd);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPointerUp = () => {
|
||||||
|
if (activeTool !== 'pen') return;
|
||||||
|
setIsAnyDragging("");
|
||||||
|
dragStart.current = null;
|
||||||
|
gl.domElement.style.cursor = 'default';
|
||||||
|
if (controls) (controls as any).enabled = true;
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
gl.domElement.addEventListener("pointerup", onPointerUp);
|
||||||
|
return (() => {
|
||||||
|
gl.domElement.removeEventListener("pointerup", onPointerUp);
|
||||||
|
})
|
||||||
|
}, [activeTool])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Line
|
||||||
|
points={[start, end]}
|
||||||
|
color="blue"
|
||||||
|
lineWidth={5}
|
||||||
|
onPointerDown={onPointerDown}
|
||||||
|
onPointerMove={onPointerMove}
|
||||||
|
onPointerUp={onPointerUp}
|
||||||
|
onPointerMissed={onPointerUp}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
import { useEffect, useRef, useState } from 'react'
|
|
||||||
import { useFrame, useThree } from '@react-three/fiber';
|
import React, { useEffect, useMemo, useRef, useState } from 'react'
|
||||||
|
import { useFrame, useThree, ThreeEvent } from '@react-three/fiber';
|
||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
import { Line } from '@react-three/drei';
|
import { Line, TransformControls } from '@react-three/drei';
|
||||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore';
|
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||||
|
import { useActiveTool, useSelectedPath } from '../../../../../store/builder/store';
|
||||||
|
|
||||||
|
|
||||||
interface VehicleAnimatorProps {
|
interface VehicleAnimatorProps {
|
||||||
path: [number, number, number][];
|
path: [number, number, number][];
|
||||||
@@ -28,10 +31,13 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
|
|||||||
const [objectRotation, setObjectRotation] = useState<{ x: number; y: number; z: number } | undefined>(agvDetail.point?.action?.pickUpPoint?.rotation || { x: 0, y: 0, z: 0 })
|
const [objectRotation, setObjectRotation] = useState<{ x: number; y: number; z: number } | undefined>(agvDetail.point?.action?.pickUpPoint?.rotation || { x: 0, y: 0, z: 0 })
|
||||||
const [restRotation, setRestingRotation] = useState<boolean>(true);
|
const [restRotation, setRestingRotation] = useState<boolean>(true);
|
||||||
const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]);
|
const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]);
|
||||||
const { scene } = useThree();
|
const { scene, controls } = useThree();
|
||||||
|
const { selectedPath } = useSelectedPath();
|
||||||
|
const [isAnyDragging, setIsAnyDragging] = useState<string>("");
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (currentPhase === 'stationed-pickup' && path.length > 0) {
|
if (currentPhase === 'stationed-pickup' && path.length > 0 && selectedPath === "auto") {
|
||||||
setCurrentPath(path);
|
setCurrentPath(path);
|
||||||
setObjectRotation(agvDetail.point.action?.pickUpPoint?.rotation)
|
setObjectRotation(agvDetail.point.action?.pickUpPoint?.rotation)
|
||||||
} else if (currentPhase === 'pickup-drop' && path.length > 0) {
|
} else if (currentPhase === 'pickup-drop' && path.length > 0) {
|
||||||
@@ -41,7 +47,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
|
|||||||
setObjectRotation(agvDetail.point.action?.pickUpPoint?.rotation)
|
setObjectRotation(agvDetail.point.action?.pickUpPoint?.rotation)
|
||||||
setCurrentPath(path);
|
setCurrentPath(path);
|
||||||
}
|
}
|
||||||
}, [currentPhase, path, objectRotation]);
|
}, [currentPhase, path, objectRotation, selectedPath]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
completedRef.current = false;
|
completedRef.current = false;
|
||||||
@@ -68,6 +74,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
|
|||||||
const lastTimeRef = useRef(performance.now());
|
const lastTimeRef = useRef(performance.now());
|
||||||
|
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
|
if (!isPlaying) return
|
||||||
const now = performance.now();
|
const now = performance.now();
|
||||||
const delta = (now - lastTimeRef.current) / 1000;
|
const delta = (now - lastTimeRef.current) / 1000;
|
||||||
lastTimeRef.current = now;
|
lastTimeRef.current = now;
|
||||||
@@ -146,26 +153,198 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
|
|||||||
handleCallBack();
|
handleCallBack();
|
||||||
if (currentPhase === 'pickup-drop') {
|
if (currentPhase === 'pickup-drop') {
|
||||||
requestAnimationFrame(startUnloadingProcess);
|
requestAnimationFrame(startUnloadingProcess);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const updatePoint = (index: number, pos: THREE.Vector3) => {
|
||||||
|
const updated = [...currentPath];
|
||||||
|
updated[index] = pos.toArray() as [number, number, number];
|
||||||
|
setCurrentPath(updated);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{currentPath.length > 0 && (
|
{selectedPath === "auto" && <group>
|
||||||
// helper
|
{currentPath.map((pos, i) => {
|
||||||
<group visible={false}>
|
if (i < currentPath.length - 1) {
|
||||||
<Line points={currentPath} color="blue" lineWidth={3} />
|
return (
|
||||||
{currentPath.map((point, index) => (
|
<DraggableLineSegment
|
||||||
<mesh key={index} position={point}>
|
key={i}
|
||||||
<sphereGeometry args={[0.1, 16, 16]} />
|
index={i}
|
||||||
<meshStandardMaterial color="red" />
|
start={new THREE.Vector3(...currentPath[i])}
|
||||||
</mesh>
|
end={new THREE.Vector3(...currentPath[i + 1])}
|
||||||
))}
|
updatePoints={(i0, p0, i1, p1) => {
|
||||||
</group>
|
const updated = [...currentPath];
|
||||||
)}
|
updated[i0] = p0.toArray() as [number, number, number];
|
||||||
|
updated[i1] = p1.toArray() as [number, number, number];
|
||||||
|
setCurrentPath(updated);
|
||||||
|
}}
|
||||||
|
isAnyDragging={isAnyDragging}
|
||||||
|
setIsAnyDragging={setIsAnyDragging}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})}
|
||||||
|
{currentPath.length > 0 && (
|
||||||
|
<group onPointerMissed={() => { if (controls) (controls as any).enabled = true; }}>
|
||||||
|
{currentPath.map((pos, i) =>
|
||||||
|
(
|
||||||
|
<DraggableSphere
|
||||||
|
key={i}
|
||||||
|
index={i}
|
||||||
|
position={new THREE.Vector3(...pos)}
|
||||||
|
onMove={updatePoint}
|
||||||
|
isAnyDragging={isAnyDragging}
|
||||||
|
setIsAnyDragging={setIsAnyDragging}
|
||||||
|
/>)
|
||||||
|
)}
|
||||||
|
</group >
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</group >
|
||||||
|
}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default VehicleAnimator;
|
|
||||||
|
|
||||||
|
export default VehicleAnimator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function DraggableSphere({
|
||||||
|
index,
|
||||||
|
position,
|
||||||
|
onMove,
|
||||||
|
isAnyDragging,
|
||||||
|
setIsAnyDragging,
|
||||||
|
}: {
|
||||||
|
index: number;
|
||||||
|
position: THREE.Vector3;
|
||||||
|
onMove: (index: number, pos: THREE.Vector3) => void;
|
||||||
|
isAnyDragging: string;
|
||||||
|
setIsAnyDragging: (val: string) => void;
|
||||||
|
}) {
|
||||||
|
const meshRef = useRef<THREE.Mesh>(null);
|
||||||
|
const { gl, controls, raycaster } = useThree();
|
||||||
|
const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
|
||||||
|
const { activeTool } = useActiveTool();
|
||||||
|
|
||||||
|
const onPointerDown = (e: ThreeEvent<PointerEvent>) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
if (activeTool !== 'pen') return;
|
||||||
|
setIsAnyDragging("point");
|
||||||
|
gl.domElement.style.cursor = 'grabbing';
|
||||||
|
if (controls) (controls as any).enabled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPointerMove = (e: ThreeEvent<PointerEvent>) => {
|
||||||
|
if (isAnyDragging !== "point" || activeTool !== 'pen') return;
|
||||||
|
|
||||||
|
const intersect = new THREE.Vector3();
|
||||||
|
if (raycaster.ray.intersectPlane(plane, intersect)) {
|
||||||
|
meshRef.current!.position.copy(intersect);
|
||||||
|
onMove(index, intersect);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPointerUp = () => {
|
||||||
|
if (activeTool !== 'pen') return;
|
||||||
|
setIsAnyDragging("");
|
||||||
|
gl.domElement.style.cursor = 'default';
|
||||||
|
if (controls) (controls as any).enabled = true;
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
gl.domElement.addEventListener("pointerup", onPointerUp);
|
||||||
|
return (() => {
|
||||||
|
gl.domElement.removeEventListener("pointerup", onPointerUp);
|
||||||
|
})
|
||||||
|
}, [activeTool])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<mesh
|
||||||
|
ref={meshRef}
|
||||||
|
position={position}
|
||||||
|
onPointerDown={onPointerDown}
|
||||||
|
onPointerMove={onPointerMove}
|
||||||
|
onPointerUp={onPointerUp}
|
||||||
|
onPointerMissed={onPointerUp}
|
||||||
|
>
|
||||||
|
<sphereGeometry args={[0.2, 16, 16]} />
|
||||||
|
<meshStandardMaterial color="red" />
|
||||||
|
</mesh>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function DraggableLineSegment({
|
||||||
|
index,
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
updatePoints,
|
||||||
|
isAnyDragging,
|
||||||
|
setIsAnyDragging,
|
||||||
|
}: {
|
||||||
|
index: number;
|
||||||
|
start: THREE.Vector3;
|
||||||
|
end: THREE.Vector3;
|
||||||
|
updatePoints: (i0: number, p0: THREE.Vector3, i1: number, p1: THREE.Vector3) => void;
|
||||||
|
isAnyDragging: string;
|
||||||
|
setIsAnyDragging: (val: string) => void;
|
||||||
|
}) {
|
||||||
|
const { gl, raycaster, controls } = useThree();
|
||||||
|
const { activeTool } = useActiveTool();
|
||||||
|
const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
|
||||||
|
const dragStart = useRef<THREE.Vector3 | null>(null);
|
||||||
|
|
||||||
|
const onPointerDown = () => {
|
||||||
|
if (activeTool !== 'pen' || isAnyDragging) return;
|
||||||
|
setIsAnyDragging("line");
|
||||||
|
gl.domElement.style.cursor = 'grabbing';
|
||||||
|
if (controls) (controls as any).enabled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPointerMove = (e: ThreeEvent<PointerEvent>) => {
|
||||||
|
console.log('isAnyDragging: ', isAnyDragging);
|
||||||
|
if (isAnyDragging !== "line" || activeTool !== 'pen') return;
|
||||||
|
|
||||||
|
const intersect = new THREE.Vector3();
|
||||||
|
if (raycaster.ray.intersectPlane(plane, intersect)) {
|
||||||
|
if (!dragStart.current) dragStart.current = intersect.clone();
|
||||||
|
const offset = new THREE.Vector3().subVectors(intersect, dragStart.current);
|
||||||
|
const newStart = start.clone().add(offset);
|
||||||
|
const newEnd = end.clone().add(offset);
|
||||||
|
updatePoints(index, newStart, index + 1, newEnd);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPointerUp = () => {
|
||||||
|
if (activeTool !== 'pen') return;
|
||||||
|
setIsAnyDragging("");
|
||||||
|
dragStart.current = null;
|
||||||
|
gl.domElement.style.cursor = 'default';
|
||||||
|
if (controls) (controls as any).enabled = true;
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
gl.domElement.addEventListener("pointerup", onPointerUp);
|
||||||
|
return (() => {
|
||||||
|
gl.domElement.removeEventListener("pointerup", onPointerUp);
|
||||||
|
})
|
||||||
|
}, [activeTool])
|
||||||
|
return (
|
||||||
|
<Line
|
||||||
|
points={[start, end]}
|
||||||
|
color="blue"
|
||||||
|
lineWidth={5}
|
||||||
|
onPointerDown={onPointerDown}
|
||||||
|
onPointerMove={onPointerMove}
|
||||||
|
onPointerUp={onPointerUp}
|
||||||
|
onPointerMissed={onPointerUp}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
import { NavMeshQuery } from '@recast-navigation/core';
|
import { NavMeshQuery } from '@recast-navigation/core';
|
||||||
import { useNavMesh } from '../../../../../store/builder/store';
|
import { useNavMesh, useSelectedPath } from '../../../../../store/builder/store';
|
||||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
|
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||||
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
|
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
|
||||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||||
import { useProductContext } from '../../../products/productContext';
|
import { useProductContext } from '../../../products/productContext';
|
||||||
|
import InteractivePoints from '../animator/interactivePoint';
|
||||||
|
|
||||||
import MaterialAnimator from '../animator/materialAnimator';
|
import MaterialAnimator from '../animator/materialAnimator';
|
||||||
import VehicleAnimator from '../animator/vehicleAnimator';
|
import VehicleAnimator from '../animator/vehicleAnimator';
|
||||||
@@ -24,7 +25,6 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||||||
const { selectedProductStore } = useProductContext();
|
const { selectedProductStore } = useProductContext();
|
||||||
const { selectedProduct } = selectedProductStore();
|
const { selectedProduct } = selectedProductStore();
|
||||||
const { vehicles, setVehicleActive, setVehicleState, setVehiclePicking, clearCurrentMaterials, setVehicleLoad, decrementVehicleLoad, removeLastMaterial, getLastMaterial, incrementIdleTime, incrementActiveTime, resetTime } = vehicleStore();
|
const { vehicles, setVehicleActive, setVehicleState, setVehiclePicking, clearCurrentMaterials, setVehicleLoad, decrementVehicleLoad, removeLastMaterial, getLastMaterial, incrementIdleTime, incrementActiveTime, resetTime } = vehicleStore();
|
||||||
|
|
||||||
const [currentPhase, setCurrentPhase] = useState<string>('stationed');
|
const [currentPhase, setCurrentPhase] = useState<string>('stationed');
|
||||||
const [path, setPath] = useState<[number, number, number][]>([]);
|
const [path, setPath] = useState<[number, number, number][]>([]);
|
||||||
const pauseTimeRef = useRef<number | null>(null);
|
const pauseTimeRef = useRef<number | null>(null);
|
||||||
@@ -38,6 +38,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||||||
const { isPaused } = usePauseButtonStore();
|
const { isPaused } = usePauseButtonStore();
|
||||||
const previousTimeRef = useRef<number | null>(null);
|
const previousTimeRef = useRef<number | null>(null);
|
||||||
const animationFrameIdRef = useRef<number | null>(null);
|
const animationFrameIdRef = useRef<number | null>(null);
|
||||||
|
const { selectedPath, setSelectedPath } = useSelectedPath();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
isPausedRef.current = isPaused;
|
isPausedRef.current = isPaused;
|
||||||
@@ -57,12 +58,14 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||||||
Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(end.x) &&
|
Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(end.x) &&
|
||||||
Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(end.z)
|
Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(end.z)
|
||||||
) {
|
) {
|
||||||
|
console.log('segmentPath: ', segmentPath);
|
||||||
return segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
return segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
||||||
} else {
|
} else {
|
||||||
console.log("There is no path here...Choose valid path")
|
console.log("There is no path here...Choose valid path")
|
||||||
const { path: segmentPaths } = navMeshQuery.computePath(start, start);
|
const { path: segmentPaths } = navMeshQuery.computePath(start, start);
|
||||||
return segmentPaths.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
return segmentPaths.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch {
|
} catch {
|
||||||
console.error("Failed to compute path");
|
console.error("Failed to compute path");
|
||||||
return [];
|
return [];
|
||||||
@@ -97,7 +100,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isPlaying) {
|
if (isPlaying || selectedPath === "auto") {
|
||||||
if (!agvDetail.point.action.unLoadPoint || !agvDetail.point.action.pickUpPoint) return;
|
if (!agvDetail.point.action.unLoadPoint || !agvDetail.point.action.pickUpPoint) return;
|
||||||
|
|
||||||
if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'stationed') {
|
if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'stationed') {
|
||||||
@@ -105,10 +108,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||||||
new THREE.Vector3(agvDetail?.position[0], agvDetail?.position[1], agvDetail?.position[2]),
|
new THREE.Vector3(agvDetail?.position[0], agvDetail?.position[1], agvDetail?.position[2]),
|
||||||
agvDetail?.point?.action?.pickUpPoint?.position
|
agvDetail?.point?.action?.pickUpPoint?.position
|
||||||
);
|
);
|
||||||
// const toPickupPath = computePath(
|
|
||||||
// new THREE.Vector3(agvDetail?.position[0], agvDetail?.position[1], agvDetail?.position[2]),
|
|
||||||
// new THREE.Vector3(agvDetail?.position[0], agvDetail?.position[1], agvDetail?.position[2])
|
|
||||||
// );
|
|
||||||
setPath(toPickupPath);
|
setPath(toPickupPath);
|
||||||
setCurrentPhase('stationed-pickup');
|
setCurrentPhase('stationed-pickup');
|
||||||
setVehicleState(agvDetail.modelUuid, 'running');
|
setVehicleState(agvDetail.modelUuid, 'running');
|
||||||
@@ -149,8 +149,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||||||
else {
|
else {
|
||||||
reset()
|
reset()
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
}, [vehicles, currentPhase, path, isPlaying, selectedPath]);
|
||||||
}, [vehicles, currentPhase, path, isPlaying]);
|
|
||||||
|
|
||||||
function animate(currentTime: number) {
|
function animate(currentTime: number) {
|
||||||
if (previousTimeRef.current === null) {
|
if (previousTimeRef.current === null) {
|
||||||
@@ -600,6 +599,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||||||
reset={reset}
|
reset={reset}
|
||||||
startUnloadingProcess={startUnloadingProcess}
|
startUnloadingProcess={startUnloadingProcess}
|
||||||
/>
|
/>
|
||||||
|
{selectedPath === "manual" && (<InteractivePoints agvUuid={agvDetail?.modelUuid} />)}
|
||||||
<MaterialAnimator agvDetail={agvDetail} />
|
<MaterialAnimator agvDetail={agvDetail} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { useWidgetStore } from "../../store/useWidgetStore";
|
|||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import { getUserData } from "../../functions/getUserData";
|
import { getUserData } from "../../functions/getUserData";
|
||||||
import { useVersionContext } from "../builder/version/versionContext";
|
import { useVersionContext } from "../builder/version/versionContext";
|
||||||
|
import { useSceneContext } from "../scene/sceneContext";
|
||||||
|
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
@@ -28,6 +29,7 @@ type FormattedZoneData = Record<
|
|||||||
points: [];
|
points: [];
|
||||||
lockedPanels: Side[];
|
lockedPanels: Side[];
|
||||||
zoneUuid: string;
|
zoneUuid: string;
|
||||||
|
zoneName: string;
|
||||||
zoneViewPortTarget: number[];
|
zoneViewPortTarget: number[];
|
||||||
zoneViewPortPosition: number[];
|
zoneViewPortPosition: number[];
|
||||||
widgets: Widget[];
|
widgets: Widget[];
|
||||||
@@ -64,6 +66,9 @@ const RealTimeVisulization: React.FC = () => {
|
|||||||
const { selectedVersion } = selectedVersionStore();
|
const { selectedVersion } = selectedVersionStore();
|
||||||
const { projectId } = useParams();
|
const { projectId } = useParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const { zoneStore } = useSceneContext();
|
||||||
|
const { zones } = zoneStore();
|
||||||
|
|
||||||
|
|
||||||
OuterClick({
|
OuterClick({
|
||||||
contextClassName: [
|
contextClassName: [
|
||||||
@@ -82,6 +87,7 @@ const RealTimeVisulization: React.FC = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!projectId || !selectedVersion) return;
|
if (!projectId || !selectedVersion) return;
|
||||||
getZone2dData(organization, projectId, selectedVersion?.versionId || '').then((response) => {
|
getZone2dData(organization, projectId, selectedVersion?.versionId || '').then((response) => {
|
||||||
|
// console.log('response: ', response);
|
||||||
if (!response) return;
|
if (!response) return;
|
||||||
// if (response.status === 401) {
|
// if (response.status === 401) {
|
||||||
// console.log("force logout");
|
// console.log("force logout");
|
||||||
@@ -94,19 +100,21 @@ const RealTimeVisulization: React.FC = () => {
|
|||||||
const formattedData = response.reduce<FormattedZoneData>(
|
const formattedData = response.reduce<FormattedZoneData>(
|
||||||
(acc, zone) => {
|
(acc, zone) => {
|
||||||
|
|
||||||
acc[zone.zoneName] = {
|
acc[zone.zoneUuid] = {
|
||||||
activeSides: [],
|
activeSides: [],
|
||||||
panelOrder: [],
|
panelOrder: [],
|
||||||
lockedPanels: [],
|
lockedPanels: [],
|
||||||
points: zone.points,
|
points: zone.points,
|
||||||
zoneUuid: zone.zoneUuid,
|
zoneUuid: zone.zoneUuid,
|
||||||
zoneViewPortTarget: zone.viewPortCenter,
|
zoneName: zone.zoneName,
|
||||||
zoneViewPortPosition: zone.viewPortposition,
|
zoneViewPortTarget: zone.viewPortTarget,
|
||||||
|
zoneViewPortPosition: zone.viewPortPosition,
|
||||||
widgets: [],
|
widgets: [],
|
||||||
};
|
};
|
||||||
return acc;
|
return acc;
|
||||||
}, {}
|
}, {}
|
||||||
);
|
);
|
||||||
|
// console.log('formattedData: ', formattedData);
|
||||||
setZonesData(formattedData);
|
setZonesData(formattedData);
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -119,13 +127,14 @@ const RealTimeVisulization: React.FC = () => {
|
|||||||
if (!selectedZone) return prev;
|
if (!selectedZone) return prev;
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
[selectedZone.zoneName]: {
|
[selectedZone.zoneUuid]: {
|
||||||
...prev[selectedZone.zoneName], // Keep existing properties
|
...prev[selectedZone.zoneUuid], // Keep existing properties
|
||||||
activeSides: selectedZone.activeSides || [],
|
activeSides: selectedZone.activeSides || [],
|
||||||
panelOrder: selectedZone.panelOrder || [],
|
panelOrder: selectedZone.panelOrder || [],
|
||||||
lockedPanels: selectedZone.lockedPanels || [],
|
lockedPanels: selectedZone.lockedPanels || [],
|
||||||
points: selectedZone.points || [],
|
points: selectedZone.points || [],
|
||||||
zoneUuid: selectedZone.zoneUuid || "",
|
zoneUuid: selectedZone.zoneUuid || "",
|
||||||
|
zoneName: selectedZone.zoneName || "",
|
||||||
zoneViewPortTarget: selectedZone.zoneViewPortTarget || [],
|
zoneViewPortTarget: selectedZone.zoneViewPortTarget || [],
|
||||||
zoneViewPortPosition: selectedZone.zoneViewPortPosition || [],
|
zoneViewPortPosition: selectedZone.zoneViewPortPosition || [],
|
||||||
widgets: selectedZone.widgets || [],
|
widgets: selectedZone.widgets || [],
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ interface DisplayZoneProps {
|
|||||||
points: [];
|
points: [];
|
||||||
widgets: Widget[];
|
widgets: Widget[];
|
||||||
zoneUuid: string;
|
zoneUuid: string;
|
||||||
|
zoneName: string;
|
||||||
zoneViewPortTarget: number[];
|
zoneViewPortTarget: number[];
|
||||||
zoneViewPortPosition: number[];
|
zoneViewPortPosition: number[];
|
||||||
};
|
};
|
||||||
@@ -111,8 +112,8 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
|||||||
setShowLeftArrow(isOverflowing && canScrollLeft);
|
setShowLeftArrow(isOverflowing && canScrollLeft);
|
||||||
setShowRightArrow(isOverflowing && canScrollRight);
|
setShowRightArrow(isOverflowing && canScrollRight);
|
||||||
|
|
||||||
// console.log('canScrollRight: ', canScrollRight);
|
//
|
||||||
// console.log('isOverflowing: ', isOverflowing);
|
//
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -180,9 +181,10 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
|||||||
// setSelectedChartId(null);
|
// setSelectedChartId(null);
|
||||||
|
|
||||||
let response = await getSelect2dZoneData(zoneUuid, organization, projectId, selectedVersion?.versionId || '');
|
let response = await getSelect2dZoneData(zoneUuid, organization, projectId, selectedVersion?.versionId || '');
|
||||||
// console.log('response2d: ', response);
|
|
||||||
|
//
|
||||||
let res = await getFloatingZoneData(zoneUuid, organization, projectId, selectedVersion?.versionId || '');
|
let res = await getFloatingZoneData(zoneUuid, organization, projectId, selectedVersion?.versionId || '');
|
||||||
// console.log("resFloating: ", res);
|
//
|
||||||
|
|
||||||
setFloatingWidget(res);
|
setFloatingWidget(res);
|
||||||
// Set the selected zone in the store
|
// Set the selected zone in the store
|
||||||
@@ -201,8 +203,8 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
|||||||
widgets: response.widgets || [],
|
widgets: response.widgets || [],
|
||||||
points: response.points || [],
|
points: response.points || [],
|
||||||
zoneUuid: zoneUuid,
|
zoneUuid: zoneUuid,
|
||||||
zoneViewPortTarget: response.viewPortCenter || {},
|
zoneViewPortTarget: response.viewPortTarget || [],
|
||||||
zoneViewPortPosition: response.viewPortposition || {},
|
zoneViewPortPosition: response.viewPortPosition || [],
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
echo.error("Failed to select zone");
|
echo.error("Failed to select zone");
|
||||||
@@ -238,20 +240,22 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
|||||||
>
|
>
|
||||||
{Object.keys(zonesData).length !== 0 ? (
|
{Object.keys(zonesData).length !== 0 ? (
|
||||||
<>
|
<>
|
||||||
{Object.keys(zonesData).map((zoneName, index) => (
|
{Object.values(zonesData).map((zone, index) => (
|
||||||
<div
|
<>
|
||||||
key={index}
|
{ }
|
||||||
className={`zone ${selectedZone.zoneName === zoneName ? "active" : ""
|
<div
|
||||||
}`}
|
key={index}
|
||||||
onClick={() => {
|
className={`zone ${selectedZone.zoneUuid === zone.zoneUuid ? "active" : ""
|
||||||
|
}`}
|
||||||
|
onClick={() => {
|
||||||
|
|
||||||
console.log('zonesData: ', zonesData);
|
handleSelect2dZoneData(zonesData[zone.zoneUuid]?.zoneUuid, zone.zoneName)
|
||||||
handleSelect2dZoneData(zonesData[zoneName]?.zoneUuid, zoneName)
|
}
|
||||||
}
|
}
|
||||||
}
|
>
|
||||||
>
|
{zone.zoneName}
|
||||||
{zoneName}
|
</div>
|
||||||
</div>
|
</>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
|
|
||||||
export default function ZoneCentreTarget() {
|
export default function ZoneCentreTarget() {
|
||||||
const { selectedZone } = useSelectedZoneStore();
|
const { selectedZone } = useSelectedZoneStore();
|
||||||
|
//
|
||||||
const [previousZoneCentre, setPreviousZoneCentre] = useState<number[] | null>(
|
const [previousZoneCentre, setPreviousZoneCentre] = useState<number[] | null>(
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ const Dashboard: React.FC = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const token = localStorage.getItem("token");
|
const token = localStorage.getItem("token");
|
||||||
|
const refreshToken = localStorage.getItem("refreshToken")
|
||||||
if (token) {
|
if (token) {
|
||||||
useSocketStore.getState().initializeSocket(email, organization, token);
|
useSocketStore.getState().initializeSocket(email, organization, token, refreshToken);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,8 +114,9 @@ const Project: React.FC = () => {
|
|||||||
setActiveModule("builder");
|
setActiveModule("builder");
|
||||||
if (email) {
|
if (email) {
|
||||||
const token = localStorage.getItem("token");
|
const token = localStorage.getItem("token");
|
||||||
|
const refreshToken = localStorage.getItem("refreshToken")
|
||||||
if (token) {
|
if (token) {
|
||||||
useSocketStore.getState().initializeSocket(email, organization, token);
|
useSocketStore.getState().initializeSocket(email, organization, token, refreshToken);
|
||||||
}
|
}
|
||||||
if (organization && userName) {
|
if (organization && userName) {
|
||||||
setOrganization(organization);
|
setOrganization(organization);
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ const UserAuth: React.FC = () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const projects = await recentlyViewed(organization, res.message.userId);
|
const projects = await recentlyViewed(organization, res.message.userId);
|
||||||
console.log('projects: ', projects);
|
|
||||||
if (res.message.isShare) {
|
if (res.message.isShare) {
|
||||||
if (Object.values(projects.RecentlyViewed).length > 0) {
|
if (Object.values(projects.RecentlyViewed).length > 0) {
|
||||||
const firstId = (Object.values(projects?.RecentlyViewed || {})[0] as any)?._id;
|
const firstId = (Object.values(projects?.RecentlyViewed || {})[0] as any)?._id;
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||||
|
|
||||||
export const getZonesApi = async (
|
export const getZonesApi = async (projectId: string, versionId: string,) => {
|
||||||
projectId: string,
|
|
||||||
versionId: string,
|
|
||||||
) => {
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${url_Backend_dwinzo}/api/V1/zones/${projectId}/${versionId}`, {
|
const response = await fetch(`${url_Backend_dwinzo}/api/V1/zones/${projectId}/${versionId}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_UR
|
|||||||
|
|
||||||
export const zoneCameraUpdate = async (zoneData: {}, organization: string, projectId?: string, versionId?: string) => {
|
export const zoneCameraUpdate = async (zoneData: {}, organization: string, projectId?: string, versionId?: string) => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${url_Backend_dwinzo}/api/V1/zones`, {
|
const response = await fetch(`${url_Backend_dwinzo}/api/V1/upsertZone`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: "Bearer <access_token>", // Replace with actual token
|
Authorization: "Bearer <access_token>", // Replace with actual token
|
||||||
|
|||||||
@@ -5,7 +5,12 @@ import * as CONSTANTS from "../../types/world/worldConstants";
|
|||||||
|
|
||||||
export const useSocketStore = create<any>((set: any, get: any) => ({
|
export const useSocketStore = create<any>((set: any, get: any) => ({
|
||||||
socket: null,
|
socket: null,
|
||||||
initializeSocket: (email?: string, organization?: string, token?: string) => {
|
initializeSocket: (
|
||||||
|
email?: string,
|
||||||
|
organization?: string,
|
||||||
|
token?: string,
|
||||||
|
refreshToken?: string
|
||||||
|
) => {
|
||||||
const existingSocket = get().socket;
|
const existingSocket = get().socket;
|
||||||
if (existingSocket) {
|
if (existingSocket) {
|
||||||
return;
|
return;
|
||||||
@@ -15,7 +20,7 @@ export const useSocketStore = create<any>((set: any, get: any) => ({
|
|||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder_v1`,
|
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder_v1`,
|
||||||
{
|
{
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token },
|
auth: { token, refreshToken },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -23,7 +28,7 @@ export const useSocketStore = create<any>((set: any, get: any) => ({
|
|||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization_v1`,
|
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization_v1`,
|
||||||
{
|
{
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token },
|
auth: { token, refreshToken },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -31,21 +36,21 @@ export const useSocketStore = create<any>((set: any, get: any) => ({
|
|||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/dashboard`,
|
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/dashboard`,
|
||||||
{
|
{
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token },
|
auth: { token, refreshToken },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const projectSocket = io(
|
const projectSocket = io(
|
||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/project`,
|
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/project`,
|
||||||
{
|
{
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token },
|
auth: { token, refreshToken },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const threadSocket = io(
|
const threadSocket = io(
|
||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/thread`,
|
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/thread`,
|
||||||
{
|
{
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token },
|
auth: { token, refreshToken },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -724,3 +729,7 @@ export const useSelectedComment = create<any>((set: any) => ({
|
|||||||
commentPositionState: null,
|
commentPositionState: null,
|
||||||
setCommentPositionState: (x: any) => set({ commentPositionState: x }),
|
setCommentPositionState: (x: any) => set({ commentPositionState: x }),
|
||||||
}));
|
}));
|
||||||
|
export const useSelectedPath = create<any>((set: any) => ({
|
||||||
|
selectedPath: "",
|
||||||
|
setSelectedPath: (x: any) => set({ selectedPath: x }),
|
||||||
|
}));
|
||||||
|
|||||||
Reference in New Issue
Block a user