Update Path Drawing Component to Match Wall Drawing Component Behavior
This commit is contained in:
186
app/src/modules/simulation/vehicle/pathCreator/pathHandler.tsx
Normal file
186
app/src/modules/simulation/vehicle/pathCreator/pathHandler.tsx
Normal file
@@ -0,0 +1,186 @@
|
||||
import { DragControls, Line } from "@react-three/drei";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import { useActiveSubTool, useToolMode } from "../../../../store/builder/store";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { LineCurve3, Plane, Vector3 } from "three";
|
||||
import { getPathsByPointId, setPathPosition } from "./function/getPaths";
|
||||
import { handleCanvasCursors } from "../../../../utils/mouseUtils/handleCanvasCursors";
|
||||
type PointData = {
|
||||
pointId: string;
|
||||
position: [number, number, number];
|
||||
isCurved?: boolean;
|
||||
handleA?: [number, number, number] | null;
|
||||
handleB?: [number, number, number] | null;
|
||||
};
|
||||
|
||||
interface PathDataInterface {
|
||||
pathId: string;
|
||||
isActive?: boolean;
|
||||
isCurved?: boolean;
|
||||
pathPoints: [PointData, PointData];
|
||||
}
|
||||
|
||||
type PathData = PathDataInterface[];
|
||||
|
||||
type PathHandlerProps = {
|
||||
selectedPath: PathDataInterface;
|
||||
points: [PointData, PointData];
|
||||
paths: PathData;
|
||||
setPaths: React.Dispatch<React.SetStateAction<PathData>>;
|
||||
setHoveredLine: React.Dispatch<
|
||||
React.SetStateAction<PathDataInterface | null>
|
||||
>;
|
||||
hoveredLine: PathDataInterface | null;
|
||||
hoveredPoint: PointData | null;
|
||||
};
|
||||
export default function PathHandler({
|
||||
selectedPath,
|
||||
setPaths,
|
||||
points,
|
||||
paths,
|
||||
setHoveredLine,
|
||||
hoveredLine,
|
||||
hoveredPoint,
|
||||
}: PathHandlerProps) {
|
||||
const { toolMode } = useToolMode();
|
||||
const { scene, raycaster } = useThree();
|
||||
const [dragOffset, setDragOffset] = useState<Vector3 | null>(null);
|
||||
const [initialPositions, setInitialPositions] = useState<{
|
||||
paths?: any;
|
||||
}>({});
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const { activeSubTool } = useActiveSubTool();
|
||||
const plane = useMemo(() => new Plane(new Vector3(0, 1, 0), 0), []);
|
||||
const path = useMemo(() => {
|
||||
const [start, end] = points.map((p) => new Vector3(...p.position));
|
||||
return new LineCurve3(start, end);
|
||||
}, [points]);
|
||||
const removePath = (pathId: string) => {
|
||||
setPaths((prevPaths) => prevPaths.filter((p) => p.pathId !== pathId));
|
||||
};
|
||||
const handlePathClick = (pointId: string) => {
|
||||
if (toolMode === "3D-Delete") {
|
||||
removePath(pointId);
|
||||
}
|
||||
};
|
||||
const handleDragStart = (points: [PointData, PointData]) => {
|
||||
if (activeSubTool !== "free-hand") return;
|
||||
const intersectionPoint = new Vector3();
|
||||
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||
if (hit) {
|
||||
const start = new Vector3(...points[0].position);
|
||||
const end = new Vector3(...points[1].position);
|
||||
const midPoint = new Vector3().addVectors(start, end).multiplyScalar(0.5);
|
||||
const offset = new Vector3().subVectors(midPoint, hit);
|
||||
setDragOffset(offset);
|
||||
const pathSet = getPathsByPointId(points[0].pointId, paths);
|
||||
setInitialPositions({ paths: pathSet });
|
||||
}
|
||||
};
|
||||
// const handleDrag = (points: [PointData, PointData]) => {
|
||||
// if (isHovered && dragOffset) {
|
||||
// const intersectionPoint = new Vector3();
|
||||
// const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||
|
||||
// if (hit) {
|
||||
// handleCanvasCursors("grabbing");
|
||||
// const positionWithOffset = new Vector3().addVectors(hit, dragOffset);
|
||||
// const start = new Vector3(...points[0].position);
|
||||
// const end = new Vector3(...points[1].position);
|
||||
// const midPoint = new Vector3()
|
||||
// .addVectors(start, end)
|
||||
// .multiplyScalar(0.5);
|
||||
// const delta = new Vector3().subVectors(positionWithOffset, midPoint);
|
||||
// const newStart = new Vector3().addVectors(start, delta);
|
||||
// const newEnd = new Vector3().addVectors(end, delta);
|
||||
// setPathPosition(
|
||||
// points[0].pointId,
|
||||
// [newStart.x, newStart.y, newStart.z],
|
||||
// setPaths
|
||||
// );
|
||||
// setPathPosition(
|
||||
// points[1].pointId,
|
||||
// [newEnd.x, newEnd.y, newEnd.z],
|
||||
// setPaths
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
const handleDrag = (points: [PointData, PointData]) => {
|
||||
if (isHovered && dragOffset) {
|
||||
const intersectionPoint = new Vector3();
|
||||
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||
|
||||
if (hit) {
|
||||
handleCanvasCursors("grabbing");
|
||||
const positionWithOffset = new Vector3().addVectors(hit, dragOffset);
|
||||
|
||||
const start = new Vector3(...points[0].position);
|
||||
const end = new Vector3(...points[1].position);
|
||||
const midPoint = new Vector3()
|
||||
.addVectors(start, end)
|
||||
.multiplyScalar(0.5);
|
||||
const delta = new Vector3().subVectors(positionWithOffset, midPoint);
|
||||
|
||||
const newStart: [number, number, number] = [
|
||||
start.x + delta.x,
|
||||
start.y + delta.y,
|
||||
start.z + delta.z,
|
||||
];
|
||||
const newEnd: [number, number, number] = [
|
||||
end.x + delta.x,
|
||||
end.y + delta.y,
|
||||
end.z + delta.z,
|
||||
];
|
||||
|
||||
// ✅ Move both points separately (won’t overwrite other updates)
|
||||
setPathPosition(points[0].pointId, newStart, setPaths);
|
||||
setPathPosition(points[1].pointId, newEnd, setPaths);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleDragEnd = (points: [PointData, PointData]) => {};
|
||||
return (
|
||||
<>
|
||||
<DragControls
|
||||
axisLock="y"
|
||||
autoTransform={false}
|
||||
onDragStart={() => handleDragStart(points)}
|
||||
onDrag={() => handleDrag(points)}
|
||||
onDragEnd={() => handleDragEnd(points)}
|
||||
>
|
||||
<Line
|
||||
name="Path-Line"
|
||||
key={selectedPath.pathId}
|
||||
points={[points[0].position, points[1].position]}
|
||||
color="purple"
|
||||
lineWidth={5}
|
||||
userData={selectedPath}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handlePathClick(selectedPath.pathId);
|
||||
}}
|
||||
onPointerOver={(e) => {
|
||||
if (e.buttons === 0 && !e.ctrlKey) {
|
||||
setHoveredLine(selectedPath);
|
||||
setIsHovered(true);
|
||||
if (!hoveredPoint) {
|
||||
// handleCanvasCursors("grab");
|
||||
}
|
||||
}
|
||||
}}
|
||||
onPointerOut={() => {
|
||||
if (isHovered && hoveredLine) {
|
||||
setHoveredLine(null);
|
||||
if (!hoveredPoint) {
|
||||
// handleCanvasCursors("default");
|
||||
}
|
||||
}
|
||||
setIsHovered(false);
|
||||
}}
|
||||
/>
|
||||
</DragControls>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user