Merge pull request 'simulation' (#4) from simulation into main
Reviewed-on: http://185.100.212.76:7776/Dwinzo-Beta/Dwinzo_dev/pulls/4
This commit is contained in:
commit
6971fff571
|
@ -1,28 +1,29 @@
|
||||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
/node_modules
|
/node_modules
|
||||||
/.pnp
|
/package-lock.json
|
||||||
.pnp.js
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
# testing
|
|
||||||
/coverage
|
# testing
|
||||||
|
/coverage
|
||||||
# production
|
|
||||||
/build
|
# production
|
||||||
|
/build
|
||||||
# misc
|
|
||||||
.DS_Store
|
# misc
|
||||||
.env.local
|
.DS_Store
|
||||||
.env.development.local
|
.env.local
|
||||||
.env.test.local
|
.env.development.local
|
||||||
.env.production.local
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
npm-debug.log*
|
||||||
yarn-error.log*
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
# remove zip
|
|
||||||
*.zip
|
# remove zip
|
||||||
**/temp/
|
*.zip
|
||||||
|
**/temp/
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,466 +1,509 @@
|
||||||
import React, { useState, useEffect, useMemo, useRef } from "react";
|
import React, { useState, useEffect, useMemo, useRef } from "react";
|
||||||
import { Line, Sphere } from "@react-three/drei";
|
import { Line, Sphere } from "@react-three/drei";
|
||||||
import { useThree, useFrame } from "@react-three/fiber";
|
import { useThree, useFrame } from "@react-three/fiber";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { useActiveLayer, useDeleteModels, useDeletePointOrLine, useMovePoint, useSocketStore, useToggleView, useToolMode, useRemovedLayer, useZones, useZonePoints } from "../../../store/store";
|
import { useActiveLayer, useDeleteModels, useDeletePointOrLine, useMovePoint, useSocketStore, useToggleView, useToolMode, useRemovedLayer, useZones, useZonePoints } from "../../../store/store";
|
||||||
// import { setZonesApi } from "../../../services/factoryBuilder/zones/setZonesApi";
|
// import { setZonesApi } from "../../../services/factoryBuilder/zones/setZonesApi";
|
||||||
// import { deleteZonesApi } from "../../../services/factoryBuilder/zones/deleteZoneApi";
|
// import { deleteZonesApi } from "../../../services/factoryBuilder/zones/deleteZoneApi";
|
||||||
import { getZonesApi } from "../../../services/factoryBuilder/zones/getZonesApi";
|
import { getZonesApi } from "../../../services/factoryBuilder/zones/getZonesApi";
|
||||||
|
|
||||||
import * as CONSTANTS from '../../../types/world/worldConstants';
|
import * as CONSTANTS from '../../../types/world/worldConstants';
|
||||||
|
|
||||||
const ZoneGroup: React.FC = () => {
|
const ZoneGroup: React.FC = () => {
|
||||||
const { camera, pointer, gl, raycaster, scene, controls } = useThree();
|
const { camera, pointer, gl, raycaster, scene, controls } = useThree();
|
||||||
const [startPoint, setStartPoint] = useState<THREE.Vector3 | null>(null);
|
const [startPoint, setStartPoint] = useState<THREE.Vector3 | null>(null);
|
||||||
const [endPoint, setEndPoint] = useState<THREE.Vector3 | null>(null);
|
const [endPoint, setEndPoint] = useState<THREE.Vector3 | null>(null);
|
||||||
const { zones, setZones } = useZones();
|
const { zones, setZones } = useZones();
|
||||||
const { zonePoints, setZonePoints } = useZonePoints();
|
const { zonePoints, setZonePoints } = useZonePoints();
|
||||||
const [isDragging, setIsDragging] = useState(false);
|
const [isDragging, setIsDragging] = useState(false);
|
||||||
const [draggedSphere, setDraggedSphere] = useState<THREE.Vector3 | null>(null);
|
const [draggedSphere, setDraggedSphere] = useState<THREE.Vector3 | null>(null);
|
||||||
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
|
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
|
||||||
const { toggleView } = useToggleView();
|
const { toggleView } = useToggleView();
|
||||||
const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine();
|
const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine();
|
||||||
const { removedLayer, setRemovedLayer } = useRemovedLayer();
|
const { removedLayer, setRemovedLayer } = useRemovedLayer();
|
||||||
const { toolMode, setToolMode } = useToolMode();
|
const { toolMode, setToolMode } = useToolMode();
|
||||||
const { movePoint, setMovePoint } = useMovePoint();
|
const { movePoint, setMovePoint } = useMovePoint();
|
||||||
const { deleteModels, setDeleteModels } = useDeleteModels();
|
const { deleteModels, setDeleteModels } = useDeleteModels();
|
||||||
const { activeLayer, setActiveLayer } = useActiveLayer();
|
const { activeLayer, setActiveLayer } = useActiveLayer();
|
||||||
const { socket } = useSocketStore();
|
const { socket } = useSocketStore();
|
||||||
|
|
||||||
const groupsRef = useRef<any>();
|
const groupsRef = useRef<any>();
|
||||||
|
|
||||||
const zoneMaterial = useMemo(() => new THREE.ShaderMaterial({
|
const zoneMaterial = useMemo(() => new THREE.ShaderMaterial({
|
||||||
side: THREE.DoubleSide,
|
side: THREE.DoubleSide,
|
||||||
vertexShader: `
|
vertexShader: `
|
||||||
varying vec2 vUv;
|
varying vec2 vUv;
|
||||||
void main(){
|
void main(){
|
||||||
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
||||||
vUv = uv;
|
vUv = uv;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
fragmentShader: `
|
fragmentShader: `
|
||||||
varying vec2 vUv;
|
varying vec2 vUv;
|
||||||
uniform vec3 uColor;
|
uniform vec3 uColor;
|
||||||
void main(){
|
void main(){
|
||||||
float alpha = 1.0 - vUv.y;
|
float alpha = 1.0 - vUv.y;
|
||||||
gl_FragColor = vec4(uColor, alpha);
|
gl_FragColor = vec4(uColor, alpha);
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
uniforms: {
|
uniforms: {
|
||||||
uColor: { value: new THREE.Color(CONSTANTS.zoneConfig.color) },
|
uColor: { value: new THREE.Color(CONSTANTS.zoneConfig.color) },
|
||||||
},
|
},
|
||||||
transparent: true,
|
transparent: true,
|
||||||
}), []);
|
}), []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchZones = async () => {
|
const fetchZones = async () => {
|
||||||
const email = localStorage.getItem('email');
|
const email = localStorage.getItem('email');
|
||||||
if (!email) return;
|
if (!email) return;
|
||||||
|
|
||||||
const organization = email.split("@")[1].split(".")[0];
|
const organization = email.split("@")[1].split(".")[0];
|
||||||
const data = await getZonesApi(organization);
|
const data = await getZonesApi(organization);
|
||||||
|
|
||||||
if (data.data && data.data.length > 0) {
|
if (data.data && data.data.length > 0) {
|
||||||
const fetchedZones = data.data.map((zone: any) => ({
|
const fetchedZones = data.data.map((zone: any) => ({
|
||||||
zoneId: zone.zoneId,
|
zoneId: zone.zoneId,
|
||||||
zoneName: zone.zoneName,
|
zoneName: zone.zoneName,
|
||||||
points: zone.points,
|
points: zone.points,
|
||||||
layer: zone.layer
|
layer: zone.layer
|
||||||
}));
|
}));
|
||||||
|
|
||||||
setZones(fetchedZones);
|
setZones(fetchedZones);
|
||||||
|
|
||||||
const fetchedPoints = data.data.flatMap((zone: any) =>
|
const fetchedPoints = data.data.flatMap((zone: any) =>
|
||||||
zone.points.slice(0, 4).map((point: [number, number, number]) => new THREE.Vector3(...point))
|
zone.points.slice(0, 4).map((point: [number, number, number]) => new THREE.Vector3(...point))
|
||||||
);
|
);
|
||||||
|
|
||||||
setZonePoints(fetchedPoints);
|
setZonePoints(fetchedPoints);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchZones();
|
fetchZones();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
localStorage.setItem('zones', JSON.stringify(zones));
|
localStorage.setItem('zones', JSON.stringify(zones));
|
||||||
|
|
||||||
}, [zones])
|
}, [zones])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (removedLayer) {
|
if (removedLayer) {
|
||||||
const updatedZones = zones.filter((zone: any) => zone.layer !== removedLayer);
|
const updatedZones = zones.filter((zone: any) => zone.layer !== removedLayer);
|
||||||
setZones(updatedZones);
|
setZones(updatedZones);
|
||||||
|
|
||||||
const updatedzonePoints = zonePoints.filter((_: any, index: any) => {
|
const updatedzonePoints = zonePoints.filter((_: any, index: any) => {
|
||||||
const zoneIndex = Math.floor(index / 4);
|
const zoneIndex = Math.floor(index / 4);
|
||||||
return zones[zoneIndex]?.layer !== removedLayer;
|
return zones[zoneIndex]?.layer !== removedLayer;
|
||||||
});
|
});
|
||||||
setZonePoints(updatedzonePoints);
|
setZonePoints(updatedzonePoints);
|
||||||
|
|
||||||
zones.filter((zone: any) => zone.layer === removedLayer).forEach((zone: any) => {
|
zones.filter((zone: any) => zone.layer === removedLayer).forEach((zone: any) => {
|
||||||
deleteZoneFromBackend(zone.zoneId);
|
deleteZoneFromBackend(zone.zoneId);
|
||||||
});
|
});
|
||||||
|
|
||||||
setRemovedLayer(null);
|
setRemovedLayer(null);
|
||||||
}
|
}
|
||||||
}, [removedLayer]);
|
}, [removedLayer]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (toolMode !== "Zone") {
|
if (toolMode !== "Zone") {
|
||||||
setStartPoint(null);
|
setStartPoint(null);
|
||||||
setEndPoint(null);
|
setEndPoint(null);
|
||||||
} else {
|
} else {
|
||||||
setDeletePointOrLine(false);
|
setDeletePointOrLine(false);
|
||||||
setMovePoint(false);
|
setMovePoint(false);
|
||||||
setDeleteModels(false);
|
setDeleteModels(false);
|
||||||
}
|
}
|
||||||
if (!toggleView) {
|
if (!toggleView) {
|
||||||
setStartPoint(null);
|
setStartPoint(null);
|
||||||
setEndPoint(null);
|
setEndPoint(null);
|
||||||
}
|
}
|
||||||
}, [toolMode, toggleView]);
|
}, [toolMode, toggleView]);
|
||||||
|
|
||||||
|
|
||||||
const addZoneToBackend = async (zone: { zoneId: string; zoneName: string; points: [number, number, number][]; layer: string }) => {
|
const addZoneToBackend = async (zone: { zoneId: string; zoneName: string; points: [number, number, number][]; layer: string }) => {
|
||||||
|
|
||||||
const email = localStorage.getItem('email');
|
const email = localStorage.getItem('email');
|
||||||
const userId = localStorage.getItem('userId');
|
const userId = localStorage.getItem('userId');
|
||||||
const organization = (email!.split("@")[1]).split(".")[0];
|
const organization = (email!.split("@")[1]).split(".")[0];
|
||||||
|
|
||||||
const input = {
|
const calculateCenter = (points: number[][]) => {
|
||||||
userId: userId,
|
if (!points || points.length === 0) return null;
|
||||||
organization: organization,
|
|
||||||
zoneData: {
|
let sumX = 0, sumY = 0, sumZ = 0;
|
||||||
zoneName: zone.zoneName,
|
const numPoints = points.length;
|
||||||
zoneId: zone.zoneId,
|
|
||||||
points: zone.points,
|
points.forEach(([x, y, z]) => {
|
||||||
layer: zone.layer
|
sumX += x;
|
||||||
}
|
sumY += y;
|
||||||
}
|
sumZ += z;
|
||||||
|
});
|
||||||
socket.emit('v2:zone:set', input);
|
|
||||||
};
|
return [sumX / numPoints, sumY / numPoints, sumZ / numPoints] as [number, number, number];
|
||||||
|
};
|
||||||
const updateZoneToBackend = async (zone: { zoneId: string; zoneName: string; points: [number, number, number][]; layer: string }) => {
|
|
||||||
|
const target: [number, number, number] | null = calculateCenter(zone.points);
|
||||||
const email = localStorage.getItem('email');
|
if (!target) return;
|
||||||
const userId = localStorage.getItem('userId');
|
const position = [target[0], 75, target[2]];
|
||||||
const organization = (email!.split("@")[1]).split(".")[0];
|
|
||||||
|
const input = {
|
||||||
const input = {
|
userId: userId,
|
||||||
userId: userId,
|
organization: organization,
|
||||||
organization: organization,
|
zoneData: {
|
||||||
zoneData: {
|
zoneName: zone.zoneName,
|
||||||
zoneName: zone.zoneName,
|
zoneId: zone.zoneId,
|
||||||
zoneId: zone.zoneId,
|
points: zone.points,
|
||||||
points: zone.points,
|
viewPortCenter: target,
|
||||||
layer: zone.layer
|
viewPortposition: position,
|
||||||
}
|
layer: zone.layer
|
||||||
}
|
}
|
||||||
|
}
|
||||||
socket.emit('v2:zone:set', input);
|
|
||||||
};
|
socket.emit('v2:zone:set', input);
|
||||||
|
};
|
||||||
const deleteZoneFromBackend = async (zoneId: string) => {
|
|
||||||
|
const updateZoneToBackend = async (zone: { zoneId: string; zoneName: string; points: [number, number, number][]; layer: string }) => {
|
||||||
const email = localStorage.getItem('email');
|
|
||||||
const userId = localStorage.getItem('userId');
|
const email = localStorage.getItem('email');
|
||||||
const organization = (email!.split("@")[1]).split(".")[0];
|
const userId = localStorage.getItem('userId');
|
||||||
|
const organization = (email!.split("@")[1]).split(".")[0];
|
||||||
const input = {
|
|
||||||
userId: userId,
|
const calculateCenter = (points: number[][]) => {
|
||||||
organization: organization,
|
if (!points || points.length === 0) return null;
|
||||||
zoneId: zoneId
|
|
||||||
}
|
let sumX = 0, sumY = 0, sumZ = 0;
|
||||||
|
const numPoints = points.length;
|
||||||
socket.emit('v2:zone:delete', input);
|
|
||||||
};
|
points.forEach(([x, y, z]) => {
|
||||||
|
sumX += x;
|
||||||
const handleDeleteZone = (zoneId: string) => {
|
sumY += y;
|
||||||
const updatedZones = zones.filter((zone: any) => zone.zoneId !== zoneId);
|
sumZ += z;
|
||||||
setZones(updatedZones);
|
});
|
||||||
|
|
||||||
const zoneIndex = zones.findIndex((zone: any) => zone.zoneId === zoneId);
|
return [sumX / numPoints, sumY / numPoints, sumZ / numPoints] as [number, number, number];
|
||||||
if (zoneIndex !== -1) {
|
};
|
||||||
const zonePointsToRemove = zonePoints.slice(zoneIndex * 4, zoneIndex * 4 + 4);
|
|
||||||
zonePointsToRemove.forEach((point: any) => groupsRef.current.remove(point));
|
const target: [number, number, number] | null = calculateCenter(zone.points);
|
||||||
const updatedzonePoints = zonePoints.filter((_: any, index: any) => index < zoneIndex * 4 || index >= zoneIndex * 4 + 4);
|
if (!target) return;
|
||||||
setZonePoints(updatedzonePoints);
|
const position = [target[0], 75, target[2]];
|
||||||
}
|
|
||||||
|
const input = {
|
||||||
deleteZoneFromBackend(zoneId);
|
userId: userId,
|
||||||
};
|
organization: organization,
|
||||||
|
zoneData: {
|
||||||
useEffect(() => {
|
zoneName: zone.zoneName,
|
||||||
if (!camera || !toggleView) return;
|
zoneId: zone.zoneId,
|
||||||
const canvasElement = gl.domElement;
|
points: zone.points,
|
||||||
|
viewPortCenter: target,
|
||||||
let drag = false;
|
viewPortposition: position,
|
||||||
let isLeftMouseDown = false;
|
layer: zone.layer
|
||||||
|
}
|
||||||
const onMouseDown = (evt: any) => {
|
}
|
||||||
if (evt.button === 0) {
|
|
||||||
isLeftMouseDown = true;
|
socket.emit('v2:zone:set', input);
|
||||||
drag = false;
|
};
|
||||||
|
|
||||||
raycaster.setFromCamera(pointer, camera);
|
|
||||||
const intersects = raycaster.intersectObjects(groupsRef.current.children, true);
|
const deleteZoneFromBackend = async (zoneId: string) => {
|
||||||
|
|
||||||
if (intersects.length > 0 && movePoint) {
|
const email = localStorage.getItem('email');
|
||||||
const clickedObject = intersects[0].object;
|
const userId = localStorage.getItem('userId');
|
||||||
const sphereIndex = zonePoints.findIndex((point: any) => point.equals(clickedObject.position));
|
const organization = (email!.split("@")[1]).split(".")[0];
|
||||||
if (sphereIndex !== -1) {
|
|
||||||
(controls as any).enabled = false;
|
const input = {
|
||||||
setDraggedSphere(zonePoints[sphereIndex]);
|
userId: userId,
|
||||||
setIsDragging(true);
|
organization: organization,
|
||||||
}
|
zoneId: zoneId
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
socket.emit('v2:zone:delete', input);
|
||||||
|
};
|
||||||
const onMouseUp = (evt: any) => {
|
|
||||||
if (evt.button === 0 && !drag && !isDragging && !deletePointOrLine) {
|
const handleDeleteZone = (zoneId: string) => {
|
||||||
isLeftMouseDown = false;
|
const updatedZones = zones.filter((zone: any) => zone.zoneId !== zoneId);
|
||||||
|
setZones(updatedZones);
|
||||||
if (!startPoint && !movePoint) {
|
|
||||||
raycaster.setFromCamera(pointer, camera);
|
const zoneIndex = zones.findIndex((zone: any) => zone.zoneId === zoneId);
|
||||||
const intersectionPoint = new THREE.Vector3();
|
if (zoneIndex !== -1) {
|
||||||
const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
const zonePointsToRemove = zonePoints.slice(zoneIndex * 4, zoneIndex * 4 + 4);
|
||||||
if (point) {
|
zonePointsToRemove.forEach((point: any) => groupsRef.current.remove(point));
|
||||||
setStartPoint(point);
|
const updatedzonePoints = zonePoints.filter((_: any, index: any) => index < zoneIndex * 4 || index >= zoneIndex * 4 + 4);
|
||||||
setEndPoint(null);
|
setZonePoints(updatedzonePoints);
|
||||||
}
|
}
|
||||||
} else if (startPoint && !movePoint) {
|
|
||||||
raycaster.setFromCamera(pointer, camera);
|
deleteZoneFromBackend(zoneId);
|
||||||
const intersectionPoint = new THREE.Vector3();
|
};
|
||||||
const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
|
||||||
if (!point) return;
|
useEffect(() => {
|
||||||
|
if (!camera || !toggleView) return;
|
||||||
const points = [
|
const canvasElement = gl.domElement;
|
||||||
[startPoint.x, 0.15, startPoint.z],
|
|
||||||
[point.x, 0.15, startPoint.z],
|
let drag = false;
|
||||||
[point.x, 0.15, point.z],
|
let isLeftMouseDown = false;
|
||||||
[startPoint.x, 0.15, point.z],
|
|
||||||
[startPoint.x, 0.15, startPoint.z],
|
const onMouseDown = (evt: any) => {
|
||||||
] as [number, number, number][];
|
if (evt.button === 0) {
|
||||||
|
isLeftMouseDown = true;
|
||||||
const zoneName = `Zone ${zones.length + 1}`;
|
drag = false;
|
||||||
const zoneId = THREE.MathUtils.generateUUID();
|
|
||||||
const newZone = {
|
raycaster.setFromCamera(pointer, camera);
|
||||||
zoneId,
|
const intersects = raycaster.intersectObjects(groupsRef.current.children, true);
|
||||||
zoneName,
|
|
||||||
points: points,
|
if (intersects.length > 0 && movePoint) {
|
||||||
layer: activeLayer
|
const clickedObject = intersects[0].object;
|
||||||
};
|
const sphereIndex = zonePoints.findIndex((point: any) => point.equals(clickedObject.position));
|
||||||
|
if (sphereIndex !== -1) {
|
||||||
const newZones = [...zones, newZone];
|
(controls as any).enabled = false;
|
||||||
|
setDraggedSphere(zonePoints[sphereIndex]);
|
||||||
setZones(newZones);
|
setIsDragging(true);
|
||||||
|
}
|
||||||
const newzonePoints = [
|
}
|
||||||
new THREE.Vector3(startPoint.x, 0.15, startPoint.z),
|
}
|
||||||
new THREE.Vector3(point.x, 0.15, startPoint.z),
|
};
|
||||||
new THREE.Vector3(point.x, 0.15, point.z),
|
|
||||||
new THREE.Vector3(startPoint.x, 0.15, point.z),
|
const onMouseUp = (evt: any) => {
|
||||||
];
|
if (evt.button === 0 && !drag && !isDragging && !deletePointOrLine) {
|
||||||
|
isLeftMouseDown = false;
|
||||||
const updatedZonePoints = [...zonePoints, ...newzonePoints];
|
|
||||||
setZonePoints(updatedZonePoints);
|
if (!startPoint && !movePoint) {
|
||||||
|
raycaster.setFromCamera(pointer, camera);
|
||||||
addZoneToBackend(newZone);
|
const intersectionPoint = new THREE.Vector3();
|
||||||
|
const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||||
setStartPoint(null);
|
if (point) {
|
||||||
setEndPoint(null);
|
setStartPoint(point);
|
||||||
}
|
setEndPoint(null);
|
||||||
} else if (evt.button === 0 && !drag && !isDragging && deletePointOrLine) {
|
}
|
||||||
raycaster.setFromCamera(pointer, camera);
|
} else if (startPoint && !movePoint) {
|
||||||
const intersects = raycaster.intersectObjects(groupsRef.current.children, true);
|
raycaster.setFromCamera(pointer, camera);
|
||||||
|
const intersectionPoint = new THREE.Vector3();
|
||||||
if (intersects.length > 0) {
|
const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||||
const clickedObject = intersects[0].object;
|
if (!point) return;
|
||||||
|
|
||||||
const sphereIndex = zonePoints.findIndex((point: any) => point.equals(clickedObject.position));
|
const points = [
|
||||||
if (sphereIndex !== -1) {
|
[startPoint.x, 0.15, startPoint.z],
|
||||||
const zoneIndex = Math.floor(sphereIndex / 4);
|
[point.x, 0.15, startPoint.z],
|
||||||
const zoneId = zones[zoneIndex].zoneId;
|
[point.x, 0.15, point.z],
|
||||||
handleDeleteZone(zoneId);
|
[startPoint.x, 0.15, point.z],
|
||||||
return;
|
[startPoint.x, 0.15, startPoint.z],
|
||||||
}
|
] as [number, number, number][];
|
||||||
}
|
|
||||||
}
|
const zoneName = `Zone ${zones.length + 1}`;
|
||||||
|
const zoneId = THREE.MathUtils.generateUUID();
|
||||||
if (evt.button === 0) {
|
const newZone = {
|
||||||
if (isDragging && draggedSphere) {
|
zoneId,
|
||||||
setIsDragging(false);
|
zoneName,
|
||||||
setDraggedSphere(null);
|
points: points,
|
||||||
|
layer: activeLayer
|
||||||
const sphereIndex = zonePoints.findIndex((point: any) => point === draggedSphere);
|
};
|
||||||
if (sphereIndex !== -1) {
|
|
||||||
const zoneIndex = Math.floor(sphereIndex / 4);
|
const newZones = [...zones, newZone];
|
||||||
|
|
||||||
if (zoneIndex !== -1 && zones[zoneIndex]) {
|
setZones(newZones);
|
||||||
updateZoneToBackend(zones[zoneIndex]);
|
|
||||||
}
|
const newzonePoints = [
|
||||||
}
|
new THREE.Vector3(startPoint.x, 0.15, startPoint.z),
|
||||||
}
|
new THREE.Vector3(point.x, 0.15, startPoint.z),
|
||||||
}
|
new THREE.Vector3(point.x, 0.15, point.z),
|
||||||
};
|
new THREE.Vector3(startPoint.x, 0.15, point.z),
|
||||||
|
];
|
||||||
const onMouseMove = () => {
|
|
||||||
if (isLeftMouseDown) {
|
const updatedZonePoints = [...zonePoints, ...newzonePoints];
|
||||||
drag = true;
|
setZonePoints(updatedZonePoints);
|
||||||
}
|
|
||||||
raycaster.setFromCamera(pointer, camera);
|
addZoneToBackend(newZone);
|
||||||
const intersects = raycaster.intersectObjects(groupsRef.current.children, true);
|
|
||||||
|
setStartPoint(null);
|
||||||
if (intersects.length > 0 && intersects[0].object.name.includes('point')) {
|
setEndPoint(null);
|
||||||
gl.domElement.style.cursor = movePoint ? "pointer" : "default";
|
}
|
||||||
} else {
|
} else if (evt.button === 0 && !drag && !isDragging && deletePointOrLine) {
|
||||||
gl.domElement.style.cursor = "default";
|
raycaster.setFromCamera(pointer, camera);
|
||||||
}
|
const intersects = raycaster.intersectObjects(groupsRef.current.children, true);
|
||||||
if (isDragging && draggedSphere) {
|
|
||||||
raycaster.setFromCamera(pointer, camera);
|
if (intersects.length > 0) {
|
||||||
const intersectionPoint = new THREE.Vector3();
|
const clickedObject = intersects[0].object;
|
||||||
const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
|
||||||
if (point) {
|
const sphereIndex = zonePoints.findIndex((point: any) => point.equals(clickedObject.position));
|
||||||
draggedSphere.set(point.x, 0.15, point.z);
|
if (sphereIndex !== -1) {
|
||||||
|
const zoneIndex = Math.floor(sphereIndex / 4);
|
||||||
const sphereIndex = zonePoints.findIndex((point: any) => point === draggedSphere);
|
const zoneId = zones[zoneIndex].zoneId;
|
||||||
if (sphereIndex !== -1) {
|
handleDeleteZone(zoneId);
|
||||||
const zoneIndex = Math.floor(sphereIndex / 4);
|
return;
|
||||||
const cornerIndex = sphereIndex % 4;
|
}
|
||||||
|
}
|
||||||
const updatedZones = zones.map((zone: any, index: number) => {
|
}
|
||||||
if (index === zoneIndex) {
|
|
||||||
const updatedPoints = [...zone.points];
|
if (evt.button === 0) {
|
||||||
updatedPoints[cornerIndex] = [point.x, 0.15, point.z];
|
if (isDragging && draggedSphere) {
|
||||||
updatedPoints[4] = updatedPoints[0];
|
setIsDragging(false);
|
||||||
return { ...zone, points: updatedPoints };
|
setDraggedSphere(null);
|
||||||
}
|
|
||||||
return zone;
|
const sphereIndex = zonePoints.findIndex((point: any) => point === draggedSphere);
|
||||||
});
|
if (sphereIndex !== -1) {
|
||||||
|
const zoneIndex = Math.floor(sphereIndex / 4);
|
||||||
setZones(updatedZones);
|
|
||||||
}
|
if (zoneIndex !== -1 && zones[zoneIndex]) {
|
||||||
}
|
updateZoneToBackend(zones[zoneIndex]);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
const onContext = (event: any) => {
|
}
|
||||||
event.preventDefault();
|
};
|
||||||
setStartPoint(null);
|
|
||||||
setEndPoint(null);
|
const onMouseMove = () => {
|
||||||
};
|
if (isLeftMouseDown) {
|
||||||
|
drag = true;
|
||||||
if (toolMode === 'Zone' || deletePointOrLine || movePoint) {
|
}
|
||||||
canvasElement.addEventListener("mousedown", onMouseDown);
|
raycaster.setFromCamera(pointer, camera);
|
||||||
canvasElement.addEventListener("mouseup", onMouseUp);
|
const intersects = raycaster.intersectObjects(groupsRef.current.children, true);
|
||||||
canvasElement.addEventListener("mousemove", onMouseMove);
|
|
||||||
canvasElement.addEventListener("contextmenu", onContext);
|
if (intersects.length > 0 && intersects[0].object.name.includes('point')) {
|
||||||
}
|
gl.domElement.style.cursor = movePoint ? "pointer" : "default";
|
||||||
return () => {
|
} else {
|
||||||
canvasElement.removeEventListener("mousedown", onMouseDown);
|
gl.domElement.style.cursor = "default";
|
||||||
canvasElement.removeEventListener("mouseup", onMouseUp);
|
}
|
||||||
canvasElement.removeEventListener("mousemove", onMouseMove);
|
if (isDragging && draggedSphere) {
|
||||||
canvasElement.removeEventListener("contextmenu", onContext);
|
raycaster.setFromCamera(pointer, camera);
|
||||||
};
|
const intersectionPoint = new THREE.Vector3();
|
||||||
}, [gl, camera, startPoint, toggleView, scene, toolMode, zones, isDragging, deletePointOrLine, zonePoints, draggedSphere, movePoint, activeLayer]);
|
const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||||
|
if (point) {
|
||||||
useFrame(() => {
|
draggedSphere.set(point.x, 0.15, point.z);
|
||||||
if (!startPoint) return;
|
|
||||||
raycaster.setFromCamera(pointer, camera);
|
const sphereIndex = zonePoints.findIndex((point: any) => point === draggedSphere);
|
||||||
const intersectionPoint = new THREE.Vector3();
|
if (sphereIndex !== -1) {
|
||||||
const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
const zoneIndex = Math.floor(sphereIndex / 4);
|
||||||
if (point) {
|
const cornerIndex = sphereIndex % 4;
|
||||||
setEndPoint(point);
|
|
||||||
}
|
const updatedZones = zones.map((zone: any, index: number) => {
|
||||||
});
|
if (index === zoneIndex) {
|
||||||
return (
|
const updatedPoints = [...zone.points];
|
||||||
<group ref={groupsRef} name='zoneGroup' >
|
updatedPoints[cornerIndex] = [point.x, 0.15, point.z];
|
||||||
<group name="zones" visible={!toggleView}>
|
updatedPoints[4] = updatedPoints[0];
|
||||||
{zones
|
return { ...zone, points: updatedPoints };
|
||||||
.map((zone: any) => (
|
}
|
||||||
<group key={zone.zoneId} name={zone.zoneName}>
|
return zone;
|
||||||
{zone.points.slice(0, -1).map((point: [number, number, number], index: number) => {
|
});
|
||||||
const nextPoint = zone.points[index + 1];
|
|
||||||
|
setZones(updatedZones);
|
||||||
const point1 = new THREE.Vector3(point[0], point[1], point[2]);
|
}
|
||||||
const point2 = new THREE.Vector3(nextPoint[0], nextPoint[1], nextPoint[2]);
|
}
|
||||||
|
}
|
||||||
const planeWidth = point1.distanceTo(point2);
|
};
|
||||||
const planeHeight = CONSTANTS.wallConfig.height;
|
|
||||||
|
const onContext = (event: any) => {
|
||||||
const midpoint = new THREE.Vector3((point1.x + point2.x) / 2, (CONSTANTS.wallConfig.height / 2) + ((zone.layer - 1) * CONSTANTS.wallConfig.height), (point1.z + point2.z) / 2);
|
event.preventDefault();
|
||||||
|
setStartPoint(null);
|
||||||
const angle = Math.atan2(point2.z - point1.z, point2.x - point1.x);
|
setEndPoint(null);
|
||||||
|
};
|
||||||
return (
|
|
||||||
<mesh
|
if (toolMode === 'Zone' || deletePointOrLine || movePoint) {
|
||||||
key={index}
|
canvasElement.addEventListener("mousedown", onMouseDown);
|
||||||
position={midpoint}
|
canvasElement.addEventListener("mouseup", onMouseUp);
|
||||||
rotation={[0, -angle, 0]}
|
canvasElement.addEventListener("mousemove", onMouseMove);
|
||||||
>
|
canvasElement.addEventListener("contextmenu", onContext);
|
||||||
<planeGeometry args={[planeWidth, planeHeight]} />
|
}
|
||||||
<primitive
|
return () => {
|
||||||
object={zoneMaterial.clone()}
|
canvasElement.removeEventListener("mousedown", onMouseDown);
|
||||||
attach="material"
|
canvasElement.removeEventListener("mouseup", onMouseUp);
|
||||||
/>
|
canvasElement.removeEventListener("mousemove", onMouseMove);
|
||||||
</mesh>
|
canvasElement.removeEventListener("contextmenu", onContext);
|
||||||
);
|
};
|
||||||
})}
|
}, [gl, camera, startPoint, toggleView, scene, toolMode, zones, isDragging, deletePointOrLine, zonePoints, draggedSphere, movePoint, activeLayer]);
|
||||||
</group>
|
|
||||||
))}
|
useFrame(() => {
|
||||||
</group>
|
if (!startPoint) return;
|
||||||
<group name='zoneLines' visible={toggleView}>
|
raycaster.setFromCamera(pointer, camera);
|
||||||
{zones
|
const intersectionPoint = new THREE.Vector3();
|
||||||
.filter((zone: any) => zone.layer === activeLayer)
|
const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||||
.map((zone: any) => (
|
if (point) {
|
||||||
<Line
|
setEndPoint(point);
|
||||||
key={zone.zoneId}
|
}
|
||||||
points={zone.points}
|
});
|
||||||
color="#007BFF"
|
return (
|
||||||
lineWidth={3}
|
<group ref={groupsRef} name='zoneGroup' >
|
||||||
onClick={(e) => {
|
<group name="zones" visible={!toggleView}>
|
||||||
e.stopPropagation();
|
{zones
|
||||||
if (deletePointOrLine) {
|
.map((zone: any) => (
|
||||||
handleDeleteZone(zone.zoneId);
|
<group key={zone.zoneId} name={zone.zoneName}>
|
||||||
}
|
{zone.points.slice(0, -1).map((point: [number, number, number], index: number) => {
|
||||||
}}
|
const nextPoint = zone.points[index + 1];
|
||||||
/>
|
|
||||||
))}
|
const point1 = new THREE.Vector3(point[0], point[1], point[2]);
|
||||||
</group>
|
const point2 = new THREE.Vector3(nextPoint[0], nextPoint[1], nextPoint[2]);
|
||||||
<group name="zonePoints" visible={toggleView}>
|
|
||||||
{zones.filter((zone: any) => zone.layer === activeLayer).flatMap((zone: any) => (
|
const planeWidth = point1.distanceTo(point2);
|
||||||
zone.points.slice(0, 4).map((point: any, pointIndex: number) => (
|
const planeHeight = CONSTANTS.wallConfig.height;
|
||||||
<Sphere
|
|
||||||
key={`${zone.zoneId}-point-${pointIndex}`}
|
const midpoint = new THREE.Vector3((point1.x + point2.x) / 2, (CONSTANTS.wallConfig.height / 2) + ((zone.layer - 1) * CONSTANTS.wallConfig.height), (point1.z + point2.z) / 2);
|
||||||
position={new THREE.Vector3(...point)}
|
|
||||||
args={[0.3, 16, 16]}
|
const angle = Math.atan2(point2.z - point1.z, point2.x - point1.x);
|
||||||
name={`point-${zone.zoneId}-${pointIndex}`}
|
|
||||||
>
|
return (
|
||||||
<meshBasicMaterial color="red" />
|
<mesh
|
||||||
</Sphere>
|
key={index}
|
||||||
))
|
position={midpoint}
|
||||||
))}
|
rotation={[0, -angle, 0]}
|
||||||
</group>
|
>
|
||||||
<group name="tempGroup" visible={toggleView}>
|
<planeGeometry args={[planeWidth, planeHeight]} />
|
||||||
{startPoint && endPoint && (
|
<primitive
|
||||||
<Line
|
object={zoneMaterial.clone()}
|
||||||
points={[
|
attach="material"
|
||||||
[startPoint.x, 0.15, startPoint.z],
|
/>
|
||||||
[endPoint.x, 0.15, startPoint.z],
|
</mesh>
|
||||||
[endPoint.x, 0.15, endPoint.z],
|
);
|
||||||
[startPoint.x, 0.15, endPoint.z],
|
})}
|
||||||
[startPoint.x, 0.15, startPoint.z],
|
</group>
|
||||||
]}
|
))}
|
||||||
color="#C164FF"
|
</group>
|
||||||
lineWidth={3}
|
<group name='zoneLines' visible={toggleView}>
|
||||||
/>
|
{zones
|
||||||
)}
|
.filter((zone: any) => zone.layer === activeLayer)
|
||||||
</group>
|
.map((zone: any) => (
|
||||||
</group>
|
<Line
|
||||||
);
|
key={zone.zoneId}
|
||||||
};
|
points={zone.points}
|
||||||
|
color="#007BFF"
|
||||||
|
lineWidth={3}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
if (deletePointOrLine) {
|
||||||
|
handleDeleteZone(zone.zoneId);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</group>
|
||||||
|
<group name="zonePoints" visible={toggleView}>
|
||||||
|
{zones.filter((zone: any) => zone.layer === activeLayer).flatMap((zone: any) => (
|
||||||
|
zone.points.slice(0, 4).map((point: any, pointIndex: number) => (
|
||||||
|
<Sphere
|
||||||
|
key={`${zone.zoneId}-point-${pointIndex}`}
|
||||||
|
position={new THREE.Vector3(...point)}
|
||||||
|
args={[0.3, 16, 16]}
|
||||||
|
name={`point-${zone.zoneId}-${pointIndex}`}
|
||||||
|
>
|
||||||
|
<meshBasicMaterial color="red" />
|
||||||
|
</Sphere>
|
||||||
|
))
|
||||||
|
))}
|
||||||
|
</group>
|
||||||
|
<group name="tempGroup" visible={toggleView}>
|
||||||
|
{startPoint && endPoint && (
|
||||||
|
<Line
|
||||||
|
points={[
|
||||||
|
[startPoint.x, 0.15, startPoint.z],
|
||||||
|
[endPoint.x, 0.15, startPoint.z],
|
||||||
|
[endPoint.x, 0.15, endPoint.z],
|
||||||
|
[startPoint.x, 0.15, endPoint.z],
|
||||||
|
[startPoint.x, 0.15, startPoint.z],
|
||||||
|
]}
|
||||||
|
color="#C164FF"
|
||||||
|
lineWidth={3}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default ZoneGroup;
|
export default ZoneGroup;
|
Loading…
Reference in New Issue