playSpeed,reset,exit added and armbot movemets added

This commit is contained in:
Gomathi 2025-04-29 19:01:06 +05:30
parent 32a44adb7c
commit fe57e6c873
6 changed files with 576 additions and 163 deletions

View File

@ -1,68 +1,117 @@
import React, { useEffect, useMemo, useRef, useState } from 'react'
import { useArmBotStore } from '../../../../../store/simulation/useArmBotStore';
import { useFrame, useThree } from '@react-three/fiber';
import * as THREE from "three"
import { usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
import React, { useEffect, useRef, useState } from 'react';
import { useFrame } from '@react-three/fiber';
import * as THREE from 'three';
import {
useAnimationPlaySpeed,
usePauseButtonStore,
usePlayButtonStore,
useResetButtonStore
} from '../../../../../store/usePlayButtonStore';
import { Line } from '@react-three/drei';
function RoboticArmAnimator({ armUuid, HandleCallback, currentPhase, ikSolver, targetBone, robot, logStatus, groupRef, processes, armBotCurveRef, path }: any) {
const { armBots } = useArmBotStore();
const { scene } = useThree();
const restSpeed = 0.1;
const restPosition = new THREE.Vector3(0, 1, -1.6);
const initialCurveRef = useRef<THREE.CatmullRomCurve3 | null>(null);
const initialStartPositionRef = useRef<THREE.Vector3 | null>(null);
const [initialProgress, setInitialProgress] = useState(0);
const [progress, setProgress] = useState(0);
const [needsInitialMovement, setNeedsInitialMovement] = useState(true);
const [isInitializing, setIsInitializing] = useState(true);
const { isPlaying } = usePlayButtonStore();
const statusRef = useRef("idle");
// Create a ref for initialProgress
const initialProgressRef = useRef(0);
function RoboticArmAnimator({
HandleCallback,
restPosition,
ikSolver,
targetBone,
armBot,
logStatus,
path
}: any) {
const progressRef = useRef(0);
const curveRef = useRef<THREE.Vector3[] | null>(null);
const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]);
const [curvePoints, setCurvePoints] = useState<THREE.Vector3[] | null>(null);
// Zustand stores
const { isPlaying } = usePlayButtonStore();
const { isPaused } = usePauseButtonStore();
const { isReset } = useResetButtonStore(); // optional use depending on your logic
const { speed } = useAnimationPlaySpeed();
useEffect(() => {
setCurrentPath(path)
}, [path])
useEffect(() => {
if (!isPlaying) {
setCurrentPath([])
curveRef.current = null
}
}, [isPlaying])
}, [currentPath])
useEffect(() => {
if (currentPath && currentPath.length === 3) {
const [start, mid, end] = currentPath;
const points = [
new THREE.Vector3(start[0], start[1], start[2]),
new THREE.Vector3(start[0], mid[1] + 0.5, start[2]),
new THREE.Vector3(mid[0], mid[1] + 0.5, mid[2]),
new THREE.Vector3(mid[0], end[1] + 0.5, mid[2]),
new THREE.Vector3(end[0], end[1], end[2])
];
const generatedCurve = new THREE.CatmullRomCurve3(points, false, 'centripetal', 1).getPoints(100);
// console.log('generatedCurve: ', generatedCurve);
curveRef.current = generatedCurve;
setCurvePoints(generatedCurve);
}
}, [currentPath]);
useFrame((_, delta) => {
if (!ikSolver || !currentPath || currentPath.length === 0) return;
if (ikSolver && curveRef.current && currentPath.length >= 0) {
const bone = ikSolver.mesh.skeleton.bones.find(
(b: any) => b.name === targetBone
);
if (!bone) return;
const bone = ikSolver.mesh.skeleton.bones.find(
(b: any) => b.name === targetBone
);
if (!bone) return;
if (isPlaying) {
if (!isPaused) {
const curvePoints = curveRef.current;
const speedAdjustedProgress = progressRef.current + (speed * armBot.speed);
const index = Math.floor(speedAdjustedProgress);
if (index >= curvePoints.length) {
HandleCallback();
setCurrentPath([]);
curveRef.current = null;
progressRef.current = 0;
} else {
const point = curvePoints[index];
bone.position.copy(point);
progressRef.current = speedAdjustedProgress;
}
}
} else {
logStatus(armBot.modelUuid, 'Simulation Play Exited');
// bone.position.copy(restPosition);
}
// Ensure currentPath is a valid array of 3D points, create a CatmullRomCurve3 from it
const curve = new THREE.CatmullRomCurve3(
currentPath.map(point => new THREE.Vector3(point[0], point[1], point[2]))
);
ikSolver.update();
} else if (ikSolver && !isPlaying && currentPath.length === 0) {
const bone = ikSolver.mesh.skeleton.bones.find(
(b: any) => b.name === targetBone
);
bone.position.copy(restPosition);
ikSolver.update();
};
const next = initialProgressRef.current + delta * 0.5;
if (next >= 1) {
// bone.position.copy(restPosition);
HandleCallback(); // Call the callback when the path is completed
initialProgressRef.current = 0; // Set ref to 1 when done
} else {
const point = curve.getPoint(next); // Get the interpolated point from the curve
bone.position.copy(point); // Update the bone position along the curve
initialProgressRef.current = next; // Update progress
}
ikSolver.update();
});
return (
<></>
)
<>
{/* {currentPath.length > 0 && (
<>
<Line points={currentPath} color="green" lineWidth={3} />
{currentPath.map((point, index) => (
<mesh key={index} position={point} rotation={armBot.rotation}>
<sphereGeometry args={[0.1, 16, 16]} />
<meshStandardMaterial color="red" />
</mesh>
))}
</>
)} */}
</>
);
}
export default RoboticArmAnimator;
export default RoboticArmAnimator;

View File

@ -1,42 +1,100 @@
import React, { useEffect, useRef, useState } from 'react'
import IKInstance from '../ikInstance/ikInstance';
import RoboticArmAnimator from '../animator/roboticArmAnimator';
import { usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
import { usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore';
import { useArmBotStore } from '../../../../../store/simulation/useArmBotStore';
import armModel from "../../../../../assets/gltf-glb/rigged/ik_arm_4.glb";
import { useThree } from "@react-three/fiber";
import { useFloorItems } from '../../../../../store/store';
import useModuleStore from '../../../../../store/useModuleStore';
import { Vector3 } from "three";
import * as THREE from "three";
interface Process {
triggerId: string;
startPoint?: Vector3;
endPoint?: Vector3;
speed: number;
}
function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
function RoboticArmInstance({ robot }: { robot: ArmBotStatus }) {
const { isPlaying } = usePlayButtonStore();
const [currentPhase, setCurrentPhase] = useState<(string)>("init");
const { scene } = useThree();
const targetBone = "Target";
const { activeModule } = useModuleStore();
const [path, setPath] = useState<[number, number, number][]>([]);
const [ikSolver, setIkSolver] = useState<any>(null);
const { scene } = useThree();
const restPosition = new THREE.Vector3(0, 1.75, -1.6);
const targetBone = "Target";
const groupRef = useRef<any>(null);
const pauseTimeRef = useRef<number | null>(null);
const isPausedRef = useRef<boolean>(false);
let startTime: number;
//zustand
const { addCurrentAction, setArmBotActive, setArmBotState, removeCurrentAction } = useArmBotStore();
const { floorItems } = useFloorItems();
const groupRef = useRef<any>(null);
const [processes, setProcesses] = useState<Process[]>([]);
const [armBotCurvePoints, setArmBotCurvePoints] = useState({ start: [], end: [] })
const restPosition = new THREE.Vector3(0, 1, -1.6);
let armBotCurveRef = useRef<THREE.CatmullRomCurve3 | null>(null)
const [path, setPath] = useState<[number, number, number][]>([]);
const { activeModule } = useModuleStore();
const { isPlaying } = usePlayButtonStore();
const { isReset, setReset } = useResetButtonStore();
const { isPaused } = usePauseButtonStore();
function firstFrame() {
startTime = performance.now();
step();
}
function step() {
if (isPausedRef.current) {
if (!pauseTimeRef.current) {
pauseTimeRef.current = performance.now();
}
requestAnimationFrame(() => step());
return;
}
if (pauseTimeRef.current) {
const pauseDuration = performance.now() - pauseTimeRef.current;
startTime += pauseDuration;
pauseTimeRef.current = null;
}
const elapsedTime = performance.now() - startTime;
if (elapsedTime < 1500) {
// Wait until 1500ms has passed
requestAnimationFrame(step);
return;
}
if(currentPhase==="picking"){
setArmBotActive(armBot.modelUuid, true);
setArmBotState(armBot.modelUuid, "running");
setCurrentPhase("start-to-end");
startTime=0
const startPoint = armBot.point.actions[0].process.startPoint;
const endPoint = armBot.point.actions[0].process.endPoint;
if (startPoint && endPoint) {
let curve = createCurveBetweenTwoPoints(
new THREE.Vector3(startPoint[0], startPoint[1], startPoint[2]),
new THREE.Vector3(endPoint[0], endPoint[1], endPoint[2]));
if (curve) {
logStatus(armBot.modelUuid, "picking the object");
setPath(curve.points.map(point => [point.x, point.y, point.z]))
}
}
logStatus(armBot.modelUuid, "Moving armBot from start point to end position.")
}else if(currentPhase==="dropping"){
setArmBotActive(armBot.modelUuid, true);
setArmBotState(armBot.modelUuid, "running");
setCurrentPhase("end-to-rest");
startTime=0;
const endPoint = armBot.point.actions[0].process.endPoint;
if (endPoint) {
let curve = createCurveBetweenTwoPoints(new THREE.Vector3(endPoint[0], endPoint[1], endPoint[2]), restPosition);
if (curve) {
logStatus(armBot.modelUuid, "dropping the object");
setPath(curve.points.map(point => [point.x, point.y, point.z]));
}
}
logStatus(armBot.modelUuid, "Moving armBot from end point to rest position.")
}
}
useEffect(() => {
isPausedRef.current = isPaused;
}, [isPaused]);
useEffect(() => {
let armItems = floorItems?.filter((val: any) =>
val.modeluuid === "3abf5d46-b59e-4e6b-9c02-a4634b64b82d"
val.modeluuid === armBot.modelUuid
);
// Get the first matching item
let armItem = armItems?.[0];
@ -49,13 +107,30 @@ function RoboticArmInstance({ robot }: { robot: ArmBotStatus }) {
const targetBones = ikSolver?.mesh.skeleton.bones.find(
(b: any) => b.name === targetBone
);
if (isReset) {
logStatus(armBot.modelUuid, "Simulation Play Reset Successfully")
removeCurrentAction(armBot.modelUuid)
setArmBotActive(armBot.modelUuid, true)
setArmBotState(armBot.modelUuid, "running")
setCurrentPhase("init-to-rest");
isPausedRef.current=false
pauseTimeRef.current=null
isPausedRef.current=false
startTime=0
if (targetBones) {
let curve = createCurveBetweenTwoPoints(targetBones.position, restPosition)
if (curve) {
setPath(curve.points.map(point => [point.x, point.y, point.z]));
}
}
setReset(false);
logStatus(armBot.modelUuid, "Moving armBot from initial point to rest position.")
}
if (isPlaying) {
//Moving armBot from initial point to rest position.
if (!robot?.isActive && robot?.state == "idle" && currentPhase == "init") {
setArmBotActive(robot.modelUuid, true)
setArmBotState(robot.modelUuid, "running")
if (!armBot?.isActive && armBot?.state == "idle" && currentPhase == "init") {
setArmBotActive(armBot.modelUuid, true)
setArmBotState(armBot.modelUuid, "running")
setCurrentPhase("init-to-rest");
if (targetBones) {
let curve = createCurveBetweenTwoPoints(targetBones.position, restPosition)
@ -63,21 +138,22 @@ function RoboticArmInstance({ robot }: { robot: ArmBotStatus }) {
setPath(curve.points.map(point => [point.x, point.y, point.z]));
}
}
logStatus(robot.modelUuid, "Moving armBot from initial point to rest position.")
logStatus(armBot.modelUuid, "Moving armBot from initial point to rest position.")
}
//Waiting for trigger.
else if (robot && !robot.isActive && robot.state === "idle" && currentPhase === "rest" && !robot.currentAction) {
logStatus(robot.modelUuid, "Waiting to trigger CurrentAction")
setTimeout(() => {
addCurrentAction(robot.modelUuid, 'action-003');
else if (armBot && !armBot.isActive && armBot.state === "idle" && currentPhase === "rest" && !armBot.currentAction) {
logStatus(armBot.modelUuid, "Waiting to trigger CurrentAction")
const timeoutId = setTimeout(() => {
addCurrentAction(armBot.modelUuid, 'action-003');
}, 3000);
return () => clearTimeout(timeoutId);
}
else if (robot && !robot.isActive && robot.state === "idle" && currentPhase === "rest" && robot.currentAction) {
if (robot.currentAction) {
setArmBotActive(robot.modelUuid, true);
setArmBotState(robot.modelUuid, "running");
else if (armBot && !armBot.isActive && armBot.state === "idle" && currentPhase === "rest" && armBot.currentAction) {
if (armBot.currentAction) {
setArmBotActive(armBot.modelUuid, true);
setArmBotState(armBot.modelUuid, "running");
setCurrentPhase("rest-to-start");
const startPoint = robot.point.actions[0].process.startPoint;
const startPoint = armBot.point.actions[0].process.startPoint;
if (startPoint) {
let curve = createCurveBetweenTwoPoints(restPosition, new THREE.Vector3(startPoint[0], startPoint[1], startPoint[2]));
if (curve) {
@ -85,105 +161,396 @@ function RoboticArmInstance({ robot }: { robot: ArmBotStatus }) {
}
}
}
logStatus(robot.modelUuid, "Moving armBot from rest point to start position.")
logStatus(armBot.modelUuid, "Moving armBot from rest point to start position.")
}
else if (robot && !robot.isActive && robot.state === "idle" && currentPhase === "picking" && robot.currentAction) {
setArmBotActive(robot.modelUuid, true);
setArmBotState(robot.modelUuid, "running");
setCurrentPhase("start-to-end");
const startPoint = robot.point.actions[0].process.startPoint;
const endPoint = robot.point.actions[0].process.endPoint;
if (startPoint && endPoint) {
let curve = createCurveBetweenTwoPoints(
new THREE.Vector3(startPoint[0], startPoint[1], startPoint[2]),
new THREE.Vector3(endPoint[0], endPoint[1], endPoint[2])
);
if (curve) {
setTimeout(() => {
logStatus(robot.modelUuid, "picking the object");
setPath(curve.points.map(point => [point.x, point.y, point.z]));
}, 1500)
}
}
logStatus(robot.modelUuid, "Moving armBot from start point to end position.")
else if (armBot && !armBot.isActive && armBot.state === "idle" && currentPhase === "picking" && armBot.currentAction) {
requestAnimationFrame(firstFrame);
// setArmBotActive(armBot.modelUuid, true);
// setArmBotState(armBot.modelUuid, "running");
// setCurrentPhase("start-to-end");
// const startPoint = armBot.point.actions[0].process.startPoint;
// const endPoint = armBot.point.actions[0].process.endPoint;
// if (startPoint && endPoint) {
// let curve = createCurveBetweenTwoPoints(
// new THREE.Vector3(startPoint[0], startPoint[1], startPoint[2]),
// new THREE.Vector3(endPoint[0], endPoint[1], endPoint[2]));
// if (curve) {
// setTimeout(() => {
// logStatus(armBot.modelUuid, "picking the object");
// setPath(curve.points.map(point => [point.x, point.y, point.z]));
// }, 1500)
// }
// }
// logStatus(armBot.modelUuid, "Moving armBot from start point to end position.")
}
else if (robot && !robot.isActive && robot.state === "idle" && currentPhase === "dropping" && robot.currentAction) {
setArmBotActive(robot.modelUuid, true);
setArmBotState(robot.modelUuid, "running");
setCurrentPhase("end-to-rest");
const endPoint = robot.point.actions[0].process.endPoint;
if (endPoint) {
let curve = createCurveBetweenTwoPoints(new THREE.Vector3(endPoint[0], endPoint[1], endPoint[2]), restPosition
);
if (curve) {
setTimeout(() => {
logStatus(robot.modelUuid, "dropping the object");
setPath(curve.points.map(point => [point.x, point.y, point.z]));
}, 1500)
}
}
logStatus(robot.modelUuid, "Moving armBot from end point to rest position.")
else if (armBot && !armBot.isActive && armBot.state === "idle" && currentPhase === "dropping" && armBot.currentAction) {
requestAnimationFrame(firstFrame);
// setArmBotActive(armBot.modelUuid, true);
// setArmBotState(armBot.modelUuid, "running");
// setCurrentPhase("end-to-rest");
// const endPoint = armBot.point.actions[0].process.endPoint;
// if (endPoint) {
// let curve = createCurveBetweenTwoPoints(new THREE.Vector3(endPoint[0], endPoint[1], endPoint[2]), restPosition);
// if (curve) {
// setTimeout(() => {
// logStatus(armBot.modelUuid, "dropping the object");
// setPath(curve.points.map(point => [point.x, point.y, point.z]));
// }, 1500)
// }
// }
// logStatus(armBot.modelUuid, "Moving armBot from end point to rest position.")
}
} else {
logStatus(armBot.modelUuid, "Simulation Play Stopped")
setArmBotActive(armBot.modelUuid, false)
setArmBotState(armBot.modelUuid, "idle")
setCurrentPhase("init");
setPath([])
removeCurrentAction(armBot.modelUuid)
}
}, [currentPhase, robot, isPlaying, ikSolver])
}, [currentPhase, armBot, isPlaying, ikSolver, isReset])
function createCurveBetweenTwoPoints(p1: any, p2: any) {
const mid = new THREE.Vector3().addVectors(p1, p2).multiplyScalar(0.5);
mid.y += 0.5;
// mid.y += 0.5;
const points = [p1, mid, p2];
return new THREE.CatmullRomCurve3(points);
}
const HandleCallback = () => {
if (robot.isActive && robot.state == "running" && currentPhase == "init-to-rest") {
logStatus(robot.modelUuid, "Callback triggered: rest");
setArmBotActive(robot.modelUuid, false)
setArmBotState(robot.modelUuid, "idle")
if (armBot.isActive && armBot.state == "running" && currentPhase == "init-to-rest") {
logStatus(armBot.modelUuid, "Callback triggered: rest");
setArmBotActive(armBot.modelUuid, false)
setArmBotState(armBot.modelUuid, "idle")
setCurrentPhase("rest");
setPath([])
}
else if (robot.isActive && robot.state == "running" && currentPhase == "rest-to-start") {
logStatus(robot.modelUuid, "Callback triggered: pick.");
setArmBotActive(robot.modelUuid, false)
setArmBotState(robot.modelUuid, "idle")
else if (armBot.isActive && armBot.state == "running" && currentPhase == "rest-to-start") {
logStatus(armBot.modelUuid, "Callback triggered: pick.");
setArmBotActive(armBot.modelUuid, false)
setArmBotState(armBot.modelUuid, "idle")
setCurrentPhase("picking");
setPath([])
}
else if (robot.isActive && robot.state == "running" && currentPhase == "start-to-end") {
logStatus(robot.modelUuid, "Callback triggered: drop.");
setArmBotActive(robot.modelUuid, false)
setArmBotState(robot.modelUuid, "idle")
else if (armBot.isActive && armBot.state == "running" && currentPhase == "start-to-end") {
logStatus(armBot.modelUuid, "Callback triggered: drop.");
setArmBotActive(armBot.modelUuid, false)
setArmBotState(armBot.modelUuid, "idle")
setCurrentPhase("dropping");
setPath([])
}
else if (robot.isActive && robot.state == "running" && currentPhase == "end-to-rest") {
logStatus(robot.modelUuid, "Callback triggered: rest, cycle completed.");
setArmBotActive(robot.modelUuid, false)
setArmBotState(robot.modelUuid, "idle")
else if (armBot.isActive && armBot.state == "running" && currentPhase == "end-to-rest") {
logStatus(armBot.modelUuid, "Callback triggered: rest, cycle completed.");
setArmBotActive(armBot.modelUuid, false)
setArmBotState(armBot.modelUuid, "idle")
setCurrentPhase("rest");
setPath([])
removeCurrentAction(robot.modelUuid)
removeCurrentAction(armBot.modelUuid)
}
}
const logStatus = (id: string, status: string) => {
// console.log(id + "," + status);
console.log( status);
// console.log('status: ', status);
}
return (
<>
<IKInstance modelUrl={armModel} setIkSolver={setIkSolver} ikSolver={ikSolver} robot={robot} groupRef={groupRef} processes={processes}
setArmBotCurvePoints={setArmBotCurvePoints} />
<RoboticArmAnimator armUuid={robot?.modelUuid} HandleCallback={HandleCallback}
currentPhase={currentPhase} targetBone={targetBone} ikSolver={ikSolver} robot={robot}
logStatus={logStatus} groupRef={groupRef} processes={processes} armBotCurveRef={armBotCurveRef} path={path} />
<IKInstance modelUrl={armModel} setIkSolver={setIkSolver} ikSolver={ikSolver} armBot={armBot} groupRef={groupRef} />
<RoboticArmAnimator HandleCallback={HandleCallback} restPosition={restPosition} ikSolver={ikSolver} targetBone={targetBone} armBot={armBot}
logStatus={logStatus} path={path}currentPhase={currentPhase} />
</>
)
}
export default RoboticArmInstance;
export default RoboticArmInstance;
// import React, { useEffect, useRef, useState } from 'react';
// import IKInstance from '../ikInstance/ikInstance';
// import RoboticArmAnimator from '../animator/roboticArmAnimator';
// import { usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore';
// import { useArmBotStore } from '../../../../../store/simulation/useArmBotStore';
// import armModel from "../../../../../assets/gltf-glb/rigged/ik_arm_4.glb";
// import { useThree } from "@react-three/fiber";
// import { useFloorItems } from '../../../../../store/store';
// import useModuleStore from '../../../../../store/useModuleStore';
// import * as THREE from "three";
// function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
// const [currentPhase, setCurrentPhase] = useState<string>("init");
// const [path, setPath] = useState<[number, number, number][]>([]);
// const [ikSolver, setIkSolver] = useState<any>(null);
// const { scene } = useThree();
// const restPosition = new THREE.Vector3(0, 1, -1.6);
// const targetBone = "Target";
// const groupRef = useRef<any>(null);
// // Zustand Stores
// const { addCurrentAction, setArmBotActive, setArmBotState, removeCurrentAction } = useArmBotStore();
// const { floorItems } = useFloorItems();
// const { activeModule } = useModuleStore();
// const { isPlaying } = usePlayButtonStore();
// const { isReset, setReset } = useResetButtonStore();
// // Generate path according to constraints
// const generateArmPath = (
// startPoint: [number, number, number],
// endPoint: [number, number, number],
// restPos: THREE.Vector3 = new THREE.Vector3(0, 1, -1.6)
// ): [number, number, number][] => {
// const path: [number, number, number][] = [];
// const startVec = new THREE.Vector3(...startPoint);
// const endVec = new THREE.Vector3(...endPoint);
// // Helper functions
// const addLinePoints = (from: THREE.Vector3, to: THREE.Vector3, segments: number) => {
// for (let i = 0; i <= segments; i++) {
// const t = i / segments;
// const point = new THREE.Vector3().lerpVectors(from, to, t);
// path.push([point.x, point.y, point.z]);
// }
// };
// const addCurveFromTo = (from: THREE.Vector3, to: THREE.Vector3, segments: number = 15) => {
// const mid = new THREE.Vector3()
// .addVectors(from, to)
// .multiplyScalar(0.5)
// .setY(Math.max(from.y, to.y) + 0.5);
// const curve = new THREE.CatmullRomCurve3([from, mid, to]);
// const points = curve.getPoints(segments);
// for (const p of points) {
// path.push([p.x, p.y, p.z]);
// }
// };
// // Step 1: Move vertically to align Y with start point
// const step1Start = startVec.clone().setY(restPos.y);
// const step1End = startVec.clone();
// addLinePoints(step1Start, step1End, 10);
// // Step 2: Move horizontally XZ to reach start point
// const step2Start = step1End.clone();
// const step2End = startVec.clone(); // ✅ Fixed here
// addLinePoints(step2Start, step2End, 10);
// addLinePoints(step1End, step2End, 10);
// // Optional Step 3: Move to rest/midpoint if needed
// const distanceToRest = startVec.distanceTo(restPos);
// if (distanceToRest > 1) {
// addCurveFromTo(step2End, restPos, 15);
// }
// // Step 4: Move up/down to align Y with end point
// const step4Start = endVec.clone().setY(restPos.y);
// const step4End = endVec.clone();
// addLinePoints(step4Start, step4End, 10);
// // Step 5: Move horizontally XZ to end point
// addLinePoints(step4End, endVec.clone(), 10);
// // Step 6: Return to rest or mid-position after dropping
// const finalRestHeight = restPos.clone().setY(endVec.y + 0.5);
// addCurveFromTo(endVec, finalRestHeight, 15);
// return path;
// };
// useEffect(() => {
// let armItems = floorItems?.filter((val: any) =>
// val.modeluuid === armBot.modelUuid
// );
// let armItem = armItems?.[0];
// if (armItem) {
// const targetMesh = scene?.getObjectByProperty("uuid", armItem.modeluuid);
// if (targetMesh) {
// targetMesh.visible = activeModule !== "simulation";
// }
// }
// const targetBones = ikSolver?.mesh.skeleton.bones.find(
// (b: any) => b.name === targetBone
// );
// if (isReset) {
// logStatus(armBot.modelUuid, "Simulation Play Reset Successfully");
// removeCurrentAction(armBot.modelUuid);
// setArmBotActive(armBot.modelUuid, true);
// setArmBotState(armBot.modelUuid, "running");
// setCurrentPhase("init-to-rest");
// if (targetBones) {
// const startPoint = new THREE.Vector3(targetBones.position.x, targetBones.position.y, targetBones.position.z);
// const curve = new THREE.CatmullRomCurve3([
// startPoint,
// startPoint.clone().setY(restPosition.y + 0.5),
// restPosition.clone(),
// ]);
// setPath(curve.getPoints(30).map(p => [p.x, p.y, p.z]));
// }
// setReset(false);
// logStatus(armBot.modelUuid, "Moving armBot from initial point to rest position.");
// }
// if (isPlaying) {
// // Phase 1: Initial -> Rest
// if (!armBot.isActive && armBot.state === "idle" && currentPhase === "init") {
// setArmBotActive(armBot.modelUuid, true);
// setArmBotState(armBot.modelUuid, "running");
// setCurrentPhase("init-to-rest");
// if (targetBones) {
// const startPoint = new THREE.Vector3(targetBones.position.x, targetBones.position.y, targetBones.position.z);
// const curve = new THREE.CatmullRomCurve3([
// startPoint,
// startPoint.clone().setY(restPosition.y + 0.5),
// restPosition.clone(),
// ]);
// setPath(curve.getPoints(30).map(p => [p.x, p.y, p.z]));
// }
// logStatus(armBot.modelUuid, "Moving armBot from initial point to rest position.");
// }
// // Phase 2: Wait for trigger
// else if (!armBot.isActive && armBot.state === "idle" && currentPhase === "rest" && !armBot.currentAction) {
// logStatus(armBot.modelUuid, "Waiting to trigger CurrentAction");
// const timeoutId = setTimeout(() => {
// addCurrentAction(armBot.modelUuid, 'action-003');
// }, 3000);
// return () => clearTimeout(timeoutId);
// }
// // Phase 3: Rest -> Start Point
// else if (!armBot.isActive && armBot.state === "idle" && currentPhase === "rest" && armBot.currentAction) {
// setArmBotActive(armBot.modelUuid, true);
// setArmBotState(armBot.modelUuid, "running");
// setCurrentPhase("rest-to-start");
// const startPoint = armBot.point.actions[0].process.startPoint;
// if (startPoint) {
// const start = new THREE.Vector3(startPoint[0], startPoint[1], startPoint[2]);
// const curve = new THREE.CatmullRomCurve3([restPosition, restPosition.clone().setY(start.y), start]);
// setPath(curve.getPoints(30).map(p => [p.x, p.y, p.z]));
// }
// logStatus(armBot.modelUuid, "Moving armBot from rest point to start position.");
// }
// // Phase 4: Start -> End (Pick & Move Object)
// else if (!armBot.isActive && armBot.state === "idle" && currentPhase === "picking" && armBot.currentAction) {
// setArmBotActive(armBot.modelUuid, true);
// setArmBotState(armBot.modelUuid, "running");
// setCurrentPhase("start-to-end");
// const startPoint = armBot.point.actions[0].process.startPoint;
// const endPoint = armBot.point.actions[0].process.endPoint;
// if (startPoint && endPoint) {
// const path = generateArmPath(startPoint, endPoint, restPosition);
// logStatus(armBot.modelUuid, "Waiting to pick.");
// setTimeout(()=>{
// setPath(path);
// },3000)
// }
// logStatus(armBot.modelUuid, "Moving armBot from start point to end position.");
// }
// // Phase 5: End -> Rest (Drop & Return)
// else if (!armBot.isActive && armBot.state === "idle" && currentPhase === "dropping" && armBot.currentAction) {
// setArmBotActive(armBot.modelUuid, true);
// setArmBotState(armBot.modelUuid, "running");
// setCurrentPhase("end-to-rest");
// const endPoint = armBot.point.actions[0].process.endPoint;
// if (endPoint) {
// const start = new THREE.Vector3(endPoint[0], endPoint[1], endPoint[2]);
// const curve = new THREE.CatmullRomCurve3([start, start.clone().setY(restPosition.y), restPosition]);
// logStatus(armBot.modelUuid, "Waiting to drop.");
// setTimeout(()=>{
// setPath(curve.getPoints(30).map(p => [p.x, p.y, p.z]));
// },3000)
// }
// logStatus(armBot.modelUuid, "Moving armBot from end point to rest position.");
// }
// } else {
// logStatus(armBot.modelUuid, "Simulation Play Stopped");
// setArmBotActive(armBot.modelUuid, false);
// setArmBotState(armBot.modelUuid, "idle");
// setCurrentPhase("init");
// setPath([]);
// removeCurrentAction(armBot.modelUuid);
// }
// }, [currentPhase, armBot, isPlaying, ikSolver, isReset]);
// const HandleCallback = () => {
// if (armBot.isActive && armBot.state === "running" && currentPhase === "init-to-rest") {
// logStatus(armBot.modelUuid, "Callback triggered: rest");
// setArmBotActive(armBot.modelUuid, false);
// setArmBotState(armBot.modelUuid, "idle");
// setCurrentPhase("rest");
// setPath([]);
// } else if (armBot.isActive && armBot.state === "running" && currentPhase === "rest-to-start") {
// logStatus(armBot.modelUuid, "Callback triggered: pick.");
// setArmBotActive(armBot.modelUuid, false);
// setArmBotState(armBot.modelUuid, "idle");
// setCurrentPhase("picking");
// setPath([]);
// } else if (armBot.isActive && armBot.state === "running" && currentPhase === "start-to-end") {
// logStatus(armBot.modelUuid, "Callback triggered: drop.");
// setArmBotActive(armBot.modelUuid, false);
// setArmBotState(armBot.modelUuid, "idle");
// setCurrentPhase("dropping");
// setPath([]);
// } else if (armBot.isActive && armBot.state === "running" && currentPhase === "end-to-rest") {
// logStatus(armBot.modelUuid, "Callback triggered: rest, cycle completed.");
// setArmBotActive(armBot.modelUuid, false);
// setArmBotState(armBot.modelUuid, "idle");
// setCurrentPhase("rest");
// setPath([]);
// removeCurrentAction(armBot.modelUuid);
// }
// };
// const logStatus = (id: string, status: string) => {
// console.log( status);
// // console.log(`status [${id}]: ${status}`);
// };
// return (
// <>
// <IKInstance modelUrl={armModel} setIkSolver={setIkSolver} ikSolver={ikSolver} armBot={armBot} groupRef={groupRef} />
// <RoboticArmAnimator
// HandleCallback={HandleCallback}
// restPosition={restPosition}
// ikSolver={ikSolver}
// targetBone={targetBone}
// armBot={armBot}
// logStatus={logStatus}
// path={path}
// />
// </>
// );
// }
// export default RoboticArmInstance;

View File

@ -3,20 +3,18 @@ import * as THREE from "three";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { clone } from "three/examples/jsm/utils/SkeletonUtils";
import { useFrame, useLoader, useThree } from "@react-three/fiber";
import { useLoader, useThree } from "@react-three/fiber";
import { CCDIKSolver, CCDIKHelper, } from "three/examples/jsm/animation/CCDIKSolver";
type IKInstanceProps = {
modelUrl: string;
ikSolver: any;
setIkSolver: any
robot: any;
armBot: any;
groupRef: React.RefObject<THREE.Group>;
processes: any;
setArmBotCurvePoints: any
};
function IKInstance({ modelUrl, setIkSolver, ikSolver, robot, groupRef, processes, setArmBotCurvePoints }: IKInstanceProps) {
const { scene } = useThree();
function IKInstance({ modelUrl, setIkSolver, ikSolver, armBot, groupRef}: IKInstanceProps) {
const {scene}=useThree()
const gltf = useLoader(GLTFLoader, modelUrl, (loader) => {
const draco = new DRACOLoader();
draco.setDecoderPath("https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/");
@ -25,6 +23,7 @@ function IKInstance({ modelUrl, setIkSolver, ikSolver, robot, groupRef, processe
const cloned = useMemo(() => clone(gltf?.scene), [gltf]);
const targetBoneName = "Target";
const skinnedMeshName = "link_0";
useEffect(() => {
if (!gltf) return;
const OOI: any = {};
@ -67,14 +66,14 @@ function IKInstance({ modelUrl, setIkSolver, ikSolver, robot, groupRef, processe
const helper = new CCDIKHelper(OOI.Skinned_Mesh, iks, 0.05)
// scene.add(helper)
scene.add(helper)
}, [gltf]);
return (
<>
<group ref={groupRef} position={robot.position} rotation={robot.rotation}>
<group ref={groupRef} position={armBot.position} rotation={armBot.rotation}>
<primitive
uuid={"ArmBot-X200"}
object={cloned}

View File

@ -8,7 +8,7 @@ function RoboticArmInstances() {
return (
<>
{armBots?.map((robot: ArmBotStatus) => (
<RoboticArmInstance key={robot.modelUuid} robot={robot} />
<RoboticArmInstance key={robot.modelUuid} armBot={robot} />
))}
</>

View File

@ -6,8 +6,6 @@ import { useFloorItems } from "../../../store/store";
function RoboticArm() {
const { armBots, addArmBot, removeArmBot } = useArmBotStore();
const { floorItems } = useFloorItems();
const armBotStatusSample: RoboticArmEventSchema[] = [
{
state: "idle",
@ -95,7 +93,7 @@ function RoboticArm() {
position: [95.94347308985614, 0, 6.742905194869091],
rotation: [0, 0, 0],
type: "roboticArm",
speed: 1.5,
speed: 0.1,
point: {
uuid: "point-123",
position: [0, 1.5, 0],

View File

@ -80,7 +80,7 @@ export default function useDraggableGLTF(onUpdate: OnUpdateCallback) {
// Add offset for dragging
intersection.add(offsetRef.current);
console.log('intersection: ', intersection);
// Get the parent's world matrix if exists
const parent = activeObjRef.current.parent;