Add dragging and rotating state management to simulation store; enhance PointsCreator and VehicleUI components

This commit is contained in:
Jerald-Golden-B 2025-05-02 11:54:40 +05:30
parent 928c683a79
commit 96530b981f
3 changed files with 93 additions and 23 deletions

View File

@ -1,22 +1,29 @@
import React, { useEffect, useRef, useState } from "react"; import React, { useEffect, useRef, useState } from "react";
import * as THREE from "three"; import * as THREE from "three";
import { useEventsStore } from "../../../../../store/simulation/useEventsStore"; import { useEventsStore } from "../../../../../store/simulation/useEventsStore";
import useModuleStore from "../../../../../store/useModuleStore"; import useModuleStore, { useSubModuleStore } from "../../../../../store/useModuleStore";
import { TransformControls } from "@react-three/drei"; import { TransformControls } from "@react-three/drei";
import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys"; import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys";
import { import {
useSelectedEventSphere, useSelectedEventSphere,
useSelectedEventData, useSelectedEventData,
useIsDragging,
useIsRotating,
} from "../../../../../store/simulation/useSimulationStore"; } from "../../../../../store/simulation/useSimulationStore";
import { useThree } from "@react-three/fiber";
function PointsCreator() { function PointsCreator() {
const { gl, raycaster, scene, pointer, camera } = useThree();
const { subModule } = useSubModuleStore();
const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore(); const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore();
const { activeModule } = useModuleStore(); const { activeModule } = useModuleStore();
const transformRef = useRef<any>(null); const transformRef = useRef<any>(null);
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null); const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({}); const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({});
const { selectedEventSphere, setSelectedEventSphere, clearSelectedEventSphere, } = useSelectedEventSphere(); const { selectedEventSphere, setSelectedEventSphere, clearSelectedEventSphere, } = useSelectedEventSphere();
const { selectedEventData, setSelectedEventData, clearSelectedEventData } = useSelectedEventData(); const { setSelectedEventData, clearSelectedEventData } = useSelectedEventData();
const { isDragging } = useIsDragging();
const { isRotating } = useIsRotating();
useEffect(() => { useEffect(() => {
if (selectedEventSphere) { if (selectedEventSphere) {
@ -72,6 +79,53 @@ function PointsCreator() {
} }
}; };
useEffect(() => {
const canvasElement = gl.domElement;
let drag = false;
let isMouseDown = false;
const onMouseDown = () => {
isMouseDown = true;
drag = false;
};
const onMouseUp = () => {
if (selectedEventSphere && !drag) {
raycaster.setFromCamera(pointer, camera);
const intersects = raycaster
.intersectObjects(scene.children, true)
.filter(
(intersect) =>
intersect.object.name === ('Event-Sphere')
);
if (intersects.length === 0) {
clearSelectedEventSphere();
setTransformMode(null);
}
}
}
const onMouseMove = () => {
if (isMouseDown) {
drag = true;
}
};
if (subModule === 'mechanics') {
canvasElement.addEventListener("mousedown", onMouseDown);
canvasElement.addEventListener("mouseup", onMouseUp);
canvasElement.addEventListener("mousemove", onMouseMove);
}
return () => {
canvasElement.removeEventListener("mousedown", onMouseDown);
canvasElement.removeEventListener("mouseup", onMouseUp);
canvasElement.removeEventListener("mousemove", onMouseMove);
};
}, [gl, subModule, selectedEventSphere]);
return ( return (
<> <>
{activeModule === "simulation" && ( {activeModule === "simulation" && (
@ -92,10 +146,6 @@ function PointsCreator() {
sphereRefs.current[point.uuid] sphereRefs.current[point.uuid]
); );
}} }}
onPointerMissed={() => {
// clearSelectedEventSphere();
setTransformMode(null);
}}
key={`${i}-${j}`} key={`${i}-${j}`}
position={new THREE.Vector3(...point.position)} position={new THREE.Vector3(...point.position)}
// rotation={new THREE.Euler(...point.rotation)} // rotation={new THREE.Euler(...point.rotation)}
@ -120,10 +170,6 @@ function PointsCreator() {
sphereRefs.current[event.point.uuid] sphereRefs.current[event.point.uuid]
); );
}} }}
onPointerMissed={() => {
// clearSelectedEventSphere();
setTransformMode(null);
}}
position={new THREE.Vector3(...event.point.position)} position={new THREE.Vector3(...event.point.position)}
// rotation={new THREE.Euler(...event.point.rotation)} // rotation={new THREE.Euler(...event.point.rotation)}
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }} userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
@ -146,10 +192,6 @@ function PointsCreator() {
sphereRefs.current[event.point.uuid] sphereRefs.current[event.point.uuid]
); );
}} }}
onPointerMissed={() => {
// clearSelectedEventSphere();
setTransformMode(null);
}}
position={new THREE.Vector3(...event.point.position)} position={new THREE.Vector3(...event.point.position)}
// rotation={new THREE.Euler(...event.point.rotation)} // rotation={new THREE.Euler(...event.point.rotation)}
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }} userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
@ -172,10 +214,6 @@ function PointsCreator() {
sphereRefs.current[event.point.uuid] sphereRefs.current[event.point.uuid]
); );
}} }}
onPointerMissed={() => {
// clearSelectedEventSphere();
setTransformMode(null);
}}
position={new THREE.Vector3(...event.point.position)} position={new THREE.Vector3(...event.point.position)}
// rotation={new THREE.Euler(...event.point.rotation)} // rotation={new THREE.Euler(...event.point.rotation)}
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }} userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}

View File

@ -4,7 +4,7 @@ import startEnd from "../../../../assets/gltf-glb/arrow_red.glb";
import * as THREE from "three"; import * as THREE from "three";
import { useGLTF } from '@react-three/drei'; import { useGLTF } from '@react-three/drei';
import { useFrame, useThree } from '@react-three/fiber'; import { useFrame, useThree } from '@react-three/fiber';
import { useSelectedEventSphere } from '../../../../store/simulation/useSimulationStore'; import { useSelectedEventSphere, useIsDragging, useIsRotating } from '../../../../store/simulation/useSimulationStore';
import { useVehicleStore } from '../../../../store/simulation/useVehicleStore'; import { useVehicleStore } from '../../../../store/simulation/useVehicleStore';
import * as Types from "../../../../types/world/worldTypes"; import * as Types from "../../../../types/world/worldTypes";
const VehicleUI = () => { const VehicleUI = () => {
@ -19,8 +19,8 @@ const VehicleUI = () => {
const [endPosition, setEndPosition] = useState<[number, number, number]>([0, 0, 0]); const [endPosition, setEndPosition] = useState<[number, number, number]>([0, 0, 0]);
const [startRotation, setStartRotation] = useState<[number, number, number]>([0, 0, 0]); const [startRotation, setStartRotation] = useState<[number, number, number]>([0, 0, 0]);
const [endRotation, setEndRotation] = useState<[number, number, number]>([0, 0, 0]); const [endRotation, setEndRotation] = useState<[number, number, number]>([0, 0, 0]);
const [isDragging, setIsDragging] = useState<"start" | "end" | null>(null); const { isDragging, setIsDragging } = useIsDragging();
const [isRotating, setIsRotating] = useState<"start" | "end" | null>(null); const { isRotating, setIsRotating } = useIsRotating();
const { raycaster } = useThree(); const { raycaster } = useThree();
const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0)); const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0));
const state: Types.ThreeState = useThree(); const state: Types.ThreeState = useThree();
@ -46,13 +46,13 @@ const VehicleUI = () => {
pickUpPoint.rotation.y, pickUpPoint.rotation.y,
pickUpPoint.rotation.z pickUpPoint.rotation.z
); );
pickupPosition.y = 0; pickupPosition.y = 0;
setStartPosition([pickupPosition.x, 0, pickupPosition.z]); setStartPosition([pickupPosition.x, 0, pickupPosition.z]);
setStartRotation([pickupRotation.x, pickupRotation.y, pickupRotation.z]); setStartRotation([pickupRotation.x, pickupRotation.y, pickupRotation.z]);
} else { } else {
const defaultLocal = new THREE.Vector3(0, 0, 1.5); const defaultLocal = new THREE.Vector3(0, 0, 1.5);
const defaultWorld = selectedEventSphere.localToWorld(defaultLocal); const defaultWorld = selectedEventSphere.localToWorld(defaultLocal);
defaultWorld.y = 0; defaultWorld.y = 0;
setStartPosition([defaultWorld.x, 0, defaultWorld.z]); setStartPosition([defaultWorld.x, 0, defaultWorld.z]);
setStartRotation([0, 0, 0]); setStartRotation([0, 0, 0]);
} }

View File

@ -114,4 +114,36 @@ export const useSelectedAction = create<SelectedActionState>()(
}); });
}, },
})) }))
);
interface IsDraggingState {
isDragging: "start" | "end" | null;
setIsDragging: (state: "start" | "end" | null) => void;
}
export const useIsDragging = create<IsDraggingState>()(
immer((set) => ({
isDragging: null,
setIsDragging: (state) => {
set((s) => {
s.isDragging = state;
});
},
}))
);
interface IsRotatingState {
isRotating: "start" | "end" | null;
setIsRotating: (state: "start" | "end" | null) => void;
}
export const useIsRotating = create<IsRotatingState>()(
immer((set) => ({
isRotating: null,
setIsRotating: (state) => {
set((s) => {
s.isRotating = state;
});
},
}))
); );