feat: Implement human event handling in copy and duplication controls

- Added support for handling "Human" type events in the copy and duplication controls.
- Created a new HumanEventSchema to manage human-related events, including position, rotation, and action details.
- Updated the HumanAnimator to improve rotation handling using quaternions for smoother transitions.
- Enhanced the HumanInstance to ensure proper synchronization of human positions and rotations.
- Integrated human event handling in the trigger handler for various interactions, including vehicle and machine actions.
- Introduced material drop functionality from vehicles to humans, allowing for dynamic interactions in the simulation.
This commit is contained in:
2025-07-04 17:15:10 +05:30
parent ff02f01430
commit 508c88dce2
9 changed files with 821 additions and 86 deletions

View File

@@ -1,5 +1,6 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import * as THREE from 'three';
import { useThree } from '@react-three/fiber';
import { NavMeshQuery } from '@recast-navigation/core';
import { useNavMesh } from '../../../../../store/builder/store';
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
@@ -13,6 +14,7 @@ import MaterialAnimator from '../animator/materialAnimator';
function HumanInstance({ human }: { human: HumanStatus }) {
const { navMesh } = useNavMesh();
const { isPlaying } = usePlayButtonStore();
const { scene } = useThree();
const { assetStore, materialStore, armBotStore, conveyorStore, machineStore, vehicleStore, humanStore, storageUnitStore, productStore } = useSceneContext();
const { removeMaterial, setEndTime } = materialStore();
const { getStorageUnitById } = storageUnitStore();
@@ -92,6 +94,11 @@ function HumanInstance({ human }: { human: HumanStatus }) {
cancelAnimationFrame(animationFrameIdRef.current)
animationFrameIdRef.current = null
}
const object = scene.getObjectByProperty('uuid', human.modelUuid);
if (object && human) {
object.position.set(human.position[0], human.position[1], human.position[2]);
object.rotation.set(human.rotation[0], human.rotation[1], human.rotation[2]);
}
}
useEffect(() => {
@@ -292,6 +299,7 @@ function HumanInstance({ human }: { human: HumanStatus }) {
}
function handleMaterialDropToStorageUnit(model: StorageEventSchema) {
const humanAsset = getAssetById(human.modelUuid);
if (model && humanAsset?.animationState?.current !== 'drop') {
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
}
@@ -322,6 +330,7 @@ function HumanInstance({ human }: { human: HumanStatus }) {
action: HumanAction
) {
const storageUnit = getStorageUnitById(storageUnitId);
const humanAsset = getAssetById(human.modelUuid);
if (!storageUnit || humanCurrentLoad <= 0 || storageUnit.currentLoad >= storageMaxCapacity) {
return;
@@ -340,7 +349,7 @@ function HumanInstance({ human }: { human: HumanStatus }) {
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
const waitForNextDrop = () => {
if (humanAsset?.animationState?.isCompleted) {
if (humanAsset?.animationState?.current === 'drop' && humanAsset?.animationState?.isCompleted) {
loopMaterialDropToStorage(
humanId,
humanCurrentLoad,
@@ -357,6 +366,7 @@ function HumanInstance({ human }: { human: HumanStatus }) {
}
function handleMaterialDropToConveyor(model: ConveyorEventSchema) {
const humanAsset = getAssetById(human.modelUuid);
if (humanAsset?.animationState?.current !== 'drop') {
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
}
@@ -386,6 +396,7 @@ function HumanInstance({ human }: { human: HumanStatus }) {
action: HumanAction
) {
const conveyor = getConveyorById(conveyorId);
const humanAsset = getAssetById(human.modelUuid);
if (!conveyor || humanCurrentLoad <= 0) {
return;
@@ -420,12 +431,13 @@ function HumanInstance({ human }: { human: HumanStatus }) {
}
function handleMaterialDropToArmBot(model: RoboticArmEventSchema) {
const humanAsset = getAssetById(human.modelUuid);
if (humanAsset?.animationState?.current !== 'drop') {
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
}
const checkAnimation = () => {
if (humanAsset?.animationState?.isCompleted) {
if (humanAsset?.animationState?.current === 'drop' && humanAsset?.animationState?.isCompleted) {
const armBot = getArmBotById(model.modelUuid);
if (armBot && armBot.state === 'idle' && !armBot.isActive) {
loopMaterialDropToArmBot(
@@ -449,6 +461,7 @@ function HumanInstance({ human }: { human: HumanStatus }) {
action: HumanAction
) {
const armBot = getArmBotById(armBotId);
const humanAsset = getAssetById(human.modelUuid);
if (!armBot || armBot.state !== 'idle' || armBot.isActive || humanCurrentLoad <= 0) {
return;
@@ -488,12 +501,13 @@ function HumanInstance({ human }: { human: HumanStatus }) {
}
function handleMaterialDropToVehicle(model: VehicleEventSchema) {
const humanAsset = getAssetById(human.modelUuid);
if (humanAsset?.animationState?.current !== 'drop') {
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
}
const checkAnimation = () => {
if (humanAsset?.animationState?.isCompleted) {
if (humanAsset?.animationState?.current === 'drop' && humanAsset?.animationState?.isCompleted) {
const vehicle = getVehicleById(model.modelUuid);
if (vehicle && vehicle.state === 'idle' && !vehicle.isActive) {
loopMaterialDropToVehicle(
@@ -517,6 +531,7 @@ function HumanInstance({ human }: { human: HumanStatus }) {
action: HumanAction
) {
const vehicle = getVehicleById(vehicleId);
const humanAsset = getAssetById(human.modelUuid);
if (!vehicle || vehicle.state !== 'idle' || vehicle.isActive || humanCurrentLoad <= 0) {
return;
@@ -535,10 +550,10 @@ function HumanInstance({ human }: { human: HumanStatus }) {
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
const waitForNextTransfer = () => {
const currentArmBot = getVehicleById(vehicleId);
if (currentArmBot && currentArmBot.state === 'idle' && !currentArmBot.isActive) {
const currentVehicle = getVehicleById(vehicleId);
if (currentVehicle && currentVehicle.state === 'idle' && !currentVehicle.isActive) {
if (humanAsset?.animationState?.isCompleted) {
loopMaterialDropToArmBot(
loopMaterialDropToVehicle(
humanId,
humanCurrentLoad,
vehicleId,
@@ -556,12 +571,13 @@ function HumanInstance({ human }: { human: HumanStatus }) {
}
function handleMaterialDropToMachine(model: MachineEventSchema) {
const humanAsset = getAssetById(human.modelUuid);
if (humanAsset?.animationState?.current !== 'drop') {
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
}
const checkAnimation = () => {
if (humanAsset?.animationState?.isCompleted) {
if (humanAsset?.animationState?.current === 'drop' && humanAsset?.animationState?.isCompleted) {
const machine = getMachineById(model.modelUuid);
if (machine && machine.state === 'idle' && !machine.isActive) {
loopMaterialDropToMachine(
@@ -585,6 +601,7 @@ function HumanInstance({ human }: { human: HumanStatus }) {
action: HumanAction
) {
const machine = getMachineById(machineId);
const humanAsset = getAssetById(human.modelUuid);
if (!machine || machine.state !== 'idle' || machine.isActive || humanCurrentLoad <= 0) {
return;
@@ -603,10 +620,10 @@ function HumanInstance({ human }: { human: HumanStatus }) {
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
const waitForNextTransfer = () => {
const currentArmBot = getMachineById(machineId);
if (currentArmBot && currentArmBot.state === 'idle' && !currentArmBot.isActive) {
const currentMachine = getMachineById(machineId);
if (currentMachine && currentMachine.state === 'idle' && !currentMachine.isActive) {
if (humanAsset?.animationState?.isCompleted) {
loopMaterialDropToArmBot(
loopMaterialDropToMachine(
humanId,
humanCurrentLoad,
machineId,
@@ -624,6 +641,7 @@ function HumanInstance({ human }: { human: HumanStatus }) {
}
function handleMaterialDropByDefault(droppedMaterial: number) {
const humanAsset = getAssetById(human.modelUuid);
if (humanAsset?.animationState?.current !== 'drop') {
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
}