diff --git a/app/src/components/layout/sidebarRight/SideBarRight.tsx b/app/src/components/layout/sidebarRight/SideBarRight.tsx
index 1bb6996..e0d5904 100644
--- a/app/src/components/layout/sidebarRight/SideBarRight.tsx
+++ b/app/src/components/layout/sidebarRight/SideBarRight.tsx
@@ -32,13 +32,13 @@ type DisplayComponent =
| "aisleProperties"
| "wallProperties"
| "floorProperties"
+ | "zoneProperties"
| "assetProperties"
| "selectedWallProperties"
| "selectedFloorProperties"
| "selectedDecalProperties"
| "selectedAisleProperties"
| "selectedZoneProperties"
- | "zoneProperties"
| "simulations"
| "mechanics"
| "analysis"
@@ -140,7 +140,7 @@ const SideBarRight: React.FC = () => {
setDisplayComponent("selectedZoneProperties");
return;
}
- if (selectedAssets.length !== 1 && !selectedFloor && !selectedWall && !selectedDecal && !selectedAisle) {
+ if (selectedAssets.length !== 1 && !selectedFloor && !selectedWall && !selectedDecal && !selectedAisle && !selectedZone) {
if (toolMode === "Aisle") {
setDisplayComponent("aisleProperties");
return;
@@ -153,16 +153,16 @@ const SideBarRight: React.FC = () => {
setDisplayComponent("floorProperties");
return;
}
+ if (toolMode === "Zone") {
+ setDisplayComponent("zoneProperties");
+ return;
+ }
+
setDisplayComponent("globalProperties");
return;
}
}
- if (subModule === "zoneProperties" && (activeModule === "builder" || activeModule === "simulation")) {
- setDisplayComponent("zoneProperties");
- return;
- }
-
setDisplayComponent("none");
}, [viewVersionHistory, activeModule, subModule, isComparing, selectedAssets, selectedWall, selectedFloor, selectedAisle, toolMode, selectedDecal, selectedZone]);
diff --git a/app/src/components/layout/sidebarRight/properties/FloorProperties.tsx b/app/src/components/layout/sidebarRight/properties/FloorProperties.tsx
index c5938f7..ffdf2f7 100644
--- a/app/src/components/layout/sidebarRight/properties/FloorProperties.tsx
+++ b/app/src/components/layout/sidebarRight/properties/FloorProperties.tsx
@@ -2,11 +2,11 @@ import { useEffect, useState } from "react";
import InputToggle from "../../../ui/inputs/InputToggle";
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
-import defaultTexture from '../../../../assets/textures/floor/white.png';
-import flootTexture1 from '../../../../assets/textures/floor/factory wall texture.jpg';
-import flootTexture2 from '../../../../assets/textures/floor/tex1/MI_FactoryConcreteFloor01_BaseColor.001.jpg';
-import flootTexture3 from '../../../../assets/textures/floor/tex2/MI_FloorMats01_baseColor.png';
-import flootTexture4 from '../../../../assets/textures/floor/tex3/metal_plate_diff_1k.jpg';
+import defaultTexture from "../../../../assets/textures/floor/white.png";
+import flootTexture1 from "../../../../assets/textures/floor/factory wall texture.jpg";
+import flootTexture2 from "../../../../assets/textures/floor/tex1/MI_FactoryConcreteFloor01_BaseColor.001.jpg";
+import flootTexture3 from "../../../../assets/textures/floor/tex2/MI_FloorMats01_baseColor.png";
+import flootTexture4 from "../../../../assets/textures/floor/tex3/metal_plate_diff_1k.jpg";
import { useBuilderStore } from "../../../../store/builder/useBuilderStore";
@@ -29,7 +29,7 @@ const FloorProperties = () => {
const [activeSurface, setActiveSurface] = useState<"top" | "side">("top");
- const [selectedMaterials, setSelectedMaterials] = useState<{ top: Material | null; side: Material | null; }>({ top: null, side: null, });
+ const [selectedMaterials, setSelectedMaterials] = useState<{ top: Material | null; side: Material | null }>({ top: null, side: null });
useEffect(() => {
setSelectedMaterials({
@@ -61,30 +61,11 @@ const FloorProperties = () => {
return (
- Floor
+ Properties
-
- handleIsBevelChange(!isBeveled)}
- />
-
+
+ handleIsBevelChange(!isBeveled)} />
+
@@ -95,47 +76,19 @@ const FloorProperties = () => {
-
- {selectedMaterials[activeSurface] && (
-
![{selectedMaterials[activeSurface]!.textureName}]({selectedMaterials[activeSurface]!.texture})
- )}
+ {selectedMaterials[activeSurface] &&
![{selectedMaterials[activeSurface]!.textureName}]({selectedMaterials[activeSurface]!.texture})
}
@@ -155,11 +108,7 @@ const FloorProperties = () => {
>
-

+
{material.textureName}
diff --git a/app/src/components/layout/sidebarRight/properties/SelectedZoneProperties.tsx b/app/src/components/layout/sidebarRight/properties/SelectedZoneProperties.tsx
index e1d3832..27d2115 100644
--- a/app/src/components/layout/sidebarRight/properties/SelectedZoneProperties.tsx
+++ b/app/src/components/layout/sidebarRight/properties/SelectedZoneProperties.tsx
@@ -2,6 +2,8 @@ import { useState } from "react";
import { useParams } from "react-router-dom";
import { ArrowIcon } from "../../../icons/ExportCommonIcons";
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
+import RenameInput from "../../../ui/inputs/RenameInput";
+import Vector3Input from "../customInput/Vector3Input";
import { useBuilderStore } from "../../../../store/builder/useBuilderStore";
import { useSceneContext } from "../../../../modules/scene/sceneContext";
import { useSocketStore } from "../../../../store/socket/useSocketStore";
@@ -17,10 +19,10 @@ interface TextureList {
}
export const zoneTextureList: TextureList[] = [
- { color: "blue", id: "#0000ff", zoneType: "" },
- { color: "red", id: "#ff0000", zoneType: "" },
+ { color: "blue", id: "#0000FF", zoneType: "" },
+ { color: "red", id: "#FF0000", zoneType: "" },
{ color: "yellow", id: "#FBE50E", zoneType: "" },
- { color: "white", id: "#ffffff", zoneType: "" },
+ { color: "white", id: "#FFFFFF", zoneType: "" },
{ color: "green", id: "#43C06D", zoneType: "" },
{ color: "orange", id: "#FF711B", zoneType: "" },
{ color: "purple", id: "#AF52DE", zoneType: "" },
@@ -28,7 +30,7 @@ export const zoneTextureList: TextureList[] = [
function SelectedZoneProperties() {
const { projectId } = useParams();
- const { selectedZone } = useBuilderStore();
+ const { selectedZone, editZoneViewPort, setEditZoneViewPort, zoneViewPort } = useBuilderStore();
const { zoneStore, versionStore } = useSceneContext();
const { selectedVersion } = versionStore();
const { builderSocket } = useSocketStore();
@@ -90,13 +92,45 @@ function SelectedZoneProperties() {
updateZoneToBackend(updatedZone);
};
+ const handleZoneNameCHange = (newName: string) => {
+ const updatedZone = peekUpdateZone(selectedZone.zoneData.zoneUuid, { zoneName: newName });
+ updateZoneToBackend(updatedZone);
+ };
+
+ const handleSetView = () => {
+ if (zoneViewPort) {
+ setEditZoneViewPort(false);
+ const updatedZone = peekUpdateZone(selectedZone.zoneData.zoneUuid, {
+ viewPortPosition: [zoneViewPort.position.x, zoneViewPort.position.y, zoneViewPort.position.z],
+ viewPortTarget: [zoneViewPort.target.x, zoneViewPort.target.y, zoneViewPort.target.z],
+ });
+ updateZoneToBackend(updatedZone);
+ }
+ };
+
return (
Zone Properties
+
+
+
+
setEditZoneViewPort(!editZoneViewPort)}>
+ {editZoneViewPort ? "Cancel" : "Edit"}
+
+
+ {}} header="Viewport Target" value={selectedZone.zoneData.viewPortTarget} disabled={!editZoneViewPort} />
+ {}} header="Viewport Position" value={selectedZone.zoneData.viewPortPosition} disabled={!editZoneViewPort} />
+
+ {editZoneViewPort && (
+
+ Set View
+
+ )}
+
+
{/* Basic Properties */}
- {selectedZone.zoneData.zoneName}
diff --git a/app/src/components/layout/sidebarRight/properties/WallProperties.tsx b/app/src/components/layout/sidebarRight/properties/WallProperties.tsx
index e158b44..a0e4ada 100644
--- a/app/src/components/layout/sidebarRight/properties/WallProperties.tsx
+++ b/app/src/components/layout/sidebarRight/properties/WallProperties.tsx
@@ -58,7 +58,7 @@ const WallProperties = () => {
return (
- Wall
+ Properties
{
- const { Edit, setEdit } = useEditPosition();
- const { selectedZone, setSelectedZone } = useSelectedZoneStore();
- const { zonePosition, setZonePosition } = usezonePosition();
- const { zoneTarget, setZoneTarget } = usezoneTarget();
- const { zoneStore, versionStore } = useSceneContext();
- const { selectedVersion } = versionStore();
- const { zones, setZoneName } = zoneStore()
+export const zoneTextureList: TextureList[] = [
+ { color: "blue", id: "#0000FF", zoneType: "" },
+ { color: "red", id: "#FF0000", zoneType: "" },
+ { color: "yellow", id: "#FBE50E", zoneType: "" },
+ { color: "white", id: "#FFFFFF", zoneType: "" },
+ { color: "green", id: "#43C06D", zoneType: "" },
+ { color: "orange", id: "#FF711B", zoneType: "" },
+ { color: "purple", id: "#AF52DE", zoneType: "" },
+];
- const { projectId } = useParams();
- const { organization } = getUserData();
+function ZoneProperties() {
+ const { zoneHeight, zoneColor, setZoneHeight, setZoneColor } = useBuilderStore();
+ const [collapseTexture, setCollapseTexture] = useState(true);
- useEffect(() => {
- setZonePosition(selectedZone.zoneViewPortPosition);
- setZoneTarget(selectedZone.zoneViewPortTarget);
- }, [selectedZone?.zoneViewPortPosition, selectedZone?.zoneViewPortTarget]);
-
- async function handleSetView() {
- try {
-
- let zonesdata = {
- zoneUuid: selectedZone.zoneUuid,
- viewPortPosition: zonePosition,
- viewPortTarget: zoneTarget,
- };
-
-
- let response = await zoneCameraUpdate(zonesdata, organization, projectId, selectedVersion?.versionId || "");
- //
- if (response.message === "zone updated") {
- setEdit(false);
- } else {
- //
- }
- } catch (error) {
- echo.error("Failed to set zone view");
- }
- }
-
- function handleEditView() {
- setEdit(!Edit); // This will toggle the `Edit` state correctly
- }
-
- async function handleZoneNameChange(newName: string) {
- const zonesdata = {
- zoneUuid: selectedZone.zoneUuid,
- zoneName: newName,
+ const handleHeightChange = (val: string) => {
+ const height = parseFloat(val);
+ if (!isNaN(height)) {
+ setZoneHeight(height);
+ }
};
- // Call your API to update the zone
- let response = await zoneCameraUpdate(zonesdata, organization, projectId, selectedVersion?.versionId || "");
- if (response.message === "zone updated") {
- setSelectedZone((prev) => ({ ...prev, zoneName: newName }));
- setZoneName(selectedZone.zoneUuid, newName)
- // setZones((prevZones: any[]) =>
- // prevZones.map((zone) =>
- // zone.zoneUuid === selectedZone.zoneUuid
- // ? { ...zone, zoneName: newName }
- // : zone
- // )
- // );
- } else {
- //
- }
- }
- function handleVectorChange(
- key: "zoneViewPortTarget" | "zoneViewPortPosition",
- newValue: [number, number, number]
- ) {
- setSelectedZone((prev) => ({ ...prev, [key]: newValue }));
- }
- const checkZoneNameDuplicate = (name: string) => {
- return zones.some(
- (zone: any) =>
- zone.zoneName?.trim().toLowerCase() === name?.trim().toLowerCase() &&
- zone.zoneUuid !== selectedZone.zoneUuid
- );
- };
+ const handleColorChange = (val: string) => {
+ setZoneColor(val);
+ };
- return (
-
-
-
-
-
- {Edit ? "Cancel" : "Edit"}
-
+ return (
+
+
Properties
+
+ {/* Basic Properties */}
+
+ {/* Texture */}
+
+ setCollapseTexture(!collapseTexture)} aria-expanded={!collapseTexture}>
+ Zone Texture
+
+
+
+ {collapseTexture && (
+
+ {zoneTextureList.map((val) => (
+
handleColorChange(val.id)} aria-pressed={zoneColor === val.id}>
+
+ {val.color}
+
+ ))}
+
handleColorChange(e.target.value)} />
+
+ )}
+
-
handleVectorChange("zoneViewPortTarget", value)}
- header="Viewport Target"
- value={zoneTarget as [number, number, number]}
- disabled={!Edit}
- />
-
- handleVectorChange("zoneViewPortPosition", value)
- }
- header="Viewport Position"
- value={zonePosition as [number, number, number]}
- disabled={!Edit}
- />
-
- {Edit && (
-
- Set View
-
- )}
-
-
- );
-};
+ );
+}
export default ZoneProperties;
diff --git a/app/src/functions/outlineHelpers/useZoneAssetHandlers.ts b/app/src/functions/outlineHelpers/useZoneAssetHandlers.ts
index d934cc6..6cbc134 100644
--- a/app/src/functions/outlineHelpers/useZoneAssetHandlers.ts
+++ b/app/src/functions/outlineHelpers/useZoneAssetHandlers.ts
@@ -26,7 +26,6 @@ export const useZoneAssetHandlers = () => {
const handleSelectZone = useCallback(
async (id: string) => {
if (selectedZone?.zoneUuid === id || id === "unassigned-zone") return;
- setSubModule("zoneProperties");
const response = await getZoneData(id, organization, projectId, selectedVersion?.versionId || "");
if (!response) return;
diff --git a/app/src/modules/builder/zone/Instances/Instance/zoneInstance.tsx b/app/src/modules/builder/zone/Instances/Instance/zoneInstance.tsx
index b453493..eba7274 100644
--- a/app/src/modules/builder/zone/Instances/Instance/zoneInstance.tsx
+++ b/app/src/modules/builder/zone/Instances/Instance/zoneInstance.tsx
@@ -1,5 +1,7 @@
-import { useRef } from "react";
+import { useEffect, useRef } from "react";
import { Group, Vector3 } from "three";
+import { useThree } from "@react-three/fiber";
+import { CameraControls } from "@react-three/drei";
import useModuleStore from "../../../../../store/ui/useModuleStore";
import { useToggleView } from "../../../../../store/builder/store";
import { useBuilderStore } from "../../../../../store/builder/useBuilderStore";
@@ -9,6 +11,7 @@ import PolygonMaterial from "../../../wrappers/materials/polygonMaterial";
import ZoneCornerReference from "./zoneCornerReference";
function ZoneInstance({ zone }: { readonly zone: Zone }) {
+ const { controls }: { controls: CameraControls } = useThree();
const { toggleView } = useToggleView();
const { activeModule } = useModuleStore();
const { selectedZone, setSelectedZone } = useBuilderStore();
diff --git a/app/src/modules/builder/zone/Instances/zoneInstances.tsx b/app/src/modules/builder/zone/Instances/zoneInstances.tsx
index bb30455..e979cdf 100644
--- a/app/src/modules/builder/zone/Instances/zoneInstances.tsx
+++ b/app/src/modules/builder/zone/Instances/zoneInstances.tsx
@@ -1,8 +1,10 @@
import React, { useEffect, useMemo } from "react";
import { Vector3 } from "three";
-import { Html } from "@react-three/drei";
+import { useFrame, useThree } from "@react-three/fiber";
+import { CameraControls, Html } from "@react-three/drei";
import { useSceneContext } from "../../../scene/sceneContext";
import { useToggleView } from "../../../../store/builder/store";
+import { useBuilderStore } from "../../../../store/builder/useBuilderStore";
import Line from "../../line/line";
import Point from "../../point/point";
import ZoneInstance from "./Instance/zoneInstance";
@@ -10,13 +12,31 @@ import Zone2DInstance from "./Instance/zone2DInstance";
function ZoneInstances() {
const { zoneStore } = useSceneContext();
+ const { controls }: { controls: CameraControls } = useThree();
const { zones } = zoneStore();
const { toggleView } = useToggleView();
+ const { selectedZone, editZoneViewPort, setZoneViewPort, zoneViewPort } = useBuilderStore();
useEffect(() => {
// console.log('zones: ', zones);
}, [zones]);
+ useEffect(() => {
+ if (selectedZone) {
+ controls.setLookAt(...selectedZone.zoneData.viewPortPosition, ...selectedZone.zoneData.viewPortTarget, true);
+ }
+ }, [selectedZone?.zoneMesh]);
+
+ useFrame(() => {
+ if (editZoneViewPort) {
+ const position = controls.getPosition(new Vector3());
+ const target = controls.getTarget(new Vector3());
+ setZoneViewPort({ position, target });
+ } else if (!editZoneViewPort && zoneViewPort) {
+ setZoneViewPort(null);
+ }
+ });
+
const allPoints = useMemo(() => {
const points: Point[] = [];
const seenUuids = new Set();
diff --git a/app/src/store/builder/useBuilderStore.ts b/app/src/store/builder/useBuilderStore.ts
index b65a16e..4851aed 100644
--- a/app/src/store/builder/useBuilderStore.ts
+++ b/app/src/store/builder/useBuilderStore.ts
@@ -34,6 +34,8 @@ interface BuilderState {
// Zone Settings
selectedZone: { zoneMesh: Object3D | null; zoneData: Zone } | null;
+ editZoneViewPort: boolean;
+ zoneViewPort: { position: Vector3; target: Vector3 } | null;
zoneHeight: number;
zoneColor: string;
@@ -95,6 +97,8 @@ interface BuilderState {
// Setters - Zone
setSelectedZone: (zone: { zoneMesh: Object3D | null; zoneData: Zone } | null) => void;
+ setEditZoneViewPort: (edit: boolean) => void;
+ setZoneViewPort: (viewPort: { position: Vector3; target: Vector3 } | null) => void;
setZoneHeight: (height: number) => void;
setZoneColor: (color: string) => void;
@@ -153,8 +157,10 @@ export const useBuilderStore = create()(
topMaterial: "Default Material",
selectedZone: null,
+ editZoneViewPort: false,
+ zoneViewPort: null,
zoneHeight: 7,
- zoneColor: "blue",
+ zoneColor: "#0000FF",
selectedDecal: null,
deletableDecal: null,
@@ -298,6 +304,18 @@ export const useBuilderStore = create()(
});
},
+ setEditZoneViewPort: (edit: boolean) => {
+ set((state) => {
+ state.editZoneViewPort = edit;
+ });
+ },
+
+ setZoneViewPort: (viewPort: { position: Vector3; target: Vector3 } | null) => {
+ set((state) => {
+ state.zoneViewPort = viewPort;
+ });
+ },
+
setZoneHeight: (height: number) => {
set((state) => {
state.zoneHeight = height;
diff --git a/app/src/store/ui/useModuleStore.ts b/app/src/store/ui/useModuleStore.ts
index 8d70ad0..39c0c5b 100644
--- a/app/src/store/ui/useModuleStore.ts
+++ b/app/src/store/ui/useModuleStore.ts
@@ -14,7 +14,7 @@ export default useModuleStore;
// New store for subModule
-type SubModule = "properties" | "simulations" | "mechanics" | "analysis" | "zoneProperties" | "resourceManagement";
+type SubModule = "properties" | "simulations" | "mechanics" | "analysis" | "resourceManagement";
interface SubModuleStore {
subModule: SubModule;