Merge remote-tracking branch 'origin/main-dev' into feature/agv-edit
This commit is contained in:
@@ -22,7 +22,9 @@ interface AssetsStore {
|
||||
|
||||
// Animation controls
|
||||
setAnimations: (modelUuid: string, animations: string[]) => void;
|
||||
setCurrentAnimation: (modelUuid: string, current: string, isPlaying: boolean) => void;
|
||||
setCurrentAnimation: (modelUuid: string, current: string, isPlaying: boolean, loopAnimation: boolean, isCompleted: boolean) => void;
|
||||
setAnimationComplete: (modelUuid: string, isCompleted: boolean) => void;
|
||||
resetAnimation: (modelUuid: string) => void;
|
||||
addAnimation: (modelUuid: string, animation: string) => void;
|
||||
removeAnimation: (modelUuid: string, animation: string) => void;
|
||||
|
||||
@@ -149,22 +151,44 @@ export const createAssetStore = () => {
|
||||
if (asset) {
|
||||
asset.animations = animations;
|
||||
if (!asset.animationState) {
|
||||
asset.animationState = { current: '', playing: false };
|
||||
asset.animationState = { current: '', isPlaying: false, loopAnimation: true, isCompleted: true };
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setCurrentAnimation: (modelUuid, current, isPlaying) => {
|
||||
setCurrentAnimation: (modelUuid, current, isPlaying, loopAnimation, isCompleted) => {
|
||||
set((state) => {
|
||||
const asset = state.assets.find(a => a.modelUuid === modelUuid);
|
||||
if (asset?.animationState) {
|
||||
asset.animationState.current = current;
|
||||
asset.animationState.playing = isPlaying;
|
||||
asset.animationState.isPlaying = isPlaying;
|
||||
asset.animationState.loopAnimation = loopAnimation;
|
||||
asset.animationState.isCompleted = isCompleted;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setAnimationComplete: (modelUuid, isCompleted) => {
|
||||
set((state) => {
|
||||
const asset = state.assets.find(a => a.modelUuid === modelUuid);
|
||||
if (asset?.animationState) {
|
||||
asset.animationState.isCompleted = isCompleted;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
resetAnimation: (modelUuid) => {
|
||||
set((state) => {
|
||||
const asset = state.assets.find(a => a.modelUuid === modelUuid);
|
||||
if (asset?.animationState) {
|
||||
asset.animationState.current = '';
|
||||
asset.animationState.isPlaying = true;
|
||||
asset.animationState.loopAnimation = true;
|
||||
asset.animationState.isCompleted = true; }
|
||||
});
|
||||
},
|
||||
|
||||
addAnimation: (modelUuid, animation) => {
|
||||
set((state) => {
|
||||
const asset = state.assets.find(a => a.modelUuid === modelUuid);
|
||||
@@ -184,7 +208,7 @@ export const createAssetStore = () => {
|
||||
if (asset?.animations) {
|
||||
asset.animations = asset.animations.filter(a => a !== animation);
|
||||
if (asset.animationState?.current === animation) {
|
||||
asset.animationState.playing = false;
|
||||
asset.animationState.isPlaying = false;
|
||||
asset.animationState.current = '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ interface BuilderState {
|
||||
|
||||
// Floor Asset
|
||||
selectedFloorAsset: Object3D | null;
|
||||
loopAnimation: boolean;
|
||||
|
||||
// Wall Settings
|
||||
selectedWall: Object3D | null;
|
||||
@@ -64,6 +65,7 @@ interface BuilderState {
|
||||
|
||||
// Setters - Floor Asset
|
||||
setSelectedFloorAsset: (asset: Object3D | null) => void;
|
||||
setLoopAnimation: (loop: boolean) => void;
|
||||
|
||||
// Setters - Wall
|
||||
setSelectedWall: (wall: Object3D | null) => void;
|
||||
@@ -118,6 +120,7 @@ export const useBuilderStore = create<BuilderState>()(
|
||||
deletableWallAsset: null,
|
||||
|
||||
selectedFloorAsset: null,
|
||||
loopAnimation: true,
|
||||
|
||||
selectedWall: null,
|
||||
wallThickness: 0.5,
|
||||
@@ -197,6 +200,12 @@ export const useBuilderStore = create<BuilderState>()(
|
||||
});
|
||||
},
|
||||
|
||||
setLoopAnimation(loopAnimation: boolean) {
|
||||
set((state) => {
|
||||
state.loopAnimation = loopAnimation;
|
||||
});
|
||||
},
|
||||
|
||||
// === Setters: Wall ===
|
||||
|
||||
setSelectedWall: (wall: Object3D | null) => {
|
||||
|
||||
238
app/src/store/simulation/useHumanStore.ts
Normal file
238
app/src/store/simulation/useHumanStore.ts
Normal file
@@ -0,0 +1,238 @@
|
||||
import { create } from "zustand";
|
||||
import { immer } from "zustand/middleware/immer";
|
||||
|
||||
interface HumansStore {
|
||||
humans: HumanStatus[];
|
||||
|
||||
addHuman: (productUuid: string, event: HumanEventSchema) => void;
|
||||
removeHuman: (modelUuid: string) => void;
|
||||
updateHuman: (
|
||||
modelUuid: string,
|
||||
updates: Partial<Omit<HumanStatus, "modelUuid" | "productUuid">>
|
||||
) => void;
|
||||
clearHumans: () => void;
|
||||
|
||||
setHumanActive: (modelUuid: string, isActive: boolean) => void;
|
||||
setHumanPicking: (modelUuid: string, isPicking: boolean) => void;
|
||||
setHumanLoad: (modelUuid: string, load: number) => void;
|
||||
setHumanState: (
|
||||
modelUuid: string,
|
||||
newState: HumanStatus["state"]
|
||||
) => void;
|
||||
incrementHumanLoad: (modelUuid: string, incrementBy: number) => void;
|
||||
decrementHumanLoad: (modelUuid: string, decrementBy: number) => void;
|
||||
|
||||
addCurrentMaterial: (modelUuid: string, materialType: string, materialId: string) => void;
|
||||
setCurrentMaterials: (modelUuid: string, materials: { materialType: string; materialId: string }[]) => void;
|
||||
removeLastMaterial: (modelUuid: string) => { materialType: string; materialId: string } | undefined;
|
||||
getLastMaterial: (modelUuid: string) => { materialType: string; materialId: 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;
|
||||
|
||||
getHumanById: (modelUuid: string) => HumanStatus | undefined;
|
||||
getHumansByProduct: (productUuid: string) => HumanStatus[];
|
||||
getActiveHumans: () => HumanStatus[];
|
||||
}
|
||||
|
||||
export const createHumanStore = () => {
|
||||
return create<HumansStore>()(
|
||||
immer((set, get) => ({
|
||||
humans: [],
|
||||
|
||||
addHuman: (productUuid, event) => {
|
||||
set((state) => {
|
||||
const exists = state.humans.some(h => h.modelUuid === event.modelUuid);
|
||||
if (!exists) {
|
||||
state.humans.push({
|
||||
...event,
|
||||
productUuid,
|
||||
isActive: false,
|
||||
isPicking: false,
|
||||
idleTime: 0,
|
||||
activeTime: 0,
|
||||
currentLoad: 0,
|
||||
currentMaterials: [],
|
||||
distanceTraveled: 0
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
removeHuman: (modelUuid) => {
|
||||
set((state) => {
|
||||
state.humans = state.humans.filter(h => h.modelUuid !== modelUuid);
|
||||
});
|
||||
},
|
||||
|
||||
updateHuman: (modelUuid, updates) => {
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human) {
|
||||
Object.assign(human, updates);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
clearHumans: () => {
|
||||
set((state) => {
|
||||
state.humans = [];
|
||||
});
|
||||
},
|
||||
|
||||
setHumanActive: (modelUuid, isActive) => {
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human) {
|
||||
human.isActive = isActive;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setHumanPicking: (modelUuid, isPicking) => {
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human) {
|
||||
human.isPicking = isPicking;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setHumanLoad: (modelUuid, load) => {
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human) {
|
||||
human.currentLoad = load;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setHumanState: (modelUuid, newState) => {
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human) {
|
||||
human.state = newState;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
incrementHumanLoad: (modelUuid, incrementBy) => {
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human) {
|
||||
human.currentLoad += incrementBy;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
decrementHumanLoad: (modelUuid, decrementBy) => {
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human) {
|
||||
human.currentLoad -= decrementBy;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
addCurrentMaterial: (modelUuid, materialType, materialId) => {
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human) {
|
||||
human.currentMaterials.push({ materialType, materialId });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setCurrentMaterials: (modelUuid, materials) => {
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human) {
|
||||
human.currentMaterials = materials;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
removeLastMaterial: (modelUuid) => {
|
||||
let removed;
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human && human.currentMaterials.length > 0) {
|
||||
removed = JSON.parse(JSON.stringify(human.currentMaterials.pop()));
|
||||
}
|
||||
});
|
||||
return removed;
|
||||
},
|
||||
|
||||
getLastMaterial: (modelUuid) => {
|
||||
const human = get().humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human && human.currentMaterials.length > 0) {
|
||||
return human.currentMaterials[human.currentMaterials.length - 1];
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
clearCurrentMaterials: (modelUuid) => {
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human) {
|
||||
human.currentMaterials = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
incrementActiveTime: (modelUuid, incrementBy) => {
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human) {
|
||||
human.activeTime += incrementBy;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
incrementIdleTime: (modelUuid, incrementBy) => {
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human) {
|
||||
human.idleTime += incrementBy;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
incrementDistanceTraveled: (modelUuid, incrementBy) => {
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human) {
|
||||
human.distanceTraveled += incrementBy;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
resetTime: (modelUuid) => {
|
||||
set((state) => {
|
||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||
if (human) {
|
||||
human.activeTime = 0;
|
||||
human.idleTime = 0;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getHumanById: (modelUuid) => {
|
||||
return get().humans.find(h => h.modelUuid === modelUuid);
|
||||
},
|
||||
|
||||
getHumansByProduct: (productUuid) => {
|
||||
return get().humans.filter(h => h.productUuid === productUuid);
|
||||
},
|
||||
|
||||
getActiveHumans: () => {
|
||||
return get().humans.filter(h => h.isActive);
|
||||
}
|
||||
}))
|
||||
);
|
||||
};
|
||||
|
||||
export type HumanStoreType = ReturnType<typeof createHumanStore>;
|
||||
@@ -32,13 +32,13 @@ type ProductsStore = {
|
||||
productUuid: string,
|
||||
modelUuid: string,
|
||||
pointUuid: string,
|
||||
action: ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']
|
||||
action: ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action'] | HumanPointSchema['action']
|
||||
) => EventsSchema | undefined;
|
||||
removeAction: (productUuid: string, actionUuid: string) => EventsSchema | undefined;
|
||||
updateAction: (
|
||||
productUuid: string,
|
||||
actionUuid: string,
|
||||
updates: Partial<ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']>
|
||||
updates: Partial<ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action'] | HumanPointSchema['action']>
|
||||
) => EventsSchema | undefined;
|
||||
|
||||
// Trigger-level actionss
|
||||
@@ -276,6 +276,15 @@ export const createProductStore = () => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (event.type === "human") {
|
||||
if ('actions' in point) {
|
||||
const index = point.actions.findIndex((a: any) => a.actionUuid === actionUuid);
|
||||
if (index !== -1) {
|
||||
point.actions.splice(index, 1);
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if ('action' in point && point.action?.actionUuid === actionUuid) {
|
||||
point.action = undefined;
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
|
||||
@@ -146,6 +146,40 @@ export const useSelectedAction = create<SelectedActionState>()(
|
||||
}))
|
||||
);
|
||||
|
||||
interface SelectedAnimationState {
|
||||
selectedAnimation: {
|
||||
animationUuid: string;
|
||||
animationName: string;
|
||||
animationType: "behaviour" | "animatedTravel";
|
||||
animation: string | null;
|
||||
travelPoints?: { startPoint: [number, number, number] | null; endPoint: [number, number, number] | null; }
|
||||
} | null;
|
||||
setSelectedAnimation: (animation: {
|
||||
animationUuid: string;
|
||||
animationName: string;
|
||||
animationType: "behaviour" | "animatedTravel";
|
||||
animation: string | null;
|
||||
travelPoints?: { startPoint: [number, number, number] | null; endPoint: [number, number, number] | null; }
|
||||
}) => void;
|
||||
clearSelectedAnimation: () => void;
|
||||
}
|
||||
|
||||
export const useSelectedAnimation = create<SelectedAnimationState>()(
|
||||
immer((set) => ({
|
||||
selectedAnimation: null,
|
||||
setSelectedAnimation: (animation) => {
|
||||
set((state) => {
|
||||
state.selectedAnimation = animation;
|
||||
});
|
||||
},
|
||||
clearSelectedAnimation: () => {
|
||||
set((state) => {
|
||||
state.selectedAnimation = null;
|
||||
});
|
||||
},
|
||||
}))
|
||||
);
|
||||
|
||||
interface IsDraggingState {
|
||||
isDragging: "start" | "end" | null;
|
||||
setIsDragging: (state: "start" | "end" | null) => void;
|
||||
|
||||
Reference in New Issue
Block a user