diff --git a/app/src/modules/simulation/roboticArm/instances/animator/roboticArmAnimator.tsx b/app/src/modules/simulation/roboticArm/instances/animator/roboticArmAnimator.tsx index 34f191b..d96182b 100644 --- a/app/src/modules/simulation/roboticArm/instances/animator/roboticArmAnimator.tsx +++ b/app/src/modules/simulation/roboticArm/instances/animator/roboticArmAnimator.tsx @@ -76,6 +76,27 @@ function RoboticArmAnimator({ } return points; } + + + function generateRingPointsWithDegrees(radius: number, segments: number) { + const points: { position: [number, number, number]; degree: number }[] = []; + for (let i = 0; i < segments; i++) { + const angleRadians = (i / segments) * Math.PI * 2; + const x = Math.cos(angleRadians) * radius; + const z = Math.sin(angleRadians) * radius; + const degree = (angleRadians * 180) / Math.PI; // Convert radians to degrees + points.push({ + position: [x, 1.5, z], + degree, + }); + } + return points; + } + useEffect(() => { + const points = generateRingPointsWithDegrees(CIRCLE_RADIUS, 64); + + }, [armBot.position]); + // Function for find nearest Circlepoints Index const findNearestIndex = (nearestPoint: [number, number, number], points: [number, number, number][], epsilon = 1e-6) => { for (let i = 0; i < points.length; i++) { diff --git a/app/src/modules/simulation/roboticArm/roboticArm.tsx b/app/src/modules/simulation/roboticArm/roboticArm.tsx index a609ad5..e112884 100644 --- a/app/src/modules/simulation/roboticArm/roboticArm.tsx +++ b/app/src/modules/simulation/roboticArm/roboticArm.tsx @@ -3,11 +3,13 @@ import RoboticArmInstances from "./instances/roboticArmInstances"; import { useArmBotStore } from "../../../store/simulation/useArmBotStore"; import { useSelectedEventData, useSelectedEventSphere } from "../../../store/simulation/useSimulationStore"; import ArmBotUI from "../ui/arm/armBotUI"; +import { usePlayButtonStore } from "../../../store/usePlayButtonStore"; function RoboticArm() { const { armBots } = useArmBotStore(); const { selectedEventSphere } = useSelectedEventSphere(); const { selectedEventData } = useSelectedEventData(); + const { isPlaying } = usePlayButtonStore(); useEffect(() => { // console.log('armBots: ', armBots); @@ -15,10 +17,8 @@ function RoboticArm() { return ( <> - - - {selectedEventSphere && selectedEventData?.data.type === "roboticArm" && + {selectedEventSphere && selectedEventData?.data.type === "roboticArm" && !isPlaying && < ArmBotUI /> } diff --git a/app/src/modules/simulation/ui/arm/useDraggableGLTF.ts b/app/src/modules/simulation/ui/arm/useDraggableGLTF.ts index dae90ee..b819852 100644 --- a/app/src/modules/simulation/ui/arm/useDraggableGLTF.ts +++ b/app/src/modules/simulation/ui/arm/useDraggableGLTF.ts @@ -121,31 +121,59 @@ export default function useDraggableGLTF(onUpdate: OnUpdateCallback) { // CONSTRAIN MOVEMENT HERE: const centerX = selectedArmBot.position[0]; const centerZ = selectedArmBot.position[2]; - const minDistance = 1.2; // 1.4 radius - const maxDistance = 2; // 2 radius + const minDistance = 1.2; + const maxDistance = 2; - const deltaX = targetPosition.x - centerX; - const deltaZ = targetPosition.z - centerZ; - const distance = Math.sqrt(deltaX * deltaX + deltaZ * deltaZ); + let deltaX = targetPosition.x - centerX; + let deltaZ = targetPosition.z - centerZ; - if (distance < minDistance || distance > maxDistance) { - const angle = Math.atan2(deltaZ, deltaX); - const clampedDistance = Math.min( - Math.max(distance, minDistance), - maxDistance - ); + // Calculate angle in radians + let angle = Math.atan2(deltaZ, deltaX); // [-PI, PI] - targetPosition.x = centerX + Math.cos(angle) * clampedDistance; - targetPosition.z = centerZ + Math.sin(angle) * clampedDistance; + // Convert angle to degrees + let angleDeg = (angle * 180) / Math.PI; // [-180, 180] + + // Normalize to [0, 360] + if (angleDeg < 0) { + angleDeg += 360; } + + // Allow only angles between 90° and 270° + if (angleDeg < 95 || angleDeg > 270) { + // Clamp to nearest boundary (90° or 270°) + const distanceTo90 = Math.abs(angleDeg - 95); + const distanceTo270 = Math.abs(angleDeg - 270); + + if (distanceTo90 < distanceTo270) { + angleDeg = 95; + } else { + angleDeg = 270; + } + + // Update angle in radians + angle = (angleDeg * Math.PI) / 180; + } + + // Clamp distance + let distance = Math.sqrt(deltaX * deltaX + deltaZ * deltaZ); + const clampedDistance = Math.min( + Math.max(distance, minDistance), + maxDistance + ); + + // Set final target position + targetPosition.x = centerX + Math.cos(angle) * clampedDistance; + targetPosition.z = centerZ + Math.sin(angle) * clampedDistance; + + // Clamp Y axis if needed targetPosition.y = Math.min(Math.max(targetPosition.y, 0.6), 1.9); - // Convert world position to local if object is nested inside a parent + + // Convert to local if parent exists if (parent) { parent.worldToLocal(targetPosition); } - // Update object position - + // Update the object position activeObjRef.current.position.copy(targetPosition); } };