diff --git a/app/src/modules/simulation/events/points/creator/pointsCreator.tsx b/app/src/modules/simulation/events/points/creator/pointsCreator.tsx index 36ec89a..e178a81 100644 --- a/app/src/modules/simulation/events/points/creator/pointsCreator.tsx +++ b/app/src/modules/simulation/events/points/creator/pointsCreator.tsx @@ -1,22 +1,29 @@ import React, { useEffect, useRef, useState } from "react"; import * as THREE from "three"; import { useEventsStore } from "../../../../../store/simulation/useEventsStore"; -import useModuleStore from "../../../../../store/useModuleStore"; +import useModuleStore, { useSubModuleStore } from "../../../../../store/useModuleStore"; import { TransformControls } from "@react-three/drei"; import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys"; import { useSelectedEventSphere, useSelectedEventData, + useIsDragging, + useIsRotating, } from "../../../../../store/simulation/useSimulationStore"; +import { useThree } from "@react-three/fiber"; function PointsCreator() { + const { gl, raycaster, scene, pointer, camera } = useThree(); + const { subModule } = useSubModuleStore(); const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore(); const { activeModule } = useModuleStore(); const transformRef = useRef(null); const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null); const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({}); const { selectedEventSphere, setSelectedEventSphere, clearSelectedEventSphere, } = useSelectedEventSphere(); - const { selectedEventData, setSelectedEventData, clearSelectedEventData } = useSelectedEventData(); + const { setSelectedEventData, clearSelectedEventData } = useSelectedEventData(); + const { isDragging } = useIsDragging(); + const { isRotating } = useIsRotating(); useEffect(() => { 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 ( <> {activeModule === "simulation" && ( @@ -92,10 +146,6 @@ function PointsCreator() { sphereRefs.current[point.uuid] ); }} - onPointerMissed={() => { - // clearSelectedEventSphere(); - setTransformMode(null); - }} key={`${i}-${j}`} position={new THREE.Vector3(...point.position)} // rotation={new THREE.Euler(...point.rotation)} @@ -120,10 +170,6 @@ function PointsCreator() { sphereRefs.current[event.point.uuid] ); }} - onPointerMissed={() => { - // clearSelectedEventSphere(); - setTransformMode(null); - }} position={new THREE.Vector3(...event.point.position)} // rotation={new THREE.Euler(...event.point.rotation)} userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }} @@ -146,10 +192,6 @@ function PointsCreator() { sphereRefs.current[event.point.uuid] ); }} - onPointerMissed={() => { - // clearSelectedEventSphere(); - setTransformMode(null); - }} position={new THREE.Vector3(...event.point.position)} // rotation={new THREE.Euler(...event.point.rotation)} userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }} @@ -172,10 +214,6 @@ function PointsCreator() { sphereRefs.current[event.point.uuid] ); }} - onPointerMissed={() => { - // clearSelectedEventSphere(); - setTransformMode(null); - }} position={new THREE.Vector3(...event.point.position)} // rotation={new THREE.Euler(...event.point.rotation)} userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }} diff --git a/app/src/modules/simulation/ui/vehicle/vehicleUI.tsx b/app/src/modules/simulation/ui/vehicle/vehicleUI.tsx index 5dec724..43ba833 100644 --- a/app/src/modules/simulation/ui/vehicle/vehicleUI.tsx +++ b/app/src/modules/simulation/ui/vehicle/vehicleUI.tsx @@ -4,7 +4,7 @@ import startEnd from "../../../../assets/gltf-glb/arrow_red.glb"; import * as THREE from "three"; import { useGLTF } from '@react-three/drei'; 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 * as Types from "../../../../types/world/worldTypes"; const VehicleUI = () => { @@ -19,8 +19,8 @@ const VehicleUI = () => { const [endPosition, setEndPosition] = 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 [isDragging, setIsDragging] = useState<"start" | "end" | null>(null); - const [isRotating, setIsRotating] = useState<"start" | "end" | null>(null); + const { isDragging, setIsDragging } = useIsDragging(); + const { isRotating, setIsRotating } = useIsRotating(); const { raycaster } = useThree(); const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0)); const state: Types.ThreeState = useThree(); @@ -46,13 +46,13 @@ const VehicleUI = () => { pickUpPoint.rotation.y, pickUpPoint.rotation.z ); - pickupPosition.y = 0; + pickupPosition.y = 0; setStartPosition([pickupPosition.x, 0, pickupPosition.z]); setStartRotation([pickupRotation.x, pickupRotation.y, pickupRotation.z]); } else { const defaultLocal = new THREE.Vector3(0, 0, 1.5); const defaultWorld = selectedEventSphere.localToWorld(defaultLocal); - defaultWorld.y = 0; + defaultWorld.y = 0; setStartPosition([defaultWorld.x, 0, defaultWorld.z]); setStartRotation([0, 0, 0]); } diff --git a/app/src/store/simulation/useSimulationStore.ts b/app/src/store/simulation/useSimulationStore.ts index 5085688..6e4321f 100644 --- a/app/src/store/simulation/useSimulationStore.ts +++ b/app/src/store/simulation/useSimulationStore.ts @@ -114,4 +114,36 @@ export const useSelectedAction = create()( }); }, })) +); + +interface IsDraggingState { + isDragging: "start" | "end" | null; + setIsDragging: (state: "start" | "end" | null) => void; +} + +export const useIsDragging = create()( + 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()( + immer((set) => ({ + isRotating: null, + setIsRotating: (state) => { + set((s) => { + s.isRotating = state; + }); + }, + })) ); \ No newline at end of file