////////// 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 "../../builder/geomentries/lines/distanceText"; import ReferenceDistanceText from "../../builder/geomentries/lines/referenceDistanceText"; ////////// Assests Imports ////////// import arch from "../../../assets/gltf-glb/arch.glb"; import door from "../../../assets/gltf-glb/door.glb"; import Window from "../../../assets/gltf-glb/window.glb"; ////////// Zustand State Imports ////////// import { useToggleView, useDeletePointOrLine, useMovePoint, useActiveLayer, useSocketStore, useWallVisibility, useRoofVisibility, useShadows, useUpdateScene, useWalls, useToolMode } from "../../../store/store"; ////////// 3D Function Imports ////////// import loadWalls from "../../builder/geomentries/walls/loadWalls"; import * as Types from "../../../types/world/worldTypes"; import SocketResponses from "../../collaboration/socketResponses.dev"; import FloorItemsGroup from "../../builder/groups/floorItemsGroup"; import FloorPlanGroup from "../../builder/groups/floorPlanGroup"; import FloorGroup from "../../builder/groups/floorGroup"; import FloorGroupAilse from "../../builder/groups/floorGroupAisle"; import Draw from "../../builder/functions/draw"; import WallsAndWallItems from "../../builder/groups/wallsAndWallItems"; import Ground from "../environment/ground"; // import ZoneGroup from "../groups/zoneGroup1"; import { findEnvironment } from "../../../services/factoryBuilder/environment/findEnvironment"; import Layer2DVisibility from "../../builder/geomentries/layers/layer2DVisibility"; import DrieHtmlTemp from "../mqttTemp/drieHtmlTemp"; import ZoneGroup from "../../builder/groups/zoneGroup"; export default function World() { 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, setActiveLayer } = useActiveLayer(); // State that changes based on which layer the user chooses in Layers.jsx. const { toggleView, setToggleView } = useToggleView(); // State for toggling between 2D and 3D. const { toolMode, setToolMode } = useToolMode(); const { movePoint, setMovePoint } = useMovePoint(); // State that stores a boolean which represents whether the move mode is active or not. const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine(); const { socket } = useSocketStore(); const { roofVisibility, setRoofVisibility } = useRoofVisibility(); const { wallVisibility, setWallVisibility } = useWallVisibility(); const { shadows, setShadows } = useShadows(); const { updateScene, setUpdateScene } = useUpdateScene(); const { walls, setWalls } = useWalls(); const [RefTextupdate, setRefTextUpdate] = useState(-1000); // 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); ////////// Assest Configuration Values ////////// const AssetConfigurations: Types.AssetConfigurations = { arch: { modelUrl: arch, scale: [0.75, 0.75, 0.75], csgscale: [2, 4, 0.5], csgposition: [0, 2, 0], positionY: () => 0, type: "Fixed-Move", }, door: { modelUrl: door, scale: [0.75, 0.75, 0.75], csgscale: [2, 4, 0.5], csgposition: [0, 2, 0], positionY: () => 0, type: "Fixed-Move", }, window: { modelUrl: Window, scale: [0.75, 0.75, 0.75], csgscale: [5, 3, 0.5], csgposition: [0, 1.5, 0], positionY: (intersectionPoint) => intersectionPoint.point.y, type: "Free-Move", }, }; ////////// All Toggle's ////////// useEffect(() => { setRefTextUpdate((prevUpdate) => prevUpdate - 1); if (dragPointControls.current) { dragPointControls.current.enabled = false; } if (toggleView) { Layer2DVisibility(activeLayer, floorPlanGroup, floorPlanGroupLine, floorPlanGroupPoint, currentLayerPoint, dragPointControls); } else { setToolMode(null); setDeletePointOrLine(false); setMovePoint(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')!); if (visibility) { setRoofVisibility(visibility.roofVisibility); setWallVisibility(visibility.wallVisibility); setShadows(visibility.shadowVisibility); } } 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 ( <> {/* */} ); }