////////// Three and React Three Fiber Imports ////////// import * as THREE from "three"; import { useEffect, useRef, useState } from "react"; import { useThree, useFrame } from "@react-three/fiber"; ////////// Component Imports ////////// import DistanceText from "./geomentries/lines/distanceText/distanceText"; import ReferenceDistanceText from "./geomentries/lines/distanceText/referenceDistanceText"; ////////// Zustand State Imports ////////// import { useToggleView, useDeletePointOrLine, useActiveLayer, useWallVisibility, useRoofVisibility, useShadows, useUpdateScene, useWalls, useToolMode, useRefTextUpdate, useRenderDistance, useLimitDistance, } from "../../store/builder/store"; ////////// 3D Function Imports ////////// import loadWalls from "./geomentries/walls/loadWalls"; import * as Types from "../../types/world/worldTypes"; import SocketResponses from "../collaboration/socket/socketResponses.dev"; import FloorItemsGroup from "./groups/floorItemsGroup"; import FloorPlanGroup from "./groups/floorPlanGroup"; import FloorGroup from "./groups/floorGroup"; import FloorGroupAilse from "./groups/floorGroupAisle"; import Draw from "./functions/draw"; import WallsAndWallItems from "./groups/wallsAndWallItems"; import Ground from "../scene/environment/ground"; import { findEnvironment } from "../../services/factoryBuilder/environment/findEnvironment"; import Layer2DVisibility from "./geomentries/layers/layer2DVisibility"; import ZoneGroup from "./groups/zoneGroup"; import MeasurementTool from "../scene/tools/measurementTool"; import NavMesh from "../simulation/vehicle/navMesh/navMesh"; import CalculateAreaGroup from "./groups/calculateAreaGroup"; import LayoutImage from "./layout/layoutImage"; import AssetsGroup from "./assetGroup/assetsGroup"; import { Bvh } from "@react-three/drei"; import DxfFile from "./dfx/LoadBlueprint"; import { useParams } from "react-router-dom"; export default function Builder() { const state = useThree(); // Importing the state from the useThree hook, which contains the scene, camera, and other Three.js elements. const csg = useRef(); // Reference for CSG object, used for 3D modeling. const CSGGroup = useRef() as Types.RefMesh; // Reference to a group of CSG objects. const scene = useRef() as Types.RefScene; // Reference to the scene. const camera = useRef() as Types.RefCamera; // Reference to the camera object. const controls = useRef(); // Reference to the controls object. const raycaster = useRef() as Types.RefRaycaster; // Reference for raycaster used for detecting objects being pointed at in the scene. const dragPointControls = useRef() as Types.RefDragControl; // Reference for drag point controls, an array for drag control. // Assigning the scene and camera from the Three.js state to the references. scene.current = state.scene; camera.current = state.camera; controls.current = state.controls; raycaster.current = state.raycaster; const plane = useRef(null); // Reference for a plane object for raycaster reference. const grid = useRef() as any; // Reference for a grid object for raycaster reference. const snappedPoint = useRef() as Types.RefVector3; // Reference for storing a snapped point at the (end = isSnapped) and (start = ispreSnapped) of the line. const isSnapped = useRef(false) as Types.RefBoolean; // Boolean reference to indicate if an object is snapped at the (end). const anglesnappedPoint = useRef() as Types.RefVector3; // Reference for storing an angle-snapped point when the line is in 90 degree etc... const isAngleSnapped = useRef(false) as Types.RefBoolean; // Boolean to indicate if angle snapping is active. const isSnappedUUID = useRef() as Types.RefString; // UUID reference to identify the snapped point. const ispreSnapped = useRef(false) as Types.RefBoolean; // Boolean reference to indicate if an object is snapped at the (start). const tempLoader = useRef() as Types.RefMesh; // Reference for a temporary loader for the floor items. const isTempLoader = useRef() as Types.RefBoolean; // Reference to check if a temporary loader is active. const Tube = useRef() as Types.RefTubeGeometry; // Reference for tubes used for reference line creation and updation. const line = useRef([]) as Types.RefLine; // Reference for line which stores the current line that is being drawn. const lines = useRef([]) as Types.RefLines; // Reference for lines which stores all the lines that are ever drawn. const onlyFloorline = useRef([]); // Reference for floor lines which does not have walls or roof and have only floor used to store the current line that is being drawn. const onlyFloorlines = useRef([]); // Reference for all the floor lines that are ever drawn. const ReferenceLineMesh = useRef() as Types.RefMesh; // Reference for storing the mesh of the reference line for moving it during draw. const LineCreated = useRef(false) as Types.RefBoolean; // Boolean to track whether the reference line is created or not. const referencePole = useRef() as Types.RefMesh; // Reference for a pole that is used as the reference for the user to show where it is placed. const itemsGroup = useRef() as Types.RefGroup; // Reference to the THREE.Group that has the floor items (Gltf). const floorGroup = useRef() as Types.RefGroup; // Reference to the THREE.Group that has the roofs and the floors. const AttachedObject = useRef() as Types.RefMesh; // Reference for an object that is attached using dbl click for transform controls rotation. const floorPlanGroup = useRef() as Types.RefGroup; // Reference for a THREE.Group that has the lines group and the points group. const floorPlanGroupLine = useRef() as Types.RefGroup; // Reference for a THREE.Group that has the lines that are drawn. const floorPlanGroupPoint = useRef() as Types.RefGroup; // Reference for a THREE.Group that has the points that are created. const floorGroupAisle = useRef() as Types.RefGroup; const zoneGroup = useRef() as Types.RefGroup; const currentLayerPoint = useRef([]) as Types.RefMeshArray; // Reference for points that re in the current layer used to update the points in drag controls. const hoveredDeletablePoint = useRef() as Types.RefMesh; // Reference for the currently hovered point that can be deleted. const hoveredDeletableLine = useRef() as Types.RefMesh; // Reference for the currently hovered line that can be deleted. const hoveredDeletableFloorItem = useRef() as Types.RefMesh; // Reference for the currently hovered floor item that can be deleted. const hoveredDeletableWallItem = useRef() as Types.RefMesh; // Reference for the currently hovered wall item that can be deleted. const hoveredDeletablePillar = useRef() as Types.RefMesh; // Reference for the currently hovered pillar that can be deleted. const currentWallItem = useRef() as Types.RefMesh; // Reference for the currently selected wall item that can be scaled, dragged etc... const cursorPosition = new THREE.Vector3(); // 3D vector for storing the cursor position. const [selectedItemsIndex, setSelectedItemsIndex] = useState(null); // State for tracking the index of the selected item. const { activeLayer } = useActiveLayer(); // State that changes based on which layer the user chooses in Layers.jsx. const { toggleView } = useToggleView(); // State for toggling between 2D and 3D. const { toolMode, setToolMode } = useToolMode(); const { setDeletePointOrLine } = useDeletePointOrLine(); const { setRoofVisibility } = useRoofVisibility(); const { setWallVisibility } = useWallVisibility(); const { setShadows } = useShadows(); const { setRenderDistance } = useRenderDistance(); const { setLimitDistance } = useLimitDistance(); const { setUpdateScene } = useUpdateScene(); const { setWalls } = useWalls(); const { refTextupdate, setRefTextUpdate } = useRefTextUpdate(); const { projectId } = useParams(); // 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); ////////// All Toggle's ////////// useEffect(() => { setRefTextUpdate((prevUpdate: number) => prevUpdate - 1); if (toggleView) { Layer2DVisibility( activeLayer, floorPlanGroup, floorPlanGroupLine, floorPlanGroupPoint, currentLayerPoint, dragPointControls ); } else { setToolMode(null); setDeletePointOrLine(false); loadWalls(lines, setWalls); setUpdateScene(true); line.current = []; } }, [toggleView]); useEffect(() => { THREE.Cache.clear(); THREE.Cache.enabled = true; }, []); useEffect(() => { const email = localStorage.getItem("email"); const organization = email!.split("@")[1].split(".")[0]; async function fetchVisibility() { const visibility = await findEnvironment( organization, localStorage.getItem("userId")!,projectId ); if (visibility) { setRoofVisibility(visibility.roofVisibility); setWallVisibility(visibility.wallVisibility); setShadows(visibility.shadowVisibility); setRenderDistance(visibility.renderDistance); setLimitDistance(visibility.limitDistance); } } fetchVisibility(); }, []); ////////// UseFrame is Here ////////// useFrame(() => { if (toolMode) { Draw( state, plane, cursorPosition, floorPlanGroupPoint, floorPlanGroupLine, snappedPoint, isSnapped, isSnappedUUID, line, lines, ispreSnapped, floorPlanGroup, ReferenceLineMesh, LineCreated, setRefTextUpdate, Tube, anglesnappedPoint, isAngleSnapped, toolMode ); } }); ////////// Return ////////// return ( <> {/* */} ); }