feat: Refactor human action handling to replace animatedTravel with worker actions and enhance animation management
This commit is contained in:
@@ -0,0 +1,104 @@
|
|||||||
|
import React, { useRef } from "react";
|
||||||
|
import { AddIcon, RemoveIcon, ResizeHeightIcon } from "../../../../../icons/ExportCommonIcons";
|
||||||
|
import { handleResize } from "../../../../../../functions/handleResizePannel";
|
||||||
|
import { useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
|
||||||
|
import RenameInput from "../../../../../ui/inputs/RenameInput";
|
||||||
|
|
||||||
|
interface AnimationListProps {
|
||||||
|
animationOptions: string[];
|
||||||
|
animationSequences: {
|
||||||
|
animationUuid: string;
|
||||||
|
animationName: string;
|
||||||
|
animationType: "behaviour" | "animatedTravel";
|
||||||
|
animation: string | null;
|
||||||
|
travelPoints?: { startPoint: [number, number, number] | null; endPoint: [number, number, number] | null };
|
||||||
|
}[];
|
||||||
|
onAddAnimation: () => void;
|
||||||
|
onRemoveAnimation: (animationUuid: string) => void;
|
||||||
|
handleAnimationSelect: (animationUuid: string) => void;
|
||||||
|
handleRenameAnimation: (animationUuid: string, newName: string) => void;
|
||||||
|
selectedAnimation: {
|
||||||
|
animationUuid: string;
|
||||||
|
animationName: string;
|
||||||
|
animationType: "behaviour" | "animatedTravel";
|
||||||
|
animation: string | null;
|
||||||
|
travelPoints?: { startPoint: [number, number, number] | null; endPoint: [number, number, number] | null };
|
||||||
|
} | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const AnimationList: React.FC<AnimationListProps> = ({
|
||||||
|
animationSequences,
|
||||||
|
onAddAnimation,
|
||||||
|
onRemoveAnimation,
|
||||||
|
handleAnimationSelect,
|
||||||
|
handleRenameAnimation,
|
||||||
|
selectedAnimation
|
||||||
|
}) => {
|
||||||
|
const animationContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
const { selectedAction } = useSelectedAction();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="actions-list-container">
|
||||||
|
<div className="actions">
|
||||||
|
<div className="header">
|
||||||
|
<div className="header-value">Animation Sequences</div>
|
||||||
|
<button
|
||||||
|
id="add-action-button"
|
||||||
|
className="add-button"
|
||||||
|
onClick={onAddAnimation}
|
||||||
|
disabled={!selectedAction.actionId}
|
||||||
|
>
|
||||||
|
<AddIcon /> Add
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="lists-main-container"
|
||||||
|
ref={animationContainerRef}
|
||||||
|
style={{ height: "120px" }}
|
||||||
|
>
|
||||||
|
<div className="list-container">
|
||||||
|
{animationSequences.map((sequence) => (
|
||||||
|
<div
|
||||||
|
key={sequence.animationUuid}
|
||||||
|
className={`list-item ${selectedAnimation?.animationUuid === sequence.animationUuid ? "active" : ""}`}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
id="action-button"
|
||||||
|
className="value"
|
||||||
|
onClick={() =>
|
||||||
|
handleAnimationSelect(sequence.animationUuid)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<RenameInput
|
||||||
|
value={sequence.animationName}
|
||||||
|
onRename={(value) => handleRenameAnimation(sequence.animationUuid, value)}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
{animationSequences.length > 1 && (
|
||||||
|
<button
|
||||||
|
id="remove-action-button"
|
||||||
|
className="remove-button"
|
||||||
|
onClick={() => onRemoveAnimation(sequence.animationUuid)}
|
||||||
|
>
|
||||||
|
<RemoveIcon />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{animationSequences.length > 0 && (
|
||||||
|
<button
|
||||||
|
className="resize-icon"
|
||||||
|
id="action-resize"
|
||||||
|
onMouseDown={(e: any) => handleResize(e, animationContainerRef)}
|
||||||
|
>
|
||||||
|
<ResizeHeightIcon />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AnimationList;
|
||||||
@@ -1,27 +1,38 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
import { MathUtils } from "three";
|
||||||
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
|
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
|
||||||
import RenameInput from "../../../../../ui/inputs/RenameInput";
|
import RenameInput from "../../../../../ui/inputs/RenameInput";
|
||||||
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
|
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
|
||||||
import Trigger from "../trigger/Trigger";
|
import Trigger from "../trigger/Trigger";
|
||||||
import { useSelectedEventData, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
|
|
||||||
import PickAndPlaceAction from "../actions/PickAndPlaceAction";
|
import PickAndPlaceAction from "../actions/PickAndPlaceAction";
|
||||||
|
import ActionsList from "../components/ActionsList";
|
||||||
|
import AnimationList from "../components/AnimationList";
|
||||||
|
import { useSelectedEventData, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
|
||||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||||
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
|
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
|
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
|
||||||
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||||
import ActionsList from "../components/ActionsList";
|
import { useParams } from "react-router-dom";
|
||||||
|
|
||||||
function HumanMechanics() {
|
function HumanMechanics() {
|
||||||
const [activeOption, setActiveOption] = useState<"animatedTravel">("animatedTravel");
|
const [activeOption, setActiveOption] = useState<"worker">("worker");
|
||||||
|
const [animationOptions, setAnimationOptions] = useState<string[]>([]);
|
||||||
const [speed, setSpeed] = useState("0.5");
|
const [speed, setSpeed] = useState("0.5");
|
||||||
const [currentAction, setCurrentAction] = useState<HumanAction | undefined>();
|
const [currentAction, setCurrentAction] = useState<HumanAction | undefined>();
|
||||||
const [selectedPointData, setSelectedPointData] = useState<HumanPointSchema | undefined>();
|
const [selectedPointData, setSelectedPointData] = useState<HumanPointSchema | undefined>();
|
||||||
const { selectedEventData } = useSelectedEventData();
|
const { selectedEventData } = useSelectedEventData();
|
||||||
const { productStore } = useSceneContext();
|
const { productStore, assetStore } = useSceneContext();
|
||||||
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction } = productStore();
|
const { getAssetById } = assetStore();
|
||||||
|
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction, addAction, removeAction } = productStore();
|
||||||
const { selectedProductStore } = useProductContext();
|
const { selectedProductStore } = useProductContext();
|
||||||
const { selectedProduct } = selectedProductStore();
|
const { selectedProduct } = selectedProductStore();
|
||||||
|
const [selectedAnimation, setSelectedAnimation] = useState<{
|
||||||
|
animationUuid: string;
|
||||||
|
animationName: string;
|
||||||
|
animationType: "behaviour" | "animatedTravel";
|
||||||
|
animation: string | null;
|
||||||
|
travelPoints?: { startPoint: [number, number, number] | null; endPoint: [number, number, number] | null; }
|
||||||
|
}>();
|
||||||
const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
|
const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
|
||||||
const { selectedVersionStore } = useVersionContext();
|
const { selectedVersionStore } = useVersionContext();
|
||||||
const { selectedVersion } = selectedVersionStore();
|
const { selectedVersion } = selectedVersionStore();
|
||||||
@@ -35,10 +46,15 @@ function HumanMechanics() {
|
|||||||
selectedEventData.selectedPoint
|
selectedEventData.selectedPoint
|
||||||
) as HumanPointSchema | undefined;
|
) as HumanPointSchema | undefined;
|
||||||
|
|
||||||
if (point?.action) {
|
if (point?.actions) {
|
||||||
setSelectedPointData(point);
|
setSelectedPointData(point);
|
||||||
const action = point.action;
|
if (point.actions.length > 0) {
|
||||||
setSelectedAction(action.actionUuid, action.actionName);
|
setSelectedAction(point.actions[0].actionUuid, point.actions[0].actionName);
|
||||||
|
const asset = getAssetById(selectedEventData.data.modelUuid);
|
||||||
|
if (asset && asset.animations) {
|
||||||
|
setAnimationOptions(asset.animations)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clearSelectedAction();
|
clearSelectedAction();
|
||||||
@@ -62,11 +78,16 @@ function HumanMechanics() {
|
|||||||
selectedEventData.selectedPoint
|
selectedEventData.selectedPoint
|
||||||
) as HumanPointSchema | undefined;
|
) as HumanPointSchema | undefined;
|
||||||
|
|
||||||
if (point?.action) {
|
if (point?.actions) {
|
||||||
setSelectedPointData(point);
|
setSelectedPointData(point);
|
||||||
const action = point.action;
|
const action = point.actions.find((a) => a.actionUuid === selectedAction.actionId);
|
||||||
setCurrentAction(action);
|
if (action) {
|
||||||
setActiveOption(action.actionType as "animatedTravel");
|
setCurrentAction(action);
|
||||||
|
setActiveOption(action.actionType as "worker");
|
||||||
|
if (action.animationSequences.length > 0) {
|
||||||
|
setSelectedAnimation(action.animationSequences[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clearSelectedAction();
|
clearSelectedAction();
|
||||||
@@ -91,80 +112,387 @@ function HumanMechanics() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectActionType = (actionType: string) => {
|
const handleSelectActionType = (actionType: string) => {
|
||||||
if (!currentAction) return;
|
if (!selectedAction.actionId || !currentAction || !selectedPointData) return;
|
||||||
setActiveOption(actionType as "animatedTravel");
|
|
||||||
|
const updatedAction = {
|
||||||
|
...currentAction,
|
||||||
|
actionType: actionType as "worker"
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedPoint = {
|
||||||
|
...selectedPointData,
|
||||||
|
actions: selectedPointData.actions.map(action =>
|
||||||
|
action.actionUuid === selectedAction.actionId ? updatedAction : action
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
const event = updateAction(
|
const event = updateAction(
|
||||||
selectedProduct.productUuid,
|
selectedProduct.productUuid,
|
||||||
currentAction.actionUuid,
|
selectedAction.actionId,
|
||||||
{ actionType: actionType as "animatedTravel" }
|
updatedAction
|
||||||
);
|
);
|
||||||
|
|
||||||
if (event && selectedPointData) {
|
|
||||||
const updatedAction = { ...selectedPointData.action, actionType: actionType as "animatedTravel" };
|
|
||||||
setSelectedPointData({ ...selectedPointData, action: updatedAction });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setCurrentAction(updatedAction);
|
||||||
|
setSelectedPointData(updatedPoint);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRenameAction = (newName: string) => {
|
const handleChooseAnimation = (animationOption: string) => {
|
||||||
if (!currentAction) return;
|
if (!selectedAction.actionId || !currentAction || !selectedAnimation || !selectedPointData) return;
|
||||||
|
|
||||||
|
const updatedAnimation = {
|
||||||
|
...selectedAnimation,
|
||||||
|
animation: animationOption
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedAction = {
|
||||||
|
...currentAction,
|
||||||
|
animationSequences: currentAction.animationSequences.map(anim =>
|
||||||
|
anim.animationUuid === selectedAnimation.animationUuid ? updatedAnimation : anim
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedPoint = {
|
||||||
|
...selectedPointData,
|
||||||
|
actions: selectedPointData.actions.map(action =>
|
||||||
|
action.actionUuid === selectedAction.actionId ? updatedAction : action
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
const event = updateAction(
|
const event = updateAction(
|
||||||
selectedProduct.productUuid,
|
selectedProduct.productUuid,
|
||||||
currentAction.actionUuid,
|
selectedAction.actionId,
|
||||||
{ actionName: newName }
|
updatedAction
|
||||||
);
|
);
|
||||||
|
|
||||||
if (event && selectedPointData) {
|
|
||||||
const updatedAction = { ...selectedPointData.action, actionName: newName };
|
|
||||||
setSelectedPointData({ ...selectedPointData, action: updatedAction });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setCurrentAction(updatedAction);
|
||||||
|
setSelectedAnimation(updatedAnimation);
|
||||||
|
setSelectedPointData(updatedPoint);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSpeedChange = (value: string) => {
|
const handleSpeedChange = (value: string) => {
|
||||||
if (!selectedEventData) return;
|
if (!selectedEventData) return;
|
||||||
|
|
||||||
|
const numericValue = parseFloat(value);
|
||||||
|
if (isNaN(numericValue)) return;
|
||||||
|
|
||||||
|
const updatedEvent = {
|
||||||
|
...selectedEventData.data,
|
||||||
|
speed: numericValue
|
||||||
|
} as HumanEventSchema;
|
||||||
|
|
||||||
const event = updateEvent(
|
const event = updateEvent(
|
||||||
selectedProduct.productUuid,
|
selectedProduct.productUuid,
|
||||||
selectedEventData.data.modelUuid,
|
selectedEventData.data.modelUuid,
|
||||||
{ speed: parseFloat(value) }
|
updatedEvent
|
||||||
);
|
);
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setSpeed(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClearPoints = () => {
|
const handleClearPoints = (animationUuid: string) => {
|
||||||
if (!currentAction) return;
|
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
|
||||||
|
|
||||||
|
const updatedAnimation = currentAction.animationSequences.find(anim =>
|
||||||
|
anim.animationUuid === animationUuid
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!updatedAnimation) return;
|
||||||
|
|
||||||
|
updatedAnimation.travelPoints = {
|
||||||
|
startPoint: null,
|
||||||
|
endPoint: null
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedAction = {
|
||||||
|
...currentAction,
|
||||||
|
animationSequences: currentAction.animationSequences.map(anim =>
|
||||||
|
anim.animationUuid === animationUuid ? updatedAnimation : anim
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedPoint = {
|
||||||
|
...selectedPointData,
|
||||||
|
actions: selectedPointData.actions.map(action =>
|
||||||
|
action.actionUuid === selectedAction.actionId ? updatedAction : action
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
const event = updateAction(
|
const event = updateAction(
|
||||||
selectedProduct.productUuid,
|
selectedProduct.productUuid,
|
||||||
currentAction.actionUuid,
|
selectedAction.actionId,
|
||||||
{
|
updatedAction
|
||||||
travelPoints: {
|
|
||||||
startPoint: null,
|
|
||||||
endPoint: null,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setCurrentAction(updatedAction);
|
||||||
|
setSelectedPointData(updatedPoint);
|
||||||
|
if (selectedAnimation?.animationUuid === animationUuid) {
|
||||||
|
setSelectedAnimation(updatedAnimation);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddAction = () => {
|
||||||
|
if (!selectedEventData || !selectedPointData) return;
|
||||||
|
|
||||||
|
const newAction: HumanAction = {
|
||||||
|
actionUuid: MathUtils.generateUUID(),
|
||||||
|
actionName: `Action ${selectedPointData.actions.length + 1}`,
|
||||||
|
actionType: "worker",
|
||||||
|
animationSequences: [
|
||||||
|
{
|
||||||
|
animationUuid: MathUtils.generateUUID(),
|
||||||
|
animationName: 'Animation 1',
|
||||||
|
animationType: 'behaviour',
|
||||||
|
animation: null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
loadCapacity: 1,
|
||||||
|
triggers: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const event = addAction(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedEventData.data.modelUuid,
|
||||||
|
selectedEventData.selectedPoint,
|
||||||
|
newAction
|
||||||
|
);
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedPoint = { ...selectedPointData, actions: [...selectedPointData.actions, newAction] };
|
||||||
|
setSelectedPointData(updatedPoint);
|
||||||
|
setSelectedAction(newAction.actionUuid, newAction.actionName);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDeleteAction = (actionUuid: string) => {
|
||||||
|
if (!selectedPointData) return;
|
||||||
|
|
||||||
|
const event = removeAction(selectedProduct.productUuid, actionUuid);
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
|
}
|
||||||
|
|
||||||
|
const index = selectedPointData.actions.findIndex((a) => a.actionUuid === actionUuid);
|
||||||
|
const newActions = selectedPointData.actions.filter((a) => a.actionUuid !== actionUuid);
|
||||||
|
const updatedPoint = { ...selectedPointData, actions: newActions };
|
||||||
|
setSelectedPointData(updatedPoint);
|
||||||
|
|
||||||
|
if (selectedAction.actionId === actionUuid) {
|
||||||
|
const nextAction = newActions[index] || newActions[index - 1];
|
||||||
|
if (nextAction) {
|
||||||
|
setSelectedAction(nextAction.actionUuid, nextAction.actionName);
|
||||||
|
} else {
|
||||||
|
clearSelectedAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddAnimation = () => {
|
||||||
|
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
|
||||||
|
|
||||||
|
const newAnimation = {
|
||||||
|
animationUuid: MathUtils.generateUUID(),
|
||||||
|
animationName: `Animation ${currentAction.animationSequences.length + 1}`,
|
||||||
|
animationType: 'behaviour' as "behaviour",
|
||||||
|
animation: null
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedAction = {
|
||||||
|
...currentAction,
|
||||||
|
animationSequences: [...currentAction.animationSequences, newAnimation]
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedPoint = {
|
||||||
|
...selectedPointData,
|
||||||
|
actions: selectedPointData.actions.map(action =>
|
||||||
|
action.actionUuid === selectedAction.actionId ? updatedAction : action
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
const event = updateAction(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedAction.actionId,
|
||||||
|
updatedAction
|
||||||
|
);
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentAction(updatedAction);
|
||||||
|
setSelectedPointData(updatedPoint);
|
||||||
|
setSelectedAnimation(newAnimation);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRemoveAnimation = (animationUuid: string) => {
|
||||||
|
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
|
||||||
|
|
||||||
|
const updatedAction = {
|
||||||
|
...currentAction,
|
||||||
|
animationSequences: currentAction.animationSequences.filter(
|
||||||
|
anim => anim.animationUuid !== animationUuid
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedPoint = {
|
||||||
|
...selectedPointData,
|
||||||
|
actions: selectedPointData.actions.map(action =>
|
||||||
|
action.actionUuid === selectedAction.actionId ? updatedAction : action
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
const event = updateAction(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedAction.actionId,
|
||||||
|
updatedAction
|
||||||
|
);
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentAction(updatedAction);
|
||||||
|
setSelectedPointData(updatedPoint);
|
||||||
|
|
||||||
|
if (selectedAnimation?.animationUuid === animationUuid) {
|
||||||
|
setSelectedAnimation(updatedAction.animationSequences[0] || undefined);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAnimationTypeChange = (animationUuid: string, newType: "behaviour" | "animatedTravel") => {
|
||||||
|
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
|
||||||
|
|
||||||
|
const updatedAnimationSequences = currentAction.animationSequences.map(anim => {
|
||||||
|
if (anim.animationUuid === animationUuid) {
|
||||||
|
const updatedAnim = {
|
||||||
|
...anim,
|
||||||
|
animationType: newType
|
||||||
|
};
|
||||||
|
|
||||||
|
if (newType === 'animatedTravel') {
|
||||||
|
updatedAnim.travelPoints = {
|
||||||
|
startPoint: null,
|
||||||
|
endPoint: null
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
delete updatedAnim.travelPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedAnim;
|
||||||
|
}
|
||||||
|
return anim;
|
||||||
|
});
|
||||||
|
|
||||||
|
const updatedAction = {
|
||||||
|
...currentAction,
|
||||||
|
animationSequences: updatedAnimationSequences
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedPoint = {
|
||||||
|
...selectedPointData,
|
||||||
|
actions: selectedPointData.actions.map(action =>
|
||||||
|
action.actionUuid === selectedAction.actionId ? updatedAction : action
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
const event = updateAction(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedAction.actionId,
|
||||||
|
updatedAction
|
||||||
|
);
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentAction(updatedAction);
|
||||||
|
setSelectedPointData(updatedPoint);
|
||||||
|
|
||||||
|
if (selectedAnimation?.animationUuid === animationUuid) {
|
||||||
|
const updatedAnimation = updatedAnimationSequences.find(anim =>
|
||||||
|
anim.animationUuid === animationUuid
|
||||||
|
);
|
||||||
|
if (updatedAnimation) {
|
||||||
|
setSelectedAnimation(updatedAnimation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAnimationSelect = (animationUuid: string) => {
|
||||||
|
if (!currentAction || !selectedAction.actionId) return;
|
||||||
|
|
||||||
|
const animation = currentAction.animationSequences.find(
|
||||||
|
anim => anim.animationUuid === animationUuid
|
||||||
|
);
|
||||||
|
|
||||||
|
if (animation) {
|
||||||
|
setSelectedAnimation(animation);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRenameAnimation = (animationUuid: string, newName: string) => {
|
||||||
|
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
|
||||||
|
|
||||||
|
const updatedAnimation = currentAction.animationSequences.find(anim =>
|
||||||
|
anim.animationUuid === animationUuid
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!updatedAnimation) return;
|
||||||
|
|
||||||
|
const renamedAnimation = { ...updatedAnimation, animationName: newName };
|
||||||
|
|
||||||
|
const updatedAction = {
|
||||||
|
...currentAction,
|
||||||
|
animationSequences: currentAction.animationSequences.map(anim =>
|
||||||
|
anim.animationUuid === animationUuid ? renamedAnimation : anim
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedPoint = {
|
||||||
|
...selectedPointData,
|
||||||
|
actions: selectedPointData.actions.map(action =>
|
||||||
|
action.actionUuid === selectedAction.actionId ? updatedAction : action
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
const event = updateAction(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedAction.actionId,
|
||||||
|
updatedAction
|
||||||
|
);
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentAction(updatedAction);
|
||||||
|
setSelectedPointData(updatedPoint);
|
||||||
|
if (selectedAnimation?.animationUuid === animationUuid) {
|
||||||
|
setSelectedAnimation(renamedAnimation);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const availableActions = {
|
const availableActions = {
|
||||||
defaultOption: "animatedTravel",
|
defaultOption: "worker",
|
||||||
options: ["animatedTravel"],
|
options: ["worker"],
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -186,21 +514,20 @@ function HumanMechanics() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<section>
|
||||||
|
<ActionsList
|
||||||
|
selectedPointData={selectedPointData}
|
||||||
|
multipleAction
|
||||||
|
handleAddAction={handleAddAction}
|
||||||
|
handleDeleteAction={handleDeleteAction}
|
||||||
|
/>
|
||||||
|
|
||||||
{currentAction && (
|
{selectedAction.actionId && currentAction && (
|
||||||
<section>
|
|
||||||
|
|
||||||
<ActionsList
|
|
||||||
selectedPointData={selectedPointData}
|
|
||||||
multipleAction={false}
|
|
||||||
handleAddAction={() => { }}
|
|
||||||
handleDeleteAction={() => { }}
|
|
||||||
/>
|
|
||||||
<div className="selected-actions-details">
|
<div className="selected-actions-details">
|
||||||
<div className="selected-actions-header">
|
<div className="selected-actions-header">
|
||||||
<RenameInput
|
<RenameInput
|
||||||
value={currentAction.actionName || ""}
|
value={selectedAction.actionName || ""}
|
||||||
onRename={handleRenameAction}
|
canEdit={false}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="selected-actions-list">
|
<div className="selected-actions-list">
|
||||||
@@ -211,19 +538,61 @@ function HumanMechanics() {
|
|||||||
onSelect={handleSelectActionType}
|
onSelect={handleSelectActionType}
|
||||||
disabled={true}
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
{activeOption === 'animatedTravel' && (
|
|
||||||
<PickAndPlaceAction clearPoints={handleClearPoints} />
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
<AnimationList
|
||||||
|
animationOptions={animationOptions}
|
||||||
|
animationSequences={currentAction?.animationSequences || []}
|
||||||
|
onAddAnimation={handleAddAnimation}
|
||||||
|
onRemoveAnimation={handleRemoveAnimation}
|
||||||
|
handleAnimationSelect={handleAnimationSelect}
|
||||||
|
handleRenameAnimation={handleRenameAnimation}
|
||||||
|
selectedAnimation={selectedAnimation}
|
||||||
|
/>
|
||||||
|
{selectedAnimation && (
|
||||||
|
<>
|
||||||
|
<div className="selected-actions-header">
|
||||||
|
<RenameInput
|
||||||
|
value={selectedAnimation.animationName || ""}
|
||||||
|
canEdit={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="animation-controls">
|
||||||
|
<LabledDropdown
|
||||||
|
label="Animation Type"
|
||||||
|
defaultOption={selectedAnimation.animationType}
|
||||||
|
options={["behaviour", "animatedTravel"]}
|
||||||
|
onSelect={(type) =>
|
||||||
|
handleAnimationTypeChange(
|
||||||
|
selectedAnimation.animationUuid,
|
||||||
|
type as "behaviour" | "animatedTravel"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LabledDropdown
|
||||||
|
label="Animation"
|
||||||
|
defaultOption={selectedAnimation.animation || ''}
|
||||||
|
options={animationOptions}
|
||||||
|
onSelect={handleChooseAnimation}
|
||||||
|
disabled={true}
|
||||||
|
/>
|
||||||
|
{selectedAnimation.animationType === "animatedTravel" && (
|
||||||
|
<PickAndPlaceAction
|
||||||
|
clearPoints={() => handleClearPoints(selectedAnimation.animationUuid)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<div className="tirgger">
|
<div className="tirgger">
|
||||||
<Trigger
|
<Trigger
|
||||||
selectedPointData={selectedPointData as any}
|
selectedPointData={selectedPointData as any}
|
||||||
type="Human"
|
type={"Human"}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
)}
|
||||||
)}
|
</section>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,10 @@ interface RenameInputProps {
|
|||||||
value: string;
|
value: string;
|
||||||
onRename?: (newText: string) => void;
|
onRename?: (newText: string) => void;
|
||||||
checkDuplicate?: (name: string) => boolean;
|
checkDuplicate?: (name: string) => boolean;
|
||||||
|
canEdit?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RenameInput: React.FC<RenameInputProps> = ({ value, onRename, checkDuplicate }) => {
|
const RenameInput: React.FC<RenameInputProps> = ({ value, onRename, checkDuplicate, canEdit = true }) => {
|
||||||
const [isEditing, setIsEditing] = useState(false);
|
const [isEditing, setIsEditing] = useState(false);
|
||||||
const [text, setText] = useState(value);
|
const [text, setText] = useState(value);
|
||||||
const [isDuplicate, setIsDuplicate] = useState(false);
|
const [isDuplicate, setIsDuplicate] = useState(false);
|
||||||
@@ -28,13 +29,15 @@ const RenameInput: React.FC<RenameInputProps> = ({ value, onRename, checkDuplica
|
|||||||
}, [text, checkDuplicate]);
|
}, [text, checkDuplicate]);
|
||||||
|
|
||||||
const handleDoubleClick = () => {
|
const handleDoubleClick = () => {
|
||||||
setIsEditing(true);
|
if (canEdit) {
|
||||||
setTimeout(() => inputRef.current?.focus(), 0);
|
setIsEditing(true);
|
||||||
|
setTimeout(() => inputRef.current?.focus(), 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBlur = () => {
|
const handleBlur = () => {
|
||||||
|
|
||||||
if(isDuplicate) return
|
if (isDuplicate) return
|
||||||
setIsEditing(false);
|
setIsEditing(false);
|
||||||
if (onRename && !isDuplicate) {
|
if (onRename && !isDuplicate) {
|
||||||
onRename(text);
|
onRename(text);
|
||||||
|
|||||||
@@ -256,18 +256,23 @@ function AssetsGroup({ plane }: { readonly plane: RefMesh }) {
|
|||||||
uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
|
uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
|
||||||
position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
|
position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
|
||||||
rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
|
rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
|
||||||
action: {
|
actions: [
|
||||||
actionUuid: THREE.MathUtils.generateUUID(),
|
{
|
||||||
actionName: "Action 1",
|
actionUuid: THREE.MathUtils.generateUUID(),
|
||||||
actionType: "animatedTravel",
|
actionName: "Action 1",
|
||||||
loadCapacity: 1,
|
actionType: "worker",
|
||||||
travelPoints: {
|
animationSequences: [
|
||||||
startPoint: null,
|
{
|
||||||
endPoint: null,
|
animationUuid: THREE.MathUtils.generateUUID(),
|
||||||
},
|
animationName: 'Animation 1',
|
||||||
triggers: []
|
animationType: 'behaviour',
|
||||||
}
|
animation: null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
loadCapacity: 1,
|
||||||
|
triggers: []
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addEvent(humanEvent);
|
addEvent(humanEvent);
|
||||||
|
|||||||
@@ -374,17 +374,23 @@ async function handleModelLoad(
|
|||||||
uuid: THREE.MathUtils.generateUUID(),
|
uuid: THREE.MathUtils.generateUUID(),
|
||||||
position: [data.points[0].x, data.points[0].y, data.points[0].z],
|
position: [data.points[0].x, data.points[0].y, data.points[0].z],
|
||||||
rotation: [0, 0, 0],
|
rotation: [0, 0, 0],
|
||||||
action: {
|
actions: [
|
||||||
actionUuid: THREE.MathUtils.generateUUID(),
|
{
|
||||||
actionName: "Action 1",
|
actionUuid: THREE.MathUtils.generateUUID(),
|
||||||
actionType: "animatedTravel",
|
actionName: "Action 1",
|
||||||
loadCapacity: 1,
|
actionType: "worker",
|
||||||
travelPoints: {
|
animationSequences: [
|
||||||
startPoint: null,
|
{
|
||||||
endPoint: null,
|
animationUuid: THREE.MathUtils.generateUUID(),
|
||||||
},
|
animationName: 'Animation 1',
|
||||||
triggers: []
|
animationType: 'behaviour',
|
||||||
}
|
animation: null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
loadCapacity: 1,
|
||||||
|
triggers: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useCallback } from "react";
|
|||||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||||
import { useProductContext } from "../../../products/productContext";
|
import { useProductContext } from "../../../products/productContext";
|
||||||
|
|
||||||
export function useAnimatedTravelHandler() {
|
export function useWorkerHandler() {
|
||||||
const { materialStore, humanStore, productStore } = useSceneContext();
|
const { materialStore, humanStore, productStore } = useSceneContext();
|
||||||
const { getMaterialById } = materialStore();
|
const { getMaterialById } = materialStore();
|
||||||
const { } = humanStore();
|
const { } = humanStore();
|
||||||
@@ -10,12 +10,12 @@ export function useAnimatedTravelHandler() {
|
|||||||
const { selectedProductStore } = useProductContext();
|
const { selectedProductStore } = useProductContext();
|
||||||
const { selectedProduct } = selectedProductStore();
|
const { selectedProduct } = selectedProductStore();
|
||||||
|
|
||||||
const animatedTravelLogStatus = (materialUuid: string, status: string) => {
|
const workerLogStatus = (materialUuid: string, status: string) => {
|
||||||
echo.info(`${materialUuid}, ${status}`);
|
echo.info(`${materialUuid}, ${status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleAnimatedTravel = useCallback((action: HumanAction, materialId?: string) => {
|
const handleWorker = useCallback((action: HumanAction, materialId?: string) => {
|
||||||
if (!action || action.actionType !== 'animatedTravel' || !materialId) return;
|
if (!action || action.actionType !== 'worker' || !materialId) return;
|
||||||
|
|
||||||
const material = getMaterialById(materialId);
|
const material = getMaterialById(materialId);
|
||||||
if (!material) return;
|
if (!material) return;
|
||||||
@@ -24,11 +24,11 @@ export function useAnimatedTravelHandler() {
|
|||||||
if (!modelUuid) return;
|
if (!modelUuid) return;
|
||||||
|
|
||||||
|
|
||||||
animatedTravelLogStatus(material.materialName, `performing animatedTravel`);
|
workerLogStatus(material.materialName, `performing worker action`);
|
||||||
|
|
||||||
}, [getMaterialById]);
|
}, [getMaterialById]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
handleAnimatedTravel,
|
handleWorker,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,24 +1,24 @@
|
|||||||
import { useEffect, useCallback } from 'react';
|
import { useEffect, useCallback } from 'react';
|
||||||
import { useAnimatedTravelHandler } from './actionHandler/useAnimatedTravelHandler';
|
import { useWorkerHandler } from './actionHandler/useWorkerHandler';
|
||||||
|
|
||||||
export function useHumanActions() {
|
export function useHumanActions() {
|
||||||
const { handleAnimatedTravel } = useAnimatedTravelHandler();
|
const { handleWorker } = useWorkerHandler();
|
||||||
|
|
||||||
const handleAnimatedTravelAction = useCallback((action: HumanAction) => {
|
const handleWorkerAction = useCallback((action: HumanAction) => {
|
||||||
handleAnimatedTravel(action);
|
handleWorker(action);
|
||||||
}, [handleAnimatedTravel]);
|
}, [handleWorker]);
|
||||||
|
|
||||||
const handleHumanAction = useCallback((action: HumanAction, materialId: string) => {
|
const handleHumanAction = useCallback((action: HumanAction, materialId: string) => {
|
||||||
if (!action) return;
|
if (!action) return;
|
||||||
|
|
||||||
switch (action.actionType) {
|
switch (action.actionType) {
|
||||||
case 'animatedTravel':
|
case 'worker':
|
||||||
handleAnimatedTravelAction(action);
|
handleWorkerAction(action);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.warn(`Unknown Human action type: ${action.actionType}`);
|
console.warn(`Unknown Human action type: ${action.actionType}`);
|
||||||
}
|
}
|
||||||
}, [handleAnimatedTravelAction]);
|
}, [handleWorkerAction]);
|
||||||
|
|
||||||
const cleanup = useCallback(() => {
|
const cleanup = useCallback(() => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export function useActionHandler() {
|
|||||||
case 'store': case 'retrieve':
|
case 'store': case 'retrieve':
|
||||||
handleStorageAction(action as StorageAction, materialId as string);
|
handleStorageAction(action as StorageAction, materialId as string);
|
||||||
break;
|
break;
|
||||||
case 'animatedTravel':
|
case 'worker':
|
||||||
handleHumanAction(action as HumanAction, materialId as string);
|
handleHumanAction(action as HumanAction, materialId as string);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -155,8 +155,8 @@ function TriggerConnector() {
|
|||||||
// Handle Human point
|
// Handle Human point
|
||||||
else if (event.type === "human" && 'point' in event) {
|
else if (event.type === "human" && 'point' in event) {
|
||||||
const point = event.point;
|
const point = event.point;
|
||||||
if (point.action?.triggers) {
|
point.actions?.forEach(action => {
|
||||||
point.action.triggers.forEach(trigger => {
|
action.triggers?.forEach(trigger => {
|
||||||
if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint) {
|
if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint) {
|
||||||
newConnections.push({
|
newConnections.push({
|
||||||
id: `${point.uuid}-${trigger.triggeredAsset.triggeredPoint.pointUuid}-${trigger.triggerUuid}`,
|
id: `${point.uuid}-${trigger.triggeredAsset.triggeredPoint.pointUuid}-${trigger.triggerUuid}`,
|
||||||
@@ -166,7 +166,7 @@ function TriggerConnector() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ type ProductsStore = {
|
|||||||
productUuid: string,
|
productUuid: string,
|
||||||
modelUuid: string,
|
modelUuid: string,
|
||||||
pointUuid: string,
|
pointUuid: string,
|
||||||
action: ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action'] | HumanPointSchema['action']
|
action: ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action'] | HumanPointSchema['actions'][0]
|
||||||
) => EventsSchema | undefined;
|
) => EventsSchema | undefined;
|
||||||
removeAction: (productUuid: string, actionUuid: string) => EventsSchema | undefined;
|
removeAction: (productUuid: string, actionUuid: string) => EventsSchema | undefined;
|
||||||
updateAction: (
|
updateAction: (
|
||||||
productUuid: string,
|
productUuid: string,
|
||||||
actionUuid: string,
|
actionUuid: string,
|
||||||
updates: Partial<ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action'] | HumanPointSchema['action']>
|
updates: Partial<ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action'] | HumanPointSchema['actions'][0]>
|
||||||
) => EventsSchema | undefined;
|
) => EventsSchema | undefined;
|
||||||
|
|
||||||
// Trigger-level actionss
|
// Trigger-level actionss
|
||||||
|
|||||||
13
app/src/types/simulationTypes.d.ts
vendored
13
app/src/types/simulationTypes.d.ts
vendored
@@ -72,9 +72,15 @@ interface StorageAction {
|
|||||||
interface HumanAction {
|
interface HumanAction {
|
||||||
actionUuid: string;
|
actionUuid: string;
|
||||||
actionName: string;
|
actionName: string;
|
||||||
actionType: "animatedTravel";
|
actionType: "worker";
|
||||||
|
animationSequences: {
|
||||||
|
animationUuid: string;
|
||||||
|
animationName: string;
|
||||||
|
animationType: "behaviour" | "animatedTravel";
|
||||||
|
animation: string | null;
|
||||||
|
travelPoints?: { startPoint: [number, number, number] | null; endPoint: [number, number, number] | null; }
|
||||||
|
}[]
|
||||||
loadCapacity: number;
|
loadCapacity: number;
|
||||||
travelPoints?: { startPoint: [number, number, number] | null; endPoint: [number, number, number] | null; }
|
|
||||||
triggers: TriggerSchema[];
|
triggers: TriggerSchema[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +126,7 @@ interface HumanPointSchema {
|
|||||||
uuid: string;
|
uuid: string;
|
||||||
position: [number, number, number];
|
position: [number, number, number];
|
||||||
rotation: [number, number, number];
|
rotation: [number, number, number];
|
||||||
action: HumanAction;
|
actions: HumanAction[];
|
||||||
}
|
}
|
||||||
|
|
||||||
type PointsScheme = | ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema | HumanPointSchema;
|
type PointsScheme = | ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema | HumanPointSchema;
|
||||||
@@ -229,6 +235,7 @@ interface HumanStatus extends HumanEventSchema {
|
|||||||
currentAction?: {
|
currentAction?: {
|
||||||
actionUuid: string;
|
actionUuid: string;
|
||||||
actionName: string;
|
actionName: string;
|
||||||
|
animationUuid: string;
|
||||||
materialType?: string | null;
|
materialType?: string | null;
|
||||||
materialId?: string | null;
|
materialId?: string | null;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user