-
-
+ return (
+
+
+ Wall
+
+ handleHeightChange(val)}
+ />
+ handleThicknessChange(val)}
+ />
+
+
+
+
-
-
+
+
+
-
- {selectedMaterials[activeSide] && (
-
![{selectedMaterials[activeSide]!.textureName}]({selectedMaterials[activeSide]!.texture})
- )}
-
-
-
-
- {materials.length === 0 ? (
-
No materials added yet.
- ) : (
-
- {materials.map((material, index) => {
- const isSelected = selectedMaterials[activeSide]?.texture === material.texture;
-
- return (
-
- );
- })}
-
- )}
+
+
+ {selectedMaterials[activeSide] && (
+
![{selectedMaterials[activeSide]!.textureName}]({selectedMaterials[activeSide]!.texture})
+ )}
+
+
+
+
+ {materials.length === 0 ? (
+
No materials added yet.
+ ) : (
+
+ {materials.map((material, index) => {
+ const isSelected = selectedMaterials[activeSide]?.texture === material.texture;
+
+ return (
+
handleSelectMaterial(material)}
+ >
+
+
+

+
+
{material.textureName}
+
+
+ );
+ })}
+
+ )}
+
+
-
-
- );
+ );
};
export default WallProperties;
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/arcAisle.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/arcAisle.tsx
index d4c27b6..bc09b68 100644
--- a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/arcAisle.tsx
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/arcAisle.tsx
@@ -78,7 +78,7 @@ function ArcAisle({ aisle }: { readonly aisle: Aisle }) {
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
rotation={[Math.PI / 2, 0, 0]}
userData={aisle}
- onClick={handleClick}
+ onDoubleClick={handleClick}
onPointerMissed={() => {
setSelectedAisle(null);
}}
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/arrowAisle.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/arrowAisle.tsx
index 941fb7f..49bf666 100644
--- a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/arrowAisle.tsx
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/arrowAisle.tsx
@@ -65,7 +65,7 @@ function ArrowAisle({ aisle }: { readonly aisle: Aisle }) {
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
rotation={[Math.PI / 2, 0, 0]}
userData={aisle}
- onClick={handleClick}
+ onDoubleClick={handleClick}
onPointerMissed={() => {
setSelectedAisle(null);
}}
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/arrowsAisle.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/arrowsAisle.tsx
index 5dc6ee7..8bc6fd5 100644
--- a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/arrowsAisle.tsx
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/arrowsAisle.tsx
@@ -68,7 +68,7 @@ function ArrowsAisle({ aisle }: { readonly aisle: Aisle }) {
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
rotation={[Math.PI / 2, 0, 0]}
userData={aisle}
- onClick={handleClick}
+ onDoubleClick={handleClick}
onPointerMissed={() => {
setSelectedAisle(null);
}}
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/circleAisle.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/circleAisle.tsx
index 6d838de..af852e8 100644
--- a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/circleAisle.tsx
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/circleAisle.tsx
@@ -53,7 +53,7 @@ function CircleAisle({ aisle }: { readonly aisle: Aisle }) {
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
rotation={[Math.PI / 2, 0, 0]}
userData={aisle}
- onClick={handleClick}
+ onDoubleClick={handleClick}
onPointerMissed={() => {
setSelectedAisle(null);
}}
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dashedAisle.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dashedAisle.tsx
index 0c3eb7f..bbdad90 100644
--- a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dashedAisle.tsx
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dashedAisle.tsx
@@ -66,7 +66,7 @@ function DashedAisle({ aisle }: { readonly aisle: Aisle }) {
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
rotation={[Math.PI / 2, 0, 0]}
userData={aisle}
- onClick={handleClick}
+ onDoubleClick={handleClick}
onPointerMissed={() => {
setSelectedAisle(null);
}}
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dottedAisle.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dottedAisle.tsx
index f701fba..bf17d08 100644
--- a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dottedAisle.tsx
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dottedAisle.tsx
@@ -53,7 +53,7 @@ function DottedAisle({ aisle }: { readonly aisle: Aisle }) {
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
rotation={[Math.PI / 2, 0, 0]}
userData={aisle}
- onClick={handleClick}
+ onDoubleClick={handleClick}
onPointerMissed={() => {
setSelectedAisle(null);
}}
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/junctionAisle.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/junctionAisle.tsx
index 23ea6e6..a3f8bdf 100644
--- a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/junctionAisle.tsx
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/junctionAisle.tsx
@@ -100,7 +100,7 @@ function JunctionAisle({ aisle }: { readonly aisle: Aisle }) {
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
rotation={[Math.PI / 2, 0, 0]}
userData={aisle}
- onClick={handleClick}
+ onDoubleClick={handleClick}
onPointerMissed={() => {
setSelectedAisle(null);
}}
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/solidAisle.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/solidAisle.tsx
index ed78112..e9321b0 100644
--- a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/solidAisle.tsx
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/solidAisle.tsx
@@ -50,7 +50,7 @@ function SolidAisle({ aisle }: { readonly aisle: Aisle }) {
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
rotation={[Math.PI / 2, 0, 0]}
userData={aisle}
- onClick={handleClick}
+ onDoubleClick={handleClick}
onPointerMissed={() => {
setSelectedAisle(null);
}}
diff --git a/app/src/modules/builder/asset/assetsGroup.tsx b/app/src/modules/builder/asset/assetsGroup.tsx
index b597ab3..2b923f8 100644
--- a/app/src/modules/builder/asset/assetsGroup.tsx
+++ b/app/src/modules/builder/asset/assetsGroup.tsx
@@ -26,7 +26,7 @@ const gltfLoaderWorker = new Worker(
function AssetsGroup({ floorGroup, plane }: { readonly floorGroup: RefGroup, readonly plane: RefMesh }) {
const { activeModule } = useModuleStore();
const { socket } = useSocketStore();
- const { controls, gl, pointer, camera, raycaster } = useThree();
+ const { controls, gl, pointer, camera, raycaster, scene } = useThree();
const { setLoadingProgress } = useLoadingProgress();
const { assetStore, eventStore } = useSceneContext();
const { selectedVersionStore } = useVersionContext();
@@ -277,7 +277,7 @@ function AssetsGroup({ floorGroup, plane }: { readonly floorGroup: RefGroup, rea
pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
- addAssetModel(raycaster, camera, pointer, floorGroup, socket, selectedItem, setSelectedItem, addEvent, addAsset, plane, selectedVersion, projectId, userId);
+ addAssetModel(scene, raycaster, camera, pointer, socket, selectedItem, setSelectedItem, addEvent, addAsset, plane, selectedVersion, projectId, userId);
}
};
diff --git a/app/src/modules/builder/asset/functions/addAssetModel.ts b/app/src/modules/builder/asset/functions/addAssetModel.ts
index 2eaa744..3977fa7 100644
--- a/app/src/modules/builder/asset/functions/addAssetModel.ts
+++ b/app/src/modules/builder/asset/functions/addAssetModel.ts
@@ -10,489 +10,438 @@ import PointsCalculator from "../../../simulation/events/points/functions/points
import { getUserData } from "../../../../functions/getUserData";
async function addAssetModel(
- raycaster: THREE.Raycaster,
- camera: THREE.Camera,
- pointer: THREE.Vector2,
- floorGroup: Types.RefGroup,
- socket: Socket
,
- selectedItem: any,
- setSelectedItem: any,
- addEvent: (event: EventsSchema) => void,
- addAsset: (asset: Asset) => void,
- plane: Types.RefMesh,
- selectedVersion?: Version | null,
- projectId?: string,
- userId?: string
+ scene: THREE.Scene,
+ raycaster: THREE.Raycaster,
+ camera: THREE.Camera,
+ pointer: THREE.Vector2,
+ socket: Socket,
+ selectedItem: any,
+ setSelectedItem: any,
+ addEvent: (event: EventsSchema) => void,
+ addAsset: (asset: Asset) => void,
+ plane: Types.RefMesh,
+ selectedVersion?: Version | null,
+ projectId?: string,
+ userId?: string
): Promise {
- ////////// Load Floor GLtf's and set the positions, rotation, type etc. in state and store in localstorage //////////
+ ////////// Load Floor GLtf's and set the positions, rotation, type etc. in state and store in localstorage //////////
- let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
+ let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
- try {
- const loader = new GLTFLoader();
- const dracoLoader = new DRACOLoader();
+ try {
+ const loader = new GLTFLoader();
+ const dracoLoader = new DRACOLoader();
- dracoLoader.setDecoderPath(
- "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/"
- );
- loader.setDRACOLoader(dracoLoader);
+ dracoLoader.setDecoderPath("https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/");
+ loader.setDRACOLoader(dracoLoader);
- raycaster.setFromCamera(pointer, camera);
- const floorIntersections = raycaster.intersectObjects(
- floorGroup.current.children,
- true
- );
- const intersectedFloor = floorIntersections.find((intersect) =>
- intersect.object.name.includes("Floor")
- );
+ raycaster.setFromCamera(pointer, camera);
+ const wallFloorsGroup = scene.getObjectByName("Walls-Floors-Group") as Types.Group | null;
+ const floorsGroup = scene.getObjectByName("Floors-Group") as Types.Group | null;
+ const floorChildren = floorsGroup?.children ?? [];
+ const wallFloorChildren = wallFloorsGroup?.children ?? [];
+ const floorIntersections = raycaster.intersectObjects([...floorChildren, ...wallFloorChildren], true);
+ const intersectedFloor = floorIntersections.find((intersect) => intersect.object.name.includes("Floor"));
- const planeIntersections = raycaster.intersectObject(plane.current!, true);
- const intersectedPlane = planeIntersections[0];
+ const planeIntersections = raycaster.intersectObject(plane.current!, true);
+ const intersectedPlane = planeIntersections[0];
- let intersectPoint: THREE.Vector3 | null = null;
+ let intersectPoint: THREE.Vector3 | null = null;
- if (intersectedFloor && intersectedPlane) {
- intersectPoint =
- intersectedFloor.distance < intersectedPlane.distance
- ? new THREE.Vector3(
- intersectedFloor.point.x,
- Math.round(intersectedFloor.point.y),
- intersectedFloor.point.z
- )
- : new THREE.Vector3(
- intersectedPlane.point.x,
- 0,
- intersectedPlane.point.z
- );
- } else if (intersectedFloor) {
- intersectPoint = new THREE.Vector3(
- intersectedFloor.point.x,
- Math.round(intersectedFloor.point.y),
- intersectedFloor.point.z
- );
- } else if (intersectedPlane) {
- intersectPoint = new THREE.Vector3(
- intersectedPlane.point.x,
- 0,
- intersectedPlane.point.z
- );
- }
-
- if (intersectPoint) {
- if (intersectPoint.y < 0) {
- intersectPoint = new THREE.Vector3(
- intersectPoint.x,
- 0,
- intersectPoint.z
- );
- }
- const cachedModel = THREE.Cache.get(selectedItem.id);
- if (cachedModel) {
- handleModelLoad(
- cachedModel,
- intersectPoint!,
- selectedItem,
- addEvent,
- addAsset,
- socket,
- selectedVersion?.versionId || '',
- projectId,
- userId
- );
- return;
- } else {
- const cachedModelBlob = await retrieveGLTF(selectedItem.id);
- if (cachedModelBlob) {
- const blobUrl = URL.createObjectURL(cachedModelBlob);
- loader.load(blobUrl, (gltf) => {
- URL.revokeObjectURL(blobUrl);
- THREE.Cache.remove(blobUrl);
- THREE.Cache.add(selectedItem.id, gltf);
- handleModelLoad(
- gltf,
- intersectPoint!,
- selectedItem,
- addEvent,
- addAsset,
- socket,
- selectedVersion?.versionId || '',
- projectId,
- userId
- );
- });
- } else {
- loader.load(
- `${url_Backend_dwinzo}/api/v2/AssetFile/${selectedItem.id}`,
- async (gltf) => {
- const modelBlob = await fetch(
- `${url_Backend_dwinzo}/api/v2/AssetFile/${selectedItem.id}`
- ).then((res) => res.blob());
- await storeGLTF(selectedItem.id, modelBlob);
- THREE.Cache.add(selectedItem.id, gltf);
- await handleModelLoad(
- gltf,
- intersectPoint!,
- selectedItem,
- addEvent,
- addAsset,
- socket,
- selectedVersion?.versionId || '',
- projectId,
- userId
- );
+ if (intersectedFloor && intersectedPlane) {
+ // intersectPoint = intersectedFloor.distance < intersectedPlane.distance ?
+ // new THREE.Vector3(intersectedFloor.point.x, Math.round(intersectedFloor.point.y), intersectedFloor.point.z)
+ // : new THREE.Vector3(intersectedPlane.point.x, 0, intersectedPlane.point.z);
+ if (intersectedFloor.distance < intersectedPlane.distance) {
+ if (intersectedFloor.object.userData.floorUuid) {
+ intersectPoint = new THREE.Vector3(intersectedFloor.point.x, intersectedFloor.object.userData.floorDepth, intersectedFloor.point.z);
+ } else {
+ intersectPoint = new THREE.Vector3(intersectedFloor.point.x, 0, intersectedFloor.point.z);
+ }
+ } else {
+ intersectPoint = new THREE.Vector3(intersectedPlane.point.x, 0, intersectedPlane.point.z);
}
- );
+ } else if (intersectedFloor) {
+ intersectPoint = new THREE.Vector3(intersectedFloor.point.x, Math.round(intersectedFloor.point.y), intersectedFloor.point.z);
+ } else if (intersectedPlane) {
+ intersectPoint = new THREE.Vector3(intersectedPlane.point.x, 0, intersectedPlane.point.z);
}
- }
+
+ if (intersectPoint) {
+
+ if (intersectPoint.y < 0) {
+ intersectPoint = new THREE.Vector3(intersectPoint.x, 0, intersectPoint.z);
+ }
+ const cachedModel = THREE.Cache.get(selectedItem.id);
+ if (cachedModel) {
+ handleModelLoad(cachedModel, intersectPoint!, selectedItem, addEvent, addAsset, socket, selectedVersion?.versionId || '', projectId, userId);
+ return;
+ } else {
+ const cachedModelBlob = await retrieveGLTF(selectedItem.id);
+ if (cachedModelBlob) {
+ const blobUrl = URL.createObjectURL(cachedModelBlob);
+ loader.load(blobUrl, (gltf) => {
+ URL.revokeObjectURL(blobUrl);
+ THREE.Cache.remove(blobUrl);
+ THREE.Cache.add(selectedItem.id, gltf);
+ handleModelLoad(gltf, intersectPoint!, selectedItem, addEvent, addAsset, socket, selectedVersion?.versionId || '', projectId, userId);
+ });
+ } else {
+ loader.load(`${url_Backend_dwinzo}/api/v2/AssetFile/${selectedItem.id}`,
+ async (gltf) => {
+ const modelBlob = await fetch(`${url_Backend_dwinzo}/api/v2/AssetFile/${selectedItem.id}`).then((res) => res.blob());
+ await storeGLTF(selectedItem.id, modelBlob);
+ THREE.Cache.add(selectedItem.id, gltf);
+ await handleModelLoad(gltf, intersectPoint!, selectedItem, addEvent, addAsset, socket, selectedVersion?.versionId || '', projectId, userId);
+ }
+ );
+ }
+ }
+ }
+ } catch (error) {
+ echo.error("Failed to add asset");
+ } finally {
+ setSelectedItem({});
}
- } catch (error) {
- echo.error("Failed to add asset");
- } finally {
- setSelectedItem({});
- }
}
async function handleModelLoad(
- gltf: any,
- intersectPoint: THREE.Vector3,
- selectedItem: any,
- addEvent: (event: EventsSchema) => void,
- addAsset: (asset: Asset) => void,
- socket: Socket,
- versionId: string,
- projectId?: string,
- userId?: string
+ gltf: any,
+ intersectPoint: THREE.Vector3,
+ selectedItem: any,
+ addEvent: (event: EventsSchema) => void,
+ addAsset: (asset: Asset) => void,
+ socket: Socket,
+ versionId: string,
+ projectId?: string,
+ userId?: string
) {
- const { organization } = getUserData();
- const model = gltf.scene.clone();
- model.userData = {
- name: selectedItem.name,
- modelId: selectedItem.id,
- modelUuid: model.uuid,
- };
- model.position.set(intersectPoint!.x, intersectPoint!.y, intersectPoint!.z);
- model.scale.set(...CONSTANTS.assetConfig.defaultScaleAfterGsap);
-
- model.traverse((child: any) => {
- if (child) {
- child.castShadow = true;
- child.receiveShadow = true;
- }
- });
-
- const newFloorItem: Asset = {
- modelUuid: model.uuid,
- modelName: selectedItem.name,
- assetId: selectedItem.id,
- position: [intersectPoint!.x, intersectPoint!.y, intersectPoint!.z],
- rotation: [0, 0, 0],
- isLocked: false,
- isVisible: true,
- isCollidable: false,
- opacity: 1,
- };
-
-
- // API
-
- // await setAssetsApi(
- // organization,
- // newFloorItem.modelUuid,
- // newFloorItem.modelName,
- // newFloorItem.assetId,
- // newFloorItem.position,
- // { x: 0, y: 0, z: 0 },
- // false,
- // true,
- // );
-
- // SOCKET
-
- if (selectedItem.type) {
- const data = PointsCalculator(
- selectedItem.type,
- gltf.scene.clone(),
- new THREE.Vector3(...model.rotation)
- );
-
- if (!data || !data.points) return;
-
- const eventData: any = {
- type: selectedItem.type,
+ const { organization } = getUserData();
+ const model = gltf.scene.clone();
+ model.userData = {
+ name: selectedItem.name,
+ modelId: selectedItem.id,
+ modelUuid: model.uuid,
};
+ model.position.set(intersectPoint!.x, intersectPoint!.y, intersectPoint!.z);
+ model.scale.set(...CONSTANTS.assetConfig.defaultScaleAfterGsap);
- if (selectedItem.type === "Conveyor") {
- const ConveyorEvent: ConveyorEventSchema = {
- modelUuid: newFloorItem.modelUuid,
- modelName: newFloorItem.modelName,
- position: newFloorItem.position,
- rotation: newFloorItem.rotation,
- state: "idle",
- type: "transfer",
- speed: 1,
- points: data.points.map((point: THREE.Vector3, index: number) => {
- const triggers: TriggerSchema[] = [];
-
- if (data.points && index < data.points.length - 1) {
- triggers.push({
- triggerUuid: THREE.MathUtils.generateUUID(),
- triggerName: `Trigger 1`,
- triggerType: "onComplete",
- delay: 0,
- triggeredAsset: {
- triggeredModel: {
- modelName: newFloorItem.modelName,
- modelUuid: newFloorItem.modelUuid,
- },
- triggeredPoint: {
- pointName: `Point`,
- pointUuid: "",
- },
- triggeredAction: {
- actionName: `Action 1`,
- actionUuid: "",
- },
- },
- });
- }
-
- return {
- uuid: THREE.MathUtils.generateUUID(),
- position: [point.x, point.y, point.z],
- rotation: [0, 0, 0],
- action: {
- actionUuid: THREE.MathUtils.generateUUID(),
- actionName: `Action 1`,
- actionType: "default",
- material: "Default Material",
- delay: 0,
- spawnInterval: 5,
- spawnCount: 1,
- triggers: triggers,
- },
- };
- }),
- };
-
- for (let i = 0; i < ConveyorEvent.points.length - 1; i++) {
- const currentPoint = ConveyorEvent.points[i];
- const nextPoint = ConveyorEvent.points[i + 1];
-
- if (currentPoint.action.triggers.length > 0) {
- currentPoint.action.triggers[0].triggeredAsset!.triggeredPoint!.pointUuid =
- nextPoint.uuid;
- currentPoint.action.triggers[0].triggeredAsset!.triggeredAction!.actionUuid =
- nextPoint.action.actionUuid;
+ model.traverse((child: any) => {
+ if (child) {
+ child.castShadow = true;
+ child.receiveShadow = true;
}
- }
- addEvent(ConveyorEvent);
- eventData.points = ConveyorEvent.points.map((point) => ({
- uuid: point.uuid,
- position: point.position,
- rotation: point.rotation,
- }));
- } else if (selectedItem.type === "Vehicle") {
- const vehicleEvent: VehicleEventSchema = {
- modelUuid: newFloorItem.modelUuid,
- modelName: newFloorItem.modelName,
- position: newFloorItem.position,
- rotation: newFloorItem.rotation,
- state: "idle",
- type: "vehicle",
- speed: 1,
- point: {
- uuid: THREE.MathUtils.generateUUID(),
- position: [data.points[0].x, data.points[0].y, data.points[0].z],
- rotation: [0, 0, 0],
- action: {
- actionUuid: THREE.MathUtils.generateUUID(),
- actionName: "Action 1",
- actionType: "travel",
- unLoadDuration: 5,
- loadCapacity: 1,
- steeringAngle: 0,
- pickUpPoint: null,
- unLoadPoint: null,
- triggers: [],
- },
- },
- };
- addEvent(vehicleEvent);
- eventData.point = {
- uuid: vehicleEvent.point.uuid,
- position: vehicleEvent.point.position,
- rotation: vehicleEvent.point.rotation,
- };
- } else if (selectedItem.type === "ArmBot") {
- const roboticArmEvent: RoboticArmEventSchema = {
- modelUuid: newFloorItem.modelUuid,
- modelName: newFloorItem.modelName,
- position: newFloorItem.position,
- rotation: newFloorItem.rotation,
- state: "idle",
- type: "roboticArm",
- speed: 1,
- point: {
- uuid: THREE.MathUtils.generateUUID(),
- position: [data.points[0].x, data.points[0].y, data.points[0].z],
- rotation: [0, 0, 0],
- actions: [
- {
- actionUuid: THREE.MathUtils.generateUUID(),
- actionName: "Action 1",
- actionType: "pickAndPlace",
- process: {
- startPoint: null,
- endPoint: null,
- },
- triggers: [],
+ });
+
+ const newFloorItem: Asset = {
+ modelUuid: model.uuid,
+ modelName: selectedItem.name,
+ assetId: selectedItem.id,
+ position: [intersectPoint!.x, intersectPoint!.y, intersectPoint!.z],
+ rotation: [0, 0, 0],
+ isLocked: false,
+ isVisible: true,
+ isCollidable: false,
+ opacity: 1,
+ };
+
+
+ // API
+
+ // await setAssetsApi(
+ // organization,
+ // newFloorItem.modelUuid,
+ // newFloorItem.modelName,
+ // newFloorItem.assetId,
+ // newFloorItem.position,
+ // { x: 0, y: 0, z: 0 },
+ // false,
+ // true,
+ // );
+
+ // SOCKET
+
+ if (selectedItem.type) {
+ const data = PointsCalculator(
+ selectedItem.type,
+ gltf.scene.clone(),
+ new THREE.Vector3(...model.rotation)
+ );
+
+ if (!data || !data.points) return;
+
+ const eventData: any = { type: selectedItem.type, };
+
+ if (selectedItem.type === "Conveyor") {
+ const ConveyorEvent: ConveyorEventSchema = {
+ modelUuid: newFloorItem.modelUuid,
+ modelName: newFloorItem.modelName,
+ position: newFloorItem.position,
+ rotation: newFloorItem.rotation,
+ state: "idle",
+ type: "transfer",
+ speed: 1,
+ points: data.points.map((point: THREE.Vector3, index: number) => {
+ const triggers: TriggerSchema[] = [];
+
+ if (data.points && index < data.points.length - 1) {
+ triggers.push({
+ triggerUuid: THREE.MathUtils.generateUUID(),
+ triggerName: `Trigger 1`,
+ triggerType: "onComplete",
+ delay: 0,
+ triggeredAsset: {
+ triggeredModel: {
+ modelName: newFloorItem.modelName,
+ modelUuid: newFloorItem.modelUuid,
+ },
+ triggeredPoint: {
+ pointName: `Point`,
+ pointUuid: "",
+ },
+ triggeredAction: {
+ actionName: `Action 1`,
+ actionUuid: "",
+ },
+ },
+ });
+ }
+
+ return {
+ uuid: THREE.MathUtils.generateUUID(),
+ position: [point.x, point.y, point.z],
+ rotation: [0, 0, 0],
+ action: {
+ actionUuid: THREE.MathUtils.generateUUID(),
+ actionName: `Action 1`,
+ actionType: "default",
+ material: "Default Material",
+ delay: 0,
+ spawnInterval: 5,
+ spawnCount: 1,
+ triggers: triggers,
+ },
+ };
+ }),
+ };
+
+ for (let i = 0; i < ConveyorEvent.points.length - 1; i++) {
+ const currentPoint = ConveyorEvent.points[i];
+ const nextPoint = ConveyorEvent.points[i + 1];
+
+ if (currentPoint.action.triggers.length > 0) {
+ currentPoint.action.triggers[0].triggeredAsset!.triggeredPoint!.pointUuid = nextPoint.uuid;
+ currentPoint.action.triggers[0].triggeredAsset!.triggeredAction!.actionUuid = nextPoint.action.actionUuid;
+ }
+ }
+ addEvent(ConveyorEvent);
+ eventData.points = ConveyorEvent.points.map((point) => ({
+ uuid: point.uuid,
+ position: point.position,
+ rotation: point.rotation,
+ }));
+ } else if (selectedItem.type === "Vehicle") {
+ const vehicleEvent: VehicleEventSchema = {
+ modelUuid: newFloorItem.modelUuid,
+ modelName: newFloorItem.modelName,
+ position: newFloorItem.position,
+ rotation: newFloorItem.rotation,
+ state: "idle",
+ type: "vehicle",
+ speed: 1,
+ point: {
+ uuid: THREE.MathUtils.generateUUID(),
+ position: [data.points[0].x, data.points[0].y, data.points[0].z],
+ rotation: [0, 0, 0],
+ action: {
+ actionUuid: THREE.MathUtils.generateUUID(),
+ actionName: "Action 1",
+ actionType: "travel",
+ unLoadDuration: 5,
+ loadCapacity: 1,
+ steeringAngle: 0,
+ pickUpPoint: null,
+ unLoadPoint: null,
+ triggers: [],
+ },
+ },
+ };
+ addEvent(vehicleEvent);
+ eventData.point = {
+ uuid: vehicleEvent.point.uuid,
+ position: vehicleEvent.point.position,
+ rotation: vehicleEvent.point.rotation,
+ };
+ } else if (selectedItem.type === "ArmBot") {
+ const roboticArmEvent: RoboticArmEventSchema = {
+ modelUuid: newFloorItem.modelUuid,
+ modelName: newFloorItem.modelName,
+ position: newFloorItem.position,
+ rotation: newFloorItem.rotation,
+ state: "idle",
+ type: "roboticArm",
+ speed: 1,
+ point: {
+ uuid: THREE.MathUtils.generateUUID(),
+ position: [data.points[0].x, data.points[0].y, data.points[0].z],
+ rotation: [0, 0, 0],
+ actions: [
+ {
+ actionUuid: THREE.MathUtils.generateUUID(),
+ actionName: "Action 1",
+ actionType: "pickAndPlace",
+ process: {
+ startPoint: null,
+ endPoint: null,
+ },
+ triggers: [],
+ },
+ ],
+ },
+ };
+ addEvent(roboticArmEvent);
+ eventData.point = {
+ uuid: roboticArmEvent.point.uuid,
+ position: roboticArmEvent.point.position,
+ rotation: roboticArmEvent.point.rotation,
+ };
+ } else if (selectedItem.type === "StaticMachine") {
+ const machineEvent: MachineEventSchema = {
+ modelUuid: newFloorItem.modelUuid,
+ modelName: newFloorItem.modelName,
+ position: newFloorItem.position,
+ rotation: newFloorItem.rotation,
+ state: "idle",
+ type: "machine",
+ point: {
+ uuid: THREE.MathUtils.generateUUID(),
+ position: [data.points[0].x, data.points[0].y, data.points[0].z],
+ rotation: [0, 0, 0],
+ action: {
+ actionUuid: THREE.MathUtils.generateUUID(),
+ actionName: "Action 1",
+ actionType: "process",
+ processTime: 10,
+ swapMaterial: "Default Material",
+ triggers: [],
+ },
+ },
+ };
+ addEvent(machineEvent);
+ eventData.point = {
+ uuid: machineEvent.point.uuid,
+ position: machineEvent.point.position,
+ rotation: machineEvent.point.rotation,
+ };
+ } else if (selectedItem.type === "Storage") {
+ const storageEvent: StorageEventSchema = {
+ modelUuid: newFloorItem.modelUuid,
+ modelName: newFloorItem.modelName,
+ position: newFloorItem.position,
+ rotation: newFloorItem.rotation,
+ state: "idle",
+ type: "storageUnit",
+ point: {
+ uuid: THREE.MathUtils.generateUUID(),
+ position: [data.points[0].x, data.points[0].y, data.points[0].z],
+ rotation: [0, 0, 0],
+ action: {
+ actionUuid: THREE.MathUtils.generateUUID(),
+ actionName: "Action 1",
+ actionType: "store",
+ storageCapacity: 10,
+ triggers: [],
+ },
+ },
+ };
+ addEvent(storageEvent);
+ eventData.point = {
+ uuid: storageEvent.point.uuid,
+ position: storageEvent.point.position,
+ rotation: storageEvent.point.rotation,
+ };
+ }
+
+ const completeData = {
+ organization,
+ modelUuid: newFloorItem.modelUuid,
+ modelName: newFloorItem.modelName,
+ assetId: newFloorItem.assetId,
+ position: newFloorItem.position,
+ rotation: {
+ x: model.rotation.x,
+ y: model.rotation.y,
+ z: model.rotation.z,
},
- ],
- },
- };
- addEvent(roboticArmEvent);
- eventData.point = {
- uuid: roboticArmEvent.point.uuid,
- position: roboticArmEvent.point.position,
- rotation: roboticArmEvent.point.rotation,
- };
- } else if (selectedItem.type === "StaticMachine") {
- const machineEvent: MachineEventSchema = {
- modelUuid: newFloorItem.modelUuid,
- modelName: newFloorItem.modelName,
- position: newFloorItem.position,
- rotation: newFloorItem.rotation,
- state: "idle",
- type: "machine",
- point: {
- uuid: THREE.MathUtils.generateUUID(),
- position: [data.points[0].x, data.points[0].y, data.points[0].z],
- rotation: [0, 0, 0],
- action: {
- actionUuid: THREE.MathUtils.generateUUID(),
- actionName: "Action 1",
- actionType: "process",
- processTime: 10,
- swapMaterial: "Default Material",
- triggers: [],
- },
- },
- };
- addEvent(machineEvent);
- eventData.point = {
- uuid: machineEvent.point.uuid,
- position: machineEvent.point.position,
- rotation: machineEvent.point.rotation,
- };
- } else if (selectedItem.type === "Storage") {
- const storageEvent: StorageEventSchema = {
- modelUuid: newFloorItem.modelUuid,
- modelName: newFloorItem.modelName,
- position: newFloorItem.position,
- rotation: newFloorItem.rotation,
- state: "idle",
- type: "storageUnit",
- point: {
- uuid: THREE.MathUtils.generateUUID(),
- position: [data.points[0].x, data.points[0].y, data.points[0].z],
- rotation: [0, 0, 0],
- action: {
- actionUuid: THREE.MathUtils.generateUUID(),
- actionName: "Action 1",
- actionType: "store",
- storageCapacity: 10,
- triggers: [],
- },
- },
- };
- addEvent(storageEvent);
- eventData.point = {
- uuid: storageEvent.point.uuid,
- position: storageEvent.point.position,
- rotation: storageEvent.point.rotation,
- };
+ isLocked: false,
+ isVisible: true,
+ socketId: socket.id,
+ eventData: eventData,
+ versionId: versionId,
+ projectId: projectId,
+ userId: userId,
+ };
+
+ socket.emit("v1:model-asset:add", completeData);
+
+ const asset: Asset = {
+ modelUuid: completeData.modelUuid,
+ modelName: completeData.modelName,
+ assetId: completeData.assetId,
+ position: completeData.position,
+ rotation: [
+ completeData.rotation.x,
+ completeData.rotation.y,
+ completeData.rotation.z,
+ ] as [number, number, number],
+ isLocked: completeData.isLocked,
+ isCollidable: false,
+ isVisible: completeData.isVisible,
+ opacity: 1,
+ eventData: completeData.eventData,
+ };
+
+ addAsset(asset);
+ } else {
+ const data = {
+ organization,
+ modelUuid: newFloorItem.modelUuid,
+ modelName: newFloorItem.modelName,
+ assetId: newFloorItem.assetId,
+ position: newFloorItem.position,
+ rotation: {
+ x: model.rotation.x,
+ y: model.rotation.y,
+ z: model.rotation.z,
+ },
+ isLocked: false,
+ isVisible: true,
+ socketId: socket.id,
+ versionId: versionId,
+ projectId: projectId,
+ userId: userId,
+ };
+
+ socket.emit("v1:model-asset:add", data);
+
+ const asset = {
+ modelUuid: data.modelUuid,
+ modelName: data.modelName,
+ assetId: data.assetId,
+ position: data.position,
+ rotation: [data.rotation.x, data.rotation.y, data.rotation.z] as [
+ number,
+ number,
+ number
+ ],
+ isLocked: data.isLocked,
+ isCollidable: false,
+ isVisible: data.isVisible,
+ opacity: 1,
+ };
+
+ addAsset(asset);
}
-
- const completeData = {
- organization,
- modelUuid: newFloorItem.modelUuid,
- modelName: newFloorItem.modelName,
- assetId: newFloorItem.assetId,
- position: newFloorItem.position,
- rotation: {
- x: model.rotation.x,
- y: model.rotation.y,
- z: model.rotation.z,
- },
- isLocked: false,
- isVisible: true,
- socketId: socket.id,
- eventData: eventData,
- versionId: versionId,
- projectId: projectId,
- userId: userId,
- };
-
- socket.emit("v1:model-asset:add", completeData);
-
- const asset: Asset = {
- modelUuid: completeData.modelUuid,
- modelName: completeData.modelName,
- assetId: completeData.assetId,
- position: completeData.position,
- rotation: [
- completeData.rotation.x,
- completeData.rotation.y,
- completeData.rotation.z,
- ] as [number, number, number],
- isLocked: completeData.isLocked,
- isCollidable: false,
- isVisible: completeData.isVisible,
- opacity: 1,
- eventData: completeData.eventData,
- };
-
- addAsset(asset);
- } else {
- const data = {
- organization,
- modelUuid: newFloorItem.modelUuid,
- modelName: newFloorItem.modelName,
- assetId: newFloorItem.assetId,
- position: newFloorItem.position,
- rotation: {
- x: model.rotation.x,
- y: model.rotation.y,
- z: model.rotation.z,
- },
- isLocked: false,
- isVisible: true,
- socketId: socket.id,
- versionId: versionId,
- projectId: projectId,
- userId: userId,
- };
-
- socket.emit("v1:model-asset:add", data);
-
- const asset = {
- modelUuid: data.modelUuid,
- modelName: data.modelName,
- assetId: data.assetId,
- position: data.position,
- rotation: [data.rotation.x, data.rotation.y, data.rotation.z] as [
- number,
- number,
- number
- ],
- isLocked: data.isLocked,
- isCollidable: false,
- isVisible: data.isVisible,
- opacity: 1,
- };
-
- addAsset(asset);
- }
}
export default addAssetModel;
diff --git a/app/src/modules/builder/floor/Instances/Instance/floorInstance.tsx b/app/src/modules/builder/floor/Instances/Instance/floorInstance.tsx
index ce82298..e5ed733 100644
--- a/app/src/modules/builder/floor/Instances/Instance/floorInstance.tsx
+++ b/app/src/modules/builder/floor/Instances/Instance/floorInstance.tsx
@@ -59,9 +59,9 @@ function FloorInstance({ floor }: { floor: Floor }) {
receiveShadow
name={`Floor-${floor.floorUuid}`}
rotation={[Math.PI / 2, 0, 0]}
- position={[0, floor.floorDepth, 0]}
+ position={[0, !floor.isBeveled ? floor.floorDepth : (floor.floorDepth - 0.1), 0]}
userData={floor}
- onClick={(e) => {
+ onDoubleClick={(e) => {
if (!togglView && activeModule === 'builder') {
if (e.object.userData.floorUuid) {
setSelectedFloor(e.object);
@@ -76,10 +76,14 @@ function FloorInstance({ floor }: { floor: Floor }) {
}}
>
diff --git a/app/src/modules/builder/wall/Instances/instance/wall.tsx b/app/src/modules/builder/wall/Instances/instance/wall.tsx
index a07e8f9..ff0e5ce 100644
--- a/app/src/modules/builder/wall/Instances/instance/wall.tsx
+++ b/app/src/modules/builder/wall/Instances/instance/wall.tsx
@@ -123,7 +123,7 @@ function Wall({ wall }: { readonly wall: Wall }) {
rotation={[0, -angle, 0]}
userData={wall}
name={`WallReference_${wall.wallUuid}`}
- onClick={(e) => {
+ onDoubleClick={(e) => {
if (visible && !togglView && activeModule === 'builder') {
if (e.object.userData.wallUuid) {
setSelectedWall(e.object);
diff --git a/app/src/modules/builder/wall/Instances/wallInstances.tsx b/app/src/modules/builder/wall/Instances/wallInstances.tsx
index 40c60cd..267c91f 100644
--- a/app/src/modules/builder/wall/Instances/wallInstances.tsx
+++ b/app/src/modules/builder/wall/Instances/wallInstances.tsx
@@ -134,14 +134,15 @@ function Floor({ room }: { room: Point[] }) {
if (!shape) return null;
return (
-
+
-
+
);
}
diff --git a/app/src/modules/builder/wall/wallCreator/wallCreator.tsx b/app/src/modules/builder/wall/wallCreator/wallCreator.tsx
index c3a6c66..b31ad82 100644
--- a/app/src/modules/builder/wall/wallCreator/wallCreator.tsx
+++ b/app/src/modules/builder/wall/wallCreator/wallCreator.tsx
@@ -12,8 +12,8 @@ import getClosestIntersection from '../../geomentries/lines/getClosestIntersecti
import ReferencePoint from '../../point/reference/referencePoint';
import ReferenceWall from './referenceWall';
-import { upsertWallApi } from '../../../../services/factoryBuilder/wall/upsertWallApi';
-import { deleteWallApi } from '../../../../services/factoryBuilder/wall/deleteWallApi';
+// import { upsertWallApi } from '../../../../services/factoryBuilder/wall/upsertWallApi';
+// import { deleteWallApi } from '../../../../services/factoryBuilder/wall/deleteWallApi';
function WallCreator() {
const { scene, camera, raycaster, gl, pointer } = useThree();
diff --git a/app/src/modules/scene/controls/selectionControls/distanceFindingControls.tsx b/app/src/modules/scene/controls/selectionControls/distanceFindingControls.tsx
index 4f2eb02..af654d6 100644
--- a/app/src/modules/scene/controls/selectionControls/distanceFindingControls.tsx
+++ b/app/src/modules/scene/controls/selectionControls/distanceFindingControls.tsx
@@ -1,339 +1,208 @@
import React, { useRef, useState } from "react";
import {
- Vector3,
- Raycaster,
- BufferGeometry,
- LineBasicMaterial,
- Line,
- Mesh,
- Group,
+ Vector3,
+ Raycaster,
+ BufferGeometry,
+ LineBasicMaterial,
+ Line,
+ Mesh,
+ Group,
} from "three";
import { useThree, useFrame } from "@react-three/fiber";
import { Html } from "@react-three/drei";
interface DistanceFindingControlsProps {
- boundingBoxRef: React.RefObject;
- object: number;
+ boundingBoxRef: React.RefObject;
+ object: number;
}
+const material = new LineBasicMaterial({ color: "#d2baff" });
+
+const DIRECTION_LABEL_MAP = {
+ textPosX: "textPosX",
+ textNegX: "textNegX",
+ textPosZ: "textPosZ",
+ textNegZ: "textNegZ",
+} as const;
+
const DistanceFindingControls = ({
- boundingBoxRef,
- object,
+ boundingBoxRef,
+ object,
}: DistanceFindingControlsProps) => {
- const { camera, scene } = useThree();
- const [labelValues, setLabelValues] = useState<{
- textPosX: any;
- textNegX: any;
- textPosZ: any;
- textNegZ: any;
- }>({
- textPosX: "",
- textNegX: "",
- textPosZ: "",
- textNegZ: "",
- });
+ const { camera, scene } = useThree();
+ const [labelValues, setLabelValues] = useState>({
+ textPosX: "",
+ textNegX: "",
+ textPosZ: "",
+ textNegZ: "",
+ });
- // Refs for measurement lines
- const line1 = useRef(null);
- const line2 = useRef(null);
- const line3 = useRef(null);
- const line4 = useRef(null);
- const line5 = useRef(null);
-
- // Refs for measurement text labels
- const textPosX = useRef(null);
- const textNegX = useRef(null);
- const textPosZ = useRef(null);
- const textNegZ = useRef(null);
- const textPosY = useRef(null);
-
- // Store line geometries to avoid recreation
- const lineGeometries = useRef({
- posX: new BufferGeometry(),
- negX: new BufferGeometry(),
- posZ: new BufferGeometry(),
- negZ: new BufferGeometry(),
- posY: new BufferGeometry(),
- });
-
- useFrame(() => {
- if (!boundingBoxRef?.current) return;
-
- boundingBoxRef.current.geometry.computeBoundingBox();
- const bbox = boundingBoxRef.current.geometry.boundingBox;
-
- if (!bbox) return;
-
- const size = {
- x: bbox.max.x - bbox.min.x,
- y: bbox.max.y - bbox.min.y,
- z: bbox.max.z - bbox.min.z,
+ const lineRefs = {
+ posX: useRef(null),
+ negX: useRef(null),
+ posZ: useRef(null),
+ negZ: useRef(null),
+ posY: useRef(null),
};
- const vec = boundingBoxRef.current?.getWorldPosition(new Vector3()).clone();
+ const textRefs = {
+ textPosX: useRef(null),
+ textNegX: useRef(null),
+ textPosZ: useRef(null),
+ textNegZ: useRef(null),
+ textPosY: useRef(null),
+ };
- if (!vec) return;
- updateLine({
- line: line1.current,
- geometry: lineGeometries.current.posX,
- direction: new Vector3(1, 0, 0), // Positive X
- angle: "pos",
- mesh: textPosX,
- vec,
- size,
+ const lineGeometries = useRef({
+ posX: new BufferGeometry(),
+ negX: new BufferGeometry(),
+ posZ: new BufferGeometry(),
+ negZ: new BufferGeometry(),
+ posY: new BufferGeometry(),
});
- updateLine({
- line: line2.current,
- geometry: lineGeometries.current.negX,
- direction: new Vector3(-1, 0, 0), // Negative X
- angle: "neg",
- mesh: textNegX,
- vec,
- size,
+
+ useFrame(() => {
+ const bboxMesh = boundingBoxRef?.current;
+ if (!bboxMesh) return;
+
+ bboxMesh.geometry.computeBoundingBox();
+ const bbox = bboxMesh.geometry.boundingBox;
+ if (!bbox) return;
+
+ const size = {
+ x: bbox.max.x - bbox.min.x,
+ y: bbox.max.y - bbox.min.y,
+ z: bbox.max.z - bbox.min.z,
+ };
+
+ const center = bboxMesh.getWorldPosition(new Vector3()).clone();
+ if (!center) return;
+
+ updateLine("posX", new Vector3(1, 0, 0), "pos", size, center);
+ updateLine("negX", new Vector3(-1, 0, 0), "neg", size, center);
+ updateLine("posZ", new Vector3(0, 0, 1), "pos", size, center);
+ updateLine("negZ", new Vector3(0, 0, -1), "neg", size, center);
+ updateLine("posY", new Vector3(0, -1, 0), "posY", size, center);
});
- updateLine({
- line: line3.current,
- geometry: lineGeometries.current.posZ,
- direction: new Vector3(0, 0, 1), // Positive Z
- angle: "pos",
- mesh: textPosZ,
- vec,
- size,
- });
- updateLine({
- line: line4.current,
- geometry: lineGeometries.current.negZ,
- direction: new Vector3(0, 0, -1), // Negative Z
- angle: "neg",
- mesh: textNegZ,
- vec,
- size,
- });
- updateLine({
- line: line5.current,
- geometry: lineGeometries.current.posY,
- direction: new Vector3(0, -1, 0), // Down (Y)
- angle: "posY",
- mesh: textPosY,
- vec,
- size,
- });
- });
- const updateLine = ({
- line,
- geometry,
- direction,
- angle,
- mesh,
- vec,
- size,
- }: {
- line: Line | null;
- geometry: BufferGeometry;
- direction: Vector3;
- angle: string;
- mesh: React.RefObject;
- vec: Vector3;
- size: { x: number; y: number; z: number };
- }) => {
- if (!line) return;
+ const updateLine = (
+ key: keyof typeof lineRefs,
+ direction: Vector3,
+ angle: string,
+ size: { x: number; y: number; z: number },
+ origin: Vector3
+ ) => {
+ const line = lineRefs[key].current;
+ const geometry = lineGeometries.current[key];
+ const mesh = textRefs[`text${key[0].toUpperCase() + key.slice(1)}` as keyof typeof textRefs];
- const points = [];
+ if (!line) return;
- if (angle === "pos") {
- points[0] = new Vector3(vec.x, vec.y, vec.z).add(
- new Vector3((direction.x * size.x) / 2, 0, (direction.z * size.z) / 2)
- );
- } else if (angle === "neg") {
- points[0] = new Vector3(vec.x, vec.y, vec.z).sub(
- new Vector3((-direction.x * size.x) / 2, 0, (-direction.z * size.z) / 2)
- );
- } else if (angle === "posY") {
- points[0] = new Vector3(vec.x, vec.y, vec.z).sub(
- new Vector3(0, size.y / 2, 0)
- );
- }
+ const points: Vector3[] = [];
+ const halfSize = new Vector3(size.x / 2, size.y / 2, size.z / 2);
- const ray = new Raycaster();
- if (camera) ray.camera = camera;
- ray.set(new Vector3(vec.x, vec.y, vec.z), direction);
- ray.params.Line.threshold = 0.1;
+ if (angle === "pos") {
+ points[0] = origin.clone().add(direction.clone().multiply(halfSize));
+ } else if (angle === "neg") {
+ points[0] = origin.clone().sub(direction.clone().multiply(halfSize));
+ } else if (angle === "posY") {
+ points[0] = origin.clone().sub(new Vector3(0, size.y / 2, 0));
+ }
- // Find intersection points
- const wallsGroup = scene.children.find((val) =>
- val?.name.includes("Walls")
+ const ray = new Raycaster();
+ ray.camera = camera;
+ ray.set(origin, direction);
+ ray.params.Line.threshold = 0.1;
+
+ const wallsGroup = scene.children.find((val) =>
+ val?.name.includes("Walls")
+ );
+ const intersects = wallsGroup
+ ? ray.intersectObjects([wallsGroup], true)
+ : [];
+
+ const intersect = intersects.find((i) =>
+ i.object.name.includes("Wall")
+ );
+
+ if (intersect) {
+ points[1] = angle !== "posY" ? intersect.point : new Vector3(origin.x, 0, origin.z);
+ }
+
+ if (points[1]) {
+ geometry.dispose();
+ geometry.setFromPoints(points);
+ line.geometry = geometry;
+
+ const distance = points[0].distanceTo(points[1]).toFixed(2);
+
+ if (mesh?.current) {
+ geometry.computeBoundingSphere();
+ mesh.current.position.copy(geometry.boundingSphere!.center);
+
+ const labelEl = document.getElementById(mesh.current.name);
+ if (labelEl) {
+ labelEl.innerText = `${distance}m`;
+
+ if (DIRECTION_LABEL_MAP[labelEl.id as keyof typeof DIRECTION_LABEL_MAP]) {
+ setLabelValues((prev) => ({
+ ...prev,
+ [labelEl.id]: distance,
+ }));
+ }
+ }
+ }
+ } else {
+ geometry.dispose();
+ geometry.setFromPoints([new Vector3(), new Vector3()]);
+ line.geometry = geometry;
+
+ const labelEl = document.getElementById(mesh?.current?.name ?? "");
+ if (labelEl && DIRECTION_LABEL_MAP[labelEl.id as keyof typeof DIRECTION_LABEL_MAP]) {
+ labelEl.innerText = "";
+ setLabelValues((prev) => ({
+ ...prev,
+ [labelEl.id]: "",
+ }));
+ }
+ }
+ };
+
+ const renderLabel = (id: keyof typeof textRefs) => (
+
+
+ {labelValues[id]}
+
+
);
- const intersects = wallsGroup
- ? ray.intersectObjects([wallsGroup], true)
- : [];
- // Find intersection point
- if (intersects[0]) {
- for (const intersect of intersects) {
- if (intersect.object.name.includes("Wall")) {
- points[1] =
- angle !== "posY" ? intersect.point : new Vector3(vec.x, 0, vec.z); // Floor
- break;
- }
- }
- }
- if (points[1]) {
- geometry.dispose();
- geometry.setFromPoints([points[0], points[1]]);
- line.geometry = geometry;
-
- // Calculate the distance only once
- const distance = points[0].distanceTo(points[1]).toFixed(2);
-
- // Update measurement text
- if (mesh?.current) {
- geometry.computeBoundingSphere();
- const center = geometry.boundingSphere?.center;
- if (center) {
- mesh.current.position.copy(center);
- }
-
- const label = document.getElementById(mesh.current.name);
- if (label) {
- label.innerText = `${distance}m`;
-
- // Update specific label state based on the label ID
- switch (label.id) {
- case "textPosX":
- setLabelValues((prevState) => ({ ...prevState, textPosX: distance }));
- break;
- case "textNegX":
- setLabelValues((prevState) => ({ ...prevState, textNegX: distance }));
- break;
- case "textPosZ":
- setLabelValues((prevState) => ({ ...prevState, textPosZ: distance }));
- break;
- case "textNegZ":
- setLabelValues((prevState) => ({ ...prevState, textNegZ: distance }));
- break;
- default:
- break;
- }
- }
- }
- } else {
- // No intersection found - clear the line
- geometry.dispose();
- geometry.setFromPoints([new Vector3(), new Vector3()]);
- line.geometry = geometry;
-
- const label = document.getElementById(mesh?.current?.name ?? "");
- if (label) {
- label.innerText = "";
-
- // Clear the corresponding label value in the state
- switch (label.id) {
- case "textPosX":
- setLabelValues((prevState) => ({ ...prevState, textPosX: "" }));
- break;
- case "textNegX":
- setLabelValues((prevState) => ({ ...prevState, textNegX: "" }));
- break;
- case "textPosZ":
- setLabelValues((prevState) => ({ ...prevState, textPosZ: "" }));
- break;
- case "textNegZ":
- setLabelValues((prevState) => ({ ...prevState, textNegZ: "" }));
- break;
- default:
- break;
- }
- }
- }
-
- };
-
- const Material = new LineBasicMaterial({ color: "#d2baff" });
-
- return (
- <>
- {/* Measurement text labels */}
- {boundingBoxRef.current && object > 0 && (
+ return (
<>
-
-
- {labelValues.textPosX}
-
-
+ {boundingBoxRef.current && object > 0 && (
+
+ {renderLabel("textPosX")}
+ {renderLabel("textNegX")}
+ {renderLabel("textPosZ")}
+ {renderLabel("textNegZ")}
-
-
- {labelValues.textNegX}
-
-
-
-
-
- {labelValues.textPosZ}
-
-
-
-
-
- {labelValues.textNegZ}
-
-
-
- {/* Measurement lines */}
-
-
-
-
+
+
+
+
+
+ )}
>
- )
- }
- >
- );
+ );
};
export default DistanceFindingControls;
diff --git a/app/src/store/builder/useBuilderStore.ts b/app/src/store/builder/useBuilderStore.ts
index 8e240c1..e7a60ca 100644
--- a/app/src/store/builder/useBuilderStore.ts
+++ b/app/src/store/builder/useBuilderStore.ts
@@ -55,7 +55,7 @@ interface BuilderState {
// Setters - Floor
setSelectedFloor: (floor: Object3D | null) => void;
setFloorDepth: (depth: number) => void;
- setBeveled: (isBeveled: boolean) => void;
+ setIsBeveled: (isBeveled: boolean) => void;
setBevelStrength: (strength: number) => void;
setFloorMaterial: (material: string, side: 'side' | 'top') => void;
@@ -99,7 +99,7 @@ export const useBuilderStore = create()(
selectedFloor: null,
floorDepth: 0.1,
isBeveled: false,
- bevelStrength: 0.05,
+ bevelStrength: 5,
sideMaterial: 'Material 1',
topMaterial: 'Default Material',
@@ -182,7 +182,7 @@ export const useBuilderStore = create()(
});
},
- setBeveled: (isBeveled: boolean) => {
+ setIsBeveled: (isBeveled: boolean) => {
set((state) => {
state.isBeveled = isBeveled;
});
diff --git a/app/src/store/builder/useFloorStore.ts b/app/src/store/builder/useFloorStore.ts
index 7d425eb..77dc152 100644
--- a/app/src/store/builder/useFloorStore.ts
+++ b/app/src/store/builder/useFloorStore.ts
@@ -5,7 +5,7 @@ interface FloorStore {
floors: Floor[];
setFloors: (floors: Floor[]) => void;
addFloor: (floor: Floor) => void;
- updateFloor: (uuid: string, updated: Partial) => void;
+ updateFloor: (uuid: string, updated: Partial) => Floor | undefined;
removeFloor: (uuid: string) => void;
removePoint: (pointUuid: string) => { removedFloors: Floor[], updatedFloors: Floor[] };
removeFloorByPoints: (Points: [Point, Point]) => { removedFloors: Floor[], updatedFloors: Floor[] };
@@ -45,12 +45,17 @@ export const createFloorStore = () => {
state.floors.push(floor);
}),
- updateFloor: (uuid, updated) => set(state => {
- const floor = state.floors.find(f => f.floorUuid === uuid);
- if (floor) {
- Object.assign(floor, updated);
- }
- }),
+ updateFloor: (uuid, updated) => {
+ let updatedFloor: Floor | undefined;
+ set(state => {
+ const floor = state.floors.find(f => f.floorUuid === uuid);
+ if (floor) {
+ Object.assign(floor, updated);
+ updatedFloor = JSON.parse(JSON.stringify(floor));
+ }
+ });
+ return updatedFloor;
+ },
removeFloor: (uuid) => set(state => {
state.floors = state.floors.filter(f => f.floorUuid !== uuid);