human bug fix

This commit is contained in:
2025-09-09 14:08:22 +05:30
parent 24a38e47c3
commit cc87a51796
6 changed files with 92 additions and 57 deletions

View File

@@ -25,7 +25,6 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<M
const completedRef = useRef<boolean>(false);
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
const [objectRotation, setObjectRotation] = useState<[number, number, number] | null>((action as HumanAction)?.manufacturePoint?.rotation || [0, 0, 0]);
const [restingRotation, setRestingRotation] = useState<boolean>(true);
const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]);
const { scene } = useThree();
@@ -48,7 +47,6 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<M
completedRef.current = false;
progressRef.current = 0;
setReset(false);
setRestingRotation(true);
const object = scene.getObjectByProperty("uuid", human.modelUuid);
const humanData = getHumanById(human.modelUuid);
if (object && humanData) {
@@ -108,7 +106,7 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<M
const isAligned = angle < 0.01;
if (isAligned) {
progressRef.current += delta * (speed * human.speed);
progressRef.current = Math.min(progressRef.current + delta * (speed * human.speed), totalDistance);
const t = (progressRef.current - accumulatedDistance) / segmentDistance;
const position = start.clone().lerp(end, t);
object.position.copy(position);
@@ -119,16 +117,22 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<M
}
if (progressRef.current >= totalDistance) {
if (restingRotation && objectRotation) {
if (objectRotation) {
const targetEuler = new THREE.Euler(0, objectRotation[1], 0);
const baseQuaternion = new THREE.Quaternion().setFromEuler(targetEuler);
const y180 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI);
const targetQuaternion = baseQuaternion.multiply(y180);
const angle = object.quaternion.angleTo(targetQuaternion);
if (angle < 0.01) {
const step = rotationSpeed * delta * speed * human.speed;
object.quaternion.slerp(targetQuaternion, Math.min(1, step / angle));
if (object.quaternion.angleTo(targetQuaternion) < 0.001) {
object.quaternion.copy(targetQuaternion);
setRestingRotation(false);
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
progressRef.current = 0;
setCurrentPath([]);
handleCallBack();
} else {
const step = rotationSpeed * delta * speed * human.speed;
object.quaternion.rotateTowards(targetQuaternion, step);
@@ -138,13 +142,6 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<M
return;
}
}
if (progressRef.current >= totalDistance) {
setRestingRotation(true);
progressRef.current = 0;
setCurrentPath([]);
handleCallBack();
}
});
return (

View File

@@ -26,13 +26,13 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<Worke
const completedRef = useRef<boolean>(false);
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
const [objectRotation, setObjectRotation] = useState<[number, number, number] | null>((action as HumanAction)?.pickUpPoint?.rotation || [0, 0, 0]);
const [restingRotation, setRestingRotation] = useState<boolean>(true);
const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]);
const { scene } = useThree();
useEffect(() => {
if (!human.currentAction?.actionUuid) return;
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
completedRef.current = true;
if (human.currentPhase === "init-loadPoint" && path.length > 0) {
setCurrentPath(path);
setObjectRotation((action as HumanAction).pickUpPoint?.rotation ?? null);
@@ -43,7 +43,7 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<Worke
setObjectRotation((action as HumanAction)?.pickUpPoint?.rotation ?? null);
setCurrentPath(path);
}
}, [human.currentPhase, path, objectRotation, selectedProduct, human.currentAction?.actionUuid]);
}, [human.currentPhase, path, selectedProduct, human.currentAction?.actionUuid]);
useEffect(() => {
completedRef.current = false;
@@ -57,7 +57,6 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<Worke
movingForward.current = true;
progressRef.current = 0;
setReset(false);
setRestingRotation(true);
const object = scene.getObjectByProperty("uuid", human.modelUuid);
const humanData = getHumanById(human.modelUuid);
if (object && humanData) {
@@ -75,7 +74,7 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<Worke
lastTimeRef.current = now;
const object = scene.getObjectByProperty("uuid", human.modelUuid);
if (!object || currentPath.length < 2) return;
if (!object || currentPath.length < 2 || completedRef.current) return;
if (isPaused || !isPlaying) return;
let totalDistance = 0;
@@ -117,7 +116,7 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<Worke
const isAligned = angle < 0.01;
if (isAligned) {
progressRef.current += delta * (speed * human.speed);
progressRef.current = Math.min(progressRef.current + delta * (speed * human.speed), totalDistance);
const t = (progressRef.current - accumulatedDistance) / segmentDistance;
const position = start.clone().lerp(end, t);
object.position.copy(position);
@@ -128,16 +127,24 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<Worke
}
if (progressRef.current >= totalDistance) {
if (restingRotation && objectRotation) {
if (objectRotation) {
const targetEuler = new THREE.Euler(0, objectRotation[1], 0);
const baseQuaternion = new THREE.Quaternion().setFromEuler(targetEuler);
const y180 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI);
const targetQuaternion = baseQuaternion.multiply(y180);
const angle = object.quaternion.angleTo(targetQuaternion);
if (angle < 0.01) {
const step = rotationSpeed * delta * speed * human.speed;
object.quaternion.slerp(targetQuaternion, Math.min(1, step / angle));
if (object.quaternion.angleTo(targetQuaternion) < 0.001) {
object.quaternion.copy(targetQuaternion);
setRestingRotation(false);
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
progressRef.current = 0;
movingForward.current = !movingForward.current;
completedRef.current = true;
setCurrentPath([]);
handleCallBack();
} else {
const step = rotationSpeed * delta * speed * human.speed;
object.quaternion.rotateTowards(targetQuaternion, step);
@@ -147,14 +154,6 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<Worke
return;
}
}
if (progressRef.current >= totalDistance) {
setRestingRotation(true);
progressRef.current = 0;
movingForward.current = !movingForward.current;
setCurrentPath([]);
handleCallBack();
}
});
return (

View File

@@ -27,7 +27,6 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
const completedRef = useRef<boolean>(false);
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
const [objectRotation, setObjectRotation] = useState<[number, number, number] | null>((action as HumanAction)?.pickUpPoint?.rotation || [0, 0, 0]);
const [restingRotation, setRestingRotation] = useState<boolean>(true);
const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]);
const { scene } = useThree();
@@ -58,7 +57,6 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
movingForward.current = true;
progressRef.current = 0;
setReset(false);
setRestingRotation(true);
const object = scene.getObjectByProperty("uuid", human.modelUuid);
const humanData = getHumanById(human.modelUuid);
if (object && humanData) {
@@ -118,7 +116,7 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
const isAligned = angle < 0.01;
if (isAligned) {
progressRef.current += delta * (speed * human.speed);
progressRef.current = Math.min(progressRef.current + delta * (speed * human.speed), totalDistance);
const t = (progressRef.current - accumulatedDistance) / segmentDistance;
const position = start.clone().lerp(end, t);
object.position.copy(position);
@@ -137,16 +135,26 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
}
if (progressRef.current >= totalDistance) {
if (restingRotation && objectRotation) {
if (objectRotation) {
const targetEuler = new THREE.Euler(0, objectRotation[1], 0);
const baseQuaternion = new THREE.Quaternion().setFromEuler(targetEuler);
const y180 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI);
const targetQuaternion = baseQuaternion.multiply(y180);
const angle = object.quaternion.angleTo(targetQuaternion);
if (angle < 0.01) {
const step = rotationSpeed * delta * speed * human.speed;
object.quaternion.slerp(targetQuaternion, Math.min(1, step / angle));
if (object.quaternion.angleTo(targetQuaternion) < 0.001) {
object.quaternion.copy(targetQuaternion);
setRestingRotation(false);
setCurrentAnimation(human.modelUuid, human.currentMaterials.length > 0 ? "idle_with_box" : "idle", true, true, true);
progressRef.current = 0;
movingForward.current = !movingForward.current;
setCurrentPath([]);
handleCallBack();
if (human.currentPhase === "pickup-drop") {
requestAnimationFrame(startUnloadingProcess);
}
} else {
const step = rotationSpeed * delta * speed * human.speed;
object.quaternion.rotateTowards(targetQuaternion, step);
@@ -158,7 +166,6 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
}
if (progressRef.current >= totalDistance) {
setRestingRotation(true);
progressRef.current = 0;
movingForward.current = !movingForward.current;
setCurrentPath([]);

View File

@@ -49,7 +49,11 @@ function ManufacturerInstance({ human }: { readonly human: HumanStatus }) {
let startPoint = new THREE.Vector3(start[0], start[1], start[2]);
let endPoint = new THREE.Vector3(end[0], end[1], end[2]);
const { path: segmentPath } = navMeshQuery.computePath(startPoint, endPoint);
if (segmentPath.length > 0 && Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) && Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)) {
if (
segmentPath.length > 0 &&
Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) &&
Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)
) {
return segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
} else {
console.log("There is no path here...Choose valid path");
@@ -126,7 +130,14 @@ function ManufacturerInstance({ human }: { readonly human: HumanStatus }) {
processAnimationIdRef.current = requestAnimationFrame(trackManufactureProcess);
}
}
} else if (human.isActive && human.state === "running" && human.currentMaterials.length > 0 && humanAsset && humanAsset.animationState?.current === "working_standing" && humanAsset.animationState?.isCompleted) {
} else if (
human.isActive &&
human.state === "running" &&
human.currentMaterials.length > 0 &&
humanAsset &&
humanAsset.animationState?.current === "working_standing" &&
humanAsset.animationState?.isCompleted
) {
if ((action as HumanAction).manufacturePoint && human.currentPhase === "manufacturing") {
setHumanState(human.modelUuid, "idle");
setCurrentPhase(human.modelUuid, "waiting");
@@ -141,8 +152,6 @@ function ManufacturerInstance({ human }: { readonly human: HumanStatus }) {
}
}
}
} else {
reset();
}
}, [human, human.currentPhase, path, isPlaying, humanAsset?.animationState?.isCompleted]);

View File

@@ -29,13 +29,13 @@ function OperatorInstance({ human }: { readonly human: HumanStatus }) {
const animationFrameIdRef = useRef<number | null>(null);
const humanAsset = getAssetById(human.modelUuid);
useEffect(() => {
isPausedRef.current = isPaused;
}, [isPaused]);
// useEffect(() => {
// isPausedRef.current = isPaused;
// }, [isPaused]);
useEffect(() => {
isSpeedRef.current = speed;
}, [speed]);
// useEffect(() => {
// isSpeedRef.current = speed;
// }, [speed]);
const computePath = useCallback(
(start: [number, number, number], end: [number, number, number]) => {
@@ -44,7 +44,11 @@ function OperatorInstance({ human }: { readonly human: HumanStatus }) {
let startPoint = new THREE.Vector3(start[0], start[1], start[2]);
let endPoint = new THREE.Vector3(end[0], end[1], end[2]);
const { path: segmentPath } = navMeshQuery.computePath(startPoint, endPoint);
if (segmentPath.length > 0 && Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) && Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)) {
if (
segmentPath.length > 0 &&
Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) &&
Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)
) {
return segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
} else {
console.log("There is no path here...Choose valid path");
@@ -119,8 +123,6 @@ function OperatorInstance({ human }: { readonly human: HumanStatus }) {
setCurrentAnimation(human.modelUuid, "working_standing", true, false, false);
}, 1);
}
} else {
reset();
}
}, [human, human.currentAction, human.currentPhase, path, isPlaying, humanAsset?.animationState?.isCompleted]);

View File

@@ -23,7 +23,19 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
const { triggerPointActions } = useTriggerHandler();
const { setCurrentAnimation, resetAnimation, getAssetById } = assetStore();
const { getActionByUuid, getEventByModelUuid, getTriggerByUuid, selectedProduct } = productStore();
const { setHumanActive, setHumanState, clearCurrentMaterials, setHumanLoad, setHumanScheduled, decrementHumanLoad, removeLastMaterial, incrementIdleTime, incrementActiveTime, resetTime, setCurrentPhase } = humanStore();
const {
setHumanActive,
setHumanState,
clearCurrentMaterials,
setHumanLoad,
setHumanScheduled,
decrementHumanLoad,
removeLastMaterial,
incrementIdleTime,
incrementActiveTime,
resetTime,
setCurrentPhase,
} = humanStore();
const [path, setPath] = useState<[number, number, number][]>([]);
const pauseTimeRef = useRef<number | null>(null);
@@ -52,7 +64,11 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
let startPoint = new THREE.Vector3(start[0], start[1], start[2]);
let endPoint = new THREE.Vector3(end[0], end[1], end[2]);
const { path: segmentPath } = navMeshQuery.computePath(startPoint, endPoint);
if (segmentPath.length > 0 && Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) && Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)) {
if (
segmentPath.length > 0 &&
Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) &&
Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)
) {
return segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
} else {
console.log("There is no path here...Choose valid path");
@@ -115,7 +131,14 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
humanStatus(human.modelUuid, "Started from init, heading to pickup");
return;
} else if (!human.isActive && human.state === "idle" && human.currentPhase === "picking") {
if (humanAsset && human.currentLoad === action.loadCapacity && human.currentMaterials.length > 0 && human.currentLoad > 0 && humanAsset.animationState?.current === "pickup" && humanAsset.animationState?.isCompleted) {
if (
humanAsset &&
human.currentLoad === action.loadCapacity &&
human.currentMaterials.length > 0 &&
human.currentLoad > 0 &&
humanAsset.animationState?.current === "pickup" &&
humanAsset.animationState?.isCompleted
) {
if (action.pickUpPoint && action.dropPoint) {
const toDrop = computePath(action.pickUpPoint.position || [0, 0, 0], action.dropPoint.position || [0, 0, 0]);
setPath(toDrop);
@@ -168,8 +191,6 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
}
}
}
} else {
reset();
}
}, [human, human.currentAction, human.currentPhase, path, isPlaying, humanAsset?.animationState?.isCompleted]);