From 036164155f38fce9c62a8ee72d27cf7c9fadbe18 Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Sat, 20 Dec 2025 12:29:12 +0530 Subject: [PATCH] feat: Introduce animation components for worker, manufacturer, and operator humans, model animators, and a new vehicle state management store. --- .../models/model/animator/modelAnimator.tsx | 10 ++-- .../animator/manufacturerAnimator.tsx | 11 +--- .../instances/animator/operatorAnimator.tsx | 11 +--- .../instances/animator/workerAnimator.tsx | 11 +--- app/src/store/simulation/useVehicleStore.ts | 58 ++++++++++--------- 5 files changed, 42 insertions(+), 59 deletions(-) diff --git a/app/src/modules/builder/asset/models/model/animator/modelAnimator.tsx b/app/src/modules/builder/asset/models/model/animator/modelAnimator.tsx index fb27fce..97ecc2a 100644 --- a/app/src/modules/builder/asset/models/model/animator/modelAnimator.tsx +++ b/app/src/modules/builder/asset/models/model/animator/modelAnimator.tsx @@ -60,14 +60,16 @@ export function ModelAnimator({ asset, gltfScene }: ModelAnimatorProps) { if (isPlaying && currentAction && !isPaused) { blendFactor.current = 0; + Object.values(actions.current).forEach((action) => { + if (action !== currentAction) { + action.stop(); + } + }); + currentAction.reset(); currentAction.setLoop(loopAnimation ? THREE.LoopRepeat : THREE.LoopOnce, loopAnimation ? Infinity : 1); currentAction.clampWhenFinished = true; - if (previousAction && previousAction !== currentAction) { - previousAction.crossFadeTo(currentAction, blendDuration, false); - } - currentAction.play(); mixerRef.current.addEventListener("finished", handleAnimationComplete); setPreviousAnimation(current); diff --git a/app/src/modules/simulation/human/instances/animator/manufacturerAnimator.tsx b/app/src/modules/simulation/human/instances/animator/manufacturerAnimator.tsx index 0524726..e6e335e 100644 --- a/app/src/modules/simulation/human/instances/animator/manufacturerAnimator.tsx +++ b/app/src/modules/simulation/human/instances/animator/manufacturerAnimator.tsx @@ -108,15 +108,8 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly 0) { - incrementDistanceTraveled(human.modelUuid, actualStep); - } - + progressRef.current = Math.min(progressRef.current + delta * (speed * human.speed), totalDistance); + incrementDistanceTraveled(human.modelUuid, delta * (speed * human.speed)); const t = (progressRef.current - accumulatedDistance) / segmentDistance; const position = start.clone().lerp(end, t); object.position.copy(position); diff --git a/app/src/modules/simulation/human/instances/animator/operatorAnimator.tsx b/app/src/modules/simulation/human/instances/animator/operatorAnimator.tsx index c5d7891..fc6d829 100644 --- a/app/src/modules/simulation/human/instances/animator/operatorAnimator.tsx +++ b/app/src/modules/simulation/human/instances/animator/operatorAnimator.tsx @@ -116,15 +116,8 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly 0) { - incrementDistanceTraveled(human.modelUuid, actualStep); - } - + progressRef.current = Math.min(progressRef.current + delta * (speed * human.speed), totalDistance); + incrementDistanceTraveled(human.modelUuid, delta * (speed * human.speed)); const t = (progressRef.current - accumulatedDistance) / segmentDistance; const position = start.clone().lerp(end, t); object.position.copy(position); diff --git a/app/src/modules/simulation/human/instances/animator/workerAnimator.tsx b/app/src/modules/simulation/human/instances/animator/workerAnimator.tsx index 25a3fbb..6e42eb8 100644 --- a/app/src/modules/simulation/human/instances/animator/workerAnimator.tsx +++ b/app/src/modules/simulation/human/instances/animator/workerAnimator.tsx @@ -118,15 +118,8 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc const isAligned = angle < 0.01; if (isAligned) { - const distanceStep = delta * (speed * human.speed); - const previousProgress = progressRef.current; - progressRef.current = Math.min(progressRef.current + distanceStep, totalDistance); - const actualStep = progressRef.current - previousProgress; - - if (actualStep > 0) { - incrementDistanceTraveled(human.modelUuid, actualStep); - } - + progressRef.current = Math.min(progressRef.current + delta * (speed * human.speed), totalDistance); + incrementDistanceTraveled(human.modelUuid, delta * (speed * human.speed)); const t = (progressRef.current - accumulatedDistance) / segmentDistance; const position = start.clone().lerp(end, t); object.position.copy(position); diff --git a/app/src/store/simulation/useVehicleStore.ts b/app/src/store/simulation/useVehicleStore.ts index e01bbce..f160e2d 100644 --- a/app/src/store/simulation/useVehicleStore.ts +++ b/app/src/store/simulation/useVehicleStore.ts @@ -6,10 +6,7 @@ interface VehiclesStore { addVehicle: (productUuid: string, event: VehicleEventSchema) => void; removeVehicle: (modelUuid: string) => void; - updateVehicle: ( - modelUuid: string, - updates: Partial> - ) => void; + updateVehicle: (modelUuid: string, updates: Partial>) => void; addPathPoint: (modelUuid: string, pathKey: keyof VehicleAction["paths"], point: VehicleAction["paths"]["initPickup"][number]) => VehicleAction["paths"]; updatePathPoint: (modelUuid: string, pathKey: keyof VehicleAction["paths"], pointId: string, updates: Partial) => VehicleAction["paths"]; deletePathPoint: (modelUuid: string, pathKey: keyof VehicleAction["paths"], pointId: string) => VehicleAction["paths"]; @@ -22,17 +19,15 @@ interface VehiclesStore { incrementVehicleLoad: (modelUuid: string, incrementBy: number) => void; decrementVehicleLoad: (modelUuid: string, decrementBy: number) => void; setVehicleLoad: (modelUuid: string, load: number) => void; - setVehicleState: ( - modelUuid: string, - newState: VehicleStatus["state"] - ) => void; + setVehicleState: (modelUuid: string, newState: VehicleStatus["state"]) => void; addCurrentMaterial: (modelUuid: string, materialType: string, materialId: string) => void; - setCurrentMaterials: (modelUuid: string, materials: { materialType: string; materialId: string; }[]) => void; - removeLastMaterial: (modelUuid: string) => { materialId: string; materialType: string; } | undefined; - getLastMaterial: (modelUuid: string) => { materialId: string; materialType: string; } | undefined; + setCurrentMaterials: (modelUuid: string, materials: { materialType: string; materialId: string }[]) => void; + removeLastMaterial: (modelUuid: string) => { materialId: string; materialType: string } | undefined; + getLastMaterial: (modelUuid: string) => { materialId: string; materialType: string } | undefined; clearCurrentMaterials: (modelUuid: string) => void; incrementActiveTime: (modelUuid: string, incrementBy: number) => void; incrementIdleTime: (modelUuid: string, incrementBy: number) => void; + incrementDistanceTraveled: (modelUuid: string, incrementBy: number) => void; resetTime: (modelUuid: string) => void; getVehicleById: (modelUuid: string) => VehicleStatus | undefined; @@ -53,7 +48,7 @@ export const createVehicleStore = () => { state.vehicles.push({ ...event, productUuid, - currentPhase: 'stationed', + currentPhase: "stationed", isActive: false, isPicking: false, idleTime: 0, @@ -61,7 +56,7 @@ export const createVehicleStore = () => { currentLoad: 0, currentMaterials: [], distanceTraveled: 0, - state: 'idle' + state: "idle", }); } }); @@ -69,9 +64,7 @@ export const createVehicleStore = () => { removeVehicle: (modelUuid) => { set((state) => { - state.vehicles = state.vehicles.filter( - (v) => v.modelUuid !== modelUuid - ); + state.vehicles = state.vehicles.filter((v) => v.modelUuid !== modelUuid); }); }, @@ -87,7 +80,7 @@ export const createVehicleStore = () => { addPathPoint: (modelUuid, pathKey, point) => { let updatedPaths: VehicleAction["paths"] = { initPickup: [], pickupDrop: [], dropPickup: [] }; set((state) => { - const vehicle = state.vehicles.find(v => v.modelUuid === modelUuid); + const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); if (vehicle) { const path = vehicle.point.action.paths[pathKey]; path.push(point); @@ -100,10 +93,10 @@ export const createVehicleStore = () => { updatePathPoint: (modelUuid, pathKey, pointId, updates) => { let updatedPaths: VehicleAction["paths"] = { initPickup: [], pickupDrop: [], dropPickup: [] }; set((state) => { - const vehicle = state.vehicles.find(v => v.modelUuid === modelUuid); + const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); if (vehicle) { const path = vehicle.point.action.paths[pathKey]; - const index = path.findIndex(p => p.pointId === pointId); + const index = path.findIndex((p) => p.pointId === pointId); if (index !== -1) { Object.assign(path[index], updates); updatedPaths = vehicle.point.action.paths; @@ -116,10 +109,10 @@ export const createVehicleStore = () => { deletePathPoint: (modelUuid, pathKey, pointId) => { let updatedPaths: VehicleAction["paths"] = { initPickup: [], pickupDrop: [], dropPickup: [] }; set((state) => { - const vehicle = state.vehicles.find(v => v.modelUuid === modelUuid); + const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); if (vehicle) { const path = vehicle.point.action.paths[pathKey]; - vehicle.point.action.paths[pathKey] = path.filter(p => p.pointId !== pointId); + vehicle.point.action.paths[pathKey] = path.filter((p) => p.pointId !== pointId); updatedPaths = vehicle.point.action.paths; } }); @@ -134,7 +127,7 @@ export const createVehicleStore = () => { setCurrentPhase: (modelUuid, phase) => { set((state) => { - const vehicle = state.vehicles.find(v => v.modelUuid === modelUuid); + const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); if (vehicle) { vehicle.currentPhase = phase; } @@ -223,7 +216,7 @@ export const createVehicleStore = () => { }, removeLastMaterial: (modelUuid) => { - let removedMaterial: { materialId: string; materialType: string; } | undefined; + let removedMaterial: { materialId: string; materialType: string } | undefined; set((state) => { const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); if (vehicle) { @@ -239,14 +232,14 @@ export const createVehicleStore = () => { }, getLastMaterial: (modelUuid) => { - let removedMaterial: { materialId: string; materialType: string; } | undefined; + let removedMaterial: { materialId: string; materialType: string } | undefined; set((state) => { const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); if (vehicle) { if (vehicle.currentMaterials.length > 0) { removedMaterial = { materialId: vehicle.currentMaterials[vehicle.currentMaterials.length - 1].materialId, - materialType: vehicle.currentMaterials[vehicle.currentMaterials.length - 1].materialType + materialType: vehicle.currentMaterials[vehicle.currentMaterials.length - 1].materialType, }; } } @@ -281,6 +274,15 @@ export const createVehicleStore = () => { }); }, + incrementDistanceTraveled: (modelUuid, incrementBy) => { + set((state) => { + const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); + if (vehicle) { + vehicle.distanceTraveled += incrementBy; + } + }); + }, + resetTime: (modelUuid) => { set((state) => { const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); @@ -307,7 +309,7 @@ export const createVehicleStore = () => { return get().vehicles.filter((v) => v.isActive); }, })) - ) -} + ); +}; -export type VehicleStoreType = ReturnType; \ No newline at end of file +export type VehicleStoreType = ReturnType;