- {`${selectedCard.assetName} is used in factories to improve efficiency and production speed It is designed to handle heavy workloads and perform repetitive tasks with precision. Many industries rely on this machine to manufacture products quickly and accurately. It reduces human effort and minimizes errors in the production process. Regular maintenance is required to keep the machine in good working condition.With advanced technology, this machine continues to enhance industrial operations and increase productivity.`}
+ {`${selectedCard.description}`}
diff --git a/app/src/modules/market/CardsContainer.tsx b/app/src/modules/market/CardsContainer.tsx
index c2a7e6d..cdbce81 100644
--- a/app/src/modules/market/CardsContainer.tsx
+++ b/app/src/modules/market/CardsContainer.tsx
@@ -14,6 +14,7 @@ interface ModelData {
thumbnail: string;
uploadDate: number;
_id: string;
+ price: number;
}
interface ModelsProps {
models: ModelData[];
@@ -50,7 +51,7 @@ const CardsContainer: React.FC = ({ models }) => {
key={assetDetail._id}
assetName={assetDetail?.filename}
uploadedOn={assetDetail.uploadDate}
- price={36500}
+ price={assetDetail?.price}
rating={4.5}
views={800}
onSelectCard={handleCardSelect}
diff --git a/app/src/modules/market/FilterSearch.tsx b/app/src/modules/market/FilterSearch.tsx
index 84074b8..630942d 100644
--- a/app/src/modules/market/FilterSearch.tsx
+++ b/app/src/modules/market/FilterSearch.tsx
@@ -17,6 +17,7 @@ interface ModelData {
thumbnail: string;
uploadDate: number;
_id: string;
+ price: number;
}
interface ModelsProps {
models: ModelData[];
diff --git a/app/src/modules/market/MarketPlace.tsx b/app/src/modules/market/MarketPlace.tsx
index d830576..cd2e0e9 100644
--- a/app/src/modules/market/MarketPlace.tsx
+++ b/app/src/modules/market/MarketPlace.tsx
@@ -15,6 +15,7 @@ interface ModelData {
thumbnail: string;
uploadDate: number;
_id: string;
+ price: number;
}
const MarketPlace = () => {
const [models, setModels] = useState([]);
@@ -24,6 +25,7 @@ const MarketPlace = () => {
const filteredAssets = async () => {
try {
const filt = await getAssetImages("67d934ad0f42a1fdadb19aa6");
+
setModels(filt.items);
setFilteredModels(filt.items);
} catch {}
diff --git a/app/src/modules/scene/controls/selection/selectionControls.tsx b/app/src/modules/scene/controls/selection/selectionControls.tsx
index c9038ab..9d5f7ea 100644
--- a/app/src/modules/scene/controls/selection/selectionControls.tsx
+++ b/app/src/modules/scene/controls/selection/selectionControls.tsx
@@ -42,6 +42,8 @@ const SelectionControls: React.FC = () => {
itemsGroupRef.current = itemsGroup;
let isSelecting = false;
+ let isRightClick = false;
+ let rightClickMoved = false;
let isCtrlSelecting = false;
const helper = new SelectionHelper(gl);
@@ -52,16 +54,23 @@ const SelectionControls: React.FC = () => {
}
const onPointerDown = (event: PointerEvent) => {
- if (event.button !== 0) return
- isSelecting = false;
- isCtrlSelecting = event.ctrlKey;
- if (event.ctrlKey && duplicatedObjects.length === 0) {
- if (controls) (controls as any).enabled = false;
- selectionBox.startPoint.set(pointer.x, pointer.y, 0);
+ if (event.button === 2) {
+ isRightClick = true;
+ rightClickMoved = false;
+ } else if (event.button === 0) {
+ isSelecting = false;
+ isCtrlSelecting = event.ctrlKey;
+ if (event.ctrlKey && duplicatedObjects.length === 0) {
+ if (controls) (controls as any).enabled = false;
+ selectionBox.startPoint.set(pointer.x, pointer.y, 0);
+ }
}
};
const onPointerMove = (event: PointerEvent) => {
+ if (isRightClick) {
+ rightClickMoved = true;
+ }
isSelecting = true;
if (helper.isDown && event.ctrlKey && duplicatedObjects.length === 0 && isCtrlSelecting) {
selectionBox.endPoint.set(pointer.x, pointer.y, 0);
@@ -69,6 +78,14 @@ const SelectionControls: React.FC = () => {
};
const onPointerUp = (event: PointerEvent) => {
+ if (event.button === 2) {
+ isRightClick = false;
+ if (!rightClickMoved) {
+ clearSelection();
+ }
+ return;
+ }
+
if (isSelecting && isCtrlSelecting) {
isCtrlSelecting = false;
isSelecting = false;
@@ -94,10 +111,13 @@ const SelectionControls: React.FC = () => {
}
};
+
const onContextMenu = (event: MouseEvent) => {
event.preventDefault();
- clearSelection();
- }
+ if (!rightClickMoved) {
+ clearSelection();
+ }
+ };
if (!toggleView && activeModule === "builder") {
helper.enabled = true;
diff --git a/app/src/modules/scene/postProcessing/postProcessing.tsx b/app/src/modules/scene/postProcessing/postProcessing.tsx
index e1fc501..15597b8 100644
--- a/app/src/modules/scene/postProcessing/postProcessing.tsx
+++ b/app/src/modules/scene/postProcessing/postProcessing.tsx
@@ -1,111 +1,125 @@
-import * as THREE from 'three'
-import { EffectComposer, N8AO, Outline } from '@react-three/postprocessing'
-import { BlendFunction } from 'postprocessing'
-import { useDeletableFloorItem, useSelectedActionSphere, useSelectedPath, useSelectedWallItem, useselectedFloorItem } from '../../../store/store';
-import * as Types from '../../../types/world/worldTypes'
-import * as CONSTANTS from '../../../types/world/worldConstants';
+import * as THREE from "three";
+import { EffectComposer, N8AO, Outline } from "@react-three/postprocessing";
+import { BlendFunction } from "postprocessing";
+import {
+ useDeletableFloorItem,
+ useSelectedActionSphere,
+ useSelectedPath,
+ useSelectedWallItem,
+ useselectedFloorItem,
+} from "../../../store/store";
+import * as Types from "../../../types/world/worldTypes";
+import * as CONSTANTS from "../../../types/world/worldConstants";
+import { useEffect } from "react";
export default function PostProcessing() {
- const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem();
- const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
- const { selectedFloorItem, setselectedFloorItem } = useselectedFloorItem();
- const { selectedActionSphere } = useSelectedActionSphere();
- const { selectedPath } = useSelectedPath();
+ const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem();
+ const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
+ const { selectedFloorItem, setselectedFloorItem } = useselectedFloorItem();
+ const { selectedActionSphere } = useSelectedActionSphere();
+ const { selectedPath } = useSelectedPath();
- function flattenChildren(children: any[]) {
- const allChildren: any[] = [];
- children.forEach(child => {
- allChildren.push(child);
- if (child.children && child.children.length > 0) {
- allChildren.push(...flattenChildren(child.children));
- }
- });
- return allChildren;
- }
+ function flattenChildren(children: any[]) {
+ const allChildren: any[] = [];
+ children.forEach((child) => {
+ allChildren.push(child);
+ if (child.children && child.children.length > 0) {
+ allChildren.push(...flattenChildren(child.children));
+ }
+ });
+ return allChildren;
+ }
- return (
- <>
-
-
- {deletableFloorItem &&
-
- }
- {selectedWallItem &&
- child.name !== "CSG_REF"
- )
- }
- selectionLayer={10}
- width={3000}
- blendFunction={BlendFunction.ALPHA}
- edgeStrength={5}
- resolutionScale={2}
- pulseSpeed={0}
- visibleEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
- hiddenEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
- blur={true}
- xRay={true}
- />}
- {selectedFloorItem &&
-
- }
- {selectedActionSphere &&
-
- }
- {selectedPath &&
-
- }
-
- >
- )
-}
\ No newline at end of file
+ return (
+ <>
+
+
+ {deletableFloorItem && (
+
+ )}
+ {selectedWallItem && (
+ child.name !== "CSG_REF"
+ )}
+ selectionLayer={10}
+ width={3000}
+ blendFunction={BlendFunction.ALPHA}
+ edgeStrength={5}
+ resolutionScale={2}
+ pulseSpeed={0}
+ visibleEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
+ hiddenEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
+ blur={true}
+ xRay={true}
+ />
+ )}
+ {selectedFloorItem && (
+
+ )}
+ {selectedActionSphere && (
+
+ )}
+ {selectedPath && (
+
+ )}
+
+ >
+ );
+}
diff --git a/app/src/modules/scene/world/world.tsx b/app/src/modules/scene/world/world.tsx
index eb7d555..76cf539 100644
--- a/app/src/modules/scene/world/world.tsx
+++ b/app/src/modules/scene/world/world.tsx
@@ -358,7 +358,7 @@ export default function World() {
anglesnappedPoint={anglesnappedPoint}
/>
-
+ {/* */}
>
diff --git a/app/src/modules/simulation/behaviour/behaviour.tsx b/app/src/modules/simulation/behaviour/behaviour.tsx
index c1281b5..5075384 100644
--- a/app/src/modules/simulation/behaviour/behaviour.tsx
+++ b/app/src/modules/simulation/behaviour/behaviour.tsx
@@ -67,7 +67,7 @@ function Behaviour() {
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 },
+ 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,
},
diff --git a/app/src/modules/simulation/path/pathConnector.tsx b/app/src/modules/simulation/path/pathConnector.tsx
index 0888966..7352932 100644
--- a/app/src/modules/simulation/path/pathConnector.tsx
+++ b/app/src/modules/simulation/path/pathConnector.tsx
@@ -96,24 +96,16 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
};
const existingTargets = path.point.connections.targets || [];
- // Check if we're trying to add a connection to a Conveyor
+ // Check if target is a Conveyor
const toPath = simulationPaths.find(p => p.modeluuid === toPathUUID);
- const isConnectingToConveyor = toPath?.type === 'Conveyor';
-
- // Count existing connections
- if (existingTargets.length >= 2) {
- console.log("Vehicle can have maximum 2 connections");
+ if (toPath?.type !== 'Conveyor') {
+ console.log("Vehicle can only connect to Conveyors");
return path;
}
- // Check if we already have a Conveyor connection and trying to add another
- const hasConveyorConnection = existingTargets.some(target => {
- const targetPath = simulationPaths.find(p => p.modeluuid === target.pathUUID);
- return targetPath?.type === 'Conveyor';
- });
-
- if (hasConveyorConnection && isConnectingToConveyor) {
- console.log("Vehicle can only have one connection to a Conveyor");
+ // Check if already has a connection
+ if (existingTargets.length >= 1) {
+ console.log("Vehicle can have only one connection");
return path;
}
@@ -141,24 +133,16 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
};
const existingTargets = path.point.connections.targets || [];
- // Check if we're receiving a connection from a Conveyor
+ // Check if source is a Conveyor
const fromPath = simulationPaths.find(p => p.modeluuid === fromPathUUID);
- const isConnectingFromConveyor = fromPath?.type === 'Conveyor';
-
- // Count existing connections
- if (existingTargets.length >= 2) {
- console.log("Vehicle can have maximum 2 connections");
+ if (fromPath?.type !== 'Conveyor') {
+ console.log("Vehicle can only connect to Conveyors");
return path;
}
- // Check if we already have a Conveyor connection and trying to add another
- const hasConveyorConnection = existingTargets.some(target => {
- const targetPath = simulationPaths.find(p => p.modeluuid === target.pathUUID);
- return targetPath?.type === 'Conveyor';
- });
-
- if (hasConveyorConnection && isConnectingFromConveyor) {
- console.log("Vehicle can only have one connection to a Conveyor");
+ // Check if already has a connection
+ if (existingTargets.length >= 1) {
+ console.log("Vehicle can have only one connection");
return path;
}
@@ -212,6 +196,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
drag = true;
}
};
+
const onContextMenu = (evt: MouseEvent) => {
evt.preventDefault();
if (drag || evt.button === 0) return;
@@ -282,7 +267,16 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
return;
}
- // For Vehicles, skip the "already connected" check since they can have multiple connections
+ // For Vehicles, check if they're already connected to anything
+ if (intersected.userData.path.type === 'Vehicle') {
+ const vehicleConnections = intersected.userData.path.point.connections.targets.length;
+ if (vehicleConnections >= 1) {
+ console.log("Vehicle can only have one connection");
+ return;
+ }
+ }
+
+ // For non-Vehicle paths, check if already connected
if (intersected.userData.path.type !== 'Vehicle') {
const isAlreadyConnected = simulationPaths.some(path => {
if (path.type === 'Conveyor') {
@@ -300,48 +294,14 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
}
}
- // Check vehicle connection limits
- const checkVehicleConnections = (pathUUID: string) => {
- const path = simulationPaths.find(p => p.modeluuid === pathUUID);
- if (path?.type === 'Vehicle') {
- return path.point.connections.targets.length >= 2;
- }
- return false;
- };
-
if (firstSelected) {
- // Check if either selected point is from a Vehicle with max connections
- if (checkVehicleConnections(firstSelected.pathUUID) ||
- checkVehicleConnections(pathUUID)) {
- console.log("Vehicle already has maximum connections");
+ // Check if trying to connect Vehicle to non-Conveyor
+ if ((firstPath?.type === 'Vehicle' && secondPath?.type !== 'Conveyor') ||
+ (secondPath?.type === 'Vehicle' && firstPath?.type !== 'Conveyor')) {
+ console.log("Vehicle can only connect to Conveyors");
return;
}
- // Check if we're trying to add a second Conveyor connection to a Vehicle
- if (firstPath?.type === 'Vehicle' && secondPath?.type === 'Conveyor') {
- const hasConveyorConnection = firstPath.point.connections.targets.some(target => {
- const targetPath = simulationPaths.find(p => p.modeluuid === target.pathUUID);
- return targetPath?.type === 'Conveyor';
- });
-
- if (hasConveyorConnection) {
- console.log("Vehicle can only have one connection to a Conveyor");
- return;
- }
- }
-
- if (secondPath?.type === 'Vehicle' && firstPath?.type === 'Conveyor') {
- const hasConveyorConnection = secondPath.point.connections.targets.some(target => {
- const targetPath = simulationPaths.find(p => p.modeluuid === target.pathUUID);
- return targetPath?.type === 'Conveyor';
- });
-
- if (hasConveyorConnection) {
- console.log("Vehicle can only have one connection to a Conveyor");
- return;
- }
- }
-
// Prevent same-path connections
if (firstSelected.pathUUID === pathUUID) {
console.log("Cannot connect spheres on the same path.");
@@ -478,28 +438,19 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
return false;
});
- // Check vehicle connection limits
+ // Check vehicle connection rules
const isVehicleAtMaxConnections = pathData.type === 'Vehicle' &&
- pathData.point.connections.targets.length >= 2;
-
- const isVehicleConveyorConflict =
- (firstPath?.type === 'Vehicle' && secondPath?.type === 'Conveyor' &&
- firstPath.point.connections.targets.some(t => {
- const targetPath = simulationPaths.find(p => p.modeluuid === t.pathUUID);
- return targetPath?.type === 'Conveyor';
- })) ||
- (secondPath?.type === 'Vehicle' && firstPath?.type === 'Conveyor' &&
- secondPath.point.connections.targets.some(t => {
- const targetPath = simulationPaths.find(p => p.modeluuid === t.pathUUID);
- return targetPath?.type === 'Conveyor';
- }));
+ pathData.point.connections.targets.length >= 1;
+ const isVehicleConnectingToNonConveyor =
+ (firstPath?.type === 'Vehicle' && secondPath?.type !== 'Conveyor') ||
+ (secondPath?.type === 'Vehicle' && firstPath?.type !== 'Conveyor');
if (
!isDuplicateConnection &&
!isVehicleToVehicle &&
!isNonVehicleAlreadyConnected &&
!isVehicleAtMaxConnections &&
- !isVehicleConveyorConflict &&
+ !isVehicleConnectingToNonConveyor &&
firstSelected.sphereUUID !== sphereUUID &&
firstSelected.pathUUID !== pathUUID &&
(firstSelected.isCorner || isConnectable)
diff --git a/app/src/modules/simulation/path/pathCreation.tsx b/app/src/modules/simulation/path/pathCreation.tsx
index 33ca2f8..202c7e7 100644
--- a/app/src/modules/simulation/path/pathCreation.tsx
+++ b/app/src/modules/simulation/path/pathCreation.tsx
@@ -1,8 +1,8 @@
import * as THREE from 'three';
import * as Types from '../../../types/world/worldTypes';
-import { useRef, useState, useEffect } from 'react';
+import { useRef, useState, useEffect, useMemo } from 'react';
import { Sphere, TransformControls } from '@react-three/drei';
-import { useIsConnecting, useRenderDistance, useSelectedActionSphere, useSelectedPath, useSimulationPaths } from '../../../store/store';
+import { useEditingPoint, useEyeDropMode, useIsConnecting, usePreviewPosition, useRenderDistance, useSelectedActionSphere, useSelectedPath, useSimulationPaths } from '../../../store/store';
import { useFrame, useThree } from '@react-three/fiber';
import { useSubModuleStore } from '../../../store/useModuleStore';
@@ -10,13 +10,18 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
const { renderDistance } = useRenderDistance();
const { setSubModule } = useSubModuleStore();
const { setSelectedActionSphere, selectedActionSphere } = useSelectedActionSphere();
+ const { eyeDropMode, setEyeDropMode } = useEyeDropMode();
+ const { editingPoint, setEditingPoint } = useEditingPoint();
+ const { previewPosition, setPreviewPosition } = usePreviewPosition();
+ const { raycaster, camera, pointer, gl } = useThree();
+ const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
const { setSelectedPath } = useSelectedPath();
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
const { isConnecting } = useIsConnecting();
- const { camera } = useThree();
-
+
const groupRefs = useRef<{ [key: string]: THREE.Group }>({});
const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({});
+ const isMovingRef = useRef(false);
const transformRef = useRef(null);
const [transformMode, setTransformMode] = useState<'translate' | 'rotate' | null>(null);
@@ -77,6 +82,83 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
setSimulationPaths(updatedPaths);
};
+ useFrame(() => {
+ if (eyeDropMode) {
+ raycaster.setFromCamera(pointer, camera);
+ const intersectionPoint = new THREE.Vector3();
+ const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
+
+ if (point) {
+ setPreviewPosition({ x: point.x, y: point.z });
+ }
+ } else {
+ setPreviewPosition(null);
+ }
+ });
+
+ useEffect(() => {
+ if (!camera) return;
+ const canvasElement = gl.domElement;
+ canvasElement.tabIndex = 0;
+
+
+ const onPointerDown = () => {
+ isMovingRef.current = false;
+ };
+
+ const onPointerMove = () => {
+ isMovingRef.current = true;
+ };
+
+ const onPointerUp = (event: PointerEvent) => {
+ if (!isMovingRef.current && eyeDropMode && event.button === 0 && previewPosition) {
+ event.preventDefault();
+ if (editingPoint) {
+ handlePointUpdate(editingPoint, previewPosition.x, previewPosition.y);
+ setEditingPoint(null);
+ setEyeDropMode(false);
+ }
+ }
+ };
+
+ if (eyeDropMode) {
+ canvasElement.addEventListener("pointerdown", onPointerDown);
+ canvasElement.addEventListener("pointermove", onPointerMove);
+ canvasElement.addEventListener("pointerup", onPointerUp);
+ }
+
+ return () => {
+ canvasElement.removeEventListener("pointerdown", onPointerDown);
+ canvasElement.removeEventListener("pointermove", onPointerMove);
+ canvasElement.removeEventListener("pointerup", onPointerUp);
+ };
+ }, [eyeDropMode, editingPoint, previewPosition]);
+
+ const handlePointUpdate = (pointType: 'start' | 'end', x: number, z: number) => {
+ if (!selectedActionSphere?.point?.uuid) return;
+
+ const updatedPaths = simulationPaths.map((path) => {
+ if (path.type === "Vehicle" && path.point.uuid === selectedActionSphere.point.uuid) {
+ return {
+ ...path,
+ point: {
+ ...path.point,
+ actions: {
+ ...path.point.actions,
+ [pointType]: {
+ ...path.point.actions[pointType],
+ x: x,
+ y: z
+ }
+ }
+ }
+ };
+ }
+ return path;
+ });
+
+ setSimulationPaths(updatedPaths);
+ };
return (
@@ -92,7 +174,7 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
position={path.assetPosition}
rotation={path.assetRotation}
onClick={(e) => {
- if (isConnecting) return;
+ if (isConnecting || eyeDropMode) return;
e.stopPropagation();
setSelectedPath({ path, group: groupRefs.current[path.modeluuid] });
setSelectedActionSphere(null);
@@ -100,6 +182,7 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
setSubModule('mechanics');
}}
onPointerMissed={() => {
+ if (eyeDropMode) return;
setSelectedPath(null);
setSubModule('properties');
}}
@@ -113,7 +196,7 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
name='events-sphere'
ref={el => (sphereRefs.current[point.uuid] = el!)}
onClick={(e) => {
- if (isConnecting) return;
+ if (isConnecting || eyeDropMode) return;
e.stopPropagation();
setSelectedActionSphere({
path,
@@ -124,6 +207,7 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
}}
userData={{ point, path }}
onPointerMissed={() => {
+ if (eyeDropMode) return;
setSubModule('properties');
setSelectedActionSphere(null);
}}
@@ -155,7 +239,7 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
ref={el => (groupRefs.current[path.modeluuid] = el!)}
position={path.assetPosition}
onClick={(e) => {
- if (isConnecting) return;
+ if (isConnecting || eyeDropMode) return;
e.stopPropagation();
setSelectedPath({ path, group: groupRefs.current[path.modeluuid] });
setSelectedActionSphere(null);
@@ -163,6 +247,7 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
setSubModule('mechanics');
}}
onPointerMissed={() => {
+ if (eyeDropMode) return;
setSelectedPath(null);
setSubModule('properties');
}}
@@ -175,7 +260,7 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
name='events-sphere'
ref={el => (sphereRefs.current[path.point.uuid] = el!)}
onClick={(e) => {
- if (isConnecting) return;
+ if (isConnecting || eyeDropMode) return;
e.stopPropagation();
setSelectedActionSphere({
path,
@@ -186,6 +271,7 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
}}
userData={{ point: path.point, path }}
onPointerMissed={() => {
+ if (eyeDropMode) return;
setSubModule('properties');
setSelectedActionSphere(null);
}}
diff --git a/app/src/modules/simulation/simulation.tsx b/app/src/modules/simulation/simulation.tsx
index 10934fb..739a92b 100644
--- a/app/src/modules/simulation/simulation.tsx
+++ b/app/src/modules/simulation/simulation.tsx
@@ -1,6 +1,5 @@
-import { useState, useEffect, useRef } from 'react';
+import { useState, useEffect, useRef, useMemo } from 'react';
import { useSelectedActionSphere, useSelectedPath, useSimulationPaths } from '../../store/store';
-import { useThree } from '@react-three/fiber';
import * as THREE from 'three';
import Behaviour from './behaviour/behaviour';
import PathCreation from './path/pathCreation';
@@ -14,7 +13,6 @@ function Simulation() {
const [processes, setProcesses] = useState([]);
useEffect(() => {
- console.log('simulationPaths: ', simulationPaths);
}, [simulationPaths]);
// useEffect(() => {
@@ -29,9 +27,10 @@ function Simulation() {
// }
// }, [selectedPath]);
+
return (
<>
-
+
{activeModule === 'simulation' && (
<>
diff --git a/app/src/modules/visualization/handleSaveTemplate.ts b/app/src/modules/visualization/handleSaveTemplate.ts
index c489688..a71e654 100644
--- a/app/src/modules/visualization/handleSaveTemplate.ts
+++ b/app/src/modules/visualization/handleSaveTemplate.ts
@@ -1,74 +1,89 @@
+import { saveTemplateApi } from "../../services/realTimeVisulization/zoneData/saveTempleteApi";
import { Template } from "../../store/useTemplateStore";
import { captureVisualization } from "./captureVisualization";
type HandleSaveTemplateProps = {
addTemplate: (template: Template) => void;
+ floatingWidget: []; // Updated type from `[]` to `any[]` for clarity
+ widgets3D: []; // Updated type from `[]` to `any[]` for clarity
selectedZone: {
- panelOrder: string[]; // Adjust the type based on actual data structure
- widgets: any[]; // Replace `any` with the actual widget type
+ panelOrder: string[];
+ widgets: any[];
};
templates?: Template[];
};
-// Generate a unique ID (placeholder function)
+// Generate a unique ID
const generateUniqueId = (): string => {
return `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
};
-// Refactored function
export const handleSaveTemplate = async ({
addTemplate,
+ floatingWidget,
+ widgets3D,
selectedZone,
templates = [],
}: HandleSaveTemplateProps): Promise => {
try {
// Check if the selected zone has any widgets
if (!selectedZone.widgets || selectedZone.widgets.length === 0) {
- console.warn("Cannot save an empty template.");
+ console.warn("No widgets found in the selected zone.");
return;
}
// Check if the template already exists
- const isDuplicate = templates.some((template) => {
- const isSamePanelOrder =
+ const isDuplicate = templates.some(
+ (template) =>
JSON.stringify(template.panelOrder) ===
- JSON.stringify(selectedZone.panelOrder);
- const isSameWidgets =
+ JSON.stringify(selectedZone.panelOrder) &&
JSON.stringify(template.widgets) ===
- JSON.stringify(selectedZone.widgets);
- return isSamePanelOrder && isSameWidgets;
- });
+ JSON.stringify(selectedZone.widgets)
+ );
if (isDuplicate) {
- console.warn("This template already exists.");
return;
}
// Capture visualization snapshot
const snapshot = await captureVisualization();
- if (!snapshot) {
- console.error("Failed to capture visualization snapshot.");
- return;
- }
-
+ console.log("snapshot: ", snapshot);
+ // if (!snapshot) {
+ // return;
+ // }
// Create a new template
const newTemplate: Template = {
id: generateUniqueId(),
- name: `Template ${Date.now()}`,
+ name: `Template ${new Date().toISOString()}`, // Better name formatting
panelOrder: selectedZone.panelOrder,
widgets: selectedZone.widgets,
snapshot,
+ floatingWidget,
+ widgets3D,
};
- console.log("Saving template:", newTemplate);
+ // Extract organization from email
+ const email = localStorage.getItem("email") || "";
+ const organization = email.includes("@")
+ ? email.split("@")[1]?.split(".")[0]
+ : "";
+
+ if (!organization) {
+ console.error("Organization could not be determined from email.");
+ return;
+ }
// Save the template
try {
+ const response = await saveTemplateApi(organization, newTemplate);
+ console.log("Save API Response:", response);
+
+ // Add template only if API call succeeds
addTemplate(newTemplate);
- } catch (error) {
- console.error("Failed to add template:", error);
+ } catch (apiError) {
+ console.error("Error saving template to API:", apiError);
}
} catch (error) {
- console.error("Failed to save template:", error);
+ console.error("Error in handleSaveTemplate:", error);
}
};
diff --git a/app/src/pages/Project.tsx b/app/src/pages/Project.tsx
index 41f04a7..7aad5cb 100644
--- a/app/src/pages/Project.tsx
+++ b/app/src/pages/Project.tsx
@@ -37,8 +37,8 @@ const Project: React.FC = () => {
setZones([]);
const email = localStorage.getItem("email");
if (email) {
- useSocketStore.getState().initializeSocket(email);
const Organization = email!.split("@")[1].split(".")[0];
+ useSocketStore.getState().initializeSocket(email, Organization);
const name = localStorage.getItem("userName");
if (Organization && name) {
setOrganization(Organization);
diff --git a/app/src/services/factoryBuilder/assest/assets/getCategoryAsset.ts b/app/src/services/factoryBuilder/assest/assets/getCategoryAsset.ts
new file mode 100644
index 0000000..522e54c
--- /dev/null
+++ b/app/src/services/factoryBuilder/assest/assets/getCategoryAsset.ts
@@ -0,0 +1,19 @@
+let BackEnd_url = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
+export const getCategoryAsset = async (categoryName: any) => {
+ try {
+ const response = await fetch(
+ `${BackEnd_url}/api/v2/getCatagoryAssets/${categoryName}`,
+ {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ }
+ );
+
+ const result = await response.json();
+ return result;
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+};
diff --git a/app/src/services/factoryBuilder/assest/floorAsset/setFloorItemApi.ts b/app/src/services/factoryBuilder/assest/floorAsset/setFloorItemApi.ts
index 31d5b11..f6cd496 100644
--- a/app/src/services/factoryBuilder/assest/floorAsset/setFloorItemApi.ts
+++ b/app/src/services/factoryBuilder/assest/floorAsset/setFloorItemApi.ts
@@ -1,13 +1,28 @@
-let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
+let url_Backend_dwinzo = `http://${process.env.REACT_APP_TEST}`;
-export const setFloorItemApi = async (organization: string, modeluuid: string, modelname: string, position: Object, rotation: Object, modelfileID: string, isLocked: boolean, isVisible: boolean) => {
+export const setFloorItemApi = async (
+ organization: string,
+ modeluuid: string,
+ modelname: string,
+ modelfileID: string,
+ position: Object,
+ rotation: Object,
+ isLocked: boolean,
+ isVisible: boolean,
+ eventData?: any
+) => {
try {
- const response = await fetch(`${url_Backend_dwinzo}/api/v1/setFloorItems`, {
+ const body: any = { organization, modeluuid, modelname, position, rotation, modelfileID, isLocked, isVisible };
+ if (eventData) {
+ body.eventData = eventData;
+ }
+
+ const response = await fetch(`${url_Backend_dwinzo}/api/v2/setasset`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
- body: JSON.stringify({ organization, modeluuid, modelname, position, rotation, modelfileID, isLocked, isVisible }),
+ body: JSON.stringify(body),
});
if (!response.ok) {
@@ -15,6 +30,7 @@ export const setFloorItemApi = async (organization: string, modeluuid: string, m
}
const result = await response.json();
+ console.log('result: ', result);
return result;
} catch (error) {
if (error instanceof Error) {
diff --git a/app/src/services/realTimeVisulization/zoneData/add3dWidget.ts b/app/src/services/realTimeVisulization/zoneData/add3dWidget.ts
new file mode 100644
index 0000000..82562b7
--- /dev/null
+++ b/app/src/services/realTimeVisulization/zoneData/add3dWidget.ts
@@ -0,0 +1,36 @@
+let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
+// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
+export const adding3dWidgets = async (
+ zoneId: string,
+ organization: string,
+ widget: {}
+) => {
+ console.log('widget: ', widget);
+ console.log('organization: ', organization);
+ console.log('zoneId: ', zoneId);
+ try {
+ const response = await fetch(
+ `${url_Backend_dwinzo}/api/v2/3dwidget/save`,
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ organization, zoneId, widget }),
+ }
+ );
+
+ if (!response.ok) {
+ throw new Error("Failed to add 3dwidget in the zone");
+ }
+
+ 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");
+ }
+ }
+};
diff --git a/app/src/services/realTimeVisulization/zoneData/addFloatingWidgets.ts b/app/src/services/realTimeVisulization/zoneData/addFloatingWidgets.ts
index 338f26b..fb644c6 100644
--- a/app/src/services/realTimeVisulization/zoneData/addFloatingWidgets.ts
+++ b/app/src/services/realTimeVisulization/zoneData/addFloatingWidgets.ts
@@ -1,10 +1,14 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
+
export const addingFloatingWidgets = async (
zoneId: string,
organization: string,
widget: {}
) => {
+ console.log('organization: ', organization);
+ console.log('widget: ', widget);
+ console.log('zoneId: ', zoneId);
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/v2/floatwidget/save`,
diff --git a/app/src/services/realTimeVisulization/zoneData/deleteFloatingWidget.ts b/app/src/services/realTimeVisulization/zoneData/deleteFloatingWidget.ts
new file mode 100644
index 0000000..85c96b8
--- /dev/null
+++ b/app/src/services/realTimeVisulization/zoneData/deleteFloatingWidget.ts
@@ -0,0 +1,35 @@
+let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
+// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
+
+export const deleteFloatingWidgetApi = async (
+ floatWidgetID: string,
+ organization: string
+) => {
+ console.log('organization: ', organization);
+ console.log('floatWidgetID: ', floatWidgetID);
+ try {
+ const response = await fetch(
+ `${url_Backend_dwinzo}/api/v2/floatwidget/delete`,
+ {
+ method: "PATCH",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ organization, floatWidgetID }),
+ }
+ );
+
+ if (!response.ok) {
+ throw new Error("Failed to delete floating widget in the zone");
+ }
+
+ 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");
+ }
+ }
+};
diff --git a/app/src/services/realTimeVisulization/zoneData/deleteTemplate.ts b/app/src/services/realTimeVisulization/zoneData/deleteTemplate.ts
new file mode 100644
index 0000000..e452f6d
--- /dev/null
+++ b/app/src/services/realTimeVisulization/zoneData/deleteTemplate.ts
@@ -0,0 +1,32 @@
+let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
+// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
+
+export const deleteTemplateApi = async (
+ templateID: string,
+ organization?: string
+) => {
+ try {
+ const response = await fetch(
+ `${url_Backend_dwinzo}/api/v2/TemplateDelete/${templateID}/${organization}`,
+ {
+ method: "PATCH",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ }
+ );
+
+ if (!response.ok) {
+ throw new Error("Failed to delete template ");
+ }
+
+ 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");
+ }
+ }
+};
diff --git a/app/src/services/realTimeVisulization/zoneData/get3dWidgetData.ts b/app/src/services/realTimeVisulization/zoneData/get3dWidgetData.ts
new file mode 100644
index 0000000..b5b6200
--- /dev/null
+++ b/app/src/services/realTimeVisulization/zoneData/get3dWidgetData.ts
@@ -0,0 +1,25 @@
+let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
+// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
+export const get3dWidgetZoneData = async (
+ ZoneId?: string,
+ organization?: string
+) => {
+ try {
+ const response = await fetch(
+ `${url_Backend_dwinzo}/api/v2/3dwidgetData/${ZoneId}/${organization}`,
+ {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ }
+ );
+ if (!response.ok) {
+ throw new Error("Failed to fetch Zone3dWidgetData");
+ }
+
+ return await response.json();
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+};
diff --git a/app/src/services/realTimeVisulization/zoneData/getSelect2dZoneData.ts b/app/src/services/realTimeVisulization/zoneData/getSelect2dZoneData.ts
index 26a88c5..00d4dfe 100644
--- a/app/src/services/realTimeVisulization/zoneData/getSelect2dZoneData.ts
+++ b/app/src/services/realTimeVisulization/zoneData/getSelect2dZoneData.ts
@@ -1,4 +1,5 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
+// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
export const getSelect2dZoneData = async (
ZoneId?: string,
diff --git a/app/src/services/realTimeVisulization/zoneData/getTemplate.ts b/app/src/services/realTimeVisulization/zoneData/getTemplate.ts
new file mode 100644
index 0000000..a3aa3a3
--- /dev/null
+++ b/app/src/services/realTimeVisulization/zoneData/getTemplate.ts
@@ -0,0 +1,23 @@
+let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
+// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
+export const getTemplateData = async (organization?: string) => {
+ try {
+ const response = await fetch(
+ `${url_Backend_dwinzo}/api/v2/templateData/${organization}`,
+ {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ }
+ );
+
+ if (!response.ok) {
+ throw new Error("Failed to fetch ZoneFloatingData");
+ }
+
+ return await response.json();
+ } catch (error: any) {
+ throw new Error(error.message);
+ }
+};
diff --git a/app/src/services/realTimeVisulization/zoneData/getZones.ts b/app/src/services/realTimeVisulization/zoneData/getZones.ts
index a760959..8dbf79a 100644
--- a/app/src/services/realTimeVisulization/zoneData/getZones.ts
+++ b/app/src/services/realTimeVisulization/zoneData/getZones.ts
@@ -1,4 +1,5 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
+// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
export const getZoneData = async (zoneId: string, organization: string) => {
console.log("organization: ", organization);
@@ -14,7 +15,6 @@ export const getZoneData = async (zoneId: string, organization: string) => {
}
);
-
if (!response.ok) {
throw new Error("Failed to fetch zoneData");
}
diff --git a/app/src/services/realTimeVisulization/zoneData/loadTemplate.ts b/app/src/services/realTimeVisulization/zoneData/loadTemplate.ts
new file mode 100644
index 0000000..915160d
--- /dev/null
+++ b/app/src/services/realTimeVisulization/zoneData/loadTemplate.ts
@@ -0,0 +1,33 @@
+let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
+// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
+export const loadTempleteApi = async (
+ templateID: string,
+ zoneId: string,
+ organization: string
+) => {
+ try {
+ const response = await fetch(
+ `${url_Backend_dwinzo}/api/v2/TemplatetoZone`,
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ organization, zoneId, templateID }),
+ }
+ );
+
+ if (!response.ok) {
+ throw new Error("Failed to add 3dwidget in the zone");
+ }
+
+ 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");
+ }
+ }
+};
diff --git a/app/src/services/realTimeVisulization/zoneData/saveTempleteApi.ts b/app/src/services/realTimeVisulization/zoneData/saveTempleteApi.ts
new file mode 100644
index 0000000..5c18031
--- /dev/null
+++ b/app/src/services/realTimeVisulization/zoneData/saveTempleteApi.ts
@@ -0,0 +1,28 @@
+let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
+// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
+export const saveTemplateApi = async (organization: string, template: {}) => {
+ console.log('template: ', template);
+ try {
+ const response = await fetch(`${url_Backend_dwinzo}/api/v2/template/save`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ organization, template }),
+ });
+
+ if (!response.ok) {
+ throw new Error("Failed to save template zone");
+ }
+
+ const result = await response.json();
+ console.log('result: ', result);
+ return result;
+ } catch (error) {
+ if (error instanceof Error) {
+ throw new Error(error.message);
+ } else {
+ throw new Error("An unknown error occurred");
+ }
+ }
+};
diff --git a/app/src/services/realTimeVisulization/zoneData/useFloatingDataStore.ts b/app/src/services/realTimeVisulization/zoneData/useFloatingDataStore.ts
new file mode 100644
index 0000000..39a542a
--- /dev/null
+++ b/app/src/services/realTimeVisulization/zoneData/useFloatingDataStore.ts
@@ -0,0 +1,8 @@
+import { create } from "zustand";
+
+const useFloatingDataStore = create((set) => ({
+ floatingdata: [], // Initial state
+ setfloatingadata: (newData: []) => set({ floatingdata: newData }), // Setter function
+}));
+
+export default useFloatingDataStore;
diff --git a/app/src/services/simulation/getAssetEventType.ts b/app/src/services/simulation/getAssetEventType.ts
new file mode 100644
index 0000000..a681b12
--- /dev/null
+++ b/app/src/services/simulation/getAssetEventType.ts
@@ -0,0 +1,25 @@
+let url_Backend_dwinzo = `http://${process.env.REACT_APP_TEST}`;
+
+export const getAssetEventType = async (modelId: string, organization: string) => {
+ try {
+ const response = await fetch(`${url_Backend_dwinzo}/api/v2/pointData/${modelId}/${organization}`, {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+
+ if (!response.ok) {
+ throw new Error("Failed to fetch model event type");
+ }
+
+ 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");
+ }
+ }
+};
\ No newline at end of file
diff --git a/app/src/store/store.ts b/app/src/store/store.ts
index a64f417..6affa99 100644
--- a/app/src/store/store.ts
+++ b/app/src/store/store.ts
@@ -5,19 +5,16 @@ import { io } from "socket.io-client";
export const useSocketStore = create((set: any, get: any) => ({
socket: null,
- initializeSocket: (email: any) => {
+ initializeSocket: (email: string, organization: string) => {
const existingSocket = get().socket;
if (existingSocket) {
return;
}
- const socket = io(
- `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/`,
- {
- reconnection: false,
- auth: { email },
- }
- );
+ const socket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`, {
+ reconnection: false,
+ auth: { email, organization },
+ });
set({ socket });
},
@@ -348,10 +345,30 @@ export const useStartSimulation = create((set: any) => ({
startSimulation: false,
setStartSimulation: (x: any) => set({ startSimulation: x }),
}));
+
+export const useEyeDropMode = create((set: any) => ({
+ eyeDropMode: false,
+ setEyeDropMode: (x: any) => set({ eyeDropMode: x }),
+}));
+
+export const useEditingPoint = create((set: any) => ({
+ editingPoint: false,
+ setEditingPoint: (x: any) => set({ editingPoint: x }),
+}));
+
+export const usePreviewPosition = create<{
+ previewPosition: { x: number; y: number } | null;
+ setPreviewPosition: (position: { x: number; y: number } | null) => void;
+}>((set) => ({
+ previewPosition: null,
+ setPreviewPosition: (position) => set({ previewPosition: position }),
+}));
+
export const usezoneTarget = create((set: any) => ({
zoneTarget: [],
setZoneTarget: (x: any) => set({ zoneTarget: x }),
}));
+
export const usezonePosition = create((set: any) => ({
zonePosition: [],
setZonePosition: (x: any) => set({ zonePosition: x }),
@@ -371,7 +388,9 @@ export const useAsset3dWidget = create((set: any) => ({
widgetSelect: "",
setWidgetSelect: (x: any) => set({ widgetSelect: x }),
}));
+
export const useWidgetSubOption = create((set: any) => ({
widgetSubOption: "2D",
setWidgetSubOption: (x: any) => set({ widgetSubOption: x }),
}));
+
diff --git a/app/src/store/useChartStore.ts b/app/src/store/useChartStore.ts
index 4d61952..079b9ff 100644
--- a/app/src/store/useChartStore.ts
+++ b/app/src/store/useChartStore.ts
@@ -9,20 +9,26 @@ interface MeasurementStore {
measurements: Record; // Change array to Record
interval: number;
duration: string;
+ name: string;
setMeasurements: (newMeasurements: Record) => void;
updateDuration: (newDuration: string) => void;
+ updateName: (newName: string) => void;
}
const useChartStore = create((set) => ({
measurements: {}, // Initialize as an empty object
interval: 1000,
duration: "1h",
+ name:'',
setMeasurements: (newMeasurements) =>
set(() => ({ measurements: newMeasurements })),
updateDuration: (newDuration) =>
set(() => ({ duration: newDuration })),
+
+ updateName: (newName) =>
+ set(() => ({ duration: newName })),
}));
export default useChartStore;
diff --git a/app/src/store/useDroppedObjectsStore.ts b/app/src/store/useDroppedObjectsStore.ts
index dc648a9..83f3a8a 100644
--- a/app/src/store/useDroppedObjectsStore.ts
+++ b/app/src/store/useDroppedObjectsStore.ts
@@ -1,4 +1,5 @@
import { create } from "zustand";
+import { addingFloatingWidgets } from "../services/realTimeVisulization/zoneData/addFloatingWidgets";
type DroppedObject = {
className: string;
@@ -35,6 +36,8 @@ type DroppedObjectsState = {
bottom: number | "auto";
}
) => void;
+ deleteObject: (zoneName: string, index: number) => void; // Add this line
+ duplicateObject: (zoneName: string, index: number) => void; // Add this line
};
export const useDroppedObjectsStore = create((set) => ({
@@ -73,6 +76,72 @@ export const useDroppedObjectsStore = create((set) => ({
},
};
}),
+
+ deleteObject: (zoneName: string, index: number) =>
+ set((state) => {
+ const zone = state.zones[zoneName];
+ if (!zone) return state;
+ return {
+ zones: {
+ [zoneName]: {
+ ...zone,
+ objects: zone.objects.filter((_, i) => i !== index), // Remove object at the given index
+ },
+ },
+ };
+ }),
+ duplicateObject: async (zoneName: string, index: number) => {
+ const state = useDroppedObjectsStore.getState(); // Get the current state
+ const zone = state.zones[zoneName];
+
+ if (!zone) return;
+
+ const originalObject = zone.objects[index];
+ if (!originalObject) return;
+
+ const email = localStorage.getItem("email") || "";
+ const organization = email?.split("@")[1]?.split(".")[0];
+
+ // Create a shallow copy of the object with a unique ID and slightly adjusted position
+ const duplicatedObject: DroppedObject = {
+ ...originalObject,
+ id: `${originalObject.id}-copy-${Date.now()}`, // Unique ID
+ position: {
+ ...originalObject.position,
+ top:
+ typeof originalObject.position.top === "number"
+ ? originalObject.position.top + 20 // Offset vertically
+ : originalObject.position.top,
+ left:
+ typeof originalObject.position.left === "number"
+ ? originalObject.position.left + 20 // Offset horizontally
+ : originalObject.position.left,
+ },
+ };
+
+ console.log("zone: ", zone.zoneId);
+ console.log("duplicatedObject: ", duplicatedObject);
+
+ // Make async API call outside of Zustand set function
+ // let response = await addingFloatingWidgets(
+ // zone.zoneId,
+ // organization,
+ // duplicatedObject
+ // );
+
+ // if (response.message === "FloatWidget created successfully") {
+ // Update the state inside `set`
+ useDroppedObjectsStore.setState((state) => ({
+ zones: {
+ ...state.zones,
+ [zoneName]: {
+ ...state.zones[zoneName],
+ objects: [...state.zones[zoneName].objects, duplicatedObject], // Append duplicated object
+ },
+ },
+ }));
+ // }
+ },
}));
export interface DroppedObjects {
@@ -90,3 +159,13 @@ export interface Zones {
zoneId: string;
objects: DroppedObject[];
}
+
+export const use3DWidget = create((set: any) => ({
+ widgets3D: [],
+ setWidgets3D: (x: any) => set({ widgets3D: x }),
+}));
+
+export const useFloatingWidget = create((set: any) => ({
+ floatingWidget: [],
+ setFloatingWidget: (x: any) => set({ floatingWidget: x }),
+}));
diff --git a/app/src/store/useTemplateStore.ts b/app/src/store/useTemplateStore.ts
index 2adcd2f..d416154 100644
--- a/app/src/store/useTemplateStore.ts
+++ b/app/src/store/useTemplateStore.ts
@@ -1,7 +1,5 @@
import { create } from "zustand";
-// type Side = "top" | "bottom" | "left" | "right";
-
export interface Widget {
id: string;
type: string;
@@ -15,21 +13,34 @@ export interface Template {
name: string;
panelOrder: string[];
widgets: Widget[];
- snapshot?: string | null; // Add an optional image property (base64)
+ floatingWidget: any[]; // Fixed empty array type
+ widgets3D: any[]; // Fixed empty array type
+ snapshot?: string | null;
}
interface TemplateStore {
templates: Template[];
addTemplate: (template: Template) => void;
+ setTemplates: (templates: Template[]) => void; // Changed from `setTemplate`
removeTemplate: (id: string) => void;
}
export const useTemplateStore = create((set) => ({
templates: [],
+
+ // Add a new template to the list
addTemplate: (template) =>
set((state) => ({
templates: [...state.templates, template],
})),
+
+ // Set (replace) the templates list with a new array
+ setTemplates: (templates) =>
+ set(() => ({
+ templates, // Ensures no duplication
+ })),
+
+ // Remove a template by ID
removeTemplate: (id) =>
set((state) => ({
templates: state.templates.filter((t) => t.id !== id),
@@ -37,3 +48,4 @@ export const useTemplateStore = create((set) => ({
}));
export default useTemplateStore;
+
diff --git a/app/src/store/useWidgetStore.ts b/app/src/store/useWidgetStore.ts
index 115c6aa..047b57b 100644
--- a/app/src/store/useWidgetStore.ts
+++ b/app/src/store/useWidgetStore.ts
@@ -33,7 +33,7 @@ interface WidgetStore {
setDraggedAsset: (asset: Widget | null) => void; // Setter for draggedAsset
addWidget: (widget: Widget) => void; // Add a new widget
setWidgets: (widgets: Widget[]) => void; // Replace the entire widgets array
- setSelectedChartId: (widget: Widget | null) => void; // Set the selected chart/widget
+ setSelectedChartId: (widget: any | null) => void; // Set the selected chart/widget
}
// Create the store with Zustand
diff --git a/app/src/styles/layout/sidebar.scss b/app/src/styles/layout/sidebar.scss
index e45dc20..f5e1b27 100644
--- a/app/src/styles/layout/sidebar.scss
+++ b/app/src/styles/layout/sidebar.scss
@@ -318,6 +318,25 @@
.sidebar-right-content-container {
.dataSideBar {
+ .inputs-wrapper {
+ .datas {
+
+ .input-value {
+
+ padding: 5px 10px;
+ }
+
+ .input-value,
+ .rename-input {
+ margin-right: 24px;
+ width: 170px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ }
+ }
+
width: 100%;
height: 100%;
display: flex;
@@ -991,11 +1010,9 @@
top: 50%;
right: -10px;
transform: translate(0, -50%);
- background: linear-gradient(
- 144.19deg,
- #f1e7cd 16.62%,
- #fffaef 85.81%
- );
+ background: linear-gradient(144.19deg,
+ #f1e7cd 16.62%,
+ #fffaef 85.81%);
}
.category-image {
@@ -1037,10 +1054,14 @@
}
.asset-image {
+ height: 100%;
+ width: 100%;
position: absolute;
- top: 50%;
- right: 5px;
- transform: translate(0, -50%);
+ // top: 50%;
+ // right: 5px;
+ // transform: translate(0, -50%);
+ top: 0;
+ left: 0;
z-index: 2;
}
}
@@ -1054,4 +1075,4 @@
cursor: pointer;
}
}
-}
+}
\ No newline at end of file
diff --git a/app/src/styles/pages/dashboard.scss b/app/src/styles/pages/dashboard.scss
index e5b07a4..3fc9a05 100644
--- a/app/src/styles/pages/dashboard.scss
+++ b/app/src/styles/pages/dashboard.scss
@@ -1,221 +1,221 @@
-@use "../abstracts/variables.scss" as *;
-@use "../abstracts/mixins.scss" as *;
-
-.dashboard-main {
- height: 100vh;
- width: 100vw;
- display: flex;
- .side-pannel-container {
- padding: 32px;
- min-width: 240px;
- height: 100vh;
- display: flex;
- flex-direction: column;
- gap: 16px;
- border-right: 1px solid var(--border-color);
- .side-pannel-header {
- @include flex-space-between;
- .user-container {
- @include flex-center;
- gap: 6px;
- .user-profile {
- height: 32px;
- width: 32px;
- line-height: 32px;
- text-align: center;
- font-weight: var(--font-weight-medium);
- background: var(--accent-color);
- color: var(--primary-color);
- border-radius: #{$border-radius-circle};
- }
- .user-name {
- color: var(--accent-color);
- }
- }
- .notifications-container {
- @include flex-center;
- height: 24px;
- width: 24px;
- cursor: pointer;
- }
- }
- .new-project-button {
- padding: 12px 16px;
- cursor: not-allowed;
- color: var(--accent-color);
- background-color: var(--background-color-secondary);
- border-radius: #{$border-radius-large};
- }
- .side-bar-content-container {
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- height: 100%;
- .side-bar-options-container {
- .option-list {
- display: flex;
- align-items: center;
- gap: 8px;
- padding: 6px 10px;
- margin: 4px 0;
- border-radius: #{$border-radius-medium};
- &:hover {
- background: var(--background-color-secondary);
- }
- }
- .active {
- color: var(--accent-color);
- font-weight: var(--font-weight-medium);
- background-color: var(--highlight-accent-color);
- &:hover {
- background-color: var(--highlight-accent-color);
- }
- }
- }
- }
- }
- .dashboard-home-container {
- width: 100%;
- .dashboard-navbar-container {
- margin-top: 28px;
- padding: 8px 34px 8px 12px;
- @include flex-center;
- .title {
- text-transform: capitalize;
- font-size: var(--font-size-large);
- width: 100%;
- }
- .market-place-button {
- @include flex-center;
- gap: 6px;
- padding: 8px 14px;
- background: var(--accent-gradient-color);
- white-space: nowrap;
- border-radius: #{$border-radius-large};
- color: var(--primary-color);
- }
- .search-wrapper {
- width: 400px;
- }
- }
- .container {
- margin: 22px 0;
- width: 100%;
- padding: 0 12px;
- .header {
- font-size: var(--font-size-large);
- }
- .cards-container {
- display: flex;
- flex-wrap: wrap;
- position: relative;
- width: 100%;
- padding: 8px;
- gap: 18px;
- }
- }
- }
-}
-
-.dashboard-card-container {
- height: 242px;
- width: calc((100% / 5) - 23px);
- min-width: 260px;
- position: relative;
- border: 1px solid var(--border-color);
- border-radius: #{$border-radius-large};
- overflow: hidden;
- .preview-container {
- height: 100%;
- width: 100%;
- img {
- height: 100%;
- width: 100%;
- object-fit: cover;
- vertical-align: top;
- border: none;
- outline: none;
- }
- }
- .project-details-container {
- @include flex-space-between;
- position: absolute;
- bottom: 0;
- width: 100%;
- padding: 8px 16px;
- background: var(--primary-color);
- border-radius: 10px;
- .project-details {
- .project-name {
- margin-bottom: 2px;
- }
- .project-data {
- color: var(--accent-color);
- }
- }
- .users-list-container {
- @include flex-center;
- gap: 6px;
- .user-profile {
- height: 26px;
- width: 26px;
- line-height: 26px;
- text-align: center;
- background-color: var(--accent-color);
- color: var(--primary-color);
- border-radius: #{$border-radius-circle};
- }
- }
- }
-}
-
-.market-place-banner-container {
- width: 100%;
- height: 230px;
- overflow: hidden;
- position: relative;
- padding: 0 24px;
- img {
- height: 100%;
- width: 100%;
- object-fit: cover;
- border-radius: 30px;
- }
- .hero-text {
- position: absolute;
- left: 52px;
- bottom: 25px;
- font-size: 48px;
- font-family: #{$font-roboto};
- font-weight: 800;
- color: #ffffff;
- text-transform: uppercase;
- }
- .context {
- position: absolute;
- top: 20px;
- right: 58px;
- text-transform: uppercase;
- font-size: 22px;
- width: 300px;
- color: #ffffff;
- font-family: #{$font-roboto};
- }
- .arrow-context {
- position: absolute;
- bottom: 27px;
- right: 300px;
- }
- .explore-button {
- position: absolute;
- top: 95px;
- right: 52px;
- padding: 10px 20px;
- text-transform: uppercase;
- font-size: 24px;
- border: 1px solid #ffffff;
- color: #ffffff;
- font-family: #{$font-roboto};
- cursor: pointer;
- }
-}
+@use "../abstracts/variables.scss" as *;
+@use "../abstracts/mixins.scss" as *;
+
+.dashboard-main {
+ height: 100vh;
+ width: 100vw;
+ display: flex;
+ .side-pannel-container {
+ padding: 32px;
+ min-width: 240px;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ border-right: 1px solid var(--border-color);
+ .side-pannel-header {
+ @include flex-space-between;
+ .user-container {
+ @include flex-center;
+ gap: 6px;
+ .user-profile {
+ height: 32px;
+ width: 32px;
+ line-height: 32px;
+ text-align: center;
+ font-weight: var(--font-weight-medium);
+ background: var(--accent-color);
+ color: var(--primary-color);
+ border-radius: #{$border-radius-circle};
+ }
+ .user-name {
+ color: var(--accent-color);
+ }
+ }
+ .notifications-container {
+ @include flex-center;
+ height: 24px;
+ width: 24px;
+ cursor: pointer;
+ }
+ }
+ .new-project-button {
+ padding: 12px 16px;
+ cursor: not-allowed;
+ color: var(--accent-color);
+ background-color: var(--background-color-secondary);
+ border-radius: #{$border-radius-large};
+ }
+ .side-bar-content-container {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ height: 100%;
+ .side-bar-options-container {
+ .option-list {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 6px 10px;
+ margin: 4px 0;
+ border-radius: #{$border-radius-medium};
+ &:hover {
+ background: var(--background-color-secondary);
+ }
+ }
+ .active {
+ color: var(--accent-color);
+ font-weight: var(--font-weight-medium);
+ background-color: var(--highlight-accent-color);
+ &:hover {
+ background-color: var(--highlight-accent-color);
+ }
+ }
+ }
+ }
+ }
+ .dashboard-home-container {
+ width: 100%;
+ .dashboard-navbar-container {
+ margin-top: 28px;
+ padding: 8px 34px 8px 12px;
+ @include flex-center;
+ .title {
+ text-transform: capitalize;
+ font-size: var(--font-size-large);
+ width: 100%;
+ }
+ .market-place-button {
+ @include flex-center;
+ gap: 6px;
+ padding: 8px 14px;
+ background: var(--accent-gradient-color);
+ white-space: nowrap;
+ border-radius: #{$border-radius-large};
+ color: var(--primary-color);
+ }
+ .search-wrapper {
+ width: 400px;
+ }
+ }
+ .container {
+ margin: 22px 0;
+ width: 100%;
+ padding: 0 12px;
+ .header {
+ font-size: var(--font-size-large);
+ }
+ .cards-container {
+ display: flex;
+ flex-wrap: wrap;
+ position: relative;
+ width: 100%;
+ padding: 8px;
+ gap: 18px;
+ }
+ }
+ }
+}
+
+.dashboard-card-container {
+ height: 242px;
+ width: calc((100% / 5) - 23px);
+ min-width: 260px;
+ position: relative;
+ border: 1px solid var(--border-color);
+ border-radius: #{$border-radius-large};
+ overflow: hidden;
+ .preview-container {
+ height: 100%;
+ width: 100%;
+ img {
+ height: 100%;
+ width: 100%;
+ object-fit: cover;
+ vertical-align: top;
+ border: none;
+ outline: none;
+ }
+ }
+ .project-details-container {
+ @include flex-space-between;
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ padding: 8px 16px;
+ background: var(--primary-color);
+ border-radius: 10px;
+ .project-details {
+ .project-name {
+ margin-bottom: 2px;
+ }
+ .project-data {
+ color: var(--accent-color);
+ }
+ }
+ .users-list-container {
+ @include flex-center;
+ gap: 6px;
+ .user-profile {
+ height: 26px;
+ width: 26px;
+ line-height: 26px;
+ text-align: center;
+ background-color: var(--accent-color);
+ color: var(--primary-color);
+ border-radius: #{$border-radius-circle};
+ }
+ }
+ }
+}
+
+.market-place-banner-container {
+ width: 100%;
+ height: 230px;
+ overflow: hidden;
+ position: relative;
+ padding: 0 24px;
+ img {
+ height: 100%;
+ width: 100%;
+ object-fit: cover;
+ border-radius: 30px;
+ }
+ .hero-text {
+ position: absolute;
+ left: 52px;
+ bottom: 25px;
+ font-size: 48px;
+ font-family: #{$font-roboto};
+ font-weight: 800;
+ color: #ffffff;
+ text-transform: uppercase;
+ }
+ .context {
+ position: absolute;
+ top: 20px;
+ right: 58px;
+ text-transform: uppercase;
+ font-size: 22px;
+ width: 300px;
+ color: #ffffff;
+ font-family: #{$font-roboto};
+ }
+ .arrow-context {
+ position: absolute;
+ bottom: 27px;
+ right: 300px;
+ }
+ .explore-button {
+ position: absolute;
+ top: 95px;
+ right: 52px;
+ padding: 10px 20px;
+ text-transform: uppercase;
+ font-size: 24px;
+ border: 1px solid #ffffff;
+ color: #ffffff;
+ font-family: #{$font-roboto};
+ cursor: pointer;
+ }
+}
diff --git a/app/src/styles/pages/realTimeViz.scss b/app/src/styles/pages/realTimeViz.scss
index aa9e1aa..d58f12d 100644
--- a/app/src/styles/pages/realTimeViz.scss
+++ b/app/src/styles/pages/realTimeViz.scss
@@ -542,4 +542,145 @@
.zone.active {
background-color: #007bff;
color: white;
+}
+
+.floating-wrapper {
+ .icon {
+ width: 25px !important;
+ height: 25px !important;
+ background-color: transparent;
+ }
+
+ .kebab {
+ width: 30px;
+ height: 30px;
+ position: absolute !important;
+ top: 0px;
+ right: 0px;
+ z-index: 10;
+ cursor: pointer;
+ @include flex-center;
+ }
+
+ .kebab-options {
+ position: absolute;
+ top: 18px;
+ right: 5px;
+ transform: translate(0px, 0);
+ background-color: var(--background-color);
+ z-index: 10;
+
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ border-radius: 4px;
+
+ box-shadow: var(--box-shadow-medium);
+
+ .btn {
+ display: flex;
+ gap: 6px;
+ align-items: center;
+ padding: 5px 10px;
+ color: var(--text-color);
+ cursor: pointer;
+
+ &:hover {
+ .label {
+ color: var(--accent-color);
+ }
+ }
+
+ &:hover {
+ background-color: var(--highlight-accent-color);
+ width: 100%;
+
+ svg {
+ &:first-child {
+ fill: var(--accent-color);
+ }
+
+ &:last-child {
+ fill: auto;
+ stroke: var(--accent-color);
+ }
+ }
+ }
+ }
+
+ .dublicate {
+ cursor: not-allowed;
+ }
+ }
+}
+
+
+
+
+
+.distance-line {
+ position: absolute;
+ border-style: dashed;
+ border-color: var(--accent-color); /* Green color for visibility */
+ border-width: 1px;
+ pointer-events: none; /* Ensure lins don't interfere with dragging */
+ z-index: 10000;
+}
+
+/* Label styles for displaying distance values */
+.distance-label {
+ position: absolute;
+ background-color: var(--accent-color);
+ color: white;
+ font-size: 12px;
+ padding: 2px 6px;
+ border-radius: 3px;
+ white-space: nowrap;
+ transform: translate(-50%, -50%); /* Center the label */
+}
+
+/* Specific styles for each type of line */
+
+/* Top distance line */
+.distance-line.top {
+ border-bottom: none; /* Remove bottom border for a single line */
+ width: 2px; /* Thin vertical line */
+}
+
+.distance-line.top .distance-label {
+ top: -10px; /* Position label above the line */
+ left: 50%; /* Center horizontally */
+}
+
+/* Bottom distance line */
+.distance-line.bottom {
+ border-top: none; /* Remove top border for a single line */
+ width: 2px; /* Thin vertical line */
+}
+
+.distance-line.bottom .distance-label {
+ bottom: -10px; /* Position label below the line */
+ left: 50%; /* Center horizontally */
+}
+
+/* Left distance line */
+.distance-line.left {
+ border-right: none; /* Remove right border for a single line */
+ height: 2px; /* Thin horizontal line */
+}
+
+.distance-line.left .distance-label {
+ left: -10px; /* Position label to the left of the line */
+ top: 50%; /* Center vertically */
+}
+
+/* Right distance line */
+.distance-line.right {
+ border-left: none; /* Remove left border for a single line */
+ height: 2px; /* Thin horizontal line */
+}
+
+.distance-line.right .distance-label {
+ right: -10px; /* Position label to the right of the line */
+ top: 50%; /* Center vertically */
}
\ No newline at end of file
diff --git a/app/src/types/world/worldConstants.ts b/app/src/types/world/worldConstants.ts
index 0a62e9d..2bc3835 100644
--- a/app/src/types/world/worldConstants.ts
+++ b/app/src/types/world/worldConstants.ts
@@ -1,64 +1,63 @@
const savedTheme: string | null = localStorage.getItem("theme");
export type Controls = {
- azimuthRotateSpeed: number;
- polarRotateSpeed: number;
- truckSpeed: number;
- minDistance: number;
- maxDistance: number;
- maxPolarAngle: number;
- leftMouse: number;
- forwardSpeed: number;
- backwardSpeed: number;
- leftSpeed: number;
- rightSpeed: number;
+ azimuthRotateSpeed: number;
+ polarRotateSpeed: number;
+ truckSpeed: number;
+ minDistance: number;
+ maxDistance: number;
+ maxPolarAngle: number;
+ leftMouse: number;
+ forwardSpeed: number;
+ backwardSpeed: number;
+ leftSpeed: number;
+ rightSpeed: number;
};
export type ThirdPersonControls = {
- azimuthRotateSpeed: number;
- polarRotateSpeed: number;
- truckSpeed: number;
- maxDistance: number;
- maxPolarAngle: number;
- minZoom: number;
- maxZoom: number;
- targetOffset: number;
- cameraHeight: number;
- leftMouse: number;
- rightMouse: number;
- wheelMouse: number;
- middleMouse: number;
+ azimuthRotateSpeed: number;
+ polarRotateSpeed: number;
+ truckSpeed: number;
+ maxDistance: number;
+ maxPolarAngle: number;
+ minZoom: number;
+ maxZoom: number;
+ targetOffset: number;
+ cameraHeight: number;
+ leftMouse: number;
+ rightMouse: number;
+ wheelMouse: number;
+ middleMouse: number;
};
export type ControlsTransition = {
- leftMouse: number;
- rightMouse: number;
- wheelMouse: number;
- middleMouse: number;
+ leftMouse: number;
+ rightMouse: number;
+ wheelMouse: number;
+ middleMouse: number;
};
export type TwoDimension = {
- defaultPosition: [x: number, y: number, z: number];
- defaultTarget: [x: number, y: number, z: number];
- defaultAzimuth: number;
- minDistance: number;
- leftMouse: number;
- rightMouse: number;
+ defaultPosition: [x: number, y: number, z: number];
+ defaultTarget: [x: number, y: number, z: number];
+ defaultAzimuth: number;
+ minDistance: number;
+ leftMouse: number;
+ rightMouse: number;
};
export type ThreeDimension = {
- defaultPosition: [x: number, y: number, z: number];
- defaultTarget: [x: number, y: number, z: number];
- defaultRotation: [x: number, y: number, z: number];
- defaultAzimuth: number;
- boundaryBottom: [x: number, y: number, z: number];
- boundaryTop: [x: number, y: number, z: number];
- minDistance: number;
- leftMouse: number;
- rightMouse: number;
+ defaultPosition: [x: number, y: number, z: number];
+ defaultTarget: [x: number, y: number, z: number];
+ defaultRotation: [x: number, y: number, z: number];
+ defaultAzimuth: number;
+ boundaryBottom: [x: number, y: number, z: number];
+ boundaryTop: [x: number, y: number, z: number];
+ minDistance: number;
+ leftMouse: number;
+ rightMouse: number;
};
-
export type GridConfig = {
size: number;
divisions: number;
@@ -95,19 +94,19 @@ export type ShadowConfig = {
}
export type SkyConfig = {
- defaultTurbidity: number;
- maxTurbidity: number;
- minTurbidity: number;
- defaultRayleigh: number;
- mieCoefficient: number;
- mieDirectionalG: number;
- skyDistance: number;
-}
+ defaultTurbidity: number;
+ maxTurbidity: number;
+ minTurbidity: number;
+ defaultRayleigh: number;
+ mieCoefficient: number;
+ mieDirectionalG: number;
+ skyDistance: number;
+};
export type AssetConfig = {
- defaultScaleBeforeGsap: [number, number, number];
- defaultScaleAfterGsap: [number, number, number];
-}
+ defaultScaleBeforeGsap: [number, number, number];
+ defaultScaleAfterGsap: [number, number, number];
+};
export type PointConfig = {
defaultInnerColor: string;
@@ -140,10 +139,10 @@ export type LineConfig = {
}
export type WallConfig = {
- defaultColor: string;
- height: number;
- width: number;
-}
+ defaultColor: string;
+ height: number;
+ width: number;
+};
export type FloorConfig = {
defaultColor: string;
@@ -152,9 +151,9 @@ export type FloorConfig = {
}
export type RoofConfig = {
- defaultColor: string;
- height: number;
-}
+ defaultColor: string;
+ height: number;
+};
export type AisleConfig = {
width: number;
@@ -169,75 +168,75 @@ export type ZoneConfig = {
}
export type ColumnConfig = {
- defaultColor: string;
-}
+ defaultColor: string;
+};
export type OutlineConfig = {
- assetSelectColor: number;
- assetDeleteColor: number;
-}
-
-
+ assetSelectColor: number;
+ assetDeleteColor: number;
+};
+export type DistanceConfig = {
+ minDistance: number;
+ maxDistance: number;
+};
export const firstPersonControls: Controls = {
- azimuthRotateSpeed: 0.3, // Speed of rotation around the azimuth axis
- polarRotateSpeed: 0.3, // Speed of rotation around the polar axis
- truckSpeed: 10, // Speed of truck movement
- minDistance: 0, // Minimum distance from the target
- maxDistance: 0, // Maximum distance from the target
- maxPolarAngle: Math.PI, // Maximum polar angle
-
- leftMouse: 1, // Mouse button for rotation (ROTATE)
-
- forwardSpeed: 0.3, // Speed of forward movement
- backwardSpeed: -0.3, // Speed of backward movement
- leftSpeed: -0.3, // Speed of left movement
- rightSpeed: 0.3, // Speed of right movement
+ azimuthRotateSpeed: 0.3, // Speed of rotation around the azimuth axis
+ polarRotateSpeed: 0.3, // Speed of rotation around the polar axis
+ truckSpeed: 10, // Speed of truck movement
+ minDistance: 0, // Minimum distance from the target
+ maxDistance: 0, // Maximum distance from the target
+ maxPolarAngle: Math.PI, // Maximum polar angle
+ leftMouse: 1, // Mouse button for rotation (ROTATE)
+ forwardSpeed: 0.3, // Speed of forward movement
+ backwardSpeed: -0.3, // Speed of backward movement
+ leftSpeed: -0.3, // Speed of left movement
+ rightSpeed: 0.3, // Speed of right movement
};
export const thirdPersonControls: ThirdPersonControls = {
- azimuthRotateSpeed: 1, // Speed of rotation around the azimuth axis
- polarRotateSpeed: 1, // Speed of rotation around the polar axis
- truckSpeed: 2, // Speed of truck movement
- maxDistance: 100, // Maximum distance from the target
- maxPolarAngle: Math.PI / 2 - 0.05, // Maximum polar angle
- minZoom: 6, // Minimum zoom level
- maxZoom: 21, // Maximum zoom level
- targetOffset: 20, // Offset of the target from the camera
- cameraHeight: 30, // Height of the camera
- leftMouse: 2, // Mouse button for panning
- rightMouse: 1, // Mouse button for rotation
- wheelMouse: 8, // Mouse button for zooming
- middleMouse: 8, // Mouse button for zooming
+ azimuthRotateSpeed: 1, // Speed of rotation around the azimuth axis
+ polarRotateSpeed: 1, // Speed of rotation around the polar axis
+ truckSpeed: 2, // Speed of truck movement
+ maxDistance: 100, // Maximum distance from the target
+ maxPolarAngle: Math.PI / 2 - 0.05, // Maximum polar angle
+ minZoom: 6, // Minimum zoom level
+ maxZoom: 21, // Maximum zoom level
+ targetOffset: 20, // Offset of the target from the camera
+ cameraHeight: 30, // Height of the camera
+ leftMouse: 2, // Mouse button for panning
+ rightMouse: 1, // Mouse button for rotation
+ wheelMouse: 8, // Mouse button for zooming
+ middleMouse: 8, // Mouse button for zooming
};
export const controlsTransition: ControlsTransition = {
- leftMouse: 0, // Mouse button for no action
- rightMouse: 0, // Mouse button for no action
- wheelMouse: 0, // Mouse button for no action
- middleMouse: 0, // Mouse button for no action
+ leftMouse: 0, // Mouse button for no action
+ rightMouse: 0, // Mouse button for no action
+ wheelMouse: 0, // Mouse button for no action
+ middleMouse: 0, // Mouse button for no action
};
export const twoDimension: TwoDimension = {
- defaultPosition: [0, 100, 0], // Default position of the camera
- defaultTarget: [0, 0, 0], // Default target of the camera
- defaultAzimuth: 0, // Default azimuth of the camera
- minDistance: 25, // Minimum distance from the target
- leftMouse: 2, // Mouse button for panning
- rightMouse: 0, // Mouse button for no action
+ defaultPosition: [0, 100, 0], // Default position of the camera
+ defaultTarget: [0, 0, 0], // Default target of the camera
+ defaultAzimuth: 0, // Default azimuth of the camera
+ minDistance: 25, // Minimum distance from the target
+ leftMouse: 2, // Mouse button for panning
+ rightMouse: 0, // Mouse button for no action
};
export const threeDimension: ThreeDimension = {
- defaultPosition: [0, 40, 30], // Default position of the camera
- defaultTarget: [0, 0, 0], // Default target of the camera
- defaultRotation: [0, 0, 0], // Default rotation of the camera
- defaultAzimuth: 0, // Default azimuth of the camera
- boundaryBottom: [-150, 0, -150], // Bottom boundary of the camera movement
- boundaryTop: [150, 100, 150], // Top boundary of the camera movement
- minDistance: 1, // Minimum distance from the target
- leftMouse: 2, // Mouse button for panning
- rightMouse: 1, // Mouse button for rotation
+ defaultPosition: [0, 40, 30], // Default position of the camera
+ defaultTarget: [0, 0, 0], // Default target of the camera
+ defaultRotation: [0, 0, 0], // Default rotation of the camera
+ defaultAzimuth: 0, // Default azimuth of the camera
+ boundaryBottom: [-150, 0, -150], // Bottom boundary of the camera movement
+ boundaryTop: [150, 100, 150], // Top boundary of the camera movement
+ minDistance: 1, // Minimum distance from the target
+ leftMouse: 2, // Mouse button for panning
+ rightMouse: 1, // Mouse button for rotation
};
export const camPositionUpdateInterval: number = 200; // Interval for updating the camera position
@@ -253,9 +252,9 @@ export const gridConfig: GridConfig = {
}
export const planeConfig: PlaneConfig = {
- position2D: [0, -0.5, 0], // Position of the plane
- position3D: [0, -0.65, 0], // Position of the plane
- rotation: -Math.PI / 2, // Rotation of the plane
+ position2D: [0, -0.5, 0], // Position of the plane
+ position3D: [0, -0.65, 0], // Position of the plane
+ rotation: -Math.PI / 2, // Rotation of the plane
width: 300, // Width of the plane
height: 300, // Height of the plane
@@ -263,100 +262,91 @@ export const planeConfig: PlaneConfig = {
}
export const shadowConfig: ShadowConfig = {
- shadowOffset: 50, // Offset of the shadow
-
- shadowmapSizewidth: 1024, // Width of the shadow map
- shadowmapSizeheight: 1024, // Height of the shadow map
- // shadowmapSizewidth: 8192, // Width of the shadow map
- // shadowmapSizeheight: 8192, // Height of the shadow map
- shadowcamerafar: 70, // Far plane of the shadow camera
- shadowcameranear: 0.1, // Near plane of the shadow camera
- shadowcameratop: 30, // Top plane of the shadow camera
- shadowcamerabottom: -30, // Bottom plane of the shadow camera
- shadowcameraleft: -30, // Left plane of the shadow camera
- shadowcameraright: 30, // Right plane of the shadow camera
- shadowbias: -0.001, // Bias of the shadow
- shadownormalBias: 0.02, // Normal bias of the shadow
-
- shadowMaterialPosition: [0, 0.01, 0], // Position of the shadow material
- shadowMaterialRotation: [-Math.PI / 2, 0, 0], // Rotation of the shadow material
-
- shadowMaterialOpacity: 0.1 // Opacity of the shadow material
-}
+ shadowOffset: 50, // Offset of the shadow
+ shadowmapSizewidth: 1024, // Width of the shadow map
+ shadowmapSizeheight: 1024, // Height of the shadow map
+ // shadowmapSizewidth: 8192, // Width of the shadow map
+ // shadowmapSizeheight: 8192, // Height of the shadow map
+ shadowcamerafar: 70, // Far plane of the shadow camera
+ shadowcameranear: 0.1, // Near plane of the shadow camera
+ shadowcameratop: 30, // Top plane of the shadow camera
+ shadowcamerabottom: -30, // Bottom plane of the shadow camera
+ shadowcameraleft: -30, // Left plane of the shadow camera
+ shadowcameraright: 30, // Right plane of the shadow camera
+ shadowbias: -0.001, // Bias of the shadow
+ shadownormalBias: 0.02, // Normal bias of the shadow
+ shadowMaterialPosition: [0, 0.01, 0], // Position of the shadow material
+ shadowMaterialRotation: [-Math.PI / 2, 0, 0], // Rotation of the shadow material
+ shadowMaterialOpacity: 0.1, // Opacity of the shadow material
+};
export const skyConfig: SkyConfig = {
- defaultTurbidity: 10.0, // Default turbidity of the sky
- maxTurbidity: 20.0, // Maximum turbidity of the sky
- minTurbidity: 0.0, // Minimum turbidity of the sky
- defaultRayleigh: 1.9, // Default Rayleigh scattering coefficient
- mieCoefficient: 0.1, // Mie scattering coefficient
- mieDirectionalG: 1.0, // Mie directional G
- skyDistance: 2000 // Distance of the sky
-}
+ defaultTurbidity: 10.0, // Default turbidity of the sky
+ maxTurbidity: 20.0, // Maximum turbidity of the sky
+ minTurbidity: 0.0, // Minimum turbidity of the sky
+ defaultRayleigh: 1.9, // Default Rayleigh scattering coefficient
+ mieCoefficient: 0.1, // Mie scattering coefficient
+ mieDirectionalG: 1.0, // Mie directional G
+ skyDistance: 2000, // Distance of the sky
+};
export const assetConfig: AssetConfig = {
- defaultScaleBeforeGsap: [0.1, 0.1, 0.1], // Default scale of the assets
- defaultScaleAfterGsap: [1, 1, 1] // Default scale of the assets
-}
+ defaultScaleBeforeGsap: [0.1, 0.1, 0.1], // Default scale of the assets
+ defaultScaleAfterGsap: [1, 1, 1], // Default scale of the assets
+};
export const pointConfig: PointConfig = {
- defaultInnerColor: "#ffffff", // Default inner color of the points
- defaultOuterColor: "#ffffff", // Default outer color of the points
- deleteColor: "#ff0000", // Color of the points when deleting
- boxScale: [0.5, 0.5, 0.5], // Scale of the points
-
- wallOuterColor: "#C7C7C7", // Outer color of the wall points
- floorOuterColor: "#808080", // Outer color of the floor points
- aisleOuterColor: "#FBBC05", // Outer color of the aisle points
- zoneOuterColor: "#007BFF", // Outer color of the zone points
-
- snappingThreshold: 1, // Threshold for snapping
-}
+ defaultInnerColor: "#ffffff", // Default inner color of the points
+ defaultOuterColor: "#ffffff", // Default outer color of the points
+ deleteColor: "#ff0000", // Color of the points when deleting
+ boxScale: [0.5, 0.5, 0.5], // Scale of the points
+ wallOuterColor: "#C7C7C7", // Outer color of the wall points
+ floorOuterColor: "#808080", // Outer color of the floor points
+ aisleOuterColor: "#FBBC05", // Outer color of the aisle points
+ zoneOuterColor: "#007BFF", // Outer color of the zone points
+ snappingThreshold: 1, // Threshold for snapping
+};
export const lineConfig: LineConfig = {
- tubularSegments: 64, // Number of tubular segments
- radius: 0.15, // Radius of the lines
- radialSegments: 8, // Number of radial segments
-
- wallName: "WallLine", // Name of the wall lines
- floorName: "FloorLine", // Name of the floor lines
- aisleName: "AisleLine", // Name of the aisle lines
- zoneName: "ZoneLine", // Name of the zone lines
- referenceName: "ReferenceLine", // Name of the reference lines
-
- lineIntersectionPoints: 300, // Number of intersection points
-
- defaultColor: "#000000", // Default color of the lines
-
- wallColor: "#C7C7C7", // Color of the wall lines
- floorColor: "#808080", // Color of the floor lines
- aisleColor: "#FBBC05", // Color of the aisle lines
- zoneColor: "#007BFF", // Color of the zone lines
- helperColor: "#C164FF" // Color of the helper lines
-}
+ tubularSegments: 64, // Number of tubular segments
+ radius: 0.15, // Radius of the lines
+ radialSegments: 8, // Number of radial segments
+ wallName: "WallLine", // Name of the wall lines
+ floorName: "FloorLine", // Name of the floor lines
+ aisleName: "AisleLine", // Name of the aisle lines
+ zoneName: "ZoneLine", // Name of the zone lines
+ referenceName: "ReferenceLine", // Name of the reference lines
+ lineIntersectionPoints: 300, // Number of intersection points
+ defaultColor: "#000000", // Default color of the lines
+ wallColor: "#C7C7C7", // Color of the wall lines
+ floorColor: "#808080", // Color of the floor lines
+ aisleColor: "#FBBC05", // Color of the aisle lines
+ zoneColor: "#007BFF", // Color of the zone lines
+ helperColor: "#C164FF", // Color of the helper lines
+};
export const wallConfig: WallConfig = {
- defaultColor: "white", // Default color of the walls
- height: 7, // Height of the walls
- width: 0.05, // Width of the walls
-}
+ defaultColor: "white", // Default color of the walls
+ height: 7, // Height of the walls
+ width: 0.05, // Width of the walls
+};
export const floorConfig: FloorConfig = {
- defaultColor: "grey", // Default color of the floors
- height: 0.1, // Height of the floors
- textureScale: 0.1, // Scale of the floor texture
-}
+ defaultColor: "grey", // Default color of the floors
+ height: 0.1, // Height of the floors
+ textureScale: 0.1, // Scale of the floor texture
+};
export const roofConfig: RoofConfig = {
- defaultColor: "grey", // Default color of the roofs
- height: 0.1 // Height of the roofs
-}
+ defaultColor: "grey", // Default color of the roofs
+ height: 0.1, // Height of the roofs
+};
export const aisleConfig: AisleConfig = {
- width: 0.1, // Width of the aisles
- height: 0.01, // Height of the aisles
- defaultColor: 0xffff00 // Default color of the aisles
-}
+ width: 0.1, // Width of the aisles
+ height: 0.01, // Height of the aisles
+ defaultColor: 0xffff00, // Default color of the aisles
+};
export const zoneConfig: ZoneConfig = {
defaultColor: "black", // Default color of the zones
@@ -365,10 +355,15 @@ export const zoneConfig: ZoneConfig = {
}
export const columnConfig: ColumnConfig = {
- defaultColor: "White", // Default color of the columns
-}
+ defaultColor: "White", // Default color of the columns
+};
export const outlineConfig: OutlineConfig = {
- assetSelectColor: 0x0054fE, // Color of the selected assets
- assetDeleteColor: 0xFF0000 // Color of the deleted assets
-}
\ No newline at end of file
+ assetSelectColor: 0x0054fe, // Color of the selected assets
+ assetDeleteColor: 0xff0000, // Color of the deleted assets
+};
+
+export const distanceConfig: DistanceConfig = {
+ minDistance: 20,
+ maxDistance: 75,
+};
diff --git a/app/src/types/world/worldTypes.d.ts b/app/src/types/world/worldTypes.d.ts
index 31c032c..4d10a36 100644
--- a/app/src/types/world/worldTypes.d.ts
+++ b/app/src/types/world/worldTypes.d.ts
@@ -198,9 +198,30 @@ export type FloorItemType = {
modelname: string;
position: [number, number, number];
rotation: { x: number; y: number; z: number };
- modelfileID?: string;
+ modelfileID: string;
isLocked: boolean;
isVisible: boolean;
+ eventData?: {
+ type: 'Conveyor';
+ points: {
+ uuid: string;
+ position: [number, number, number];
+ rotation: [number, number, number];
+ actions: { uuid: string; name: string; type: string; material: string; delay: number | string; spawnInterval: number | string; isUsed: boolean }[] | [];
+ triggers: { uuid: string; name: string; type: string; isUsed: boolean; bufferTime: number }[] | [];
+ connections: { source: { pathUUID: string; pointUUID: string }; targets: { pathUUID: string; pointUUID: string }[] };
+ }[];
+ speed: number | string;
+ } | {
+ type: 'Vehicle';
+ point: {
+ uuid: string;
+ position: [number, number, number];
+ actions: { uuid: string; name: string; type: string; start: { x: number, y: number } | {}, hitCount: number, end: { x: number, y: number } | {}, buffer: number };
+ connections: { source: { pathUUID: string; pointUUID: string }; targets: { pathUUID: string; pointUUID: string }[] };
+ speed: number;
+ };
+ };
};
// Array of floor items for managing multiple objects on the floor
@@ -310,7 +331,7 @@ interface VehicleEventsSchema {
point: {
uuid: string;
position: [number, number, number];
- actions: { uuid: string; name: string; type: string; start: string, hitCount: number, end: string, buffer: number };
+ actions: { uuid: string; name: string; type: string; start: { x: number, y: number } | {}, hitCount: number, end: { x: number, y: number } | {}, buffer: number };
connections: { source: { pathUUID: string; pointUUID: string }; targets: { pathUUID: string; pointUUID: string }[] };
speed: number;
};