"updated single flow"
This commit is contained in:
@@ -18,18 +18,21 @@ type PathPoints = {
|
||||
interface ProcessContainerProps {
|
||||
processes: any[];
|
||||
agvRef: any;
|
||||
MaterialRef: any;
|
||||
}
|
||||
|
||||
const Agv: React.FC<ProcessContainerProps> = ({ processes, agvRef }) => {
|
||||
const Agv: React.FC<ProcessContainerProps> = ({
|
||||
processes,
|
||||
agvRef,
|
||||
MaterialRef,
|
||||
}) => {
|
||||
const [pathPoints, setPathPoints] = useState<PathPoints[]>([]);
|
||||
const { simulationStates } = useSimulationStates();
|
||||
const { navMesh } = useNavMesh();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { PlayAgv, setPlayAgv } = usePlayAgv();
|
||||
|
||||
useEffect(() => {
|
||||
console.log("agvRef: ", agvRef);
|
||||
}, [agvRef]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (simulationStates.length > 0) {
|
||||
@@ -90,6 +93,7 @@ const Agv: React.FC<ProcessContainerProps> = ({ processes, agvRef }) => {
|
||||
hitCount={pair.hitCount}
|
||||
processes={processes}
|
||||
agvRef={agvRef}
|
||||
MaterialRef={MaterialRef}
|
||||
/>
|
||||
|
||||
{pair.points.slice(1).map((point, idx) => (
|
||||
|
||||
@@ -32,7 +32,7 @@ export default function NavMeshDetails({
|
||||
|
||||
const [positions, indices] = getPositionsAndIndices(meshes);
|
||||
|
||||
const cellSize = 0.35;
|
||||
const cellSize = 0.2;
|
||||
const cellHeight = 0.7;
|
||||
const walkableRadius = 0.5;
|
||||
const { success, navMesh } = generateSoloNavMesh(positions, indices, {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
import React, { useEffect, useState, useRef, useMemo } from "react";
|
||||
import * as THREE from "three";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { NavMeshQuery } from "@recast-navigation/core";
|
||||
import { Line } from "@react-three/drei";
|
||||
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
||||
import { usePlayAgv } from "../../../store/store";
|
||||
import crate from "../../../assets/gltf-glb/crate_box.glb";
|
||||
|
||||
interface PathNavigatorProps {
|
||||
navMesh: any;
|
||||
@@ -15,6 +16,7 @@ interface PathNavigatorProps {
|
||||
hitCount: number;
|
||||
processes: any[];
|
||||
agvRef: any;
|
||||
MaterialRef: any;
|
||||
}
|
||||
interface AGVData {
|
||||
processId: string;
|
||||
@@ -23,7 +25,7 @@ interface AGVData {
|
||||
totalHits: number;
|
||||
}
|
||||
type Phase = "initial" | "toDrop" | "toPickup";
|
||||
|
||||
type MaterialType = "Box" | "Crate";
|
||||
export default function PathNavigator({
|
||||
navMesh,
|
||||
pathPoints,
|
||||
@@ -33,11 +35,13 @@ export default function PathNavigator({
|
||||
hitCount,
|
||||
processes,
|
||||
agvRef,
|
||||
MaterialRef,
|
||||
}: PathNavigatorProps) {
|
||||
const [currentPhase, setCurrentPhase] = useState<Phase>("initial");
|
||||
// console.log('agvRef: ', agvRef);
|
||||
//
|
||||
|
||||
const [path, setPath] = useState<[number, number, number][]>([]);
|
||||
const PickUpDrop = useRef([]);
|
||||
|
||||
// const [currentPhase, setCurrentPhase] = useState<"initial" | "loop">(
|
||||
// "initial"
|
||||
@@ -45,6 +49,7 @@ export default function PathNavigator({
|
||||
const [toPickupPath, setToPickupPath] = useState<[number, number, number][]>(
|
||||
[]
|
||||
);
|
||||
|
||||
const [pickupDropPath, setPickupDropPath] = useState<
|
||||
[number, number, number][]
|
||||
>([]);
|
||||
@@ -57,6 +62,7 @@ export default function PathNavigator({
|
||||
const [initialRotation, setInitialRotation] = useState<THREE.Euler | null>(
|
||||
null
|
||||
);
|
||||
const [boxVisible, setBoxVisible] = useState(false);
|
||||
|
||||
const distancesRef = useRef<number[]>([]);
|
||||
const totalDistanceRef = useRef(0);
|
||||
@@ -123,6 +129,9 @@ export default function PathNavigator({
|
||||
if (!navMesh || pathPoints.length < 2) return;
|
||||
|
||||
const [pickup, drop] = pathPoints.slice(-2);
|
||||
|
||||
PickUpDrop.current = pathPoints.slice(-2);
|
||||
|
||||
const object = scene.getObjectByProperty("uuid", id);
|
||||
|
||||
if (!object) return;
|
||||
@@ -171,13 +180,101 @@ export default function PathNavigator({
|
||||
// Add these refs outside the useFrame if not already present:
|
||||
const startPointReached = useRef(false);
|
||||
|
||||
const baseMaterials = useMemo(
|
||||
() => ({
|
||||
Box: new THREE.MeshStandardMaterial({ color: 0x8b4513 }),
|
||||
Crate: new THREE.MeshStandardMaterial({ color: 0x00ff00 }),
|
||||
// Default: new THREE.MeshStandardMaterial({ color: 0x00ff00 }),
|
||||
Default: new THREE.MeshStandardMaterial(),
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
// Example usage:
|
||||
const targetModelUUID = id; // Replace with your target ID
|
||||
const matchedProcess = findProcessByTargetModelUUID(
|
||||
processes,
|
||||
targetModelUUID
|
||||
);
|
||||
|
||||
function findProcessByTargetModelUUID(processes: any, targetModelUUID: any) {
|
||||
for (const process of processes) {
|
||||
for (const path of process.paths) {
|
||||
for (const point of path.points) {
|
||||
if (
|
||||
point.connections?.targets?.some(
|
||||
(target: any) => target.modelUUID === targetModelUUID
|
||||
)
|
||||
) {
|
||||
//
|
||||
return process.id; // Return the process if a match is found
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null; // Return null if no match is found
|
||||
}
|
||||
|
||||
useFrame((_, delta) => {});
|
||||
const boxRef = useRef<THREE.Mesh | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!scene || !boxRef || !processes) return;
|
||||
|
||||
// 1. Find the existing object by UUID
|
||||
const existingObject = scene.getObjectByProperty("uuid", id);
|
||||
if (!existingObject) return;
|
||||
|
||||
// 2. Find the process that targets this object's modelUUID
|
||||
if (boxVisible) {
|
||||
const matchedProcess = findProcessByTargetModelUUID(processes, id);
|
||||
|
||||
// 3. Determine the material (from materialref) if a process is matched
|
||||
let materialType = "Default";
|
||||
|
||||
if (matchedProcess) {
|
||||
const materialEntry = MaterialRef.current.find((item: any) =>
|
||||
item.objects.some((obj: any) => obj.processId === matchedProcess)
|
||||
);
|
||||
console.log("materialEntry: ", materialEntry);
|
||||
if (materialEntry) {
|
||||
materialType = materialEntry.material; // "Box" or "Crate"
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Create the box mesh with the assigned material
|
||||
const boxGeometry = new THREE.BoxGeometry(0.5, 0.5, 0.5);
|
||||
const boxMaterial = baseMaterials[materialType as MaterialType];
|
||||
const boxMesh = new THREE.Mesh(boxGeometry, boxMaterial);
|
||||
boxMesh.position.y = 1;
|
||||
boxMesh.name = `box-${id}`;
|
||||
|
||||
// 5. Add to scene and cleanup
|
||||
existingObject.add(boxMesh);
|
||||
boxRef.current = boxMesh;
|
||||
}
|
||||
|
||||
if (!startPointReached.current && boxVisible) {
|
||||
setBoxVisible(false);
|
||||
}
|
||||
return () => {
|
||||
if (boxRef.current?.parent) {
|
||||
boxRef.current.parent.remove(boxRef.current);
|
||||
}
|
||||
boxRef.current = null;
|
||||
};
|
||||
}, [
|
||||
processes,
|
||||
MaterialRef,
|
||||
boxVisible,
|
||||
findProcessByTargetModelUUID,
|
||||
startPointReached,
|
||||
]);
|
||||
|
||||
useFrame((_, delta) => {
|
||||
const currentAgv = (agvRef.current || []).find(
|
||||
(agv: AGVData) => agv.vehicleId === id
|
||||
);
|
||||
console.log("currentAgv: ", currentAgv?.isplaying);
|
||||
|
||||
if (!scene || !id || !isPlaying) return;
|
||||
|
||||
@@ -203,6 +300,7 @@ export default function PathNavigator({
|
||||
|
||||
// Step 1: Snap to start point on first play
|
||||
if (isPlaying && !hasStarted.current && toPickupPath.length > 0) {
|
||||
setBoxVisible(false);
|
||||
const startPoint = new THREE.Vector3(...toPickupPath[0]);
|
||||
object.position.copy(startPoint);
|
||||
|
||||
@@ -216,23 +314,23 @@ export default function PathNavigator({
|
||||
startPointReached.current = true;
|
||||
progressRef.current = 0;
|
||||
|
||||
setToPickupPath(toPickupPath.slice(-1));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 2: Wait at start point for AGV readiness (only if expected hit count is not met)
|
||||
if (
|
||||
isPlaying &&
|
||||
startPointReached.current &&
|
||||
path.length === 0 &&
|
||||
currentAgv?.isplaying
|
||||
) {
|
||||
// Step 2: Wait at start point for AGV readiness
|
||||
if (isPlaying && startPointReached.current && path.length === 0) {
|
||||
if (!isAgvReady()) {
|
||||
return; // Prevent transitioning to the next phase if AGV is not ready
|
||||
}
|
||||
|
||||
setBoxVisible(true);
|
||||
|
||||
setPath([...toPickupPath]); // Start path transition once the AGV is ready
|
||||
setCurrentPhase("toDrop");
|
||||
progressRef.current = 0;
|
||||
console.log("startPointReached: ", startPointReached.current);
|
||||
startPointReached.current = false;
|
||||
|
||||
return;
|
||||
@@ -283,12 +381,44 @@ export default function PathNavigator({
|
||||
if (currentPhase === "toDrop") {
|
||||
nextPath = dropPickupPath;
|
||||
nextPhase = "toPickup";
|
||||
setBoxVisible(false);
|
||||
} else if (currentPhase === "toPickup") {
|
||||
nextPath = pickupDropPath;
|
||||
nextPhase = "toDrop";
|
||||
// When returning to start point (toPickup phase completed)
|
||||
// Set position to toPickupPath[1] instead of [0]
|
||||
if (toPickupPath.length > 1) {
|
||||
object.position.copy(new THREE.Vector3(...toPickupPath[1]));
|
||||
// Also set rotation towards the next point if available
|
||||
if (toPickupPath.length > 2) {
|
||||
const nextPoint = new THREE.Vector3(...toPickupPath[2]);
|
||||
const direction = nextPoint
|
||||
.clone()
|
||||
.sub(object.position)
|
||||
.normalize();
|
||||
object.rotation.y = Math.atan2(direction.x, direction.z);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the path and mark start point as reached
|
||||
setPath([]);
|
||||
startPointReached.current = true;
|
||||
progressRef.current = 0;
|
||||
distancesRef.current = [];
|
||||
|
||||
// Stop the AGV by setting isplaying to false
|
||||
if (currentAgv) {
|
||||
currentAgv.isplaying = false;
|
||||
}
|
||||
|
||||
// Clear timeout and return to prevent further movement
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
timeoutRef.current = null;
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
nextPath = pickupDropPath;
|
||||
nextPhase = "toDrop";
|
||||
setBoxVisible(true);
|
||||
}
|
||||
|
||||
setPath([...nextPath]);
|
||||
@@ -297,28 +427,12 @@ export default function PathNavigator({
|
||||
isWaiting.current = false;
|
||||
distancesRef.current = [];
|
||||
|
||||
// Decrease the expected count if AGV is ready and has completed its path
|
||||
if (currentAgv) {
|
||||
currentAgv.expectedCount = Math.max(0, currentAgv.expectedCount - 1); // Decrease but ensure it's not negative
|
||||
console.log(
|
||||
"Decreased expected count to: ",
|
||||
currentAgv.expectedCount
|
||||
);
|
||||
}
|
||||
|
||||
// Reset hit count for the next cycle
|
||||
if (agvRef.current) {
|
||||
agvRef.current = agvRef.current.map((agv: AGVData) =>
|
||||
agv.vehicleId === id ? { ...agv, hitCount: null } : agv
|
||||
agv.vehicleId === id ? { ...agv, hitCount: 0 } : agv
|
||||
);
|
||||
}
|
||||
|
||||
// 🔁 Reset and wait again after reaching start
|
||||
if (currentPhase === "toPickup" && currentAgv) {
|
||||
currentAgv.isplaying = false;
|
||||
setPath([]);
|
||||
startPointReached.current = true;
|
||||
progressRef.current = 0;
|
||||
}
|
||||
}, bufferTime * 1000);
|
||||
|
||||
return;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as THREE from "three";
|
||||
import { Geometry, Base, Subtraction } from "@react-three/csg";
|
||||
import { useDeleteModels } from "../../../store/store";
|
||||
import { useDeleteTool } from "../../../store/store";
|
||||
import { useRef } from "react";
|
||||
|
||||
export interface CsgProps {
|
||||
@@ -11,19 +11,19 @@ export interface CsgProps {
|
||||
}
|
||||
|
||||
export const Csg: React.FC<CsgProps> = (props) => {
|
||||
const { deleteModels } = useDeleteModels();
|
||||
const { deleteTool } = useDeleteTool();
|
||||
const modelRef = useRef<THREE.Object3D>();
|
||||
const originalMaterials = useRef<Map<THREE.Mesh, THREE.Material>>(new Map());
|
||||
|
||||
const handleHover = (hovered: boolean, object: THREE.Mesh | null) => {
|
||||
if (modelRef.current && deleteModels) {
|
||||
if (modelRef.current && deleteTool) {
|
||||
modelRef.current.traverse((child) => {
|
||||
if (child instanceof THREE.Mesh) {
|
||||
if (!originalMaterials.current.has(child)) {
|
||||
originalMaterials.current.set(child, child.material);
|
||||
}
|
||||
child.material = child.material.clone();
|
||||
child.material.color.set(hovered && deleteModels ? 0xff0000 : (originalMaterials.current.get(child) as any).color);
|
||||
child.material.color.set(hovered && deleteTool ? 0xff0000 : (originalMaterials.current.get(child) as any).color);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -86,8 +86,8 @@ async function addAssetModel(
|
||||
} else {
|
||||
// console.log(`Added ${selectedItem.name} from Backend`);
|
||||
|
||||
loader.load(`${url_Backend_dwinzo}/api/v1/AssetFile/${selectedItem.id}`, async (gltf) => {
|
||||
const modelBlob = await fetch(`${url_Backend_dwinzo}/api/v1/AssetFile/${selectedItem.id}`).then((res) => res.blob());
|
||||
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, itemsGroup, tempLoader, isTempLoader, setFloorItems, setSimulationStates, socket);
|
||||
@@ -220,7 +220,7 @@ async function handleModelLoad(
|
||||
eventData.position = newFloorItem.position;
|
||||
eventData.rotation = [model.rotation.x, model.rotation.y, model.rotation.z];
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
eventData as Types.ConveyorEventsSchema
|
||||
]);
|
||||
@@ -237,6 +237,7 @@ async function handleModelLoad(
|
||||
points: {
|
||||
uuid: pointUUID,
|
||||
position: res.points.position as [number, number, number],
|
||||
rotation: res.points.rotation as [number, number, number],
|
||||
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: '', start: {}, hitCount: 1, end: {}, buffer: 0 },
|
||||
connections: { source: { modelUUID: model.uuid, pointUUID: pointUUID }, targets: [] },
|
||||
speed: 2,
|
||||
@@ -283,13 +284,141 @@ async function handleModelLoad(
|
||||
return updatedItems;
|
||||
});
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
eventData as Types.VehicleEventsSchema
|
||||
]);
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
|
||||
} else if (res.type === "StaticMachine") {
|
||||
|
||||
const pointUUID = THREE.MathUtils.generateUUID();
|
||||
|
||||
const backendEventData: Extract<Types.EventData['eventData'], { type: 'StaticMachine' }> = {
|
||||
type: "StaticMachine",
|
||||
points: {
|
||||
uuid: pointUUID,
|
||||
position: res.points.position as [number, number, number],
|
||||
rotation: res.points.rotation as [number, number, number],
|
||||
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', buffer: 0, material: 'Inherit' },
|
||||
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
|
||||
connections: { source: { modelUUID: model.uuid, pointUUID: pointUUID }, targets: [] },
|
||||
}
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
// await setFloorItemApi(
|
||||
// organization,
|
||||
// newFloorItem.modeluuid,
|
||||
// newFloorItem.modelname,
|
||||
// newFloorItem.modelfileID,
|
||||
// newFloorItem.position,
|
||||
// { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
|
||||
// false,
|
||||
// true,
|
||||
// { type: backendEventData.type, points: backendEventData.points }
|
||||
// );
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
organization,
|
||||
modeluuid: newFloorItem.modeluuid,
|
||||
modelname: newFloorItem.modelname,
|
||||
modelfileID: newFloorItem.modelfileID,
|
||||
position: newFloorItem.position,
|
||||
rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
eventData: { type: backendEventData.type, points: backendEventData.points },
|
||||
socketId: socket.id
|
||||
};
|
||||
|
||||
const eventData: any = backendEventData;
|
||||
eventData.modeluuid = newFloorItem.modeluuid;
|
||||
eventData.modelName = newFloorItem.modelname;
|
||||
eventData.position = newFloorItem.position;
|
||||
eventData.rotation = [model.rotation.x, model.rotation.y, model.rotation.z];
|
||||
|
||||
setFloorItems((prevItems) => {
|
||||
const updatedItems = [...(prevItems || []), newFloorItem];
|
||||
localStorage.setItem("FloorItems", JSON.stringify(updatedItems));
|
||||
return updatedItems;
|
||||
});
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
eventData as Types.StaticMachineEventsSchema
|
||||
]);
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
|
||||
} else if (res.type === "ArmBot") {
|
||||
|
||||
const pointUUID = THREE.MathUtils.generateUUID();
|
||||
|
||||
const backendEventData: Extract<Types.EventData['eventData'], { type: 'ArmBot' }> = {
|
||||
type: "ArmBot",
|
||||
points: {
|
||||
uuid: pointUUID,
|
||||
position: res.points.position as [number, number, number],
|
||||
rotation: res.points.rotation as [number, number, number],
|
||||
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', speed: 1, processes: [] },
|
||||
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
|
||||
connections: { source: { modelUUID: model.uuid, pointUUID: pointUUID }, targets: [] },
|
||||
}
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
// await setFloorItemApi(
|
||||
// organization,
|
||||
// newFloorItem.modeluuid,
|
||||
// newFloorItem.modelname,
|
||||
// newFloorItem.modelfileID,
|
||||
// newFloorItem.position,
|
||||
// { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
|
||||
// false,
|
||||
// true,
|
||||
// { type: backendEventData.type, points: backendEventData.points }
|
||||
// );
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
organization,
|
||||
modeluuid: newFloorItem.modeluuid,
|
||||
modelname: newFloorItem.modelname,
|
||||
modelfileID: newFloorItem.modelfileID,
|
||||
position: newFloorItem.position,
|
||||
rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
eventData: { type: backendEventData.type, points: backendEventData.points },
|
||||
socketId: socket.id
|
||||
};
|
||||
|
||||
const eventData: any = backendEventData;
|
||||
eventData.modeluuid = newFloorItem.modeluuid;
|
||||
eventData.modelName = newFloorItem.modelname;
|
||||
eventData.position = newFloorItem.position;
|
||||
eventData.rotation = [model.rotation.x, model.rotation.y, model.rotation.z];
|
||||
|
||||
setFloorItems((prevItems) => {
|
||||
const updatedItems = [...(prevItems || []), newFloorItem];
|
||||
localStorage.setItem("FloorItems", JSON.stringify(updatedItems));
|
||||
return updatedItems;
|
||||
});
|
||||
|
||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||
...(prevEvents || []),
|
||||
eventData as Types.ArmBotEventsSchema
|
||||
]);
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
|
||||
} else {
|
||||
|
||||
// API
|
||||
|
||||
@@ -53,7 +53,7 @@ export default async function assetManager(
|
||||
if (!activePromises.get(taskId)) return; // Stop processing if task is canceled
|
||||
|
||||
await new Promise<void>(async (resolve) => {
|
||||
const modelUrl = `${url_Backend_dwinzo}/api/v1/AssetFile/${item.modelfileID!}`;
|
||||
const modelUrl = `${url_Backend_dwinzo}/api/v2/AssetFile/${item.modelfileID!}`;
|
||||
|
||||
// Check Three.js Cache
|
||||
const cachedModel = THREE.Cache.get(item.modelfileID!);
|
||||
|
||||
@@ -53,7 +53,7 @@ export default function addFloorToScene(
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
|
||||
mesh.receiveShadow = true;
|
||||
mesh.position.y = layer;
|
||||
mesh.position.y = (layer) * CONSTANTS.wallConfig.height;
|
||||
mesh.rotateX(Math.PI / 2);
|
||||
mesh.name = `Floor_Layer_${layer}`;
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ function loadOnlyFloors(
|
||||
mesh.castShadow = true;
|
||||
mesh.receiveShadow = true;
|
||||
|
||||
mesh.position.y = (floor[0][0][2] - 1) * CONSTANTS.wallConfig.height + 0.03;
|
||||
mesh.position.y = (floor[0][0][2] - 1) * CONSTANTS.wallConfig.height;
|
||||
mesh.rotateX(Math.PI / 2);
|
||||
mesh.name = `Only_Floor_Line_${floor[0][0][2]}`;
|
||||
|
||||
|
||||
@@ -1,143 +1,143 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { getLines } from "../../../../services/factoryBuilder/lines/getLinesApi";
|
||||
import * as THREE from "three";
|
||||
import {
|
||||
useActiveLayer,
|
||||
useDeletedLines,
|
||||
useNewLines,
|
||||
useToggleView,
|
||||
} from "../../../../store/store";
|
||||
import objectLinesToArray from "./lineConvertions/objectLinesToArray";
|
||||
import { Html } from "@react-three/drei";
|
||||
import * as Types from "../../../../types/world/worldTypes";
|
||||
|
||||
const DistanceText = () => {
|
||||
const [lines, setLines] = useState<
|
||||
{
|
||||
distance: string;
|
||||
position: THREE.Vector3;
|
||||
userData: Types.Line;
|
||||
layer: string;
|
||||
}[]
|
||||
>([]);
|
||||
const { activeLayer } = useActiveLayer();
|
||||
const { toggleView } = useToggleView();
|
||||
const { newLines, setNewLines } = useNewLines();
|
||||
const { deletedLines, setDeletedLines } = useDeletedLines();
|
||||
|
||||
useEffect(() => {
|
||||
const email = localStorage.getItem("email");
|
||||
if (!email) return;
|
||||
const organization = email.split("@")[1].split(".")[0];
|
||||
|
||||
getLines(organization).then((data) => {
|
||||
data = objectLinesToArray(data);
|
||||
|
||||
const lines = data
|
||||
.filter((line: Types.Line) => line[0][2] === activeLayer)
|
||||
.map((line: Types.Line) => {
|
||||
const point1 = new THREE.Vector3(
|
||||
line[0][0].x,
|
||||
line[0][0].y,
|
||||
line[0][0].z
|
||||
);
|
||||
const point2 = new THREE.Vector3(
|
||||
line[1][0].x,
|
||||
line[1][0].y,
|
||||
line[1][0].z
|
||||
);
|
||||
const distance = point1.distanceTo(point2);
|
||||
const midpoint = new THREE.Vector3()
|
||||
.addVectors(point1, point2)
|
||||
.divideScalar(2);
|
||||
return {
|
||||
distance: distance.toFixed(1),
|
||||
position: midpoint,
|
||||
userData: line,
|
||||
layer: activeLayer,
|
||||
};
|
||||
});
|
||||
setLines(lines);
|
||||
});
|
||||
}, [activeLayer]);
|
||||
|
||||
useEffect(() => {
|
||||
if (newLines.length > 0) {
|
||||
if (newLines[0][0][2] !== activeLayer) return;
|
||||
const newLinesData = newLines.map((line: Types.Line) => {
|
||||
const point1 = new THREE.Vector3(
|
||||
line[0][0].x,
|
||||
line[0][0].y,
|
||||
line[0][0].z
|
||||
);
|
||||
const point2 = new THREE.Vector3(
|
||||
line[1][0].x,
|
||||
line[1][0].y,
|
||||
line[1][0].z
|
||||
);
|
||||
const distance = point1.distanceTo(point2);
|
||||
const midpoint = new THREE.Vector3()
|
||||
.addVectors(point1, point2)
|
||||
.divideScalar(2);
|
||||
|
||||
return {
|
||||
distance: distance.toFixed(1),
|
||||
position: midpoint,
|
||||
userData: line,
|
||||
layer: activeLayer,
|
||||
};
|
||||
});
|
||||
setLines((prevLines) => [...prevLines, ...newLinesData]);
|
||||
setNewLines([]);
|
||||
}
|
||||
}, [newLines, activeLayer]);
|
||||
|
||||
useEffect(() => {
|
||||
if ((deletedLines as Types.Lines).length > 0) {
|
||||
setLines((prevLines) =>
|
||||
prevLines.filter(
|
||||
(line) =>
|
||||
!deletedLines.some(
|
||||
(deletedLine: any) =>
|
||||
deletedLine[0][1] === line.userData[0][1] &&
|
||||
deletedLine[1][1] === line.userData[1][1]
|
||||
)
|
||||
)
|
||||
);
|
||||
setDeletedLines([]);
|
||||
}
|
||||
}, [deletedLines]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{toggleView && (
|
||||
<group name="Distance_Text">
|
||||
{lines.map((text) => (
|
||||
<Html
|
||||
// data
|
||||
key={`${text.userData[0][1]}_${text.userData[1][1]}`}
|
||||
userData={text.userData}
|
||||
position={[text.position.x, 1, text.position.z]}
|
||||
// class
|
||||
wrapperClass="distance-text-wrapper"
|
||||
className="distance-text"
|
||||
// other
|
||||
zIndexRange={[100, 0]}
|
||||
prepend
|
||||
sprite
|
||||
>
|
||||
<div
|
||||
key={`${text.userData[0][1]}_${text.userData[1][1]}`}
|
||||
className={`distance line-${text.userData[0][1]}_${text.userData[1][1]}_${text.layer}`}
|
||||
>
|
||||
{text.distance} m
|
||||
</div>
|
||||
</Html>
|
||||
))}
|
||||
</group>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default DistanceText;
|
||||
import { useEffect, useState } from "react";
|
||||
import { getLines } from "../../../../../services/factoryBuilder/lines/getLinesApi";
|
||||
import * as THREE from "three";
|
||||
import {
|
||||
useActiveLayer,
|
||||
useDeletedLines,
|
||||
useNewLines,
|
||||
useToggleView,
|
||||
} from "../../../../../store/store";
|
||||
import objectLinesToArray from "../lineConvertions/objectLinesToArray";
|
||||
import { Html } from "@react-three/drei";
|
||||
import * as Types from "../../../../../types/world/worldTypes";
|
||||
|
||||
const DistanceText = () => {
|
||||
const [lines, setLines] = useState<
|
||||
{
|
||||
distance: string;
|
||||
position: THREE.Vector3;
|
||||
userData: Types.Line;
|
||||
layer: string;
|
||||
}[]
|
||||
>([]);
|
||||
const { activeLayer } = useActiveLayer();
|
||||
const { toggleView } = useToggleView();
|
||||
const { newLines, setNewLines } = useNewLines();
|
||||
const { deletedLines, setDeletedLines } = useDeletedLines();
|
||||
|
||||
useEffect(() => {
|
||||
const email = localStorage.getItem("email");
|
||||
if (!email) return;
|
||||
const organization = email.split("@")[1].split(".")[0];
|
||||
|
||||
getLines(organization).then((data) => {
|
||||
data = objectLinesToArray(data);
|
||||
|
||||
const lines = data
|
||||
.filter((line: Types.Line) => line[0][2] === activeLayer)
|
||||
.map((line: Types.Line) => {
|
||||
const point1 = new THREE.Vector3(
|
||||
line[0][0].x,
|
||||
line[0][0].y,
|
||||
line[0][0].z
|
||||
);
|
||||
const point2 = new THREE.Vector3(
|
||||
line[1][0].x,
|
||||
line[1][0].y,
|
||||
line[1][0].z
|
||||
);
|
||||
const distance = point1.distanceTo(point2);
|
||||
const midpoint = new THREE.Vector3()
|
||||
.addVectors(point1, point2)
|
||||
.divideScalar(2);
|
||||
return {
|
||||
distance: distance.toFixed(1),
|
||||
position: midpoint,
|
||||
userData: line,
|
||||
layer: activeLayer,
|
||||
};
|
||||
});
|
||||
setLines(lines);
|
||||
});
|
||||
}, [activeLayer]);
|
||||
|
||||
useEffect(() => {
|
||||
if (newLines.length > 0) {
|
||||
if (newLines[0][0][2] !== activeLayer) return;
|
||||
const newLinesData = newLines.map((line: Types.Line) => {
|
||||
const point1 = new THREE.Vector3(
|
||||
line[0][0].x,
|
||||
line[0][0].y,
|
||||
line[0][0].z
|
||||
);
|
||||
const point2 = new THREE.Vector3(
|
||||
line[1][0].x,
|
||||
line[1][0].y,
|
||||
line[1][0].z
|
||||
);
|
||||
const distance = point1.distanceTo(point2);
|
||||
const midpoint = new THREE.Vector3()
|
||||
.addVectors(point1, point2)
|
||||
.divideScalar(2);
|
||||
|
||||
return {
|
||||
distance: distance.toFixed(1),
|
||||
position: midpoint,
|
||||
userData: line,
|
||||
layer: activeLayer,
|
||||
};
|
||||
});
|
||||
setLines((prevLines) => [...prevLines, ...newLinesData]);
|
||||
setNewLines([]);
|
||||
}
|
||||
}, [newLines, activeLayer]);
|
||||
|
||||
useEffect(() => {
|
||||
if ((deletedLines as Types.Lines).length > 0) {
|
||||
setLines((prevLines) =>
|
||||
prevLines.filter(
|
||||
(line) =>
|
||||
!deletedLines.some(
|
||||
(deletedLine: any) =>
|
||||
deletedLine[0][1] === line.userData[0][1] &&
|
||||
deletedLine[1][1] === line.userData[1][1]
|
||||
)
|
||||
)
|
||||
);
|
||||
setDeletedLines([]);
|
||||
}
|
||||
}, [deletedLines]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{toggleView && (
|
||||
<group name="Distance_Text">
|
||||
{lines.map((text) => (
|
||||
<Html
|
||||
// data
|
||||
key={`${text.userData[0][1]}_${text.userData[1][1]}`}
|
||||
userData={text.userData}
|
||||
position={[text.position.x, 1, text.position.z]}
|
||||
// class
|
||||
wrapperClass="distance-text-wrapper"
|
||||
className="distance-text"
|
||||
// other
|
||||
zIndexRange={[1, 0]}
|
||||
prepend
|
||||
sprite
|
||||
>
|
||||
<div
|
||||
key={`${text.userData[0][1]}_${text.userData[1][1]}`}
|
||||
className={`distance line-${text.userData[0][1]}_${text.userData[1][1]}_${text.layer}`}
|
||||
>
|
||||
{text.distance} m
|
||||
</div>
|
||||
</Html>
|
||||
))}
|
||||
</group>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default DistanceText;
|
||||
@@ -0,0 +1,71 @@
|
||||
import * as THREE from "three";
|
||||
import { Html } from "@react-three/drei";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useActiveLayer } from "../../../../../store/store";
|
||||
|
||||
const ReferenceDistanceText = ({ line }: { line: any }) => {
|
||||
interface TextState {
|
||||
distance: string;
|
||||
position: THREE.Vector3;
|
||||
userData: any;
|
||||
layer: any;
|
||||
}
|
||||
|
||||
const [text, setTexts] = useState<TextState | null>(null);
|
||||
const { activeLayer } = useActiveLayer();
|
||||
|
||||
useEffect(() => {
|
||||
if (line) {
|
||||
if (line.parent === null) {
|
||||
setTexts(null);
|
||||
return;
|
||||
}
|
||||
const distance = line.userData.linePoints.cursorPosition.distanceTo(
|
||||
line.userData.linePoints.startPoint
|
||||
);
|
||||
const midpoint = new THREE.Vector3()
|
||||
.addVectors(
|
||||
line.userData.linePoints.cursorPosition,
|
||||
line.userData.linePoints.startPoint
|
||||
)
|
||||
.divideScalar(2);
|
||||
const newTexts = {
|
||||
distance: distance.toFixed(1),
|
||||
position: midpoint,
|
||||
userData: line,
|
||||
layer: activeLayer,
|
||||
};
|
||||
setTexts(newTexts);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<group name="Reference_Distance_Text">
|
||||
<mesh>
|
||||
{text !== null && (
|
||||
<Html
|
||||
// data
|
||||
key={text.distance}
|
||||
userData={text.userData}
|
||||
position={[text.position.x, 1, text.position.z]}
|
||||
// class
|
||||
wrapperClass="distance-text-wrapper"
|
||||
className="distance-text"
|
||||
// other
|
||||
zIndexRange={[1, 0]}
|
||||
prepend
|
||||
sprite
|
||||
>
|
||||
<div
|
||||
className={`Reference_Distance line-${text.userData.userData}`}
|
||||
>
|
||||
{text.distance} m
|
||||
</div>
|
||||
</Html>
|
||||
)}
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
};
|
||||
|
||||
export default ReferenceDistanceText;
|
||||
@@ -1,48 +0,0 @@
|
||||
import * as THREE from 'three';
|
||||
import { Html } from '@react-three/drei';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useActiveLayer } from '../../../../store/store';
|
||||
|
||||
const ReferenceDistanceText = ({ line }: { line: any }) => {
|
||||
interface TextState {
|
||||
distance: string;
|
||||
position: THREE.Vector3;
|
||||
userData: any;
|
||||
layer: any;
|
||||
}
|
||||
|
||||
const [text, setTexts] = useState<TextState | null>(null);
|
||||
const { activeLayer } = useActiveLayer();
|
||||
|
||||
useEffect(() => {
|
||||
if (line) {
|
||||
if (line.parent === null) {
|
||||
setTexts(null);
|
||||
return;
|
||||
}
|
||||
const distance = line.userData.linePoints.cursorPosition.distanceTo(line.userData.linePoints.startPoint);
|
||||
const midpoint = new THREE.Vector3().addVectors(line.userData.linePoints.cursorPosition, line.userData.linePoints.startPoint).divideScalar(2);
|
||||
const newTexts = {
|
||||
distance: distance.toFixed(1),
|
||||
position: midpoint,
|
||||
userData: line,
|
||||
layer: activeLayer
|
||||
};
|
||||
setTexts(newTexts);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<group name='Reference_Distance_Text'>
|
||||
<mesh>
|
||||
{text !== null &&
|
||||
< Html transform sprite key={text.distance} userData={text.userData} scale={5} position={[text.position.x, 1, text.position.z]} style={{ pointerEvents: 'none' }}>
|
||||
<div className={`Reference_Distance line-${text.userData.userData}`}>{text.distance} m</div>
|
||||
</Html>
|
||||
}
|
||||
</mesh>
|
||||
</group >
|
||||
);
|
||||
};
|
||||
|
||||
export default ReferenceDistanceText;
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { useAddAction, useDeleteModels, useRoofVisibility, useToggleView, useWallVisibility, useUpdateScene } from "../../../store/store";
|
||||
import { useAddAction, useDeleteTool, useRoofVisibility, useToggleView, useWallVisibility, useUpdateScene } from "../../../store/store";
|
||||
import hideRoof from "../geomentries/roofs/hideRoof";
|
||||
import hideWalls from "../geomentries/walls/hideWalls";
|
||||
import addAndUpdateReferencePillar from "../geomentries/pillars/addAndUpdateReferencePillar";
|
||||
@@ -16,7 +16,7 @@ const FloorGroup = ({ floorGroup, lines, referencePole, hoveredDeletablePillar }
|
||||
const { toggleView, setToggleView } = useToggleView();
|
||||
const { scene, camera, pointer, raycaster, gl } = useThree();
|
||||
const { addAction, setAddAction } = useAddAction();
|
||||
const { deleteModels, setDeleteModels } = useDeleteModels();
|
||||
const { deleteTool, setDeleteTool } = useDeleteTool();
|
||||
const { updateScene, setUpdateScene } = useUpdateScene();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -56,7 +56,7 @@ const FloorGroup = ({ floorGroup, lines, referencePole, hoveredDeletablePillar }
|
||||
if (addAction === "pillar") {
|
||||
addPillar(referencePole, floorGroup);
|
||||
}
|
||||
if (deleteModels) {
|
||||
if (deleteTool) {
|
||||
DeletePillar(hoveredDeletablePillar, floorGroup);
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,7 @@ const FloorGroup = ({ floorGroup, lines, referencePole, hoveredDeletablePillar }
|
||||
canvasElement.removeEventListener("mouseup", onMouseUp);
|
||||
canvasElement.removeEventListener("mousemove", onMouseMove);
|
||||
};
|
||||
}, [deleteModels, addAction])
|
||||
}, [deleteTool, addAction])
|
||||
|
||||
useFrame(() => {
|
||||
hideRoof(roofVisibility, floorGroup, camera);
|
||||
@@ -87,7 +87,7 @@ const FloorGroup = ({ floorGroup, lines, referencePole, hoveredDeletablePillar }
|
||||
if (addAction === "pillar") {
|
||||
addAndUpdateReferencePillar(raycaster, floorGroup, referencePole);
|
||||
}
|
||||
if (deleteModels) {
|
||||
if (deleteTool) {
|
||||
DeletableHoveredPillar(state, floorGroup, hoveredDeletablePillar);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,26 +1,11 @@
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import {
|
||||
useActiveTool,
|
||||
useAsset3dWidget,
|
||||
useCamMode,
|
||||
useDeletableFloorItem,
|
||||
useDeleteModels,
|
||||
useFloorItems,
|
||||
useLoadingProgress,
|
||||
useRenderDistance,
|
||||
useselectedFloorItem,
|
||||
useSelectedItem,
|
||||
useSimulationStates,
|
||||
useSocketStore,
|
||||
useToggleView,
|
||||
useTransformMode,
|
||||
} from "../../../store/store";
|
||||
import { useActiveTool, useAsset3dWidget, useCamMode, useDeletableFloorItem, useDeleteTool, useFloorItems, useLoadingProgress, useRenderDistance, useSelectedFloorItem, useSelectedItem, useSimulationStates, useSocketStore, useToggleView, useTransformMode, } from "../../../store/store";
|
||||
import assetVisibility from "../geomentries/assets/assetVisibility";
|
||||
import { useEffect } from "react";
|
||||
import * as THREE from "three";
|
||||
import * as Types from "../../../types/world/worldTypes";
|
||||
import assetManager, {
|
||||
cancelOngoingTasks,
|
||||
cancelOngoingTasks,
|
||||
} from "../geomentries/assets/assetManager";
|
||||
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
|
||||
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
|
||||
@@ -31,413 +16,315 @@ import addAssetModel from "../geomentries/assets/addAssetModel";
|
||||
import { getFloorAssets } from "../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi";
|
||||
import useModuleStore from "../../../store/useModuleStore";
|
||||
// import { retrieveGLTF } from "../../../utils/indexDB/idbUtils";
|
||||
const assetManagerWorker = new Worker(
|
||||
new URL(
|
||||
"../../../services/factoryBuilder/webWorkers/assetManagerWorker.js",
|
||||
import.meta.url
|
||||
)
|
||||
);
|
||||
const gltfLoaderWorker = new Worker(
|
||||
new URL(
|
||||
"../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js",
|
||||
import.meta.url
|
||||
)
|
||||
);
|
||||
const assetManagerWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/assetManagerWorker.js", import.meta.url));
|
||||
const gltfLoaderWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js", import.meta.url));
|
||||
|
||||
const FloorItemsGroup = ({
|
||||
itemsGroup,
|
||||
hoveredDeletableFloorItem,
|
||||
AttachedObject,
|
||||
floorGroup,
|
||||
tempLoader,
|
||||
isTempLoader,
|
||||
plane,
|
||||
}: any) => {
|
||||
const state: Types.ThreeState = useThree();
|
||||
const { raycaster, controls }: any = state;
|
||||
const { renderDistance } = useRenderDistance();
|
||||
const { toggleView } = useToggleView();
|
||||
const { floorItems, setFloorItems } = useFloorItems();
|
||||
const { camMode } = useCamMode();
|
||||
const { deleteModels } = useDeleteModels();
|
||||
const { setDeletableFloorItem } = useDeletableFloorItem();
|
||||
const { transformMode } = useTransformMode();
|
||||
const { setselectedFloorItem } = useselectedFloorItem();
|
||||
const { activeTool } = useActiveTool();
|
||||
const { selectedItem, setSelectedItem } = useSelectedItem();
|
||||
const { simulationStates, setSimulationStates } = useSimulationStates();
|
||||
const { setLoadingProgress } = useLoadingProgress();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { socket } = useSocketStore();
|
||||
const loader = new GLTFLoader();
|
||||
const dracoLoader = new DRACOLoader();
|
||||
const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject, floorGroup, tempLoader, isTempLoader, plane, }: any) => {
|
||||
const state: Types.ThreeState = useThree();
|
||||
const { raycaster, controls }: any = state;
|
||||
const { renderDistance } = useRenderDistance();
|
||||
const { toggleView } = useToggleView();
|
||||
const { floorItems, setFloorItems } = useFloorItems();
|
||||
const { camMode } = useCamMode();
|
||||
const { deleteTool } = useDeleteTool();
|
||||
const { setDeletableFloorItem } = useDeletableFloorItem();
|
||||
const { transformMode } = useTransformMode();
|
||||
const { setSelectedFloorItem } = useSelectedFloorItem();
|
||||
const { activeTool } = useActiveTool();
|
||||
const { selectedItem, setSelectedItem } = useSelectedItem();
|
||||
const { simulationStates, setSimulationStates } = useSimulationStates();
|
||||
const { setLoadingProgress } = useLoadingProgress();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { socket } = useSocketStore();
|
||||
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);
|
||||
|
||||
useEffect(() => {
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email!.split("@")[1].split(".")[0];
|
||||
useEffect(() => {
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email!.split("@")[1].split(".")[0];
|
||||
|
||||
let totalAssets = 0;
|
||||
let loadedAssets = 0;
|
||||
let totalAssets = 0;
|
||||
let loadedAssets = 0;
|
||||
|
||||
const updateLoadingProgress = (progress: number) => {
|
||||
if (progress < 100) {
|
||||
setLoadingProgress(progress);
|
||||
} else if (progress === 100) {
|
||||
setTimeout(() => {
|
||||
setLoadingProgress(100);
|
||||
setTimeout(() => {
|
||||
setLoadingProgress(0);
|
||||
}, 1500);
|
||||
}, 1000);
|
||||
}
|
||||
};
|
||||
const updateLoadingProgress = (progress: number) => {
|
||||
if (progress < 100) {
|
||||
setLoadingProgress(progress);
|
||||
} else if (progress === 100) {
|
||||
setTimeout(() => {
|
||||
setLoadingProgress(100);
|
||||
setTimeout(() => {
|
||||
setLoadingProgress(0);
|
||||
}, 1500);
|
||||
}, 1000);
|
||||
}
|
||||
};
|
||||
|
||||
getFloorAssets(organization).then((data) => {
|
||||
if (data.length > 0) {
|
||||
const uniqueItems = (data as Types.FloorItems).filter(
|
||||
(item, index, self) =>
|
||||
index === self.findIndex((t) => t.modelfileID === item.modelfileID)
|
||||
);
|
||||
totalAssets = uniqueItems.length;
|
||||
if (totalAssets === 0) {
|
||||
updateLoadingProgress(100);
|
||||
return;
|
||||
}
|
||||
gltfLoaderWorker.postMessage({ floorItems: data });
|
||||
} else {
|
||||
gltfLoaderWorker.postMessage({ floorItems: [] });
|
||||
loadInitialFloorItems(itemsGroup, setFloorItems, setSimulationStates);
|
||||
updateLoadingProgress(100);
|
||||
}
|
||||
});
|
||||
|
||||
gltfLoaderWorker.onmessage = async (event) => {
|
||||
if (event.data.message === "gltfLoaded" && event.data.modelBlob) {
|
||||
const blobUrl = URL.createObjectURL(event.data.modelBlob);
|
||||
|
||||
loader.load(blobUrl, (gltf) => {
|
||||
URL.revokeObjectURL(blobUrl);
|
||||
THREE.Cache.remove(blobUrl);
|
||||
THREE.Cache.add(event.data.modelID, gltf);
|
||||
|
||||
loadedAssets++;
|
||||
const progress = Math.round((loadedAssets / totalAssets) * 100);
|
||||
updateLoadingProgress(progress);
|
||||
|
||||
if (loadedAssets === totalAssets) {
|
||||
loadInitialFloorItems(itemsGroup, setFloorItems, setSimulationStates);
|
||||
updateLoadingProgress(100);
|
||||
}
|
||||
getFloorAssets(organization).then((data) => {
|
||||
if (data.length > 0) {
|
||||
const uniqueItems = (data as Types.FloorItems).filter((item, index, self) => index === self.findIndex((t) => t.modelfileID === item.modelfileID));
|
||||
totalAssets = uniqueItems.length;
|
||||
if (totalAssets === 0) {
|
||||
updateLoadingProgress(100);
|
||||
return;
|
||||
}
|
||||
gltfLoaderWorker.postMessage({ floorItems: data });
|
||||
} else {
|
||||
gltfLoaderWorker.postMessage({ floorItems: [] });
|
||||
loadInitialFloorItems(itemsGroup, setFloorItems, setSimulationStates);
|
||||
updateLoadingProgress(100);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
assetManagerWorker.onmessage = async (event) => {
|
||||
cancelOngoingTasks(); // Cancel the ongoing process
|
||||
await assetManager(event.data, itemsGroup, loader);
|
||||
};
|
||||
}, [assetManagerWorker]);
|
||||
gltfLoaderWorker.onmessage = async (event) => {
|
||||
if (event.data.message === "gltfLoaded" && event.data.modelBlob) {
|
||||
const blobUrl = URL.createObjectURL(event.data.modelBlob);
|
||||
|
||||
useEffect(() => {
|
||||
if (toggleView) return;
|
||||
loader.load(blobUrl, (gltf) => {
|
||||
URL.revokeObjectURL(blobUrl);
|
||||
THREE.Cache.remove(blobUrl);
|
||||
THREE.Cache.add(event.data.modelID, gltf);
|
||||
|
||||
const uuids: string[] = [];
|
||||
itemsGroup.current?.children.forEach((child: any) => {
|
||||
uuids.push(child.uuid);
|
||||
});
|
||||
const cameraPosition = state.camera.position;
|
||||
loadedAssets++;
|
||||
const progress = Math.round((loadedAssets / totalAssets) * 100);
|
||||
updateLoadingProgress(progress);
|
||||
|
||||
assetManagerWorker.postMessage({
|
||||
floorItems,
|
||||
cameraPosition,
|
||||
uuids,
|
||||
renderDistance,
|
||||
});
|
||||
}, [camMode, renderDistance]);
|
||||
if (loadedAssets === totalAssets) {
|
||||
loadInitialFloorItems(itemsGroup, setFloorItems, setSimulationStates);
|
||||
updateLoadingProgress(100);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const controls: any = state.controls;
|
||||
const camera: any = state.camera;
|
||||
useEffect(() => {
|
||||
assetManagerWorker.onmessage = async (event) => {
|
||||
cancelOngoingTasks(); // Cancel the ongoing process
|
||||
await assetManager(event.data, itemsGroup, loader);
|
||||
};
|
||||
}, [assetManagerWorker]);
|
||||
|
||||
if (controls) {
|
||||
let intervalId: NodeJS.Timeout | null = null;
|
||||
|
||||
const handleChange = () => {
|
||||
useEffect(() => {
|
||||
if (toggleView) return;
|
||||
|
||||
const uuids: string[] = [];
|
||||
itemsGroup.current?.children.forEach((child: any) => {
|
||||
uuids.push(child.uuid);
|
||||
});
|
||||
const cameraPosition = camera.position;
|
||||
itemsGroup.current?.children.forEach((child: any) => { uuids.push(child.uuid); });
|
||||
const cameraPosition = state.camera.position;
|
||||
|
||||
assetManagerWorker.postMessage({
|
||||
floorItems,
|
||||
cameraPosition,
|
||||
uuids,
|
||||
renderDistance,
|
||||
});
|
||||
};
|
||||
assetManagerWorker.postMessage({ floorItems, cameraPosition, uuids, renderDistance, });
|
||||
}, [camMode, renderDistance]);
|
||||
|
||||
const startInterval = () => {
|
||||
if (!intervalId) {
|
||||
intervalId = setInterval(handleChange, 50);
|
||||
useEffect(() => {
|
||||
const controls: any = state.controls;
|
||||
const camera: any = state.camera;
|
||||
|
||||
if (controls) {
|
||||
let intervalId: NodeJS.Timeout | null = null;
|
||||
|
||||
const handleChange = () => {
|
||||
if (toggleView) return;
|
||||
|
||||
const uuids: string[] = [];
|
||||
itemsGroup.current?.children.forEach((child: any) => { uuids.push(child.uuid); });
|
||||
const cameraPosition = camera.position;
|
||||
|
||||
assetManagerWorker.postMessage({ floorItems, cameraPosition, uuids, renderDistance, });
|
||||
};
|
||||
|
||||
const startInterval = () => {
|
||||
if (!intervalId) {
|
||||
intervalId = setInterval(handleChange, 50);
|
||||
}
|
||||
};
|
||||
|
||||
const stopInterval = () => {
|
||||
handleChange();
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
intervalId = null;
|
||||
}
|
||||
};
|
||||
|
||||
controls.addEventListener("rest", handleChange);
|
||||
controls.addEventListener("rest", stopInterval);
|
||||
controls.addEventListener("control", startInterval);
|
||||
controls.addEventListener("controlend", stopInterval);
|
||||
|
||||
return () => {
|
||||
controls.removeEventListener("rest", handleChange);
|
||||
controls.removeEventListener("rest", stopInterval);
|
||||
controls.removeEventListener("control", startInterval);
|
||||
controls.removeEventListener("controlend", stopInterval);
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}, [state.controls, floorItems, toggleView, renderDistance]);
|
||||
|
||||
const stopInterval = () => {
|
||||
handleChange();
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
intervalId = null;
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
const canvasElement = state.gl.domElement;
|
||||
let drag = false;
|
||||
let isLeftMouseDown = false;
|
||||
|
||||
controls.addEventListener("rest", handleChange);
|
||||
controls.addEventListener("rest", stopInterval);
|
||||
controls.addEventListener("control", startInterval);
|
||||
controls.addEventListener("controlend", stopInterval);
|
||||
|
||||
return () => {
|
||||
controls.removeEventListener("rest", handleChange);
|
||||
controls.removeEventListener("rest", stopInterval);
|
||||
controls.removeEventListener("control", startInterval);
|
||||
controls.removeEventListener("controlend", stopInterval);
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
};
|
||||
}
|
||||
}, [state.controls, floorItems, toggleView, renderDistance]);
|
||||
|
||||
useEffect(() => {
|
||||
const canvasElement = state.gl.domElement;
|
||||
let drag = false;
|
||||
let isLeftMouseDown = false;
|
||||
|
||||
const onMouseDown = (evt: any) => {
|
||||
if (evt.button === 0) {
|
||||
isLeftMouseDown = true;
|
||||
drag = false;
|
||||
}
|
||||
};
|
||||
|
||||
const onMouseMove = () => {
|
||||
if (isLeftMouseDown) {
|
||||
drag = true;
|
||||
}
|
||||
};
|
||||
|
||||
const onMouseUp = async (evt: any) => {
|
||||
if (controls) {
|
||||
(controls as any).enabled = true;
|
||||
}
|
||||
if (evt.button === 0) {
|
||||
isLeftMouseDown = false;
|
||||
if (drag) return;
|
||||
|
||||
if (deleteModels) {
|
||||
DeleteFloorItems(
|
||||
itemsGroup,
|
||||
hoveredDeletableFloorItem,
|
||||
setFloorItems,
|
||||
setSimulationStates,
|
||||
socket
|
||||
);
|
||||
}
|
||||
const Mode = transformMode;
|
||||
|
||||
if (Mode !== null || activeTool === "cursor") {
|
||||
if (!itemsGroup.current) return;
|
||||
let intersects = raycaster.intersectObjects(
|
||||
itemsGroup.current.children,
|
||||
true
|
||||
);
|
||||
if (
|
||||
intersects.length > 0 &&
|
||||
intersects[0]?.object?.parent?.parent?.position &&
|
||||
intersects[0]?.object?.parent?.parent?.scale &&
|
||||
intersects[0]?.object?.parent?.parent?.rotation
|
||||
) {
|
||||
// let currentObject = intersects[0].object;
|
||||
// while (currentObject) {
|
||||
// if (currentObject.name === "Scene") {
|
||||
// break;
|
||||
// }
|
||||
// currentObject = currentObject.parent as THREE.Object3D;
|
||||
// }
|
||||
// if (currentObject) {
|
||||
// AttachedObject.current = currentObject as any;
|
||||
// setselectedFloorItem(AttachedObject.current!);
|
||||
// }
|
||||
} else {
|
||||
const target = controls.getTarget(new THREE.Vector3());
|
||||
await controls.setTarget(target.x, 0, target.z, true);
|
||||
setselectedFloorItem(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onDblClick = async (evt: any) => {
|
||||
if (evt.button === 0) {
|
||||
isLeftMouseDown = false;
|
||||
if (drag) return;
|
||||
|
||||
const Mode = transformMode;
|
||||
|
||||
if (Mode !== null || activeTool === "cursor") {
|
||||
if (!itemsGroup.current) return;
|
||||
let intersects = raycaster.intersectObjects(
|
||||
itemsGroup.current.children,
|
||||
true
|
||||
);
|
||||
if (
|
||||
intersects.length > 0 &&
|
||||
intersects[0]?.object?.parent?.parent?.position &&
|
||||
intersects[0]?.object?.parent?.parent?.scale &&
|
||||
intersects[0]?.object?.parent?.parent?.rotation
|
||||
) {
|
||||
let currentObject = intersects[0].object;
|
||||
|
||||
while (currentObject) {
|
||||
if (currentObject.name === "Scene") {
|
||||
break;
|
||||
}
|
||||
currentObject = currentObject.parent as THREE.Object3D;
|
||||
const onMouseDown = (evt: any) => {
|
||||
if (evt.button === 0) {
|
||||
isLeftMouseDown = true;
|
||||
drag = false;
|
||||
}
|
||||
if (currentObject) {
|
||||
AttachedObject.current = currentObject as any;
|
||||
// controls.fitToSphere(AttachedObject.current!, true);
|
||||
};
|
||||
|
||||
const bbox = new THREE.Box3().setFromObject(
|
||||
AttachedObject.current
|
||||
);
|
||||
const size = bbox.getSize(new THREE.Vector3());
|
||||
const center = bbox.getCenter(new THREE.Vector3());
|
||||
|
||||
const front = new THREE.Vector3(0, 0, 1);
|
||||
AttachedObject.current.localToWorld(front);
|
||||
front.sub(AttachedObject.current.position).normalize();
|
||||
|
||||
const distance = Math.max(size.x, size.y, size.z) * 2;
|
||||
const newPosition = center
|
||||
.clone()
|
||||
.addScaledVector(front, distance);
|
||||
|
||||
controls.setPosition(
|
||||
newPosition.x,
|
||||
newPosition.y,
|
||||
newPosition.z,
|
||||
true
|
||||
);
|
||||
controls.setTarget(center.x, center.y, center.z, true);
|
||||
controls.fitToBox(AttachedObject.current!, true, {
|
||||
cover: true,
|
||||
paddingTop: 5,
|
||||
paddingLeft: 5,
|
||||
paddingBottom: 5,
|
||||
paddingRight: 5,
|
||||
});
|
||||
|
||||
setselectedFloorItem(AttachedObject.current!);
|
||||
const onMouseMove = () => {
|
||||
if (isLeftMouseDown) {
|
||||
drag = true;
|
||||
}
|
||||
};
|
||||
|
||||
const onMouseUp = async (evt: any) => {
|
||||
if (controls) {
|
||||
(controls as any).enabled = true;
|
||||
}
|
||||
if (evt.button === 0) {
|
||||
isLeftMouseDown = false;
|
||||
if (drag) return;
|
||||
|
||||
if (deleteTool) {
|
||||
DeleteFloorItems(itemsGroup, hoveredDeletableFloorItem, setFloorItems, setSimulationStates, socket);
|
||||
|
||||
// Remove EventData if there are any in the asset.
|
||||
}
|
||||
const Mode = transformMode;
|
||||
|
||||
if (Mode !== null || activeTool === "cursor") {
|
||||
if (!itemsGroup.current) return;
|
||||
let intersects = raycaster.intersectObjects(
|
||||
itemsGroup.current.children,
|
||||
true
|
||||
);
|
||||
if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) {
|
||||
// let currentObject = intersects[0].object;
|
||||
// while (currentObject) {
|
||||
// if (currentObject.name === "Scene") {
|
||||
// break;
|
||||
// }
|
||||
// currentObject = currentObject.parent as THREE.Object3D;
|
||||
// }
|
||||
// if (currentObject) {
|
||||
// AttachedObject.current = currentObject as any;
|
||||
// setSelectedFloorItem(AttachedObject.current!);
|
||||
// }
|
||||
} else {
|
||||
const target = controls.getTarget(new THREE.Vector3());
|
||||
await controls.setTarget(target.x, 0, target.z, true);
|
||||
setSelectedFloorItem(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onDblClick = async (evt: any) => {
|
||||
if (evt.button === 0) {
|
||||
isLeftMouseDown = false;
|
||||
if (drag) return;
|
||||
|
||||
const Mode = transformMode;
|
||||
|
||||
if (Mode !== null || activeTool === "cursor") {
|
||||
if (!itemsGroup.current) return;
|
||||
let intersects = raycaster.intersectObjects(itemsGroup.current.children, true);
|
||||
if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) {
|
||||
let currentObject = intersects[0].object;
|
||||
|
||||
while (currentObject) {
|
||||
if (currentObject.name === "Scene") {
|
||||
break;
|
||||
}
|
||||
currentObject = currentObject.parent as THREE.Object3D;
|
||||
}
|
||||
if (currentObject) {
|
||||
AttachedObject.current = currentObject as any;
|
||||
// controls.fitToSphere(AttachedObject.current!, true);
|
||||
|
||||
const bbox = new THREE.Box3().setFromObject(AttachedObject.current);
|
||||
const size = bbox.getSize(new THREE.Vector3());
|
||||
const center = bbox.getCenter(new THREE.Vector3());
|
||||
|
||||
const front = new THREE.Vector3(0, 0, 1);
|
||||
AttachedObject.current.localToWorld(front);
|
||||
front.sub(AttachedObject.current.position).normalize();
|
||||
|
||||
const distance = Math.max(size.x, size.y, size.z) * 2;
|
||||
const newPosition = center.clone().addScaledVector(front, distance);
|
||||
|
||||
controls.setPosition(newPosition.x, newPosition.y, newPosition.z, true);
|
||||
controls.setTarget(center.x, center.y, center.z, true);
|
||||
controls.fitToBox(AttachedObject.current!, true, { cover: true, paddingTop: 5, paddingLeft: 5, paddingBottom: 5, paddingRight: 5, });
|
||||
|
||||
setSelectedFloorItem(AttachedObject.current!);
|
||||
}
|
||||
} else {
|
||||
const target = controls.getTarget(new THREE.Vector3());
|
||||
await controls.setTarget(target.x, 0, target.z, true);
|
||||
setSelectedFloorItem(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onDrop = (event: any) => {
|
||||
if (!event.dataTransfer?.files[0]) return;
|
||||
|
||||
if (selectedItem.id !== "" && event.dataTransfer?.files[0]) {
|
||||
addAssetModel(raycaster, state.camera, state.pointer, floorGroup, setFloorItems, itemsGroup, isTempLoader, tempLoader, socket, selectedItem, setSelectedItem, setSimulationStates, plane);
|
||||
}
|
||||
};
|
||||
|
||||
const onDragOver = (event: any) => {
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
if (activeModule === "builder") {
|
||||
canvasElement.addEventListener("mousedown", onMouseDown);
|
||||
canvasElement.addEventListener("mouseup", onMouseUp);
|
||||
canvasElement.addEventListener("mousemove", onMouseMove);
|
||||
canvasElement.addEventListener("dblclick", onDblClick);
|
||||
canvasElement.addEventListener("drop", onDrop);
|
||||
canvasElement.addEventListener("dragover", onDragOver);
|
||||
} else {
|
||||
if (controls) {
|
||||
const target = controls.getTarget(new THREE.Vector3());
|
||||
controls.setTarget(target.x, 0, target.z, true);
|
||||
setSelectedFloorItem(null);
|
||||
}
|
||||
} else {
|
||||
const target = controls.getTarget(new THREE.Vector3());
|
||||
await controls.setTarget(target.x, 0, target.z, true);
|
||||
setselectedFloorItem(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onDrop = (event: any) => {
|
||||
if (!event.dataTransfer?.files[0]) return;
|
||||
return () => {
|
||||
canvasElement.removeEventListener("mousedown", onMouseDown);
|
||||
canvasElement.removeEventListener("mouseup", onMouseUp);
|
||||
canvasElement.removeEventListener("mousemove", onMouseMove);
|
||||
canvasElement.removeEventListener("dblclick", onDblClick);
|
||||
canvasElement.removeEventListener("drop", onDrop);
|
||||
canvasElement.removeEventListener("dragover", onDragOver);
|
||||
};
|
||||
}, [deleteTool, transformMode, controls, selectedItem, state.camera, state.pointer, activeTool, activeModule,]);
|
||||
|
||||
if (selectedItem.id !== "" && event.dataTransfer?.files[0]) {
|
||||
addAssetModel(
|
||||
raycaster,
|
||||
state.camera,
|
||||
state.pointer,
|
||||
floorGroup,
|
||||
setFloorItems,
|
||||
itemsGroup,
|
||||
isTempLoader,
|
||||
tempLoader,
|
||||
socket,
|
||||
selectedItem,
|
||||
setSelectedItem,
|
||||
setSimulationStates,
|
||||
plane
|
||||
);
|
||||
}
|
||||
};
|
||||
useFrame(() => {
|
||||
if (controls)
|
||||
assetVisibility(itemsGroup, state.camera.position, renderDistance);
|
||||
if (deleteTool && activeModule === "builder") {
|
||||
DeletableHoveredFloorItems(state, itemsGroup, hoveredDeletableFloorItem, setDeletableFloorItem);
|
||||
} else if (!deleteTool) {
|
||||
if (hoveredDeletableFloorItem.current) {
|
||||
hoveredDeletableFloorItem.current = undefined;
|
||||
setDeletableFloorItem(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const onDragOver = (event: any) => {
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
if (activeModule === "builder") {
|
||||
canvasElement.addEventListener("mousedown", onMouseDown);
|
||||
canvasElement.addEventListener("mouseup", onMouseUp);
|
||||
canvasElement.addEventListener("mousemove", onMouseMove);
|
||||
canvasElement.addEventListener("dblclick", onDblClick);
|
||||
canvasElement.addEventListener("drop", onDrop);
|
||||
canvasElement.addEventListener("dragover", onDragOver);
|
||||
} else {
|
||||
if (controls) {
|
||||
const target = controls.getTarget(new THREE.Vector3());
|
||||
controls.setTarget(target.x, 0, target.z, true);
|
||||
setselectedFloorItem(null);
|
||||
}
|
||||
}
|
||||
|
||||
return () => {
|
||||
canvasElement.removeEventListener("mousedown", onMouseDown);
|
||||
canvasElement.removeEventListener("mouseup", onMouseUp);
|
||||
canvasElement.removeEventListener("mousemove", onMouseMove);
|
||||
canvasElement.removeEventListener("dblclick", onDblClick);
|
||||
canvasElement.removeEventListener("drop", onDrop);
|
||||
canvasElement.removeEventListener("dragover", onDragOver);
|
||||
};
|
||||
}, [
|
||||
deleteModels,
|
||||
transformMode,
|
||||
controls,
|
||||
selectedItem,
|
||||
state.camera,
|
||||
state.pointer,
|
||||
activeTool,
|
||||
activeModule,
|
||||
]);
|
||||
|
||||
|
||||
useFrame(() => {
|
||||
if (controls)
|
||||
assetVisibility(itemsGroup, state.camera.position, renderDistance);
|
||||
if (deleteModels) {
|
||||
DeletableHoveredFloorItems(
|
||||
state,
|
||||
itemsGroup,
|
||||
hoveredDeletableFloorItem,
|
||||
setDeletableFloorItem
|
||||
);
|
||||
} else if (!deleteModels) {
|
||||
if (hoveredDeletableFloorItem.current) {
|
||||
hoveredDeletableFloorItem.current = undefined;
|
||||
setDeletableFloorItem(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return <group ref={itemsGroup} name="itemsGroup"></group>;
|
||||
return <group ref={itemsGroup} name="itemsGroup"></group>;
|
||||
};
|
||||
|
||||
export default FloorItemsGroup;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect } from "react";
|
||||
import { useDeleteModels, useDeletePointOrLine, useObjectPosition, useObjectRotation, useObjectScale, useSelectedWallItem, useSocketStore, useWallItems } from "../../../store/store";
|
||||
import { useDeleteTool, useDeletePointOrLine, useObjectPosition, useObjectRotation, useObjectScale, useSelectedWallItem, useSocketStore, useWallItems } from "../../../store/store";
|
||||
import { Csg } from "../csg/csg";
|
||||
import * as Types from "../../../types/world/worldTypes";
|
||||
import * as CONSTANTS from "../../../types/world/worldConstants";
|
||||
@@ -9,20 +9,21 @@ import handleMeshMissed from "../eventFunctions/handleMeshMissed";
|
||||
import DeleteWallItems from "../geomentries/walls/deleteWallItems";
|
||||
import loadInitialWallItems from "../../scene/IntialLoad/loadInitialWallItems";
|
||||
import AddWallItems from "../geomentries/walls/addWallItems";
|
||||
import useModuleStore from "../../../store/useModuleStore";
|
||||
|
||||
|
||||
const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletableWallItem, selectedItemsIndex, setSelectedItemsIndex, CSGGroup }: any) => {
|
||||
const { deleteModels, setDeleteModels } = useDeleteModels();
|
||||
const state = useThree();
|
||||
const { socket } = useSocketStore();
|
||||
const { pointer, camera, raycaster } = state;
|
||||
const { deleteTool, setDeleteTool } = useDeleteTool();
|
||||
const { wallItems, setWallItems } = useWallItems();
|
||||
const { objectPosition, setObjectPosition } = useObjectPosition();
|
||||
const { objectScale, setObjectScale } = useObjectScale();
|
||||
const { objectRotation, setObjectRotation } = useObjectRotation();
|
||||
const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine();
|
||||
const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
|
||||
const { socket } = useSocketStore();
|
||||
const state = useThree();
|
||||
const { pointer, camera, raycaster } = state;
|
||||
|
||||
const { activeModule } = useModuleStore();
|
||||
|
||||
useEffect(() => {
|
||||
// Load Wall Items from the backend
|
||||
@@ -209,7 +210,7 @@ const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletable
|
||||
const onMouseUp = (evt: any) => {
|
||||
if (evt.button === 0) {
|
||||
isLeftMouseDown = false;
|
||||
if (!drag && deleteModels) {
|
||||
if (!drag && deleteTool && activeModule === "builder") {
|
||||
DeleteWallItems(hoveredDeletableWallItem, setWallItems, wallItems, socket);
|
||||
}
|
||||
}
|
||||
@@ -224,7 +225,7 @@ const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletable
|
||||
const onDrop = (event: any) => {
|
||||
|
||||
if (!event.dataTransfer?.files[0]) return
|
||||
|
||||
|
||||
pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
|
||||
pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
|
||||
raycaster.setFromCamera(pointer, camera);
|
||||
@@ -256,15 +257,15 @@ const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletable
|
||||
canvasElement.removeEventListener("drop", onDrop);
|
||||
canvasElement.removeEventListener("dragover", onDragOver);
|
||||
};
|
||||
}, [deleteModels, wallItems])
|
||||
}, [deleteTool, wallItems])
|
||||
|
||||
useEffect(() => {
|
||||
if (deleteModels) {
|
||||
if (deleteTool && activeModule === "builder") {
|
||||
handleMeshMissed(currentWallItem, setSelectedWallItem, setSelectedItemsIndex);
|
||||
setSelectedWallItem(null);
|
||||
setSelectedItemsIndex(null);
|
||||
}
|
||||
}, [deleteModels])
|
||||
}, [deleteTool])
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Geometry } from "@react-three/csg";
|
||||
import { useDeleteModels, useSelectedWallItem, useToggleView, useTransformMode, useWallItems, useWalls } from "../../../store/store";
|
||||
import { useDeleteTool, useSelectedWallItem, useToggleView, useTransformMode, useWallItems, useWalls } from "../../../store/store";
|
||||
import handleMeshDown from "../eventFunctions/handleMeshDown";
|
||||
import handleMeshMissed from "../eventFunctions/handleMeshMissed";
|
||||
import WallsMesh from "./wallsMesh";
|
||||
@@ -11,13 +11,13 @@ const WallsAndWallItems = ({ CSGGroup, AssetConfigurations, setSelectedItemsInde
|
||||
const { walls, setWalls } = useWalls();
|
||||
const { wallItems, setWallItems } = useWallItems();
|
||||
const { toggleView, setToggleView } = useToggleView();
|
||||
const { deleteModels, setDeleteModels } = useDeleteModels();
|
||||
const { deleteTool, setDeleteTool } = useDeleteTool();
|
||||
const { transformMode, setTransformMode } = useTransformMode();
|
||||
const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
|
||||
|
||||
useEffect(() => {
|
||||
if (transformMode === null) {
|
||||
if (!deleteModels) {
|
||||
if (!deleteTool) {
|
||||
handleMeshMissed(currentWallItem, setSelectedWallItem, setSelectedItemsIndex);
|
||||
setSelectedWallItem(null);
|
||||
setSelectedItemsIndex(null);
|
||||
@@ -33,12 +33,12 @@ const WallsAndWallItems = ({ CSGGroup, AssetConfigurations, setSelectedItemsInde
|
||||
receiveShadow
|
||||
visible={!toggleView}
|
||||
onClick={(event) => {
|
||||
if (!deleteModels && transformMode !== null) {
|
||||
if (!deleteTool && transformMode !== null) {
|
||||
handleMeshDown(event, currentWallItem, setSelectedWallItem, setSelectedItemsIndex, wallItems, toggleView);
|
||||
}
|
||||
}}
|
||||
onPointerMissed={() => {
|
||||
if (!deleteModels) {
|
||||
if (!deleteTool) {
|
||||
handleMeshMissed(currentWallItem, setSelectedWallItem, setSelectedItemsIndex);
|
||||
setSelectedWallItem(null);
|
||||
setSelectedItemsIndex(null);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ import { useEffect } from "react";
|
||||
import * as THREE from 'three';
|
||||
import * as Types from '../../../types/world/worldTypes';
|
||||
import * as CONSTANTS from "../../../types/world/worldConstants";
|
||||
import { useActiveLayer, useSocketStore, useDeleteModels, useDeletePointOrLine, useMovePoint, useToggleView, useUpdateScene, useNewLines, useToolMode } from "../../../store/store";
|
||||
import { useActiveLayer, useSocketStore, useDeleteTool, useDeletePointOrLine, useMovePoint, useToggleView, useUpdateScene, useNewLines, useToolMode } from "../../../store/store";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import arrayLineToObject from "../geomentries/lines/lineConvertions/arrayLineToObject";
|
||||
import addPointToScene from "../geomentries/points/addPointToScene";
|
||||
@@ -14,7 +14,7 @@ import loadZones from "../geomentries/zones/loadZones";
|
||||
|
||||
const ZoneGroup = ({ zoneGroup, plane, floorPlanGroupLine, floorPlanGroupPoint, line, lines, currentLayerPoint, dragPointControls, floorPlanGroup, ReferenceLineMesh, LineCreated, isSnapped, ispreSnapped, snappedPoint, isSnappedUUID, isAngleSnapped, anglesnappedPoint }: any) => {
|
||||
const { toggleView, setToggleView } = useToggleView();
|
||||
const { deleteModels, setDeleteModels } = useDeleteModels();
|
||||
const { deleteTool, setDeleteTool } = useDeleteTool();
|
||||
const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine();
|
||||
const { toolMode, setToolMode } = useToolMode();
|
||||
const { movePoint, setMovePoint } = useMovePoint();
|
||||
@@ -35,7 +35,7 @@ const ZoneGroup = ({ zoneGroup, plane, floorPlanGroupLine, floorPlanGroupPoint,
|
||||
if (toolMode === "Zone") {
|
||||
setDeletePointOrLine(false);
|
||||
setMovePoint(false);
|
||||
setDeleteModels(false);
|
||||
setDeleteTool(false);
|
||||
} else {
|
||||
removeSoloPoint(line, floorPlanGroupLine, floorPlanGroupPoint);
|
||||
removeReferenceLine(floorPlanGroup, ReferenceLineMesh, LineCreated, line);
|
||||
|
||||
Reference in New Issue
Block a user