diff --git a/app/src/modules/builder/point/point.tsx b/app/src/modules/builder/point/point.tsx index 8160a9b..7636e16 100644 --- a/app/src/modules/builder/point/point.tsx +++ b/app/src/modules/builder/point/point.tsx @@ -2,11 +2,19 @@ import * as THREE from 'three'; import * as Constants from '../../../types/world/worldConstants'; import { useRef, useState, useEffect, useMemo } from 'react'; import { useToolMode } from '../../../store/builder/store'; +import { DragControls } from '@react-three/drei'; +import { useAisleStore } from '../../../store/builder/useAisleStore'; +import { useThree } from '@react-three/fiber'; +import { useBuilderStore } from '../../../store/builder/useBuilderStore'; function Point({ point, userData }: { readonly point: Point, readonly userData: any }) { const materialRef = useRef(null); + const { raycaster, camera, scene, pointer } = useThree(); + const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []); const [isHovered, setIsHovered] = useState(false); const { toolMode } = useToolMode(); + const { setPosition } = useAisleStore(); + const { hoveredPoint, setHoveredPoint } = useBuilderStore(); const boxScale: [number, number, number] = Constants.pointConfig.boxScale; const defaultInnerColor = Constants.pointConfig.defaultInnerColor; @@ -29,48 +37,91 @@ function Point({ point, userData }: { readonly point: Point, readonly userData: uInnerColor: { value: new THREE.Color(defaultInnerColor) }, }), [borderColor, defaultInnerColor]); + const handleDrag = (point: Point) => { + if (toolMode === 'move' && isHovered) { + raycaster.setFromCamera(pointer, camera); + const intersectionPoint = new THREE.Vector3(); + const position = raycaster.ray.intersectPlane(plane, intersectionPoint); + if (userData.pointType === 'Aisle') { + if (position) { + setPosition(point.uuid, [position.x, position.y, position.z]); + } + } + } + } + + const handleDragEnd = (point: Point) => { + console.log('point: ', point); + } + + useEffect(() => { + if (hoveredPoint && hoveredPoint.uuid !== point.uuid) { + setIsHovered(false); + } + }, [hoveredPoint]) + if (!point) { return null; } return ( - setIsHovered(true)} - onPointerOut={() => setIsHovered(false)} - userData={userData} + { handleDrag(point) }} + onDragEnd={() => { handleDragEnd(point) }} > - - { + if (!hoveredPoint) { + setHoveredPoint(point); + setIsHovered(true) } - `} - fragmentShader={` - varying vec2 vUv; - uniform vec3 uColor; - uniform vec3 uInnerColor; - - void main() { - // Define the size of the white square as a proportion of the face - float borderThickness = 0.2; // Adjust this value for border thickness - if (vUv.x > borderThickness && vUv.x < 1.0 - borderThickness && - vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) { - gl_FragColor = vec4(uInnerColor, 1.0); // Inner square - } else { - gl_FragColor = vec4(uColor, 1.0); // Border - } + }} + onPointerOut={() => { + if (hoveredPoint && hoveredPoint.uuid === point.uuid) { + setHoveredPoint(null); } - `} - /> - + setIsHovered(false) + }} + userData={userData} + > + + borderThickness && vUv.x < 1.0 - borderThickness && vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) { + gl_FragColor = vec4(uInnerColor, 1.0); // Inner square + } else { + gl_FragColor = vec4(uColor, 1.0); // Border + } + } + ` + } + /> + + ); } diff --git a/app/src/store/builder/useAisleStore.ts b/app/src/store/builder/useAisleStore.ts index 9d346c8..e93b2c2 100644 --- a/app/src/store/builder/useAisleStore.ts +++ b/app/src/store/builder/useAisleStore.ts @@ -63,7 +63,6 @@ export const useAisleStore = create()( const point = aisle.points.find(p => p.uuid === pointUuid); if (point) { point.position = position; - break; } } }), @@ -73,7 +72,6 @@ export const useAisleStore = create()( const point = aisle.points.find(p => p.uuid === pointUuid); if (point) { point.layer = layer; - break; } } }), diff --git a/app/src/store/builder/useBuilderStore.ts b/app/src/store/builder/useBuilderStore.ts index e551f9f..cbf71dd 100644 --- a/app/src/store/builder/useBuilderStore.ts +++ b/app/src/store/builder/useBuilderStore.ts @@ -3,6 +3,9 @@ import { immer } from 'zustand/middleware/immer'; interface BuilderState { // Common properties + + hoveredPoint: Point | null; + aisleType: AisleTypes; aisleWidth: number; aisleColor: AisleColors; @@ -18,6 +21,9 @@ interface BuilderState { aisleLength: number; // Setters for common properties + + setHoveredPoint: (point: Point | null) => void; + setAisleType: (type: AisleTypes) => void; setAisleWidth: (width: number) => void; setAisleColor: (color: AisleColors) => void; @@ -42,6 +48,9 @@ interface BuilderState { export const useBuilderStore = create()( immer((set) => ({ // Default values + + hoveredPoint: null, + aisleType: 'solid-aisle', aisleWidth: 0.1, aisleColor: 'yellow', @@ -51,6 +60,13 @@ export const useBuilderStore = create()( aisleLength: 0.6, // Individual setters + + setHoveredPoint: (point: Point | null) => { + set((state) => { + state.hoveredPoint = point; + }); + }, + setAisleType: (type) => { set((state) => { state.aisleType = type;