diff --git a/app/src/modules/simulation/human/instances/animator/humanAnimator.tsx b/app/src/modules/simulation/human/instances/animator/humanAnimator.tsx index bb944f6..0c06826 100644 --- a/app/src/modules/simulation/human/instances/animator/humanAnimator.tsx +++ b/app/src/modules/simulation/human/instances/animator/humanAnimator.tsx @@ -34,6 +34,9 @@ function HumanAnimator({ path, handleCallBack, currentPhase, human, reset, start if (currentPhase === 'init-pickup' && path.length > 0) { setCurrentPath(path); setObjectRotation(human.point.action.pickUpPoint?.rotation ?? null) + } else if (currentPhase === 'init_assembly' && path.length > 0) { + setObjectRotation(human.point.action?.assemblyPoint?.rotation ?? null) + setCurrentPath(path); } else if (currentPhase === 'pickup-drop' && path.length > 0) { setObjectRotation(human.point.action?.dropPoint?.rotation ?? null) setCurrentPath(path); diff --git a/app/src/modules/simulation/human/instances/instance/humanInstance.tsx b/app/src/modules/simulation/human/instances/instance/humanInstance.tsx index 853d83d..c1d18ab 100644 --- a/app/src/modules/simulation/human/instances/instance/humanInstance.tsx +++ b/app/src/modules/simulation/human/instances/instance/humanInstance.tsx @@ -123,8 +123,17 @@ function HumanInstance({ human }: { human: HumanStatus }) { if (!human.point.action.assemblyPoint || human.point.action.actionType === 'worker') return; if (!human.isActive && human.state === 'idle' && currentPhase === 'init') { + const toPickupPath = computePath( + new THREE.Vector3(human?.position[0], human?.position[1], human?.position[2]), + new THREE.Vector3( + human?.point?.action?.assemblyPoint?.position?.[0] ?? 0, + human?.point?.action?.assemblyPoint?.position?.[1] ?? 0, + human?.point?.action?.assemblyPoint?.position?.[2] ?? 0 + ) + ); + setPath(toPickupPath); setHumanState(human.modelUuid, 'idle'); - setCurrentPhase('waiting'); + setCurrentPhase('init_assembly'); setHumanActive(human.modelUuid, false); setCurrentAnimation(human.modelUuid, 'idle', true, true, true); humanStatus(human.modelUuid, 'Human is waiting for material in assembly'); @@ -293,6 +302,13 @@ function HumanInstance({ human }: { human: HumanStatus }) { setCurrentAnimation(human.modelUuid, 'idle', true, true, true); humanStatus(human.modelUuid, 'Reached pickup point, waiting for material'); setPath([]); + } if (currentPhase === 'init_assembly') { + setCurrentPhase('waiting'); + setHumanState(human.modelUuid, 'idle'); + setHumanActive(human.modelUuid, false); + setCurrentAnimation(human.modelUuid, 'idle', true, true, true); + humanStatus(human.modelUuid, 'Reached assembly point, waiting for material'); + setPath([]); } else if (currentPhase === 'pickup-drop') { setCurrentPhase('dropping'); setHumanState(human.modelUuid, 'idle'); diff --git a/app/src/modules/simulation/human/instances/instance/humanUi.tsx b/app/src/modules/simulation/human/instances/instance/humanUi.tsx index da53336..35bd913 100644 --- a/app/src/modules/simulation/human/instances/instance/humanUi.tsx +++ b/app/src/modules/simulation/human/instances/instance/humanUi.tsx @@ -30,6 +30,7 @@ function HumanUi() { const { updateEvent } = productStore(); const [startPosition, setStartPosition] = useState<[number, number, number]>([0, 1, 0]); const [endPosition, setEndPosition] = useState<[number, number, number]>([0, 1, 0]); + const [assemblyPosition, setAssemblyPosition] = useState<[number, number, number]>([0, 1, 0]); const [startRotation, setStartRotation] = useState<[number, number, number]>([0, Math.PI, 0]); const [assemblyRotation, setAssemblyRotation] = useState<[number, number, number]>([0, 0, 0]); const [endRotation, setEndRotation] = useState<[number, number, number]>([0, 0, 0]); @@ -88,40 +89,44 @@ function HumanUi() { const action = selectedHuman.point.action; - if (action.pickUpPoint?.position && outerGroup.current) { - const worldPos = new Vector3(...action.pickUpPoint.position); - const localPosition = outerGroup.current.worldToLocal(worldPos.clone()); - setStartPosition([localPosition.x, 1, localPosition.z]); - setStartRotation(action.pickUpPoint.rotation || [0, 0, 0]); + if (isAssembly) { + if (action.assemblyPoint?.position && outerGroup.current) { + const worldPos = new Vector3(...action.assemblyPoint.position); + const localPosition = outerGroup.current.worldToLocal(worldPos.clone()); + setAssemblyPosition([localPosition.x, 1, localPosition.z]); + setAssemblyRotation(action.assemblyPoint.rotation || [0, 0, 0]); + } else { + setAssemblyPosition([0, 1, 0]); + setAssemblyRotation([0, 0, 0]); + } } else { - setStartPosition([0, 1, 0]); - setStartRotation([0, Math.PI, 0]); - } + if (action.pickUpPoint?.position && outerGroup.current) { + const worldPos = new Vector3(...action.pickUpPoint.position); + const localPosition = outerGroup.current.worldToLocal(worldPos.clone()); + setStartPosition([localPosition.x, 1, localPosition.z]); + setStartRotation(action.pickUpPoint.rotation || [0, 0, 0]); + } else { + setStartPosition([0, 1, 0]); + setStartRotation([0, Math.PI, 0]); + } - if (action.dropPoint?.position && outerGroup.current) { - const worldPos = new Vector3(...action.dropPoint.position); - const localPosition = outerGroup.current.worldToLocal(worldPos.clone()); - setEndPosition([localPosition.x, 1, localPosition.z]); - setEndRotation(action.dropPoint.rotation || [0, Math.PI, 0]); - } else { - setEndPosition([0, 1, 0]); - setEndRotation([0, 0, 0]); + if (action.dropPoint?.position && outerGroup.current) { + const worldPos = new Vector3(...action.dropPoint.position); + const localPosition = outerGroup.current.worldToLocal(worldPos.clone()); + setEndPosition([localPosition.x, 1, localPosition.z]); + setEndRotation(action.dropPoint.rotation || [0, Math.PI, 0]); + } else { + setEndPosition([0, 1, 0]); + setEndRotation([0, 0, 0]); + } } - - if (action.assemblyPoint?.rotation) { - setAssemblyRotation(action.assemblyPoint.rotation); - } else { - setAssemblyRotation([0, 0, 0]); - } - }, [selectedEventSphere, outerGroup.current, selectedAction, humans]); const handlePointerDown = ( e: any, - state: "start" | "end", - rotation: "start" | "end" + state: "start" | "end" | "assembly", + rotation: "start" | "end" | "assembly" ) => { - if (isAssembly) return; e.stopPropagation(); const intersection = new Vector3(); const pointer = new Vector2((e.clientX / window.innerWidth) * 2 - 1, -(e.clientY / window.innerHeight) * 2 + 1); @@ -144,7 +149,10 @@ function HumanUi() { if (outerGroup.current) { localPoint = outerGroup.current.worldToLocal(intersection.clone()); } - const marker = state === "start" ? startMarker.current : endMarker.current; + const marker = + state === "start" ? startMarker.current : + state === "end" ? endMarker.current : + assemblyMarker.current; if (marker && localPoint) { const markerPos = new Vector3().copy(marker.position); dragOffset.current.copy(markerPos.sub(localPoint)); @@ -154,7 +162,6 @@ function HumanUi() { if (controls) (controls as any).enabled = false; }; - const handlePointerUp = () => { (controls as any).enabled = true; setIsDragging(null); @@ -165,14 +172,18 @@ function HumanUi() { const selectedHuman = getHumanById(selectedEventSphere.userData.modelUuid); if (!selectedHuman || !outerGroup.current) return; - const isAssembly = selectedHuman.point?.action?.actionType === 'assembly'; - let updatedAction; if (isAssembly) { + if (!assemblyMarker.current) return; + + const worldPosAssembly = new Vector3(...assemblyPosition); + const globalAssemblyPosition = outerGroup.current.localToWorld(worldPosAssembly.clone()); + updatedAction = { ...selectedHuman.point.action, assemblyPoint: { + position: [globalAssemblyPosition.x, globalAssemblyPosition.y, globalAssemblyPosition.z] as [number, number, number], rotation: assemblyRotation }, }; @@ -221,7 +232,7 @@ function HumanUi() { }; useFrame(() => { - if (isAssembly || !isDragging || !plane.current || !raycaster || !outerGroup.current) return; + if (!isDragging || !plane.current || !raycaster || !outerGroup.current) return; const intersectPoint = new Vector3(); const intersects = raycaster.ray.intersectPlane(plane.current, intersectPoint); if (!intersects) return; @@ -232,6 +243,8 @@ function HumanUi() { setStartPosition([localPoint.x, 1, localPoint.z]); } else if (isDragging === "end") { setEndPosition([localPoint.x, 1, localPoint.z]); + } else if (isDragging === "assembly") { + setAssemblyPosition([localPoint.x, 1, localPoint.z]); } }); @@ -240,28 +253,34 @@ function HumanUi() { const currentPointerX = state.pointer.x; const deltaX = currentPointerX - prevMousePos.current.x; prevMousePos.current.x = currentPointerX; - const marker = isRotating === "start" ? isAssembly ? assemblyMarker.current : startMarker.current : isAssembly ? assemblyMarker.current : endMarker.current; + + const marker = + isRotating === "start" ? startMarker.current : + isRotating === "end" ? endMarker.current : + assemblyMarker.current; + if (marker) { const rotationSpeed = 10; marker.rotation.y += deltaX * rotationSpeed; - if (isAssembly && isRotating === "start") { - setAssemblyRotation([ - marker.rotation.x, - marker.rotation.y, - marker.rotation.z, - ]); - } else if (isRotating === "start") { + + if (isRotating === "start") { setStartRotation([ marker.rotation.x, marker.rotation.y, marker.rotation.z, ]); - } else { + } else if (isRotating === "end") { setEndRotation([ marker.rotation.x, marker.rotation.y, marker.rotation.z, ]); + } else { + setAssemblyRotation([ + marker.rotation.x, + marker.rotation.y, + marker.rotation.z, + ]); } } }); @@ -281,7 +300,7 @@ function HumanUi() { return () => { window.removeEventListener("pointerup", handleGlobalPointerUp); }; - }, [isDragging, isRotating, startPosition, startRotation, endPosition, endRotation, assemblyRotation]); + }, [isDragging, isRotating, startPosition, startRotation, endPosition, endRotation, assemblyPosition, assemblyRotation]); return ( <> @@ -295,16 +314,13 @@ function HumanUi() { { if (e.object.parent.name === "handle") { - e.stopPropagation(); - const normalizedX = (e.clientX / window.innerWidth) * 2 - 1; - prevMousePos.current.x = normalizedX; - setIsRotating("start"); - setIsDragging(null); - if (controls) (controls as any).enabled = false; + handlePointerDown(e, "assembly", "assembly"); + } else { + handlePointerDown(e, "assembly", "assembly"); } }} onPointerMissed={() => { @@ -322,8 +338,11 @@ function HumanUi() { position={startPosition} rotation={startRotation} onPointerDown={(e: any) => { - e.stopPropagation(); - handlePointerDown(e, "start", "start"); + if (e.object.parent.name === "handle") { + handlePointerDown(e, "start", "start"); + } else { + handlePointerDown(e, "start", "start"); + } }} onPointerMissed={() => { setIsDragging(null); @@ -339,8 +358,11 @@ function HumanUi() { position={endPosition} rotation={endRotation} onPointerDown={(e: any) => { - e.stopPropagation(); - handlePointerDown(e, "end", "end"); + if (e.object.parent.name === "handle") { + handlePointerDown(e, "end", "end"); + } else { + handlePointerDown(e, "end", "end"); + } }} onPointerMissed={() => { setIsDragging(null); @@ -356,4 +378,4 @@ function HumanUi() { ); } -export default HumanUi \ No newline at end of file +export default HumanUi; \ No newline at end of file diff --git a/app/src/store/simulation/useSimulationStore.ts b/app/src/store/simulation/useSimulationStore.ts index 2248491..2220afd 100644 --- a/app/src/store/simulation/useSimulationStore.ts +++ b/app/src/store/simulation/useSimulationStore.ts @@ -203,8 +203,8 @@ export const useSelectedAnimation = create()( ); interface IsDraggingState { - isDragging: "start" | "end" | null; - setIsDragging: (state: "start" | "end" | null) => void; + isDragging: "start" | "end" | "assembly" | null; + setIsDragging: (state: "start" | "end" | "assembly" | null) => void; } export const useIsDragging = create()( @@ -219,8 +219,8 @@ export const useIsDragging = create()( ); interface IsRotatingState { - isRotating: "start" | "end" | null; - setIsRotating: (state: "start" | "end" | null) => void; + isRotating: "start" | "end" | "assembly" | null; + setIsRotating: (state: "start" | "end" | "assembly" | null) => void; } export const useIsRotating = create()( diff --git a/app/src/types/simulationTypes.d.ts b/app/src/types/simulationTypes.d.ts index 5468b2a..12ca294 100644 --- a/app/src/types/simulationTypes.d.ts +++ b/app/src/types/simulationTypes.d.ts @@ -75,7 +75,7 @@ interface HumanAction { actionType: "worker" | "assembly"; processTime?: number; swapMaterial?: string; - assemblyPoint?: { rotation: [number, number, number] | null; } + assemblyPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; } pickUpPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; } dropPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; } loadCapacity: number; @@ -306,4 +306,4 @@ type IK = { maxDistance?: number; maxheight?: number; minheight?: number; -} ; +};