completed init movement for human
This commit is contained in:
@@ -40,15 +40,10 @@ function HumanMechanics() {
|
|||||||
selectedEventData.selectedPoint
|
selectedEventData.selectedPoint
|
||||||
) as HumanPointSchema | undefined;
|
) as HumanPointSchema | undefined;
|
||||||
|
|
||||||
if (point?.actions) {
|
if (point?.action) {
|
||||||
setSelectedPointData(point);
|
setSelectedPointData(point);
|
||||||
if (point.actions.length > 0) {
|
setCurrentAction(point.action);
|
||||||
setSelectedAction(point.actions[0].actionUuid, point.actions[0].actionName);
|
setSelectedAction(point.action.actionUuid, point.action.actionName);
|
||||||
const asset = getAssetById(selectedEventData.data.modelUuid);
|
|
||||||
if (asset && asset.animations) {
|
|
||||||
setAnimationOptions(asset.animations)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clearSelectedAction();
|
clearSelectedAction();
|
||||||
@@ -57,31 +52,17 @@ function HumanMechanics() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedEventData && selectedProduct.productUuid) {
|
if (selectedEventData && selectedProduct.productUuid) {
|
||||||
const event = getEventByModelUuid(
|
|
||||||
selectedProduct.productUuid,
|
|
||||||
selectedEventData.data.modelUuid
|
|
||||||
) as HumanEventSchema | undefined;
|
|
||||||
|
|
||||||
if (event?.speed !== undefined) {
|
|
||||||
setSpeed(event.speed.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
const point = getPointByUuid(
|
const point = getPointByUuid(
|
||||||
selectedProduct.productUuid,
|
selectedProduct.productUuid,
|
||||||
selectedEventData.data.modelUuid,
|
selectedEventData.data.modelUuid,
|
||||||
selectedEventData.selectedPoint
|
selectedEventData.selectedPoint
|
||||||
) as HumanPointSchema | undefined;
|
) as HumanPointSchema | undefined;
|
||||||
|
|
||||||
if (point?.actions) {
|
if (point?.action) {
|
||||||
setSelectedPointData(point);
|
setSelectedPointData(point);
|
||||||
const action = point.actions.find((a) => a.actionUuid === selectedAction.actionId);
|
setCurrentAction(point.action);
|
||||||
if (action) {
|
setActiveOption(point.action.actionType);
|
||||||
setCurrentAction(action);
|
setSelectedAction(point.action.actionUuid, point.action.actionName);
|
||||||
setActiveOption(action.actionType as "worker");
|
|
||||||
if (action.animationSequences.length > 0) {
|
|
||||||
setSelectedAnimation(action.animationSequences[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clearSelectedAction();
|
clearSelectedAction();
|
||||||
@@ -108,17 +89,8 @@ function HumanMechanics() {
|
|||||||
const handleSelectActionType = (actionType: string) => {
|
const handleSelectActionType = (actionType: string) => {
|
||||||
if (!selectedAction.actionId || !currentAction || !selectedPointData) return;
|
if (!selectedAction.actionId || !currentAction || !selectedPointData) return;
|
||||||
|
|
||||||
const updatedAction = {
|
const updatedAction = { ...currentAction, actionType: actionType as "worker" };
|
||||||
...currentAction,
|
const updatedPoint = { ...selectedPointData, action: updatedAction };
|
||||||
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,
|
||||||
@@ -134,43 +106,6 @@ function HumanMechanics() {
|
|||||||
setSelectedPointData(updatedPoint);
|
setSelectedPointData(updatedPoint);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleChooseAnimation = (animationOption: string) => {
|
|
||||||
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(
|
|
||||||
selectedProduct.productUuid,
|
|
||||||
selectedAction.actionId,
|
|
||||||
updatedAction
|
|
||||||
);
|
|
||||||
|
|
||||||
if (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;
|
||||||
|
|
||||||
@@ -195,31 +130,14 @@ function HumanMechanics() {
|
|||||||
setSpeed(value);
|
setSpeed(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClearPoints = (animationUuid: string) => {
|
const handleClearPoints = () => {
|
||||||
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
|
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
|
||||||
|
|
||||||
const updatedAnimation = currentAction.animationSequences.find(anim =>
|
const updatedAction = { ...currentAction };
|
||||||
anim.animationUuid === animationUuid
|
delete updatedAction.pickUpPoint;
|
||||||
);
|
delete updatedAction.dropPoint;
|
||||||
|
|
||||||
if (!updatedAnimation) return;
|
const updatedPoint = { ...selectedPointData, action: updatedAction };
|
||||||
|
|
||||||
delete updatedAnimation.startPoint;
|
|
||||||
delete updatedAnimation.endPoint;
|
|
||||||
|
|
||||||
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,
|
||||||
@@ -233,9 +151,6 @@ function HumanMechanics() {
|
|||||||
|
|
||||||
setCurrentAction(updatedAction);
|
setCurrentAction(updatedAction);
|
||||||
setSelectedPointData(updatedPoint);
|
setSelectedPointData(updatedPoint);
|
||||||
if (selectedAnimation?.animationUuid === animationUuid) {
|
|
||||||
setSelectedAnimation(updatedAnimation);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAddAction = () => {
|
const handleAddAction = () => {
|
||||||
@@ -243,16 +158,8 @@ function HumanMechanics() {
|
|||||||
|
|
||||||
const newAction: HumanAction = {
|
const newAction: HumanAction = {
|
||||||
actionUuid: MathUtils.generateUUID(),
|
actionUuid: MathUtils.generateUUID(),
|
||||||
actionName: `Action ${selectedPointData.actions.length + 1}`,
|
actionName: `Action`,
|
||||||
actionType: "worker",
|
actionType: "worker",
|
||||||
animationSequences: [
|
|
||||||
{
|
|
||||||
animationUuid: MathUtils.generateUUID(),
|
|
||||||
animationName: 'Animation 1',
|
|
||||||
animationType: 'behaviour',
|
|
||||||
animation: null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
loadCapacity: 1,
|
loadCapacity: 1,
|
||||||
triggers: [],
|
triggers: [],
|
||||||
};
|
};
|
||||||
@@ -268,217 +175,27 @@ function HumanMechanics() {
|
|||||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedPoint = { ...selectedPointData, actions: [...selectedPointData.actions, newAction] };
|
const updatedPoint = { ...selectedPointData, action: newAction };
|
||||||
setSelectedPointData(updatedPoint);
|
setSelectedPointData(updatedPoint);
|
||||||
setSelectedAction(newAction.actionUuid, newAction.actionName);
|
setSelectedAction(newAction.actionUuid, newAction.actionName);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteAction = (actionUuid: string) => {
|
const handleDeleteAction = () => {
|
||||||
if (!selectedPointData) return;
|
if (!selectedPointData) return;
|
||||||
|
|
||||||
const event = removeAction(selectedProduct.productUuid, actionUuid);
|
const event = removeAction(
|
||||||
|
|
||||||
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,
|
selectedProduct.productUuid,
|
||||||
selectedAction.actionId,
|
selectedPointData.action.actionUuid
|
||||||
updatedAction
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
}
|
}
|
||||||
|
|
||||||
setCurrentAction(updatedAction);
|
const updatedPoint = { ...selectedPointData, action: undefined as any };
|
||||||
setSelectedPointData(updatedPoint);
|
setSelectedPointData(updatedPoint);
|
||||||
setSelectedAnimation(newAnimation);
|
clearSelectedAction();
|
||||||
};
|
setCurrentAction(undefined);
|
||||||
|
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
delete updatedAnim.startPoint;
|
|
||||||
delete updatedAnim.endPoint;
|
|
||||||
|
|
||||||
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 = {
|
|
||||||
defaultOption: "worker",
|
|
||||||
options: ["worker"],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -503,7 +220,7 @@ function HumanMechanics() {
|
|||||||
<section>
|
<section>
|
||||||
<ActionsList
|
<ActionsList
|
||||||
selectedPointData={selectedPointData}
|
selectedPointData={selectedPointData}
|
||||||
multipleAction
|
multipleAction={false}
|
||||||
handleAddAction={handleAddAction}
|
handleAddAction={handleAddAction}
|
||||||
handleDeleteAction={handleDeleteAction}
|
handleDeleteAction={handleDeleteAction}
|
||||||
/>
|
/>
|
||||||
@@ -511,69 +228,20 @@ function HumanMechanics() {
|
|||||||
{selectedAction.actionId && currentAction && (
|
{selectedAction.actionId && currentAction && (
|
||||||
<div className="selected-actions-details">
|
<div className="selected-actions-details">
|
||||||
<div className="selected-actions-header">
|
<div className="selected-actions-header">
|
||||||
<RenameInput
|
<RenameInput value={selectedAction.actionName || ""} canEdit={false} />
|
||||||
value={selectedAction.actionName || ""}
|
|
||||||
canEdit={false}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="selected-actions-list">
|
<div className="selected-actions-list">
|
||||||
<LabledDropdown
|
<LabledDropdown
|
||||||
label="Action Type"
|
label="Action Type"
|
||||||
defaultOption={activeOption}
|
defaultOption={activeOption}
|
||||||
options={availableActions.options}
|
options={["worker"]}
|
||||||
onSelect={handleSelectActionType}
|
onSelect={handleSelectActionType}
|
||||||
disabled={true}
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<AnimationList
|
<PickAndPlaceAction clearPoints={handleClearPoints} />
|
||||||
animationOptions={animationOptions}
|
|
||||||
animationSequences={currentAction?.animationSequences || []}
|
|
||||||
onAddAnimation={handleAddAnimation}
|
|
||||||
onRemoveAnimation={handleRemoveAnimation}
|
|
||||||
handleAnimationSelect={handleAnimationSelect}
|
|
||||||
handleRenameAnimation={handleRenameAnimation}
|
|
||||||
/>
|
|
||||||
{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} type="Human" />
|
||||||
selectedPointData={selectedPointData as any}
|
|
||||||
type={"Human"}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -256,23 +256,14 @@ 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],
|
||||||
actions: [
|
action: {
|
||||||
{
|
actionUuid: THREE.MathUtils.generateUUID(),
|
||||||
actionUuid: THREE.MathUtils.generateUUID(),
|
actionName: "Action 1",
|
||||||
actionName: "Action 1",
|
actionType: "worker",
|
||||||
actionType: "worker",
|
loadCapacity: 1,
|
||||||
animationSequences: [
|
triggers: []
|
||||||
{
|
}
|
||||||
animationUuid: THREE.MathUtils.generateUUID(),
|
|
||||||
animationName: 'Animation 1',
|
|
||||||
animationType: 'behaviour',
|
|
||||||
animation: null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
loadCapacity: 1,
|
|
||||||
triggers: []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addEvent(humanEvent);
|
addEvent(humanEvent);
|
||||||
|
|||||||
@@ -373,23 +373,13 @@ 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],
|
||||||
actions: [
|
action: {
|
||||||
{
|
actionUuid: THREE.MathUtils.generateUUID(),
|
||||||
actionUuid: THREE.MathUtils.generateUUID(),
|
actionName: "Action 1",
|
||||||
actionName: "Action 1",
|
actionType: "worker",
|
||||||
actionType: "worker",
|
loadCapacity: 1,
|
||||||
animationSequences: [
|
triggers: []
|
||||||
{
|
}
|
||||||
animationUuid: THREE.MathUtils.generateUUID(),
|
|
||||||
animationName: 'Animation 1',
|
|
||||||
animationType: 'behaviour',
|
|
||||||
animation: null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
loadCapacity: 1,
|
|
||||||
triggers: []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export const handleAddEventToProduct = ({
|
|||||||
projectId: projectId || '',
|
projectId: projectId || '',
|
||||||
eventDatas: event
|
eventDatas: event
|
||||||
}).then((data) => {
|
}).then((data) => {
|
||||||
console.log(data);
|
// console.log(data);
|
||||||
})
|
})
|
||||||
|
|
||||||
if (clearSelectedAsset) {
|
if (clearSelectedAsset) {
|
||||||
|
|||||||
@@ -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;
|
||||||
point.actions?.forEach(action => {
|
if (point.action?.triggers) {
|
||||||
action.triggers?.forEach(trigger => {
|
point.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() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { useSceneContext } from '../../../scene/sceneContext';
|
|||||||
|
|
||||||
type HumanCallback = {
|
type HumanCallback = {
|
||||||
humanId: string;
|
humanId: string;
|
||||||
actionId: string;
|
|
||||||
callback: () => void;
|
callback: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -25,10 +24,10 @@ export function useHumanEventManager() {
|
|||||||
}, [isReset])
|
}, [isReset])
|
||||||
|
|
||||||
// Add a new human to monitor
|
// Add a new human to monitor
|
||||||
const addHumanToMonitor = (humanId: string, actionId: string, callback: () => void) => {
|
const addHumanToMonitor = (humanId: string, callback: () => void) => {
|
||||||
// Avoid duplicates
|
// Avoid duplicates
|
||||||
if (!callbacksRef.current.some((entry) => entry.humanId === humanId)) {
|
if (!callbacksRef.current.some((entry) => entry.humanId === humanId)) {
|
||||||
callbacksRef.current.push({ humanId, actionId, callback });
|
callbacksRef.current.push({ humanId, callback });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start monitoring if not already running
|
// Start monitoring if not already running
|
||||||
@@ -53,11 +52,9 @@ export function useHumanEventManager() {
|
|||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
if (!isMonitoringRef.current || callbacksRef.current.length === 0 || !isPlaying || isPaused) return;
|
if (!isMonitoringRef.current || callbacksRef.current.length === 0 || !isPlaying || isPaused) return;
|
||||||
|
|
||||||
callbacksRef.current.forEach(({ humanId, actionId, callback }) => {
|
callbacksRef.current.forEach(({ humanId, callback }) => {
|
||||||
const human = getHumanById(humanId);
|
const human = getHumanById(humanId);
|
||||||
if (!human) return;
|
if (human && human.isActive === false && human.state === 'idle' && human.isPicking && human.currentLoad < human.point.action.loadCapacity) {
|
||||||
const action = human.point.actions.find((action) => action.actionUuid === actionId);
|
|
||||||
if (action && human.isActive === false && human.state === 'idle' && human.isPicking && human.currentLoad < action.loadCapacity) {
|
|
||||||
callback();
|
callback();
|
||||||
removeHumanFromMonitor(humanId); // Remove after triggering
|
removeHumanFromMonitor(humanId); // Remove after triggering
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,7 @@ function Human() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedEventSphere) {
|
if (selectedEventSphere) {
|
||||||
const selectedHuman = getHumanById(selectedEventSphere.userData.modelUuid);
|
const selectedHuman = getHumanById(selectedEventSphere.userData.modelUuid);
|
||||||
if (selectedHuman &&
|
if (selectedHuman) {
|
||||||
selectedHuman.point.actions.some((action) =>
|
|
||||||
action.animationSequences.some((animation) =>
|
|
||||||
animation.animationUuid === selectedAnimation?.animationUuid && animation.animationType === 'animatedTravel'
|
|
||||||
)
|
|
||||||
)) {
|
|
||||||
setIsHumanSelected(true);
|
setIsHumanSelected(true);
|
||||||
} else {
|
} else {
|
||||||
setIsHumanSelected(false);
|
setIsHumanSelected(false);
|
||||||
|
|||||||
@@ -0,0 +1,170 @@
|
|||||||
|
import { useEffect, useRef, useState } from 'react'
|
||||||
|
import { useFrame, useThree } from '@react-three/fiber';
|
||||||
|
import * as THREE from 'three';
|
||||||
|
import { Line } from '@react-three/drei';
|
||||||
|
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||||
|
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||||
|
|
||||||
|
interface HumanAnimatorProps {
|
||||||
|
path: [number, number, number][];
|
||||||
|
handleCallBack: () => void;
|
||||||
|
reset: () => void;
|
||||||
|
startUnloadingProcess: () => void;
|
||||||
|
currentPhase: string;
|
||||||
|
human: HumanStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
function HumanAnimator({ path, handleCallBack, currentPhase, human, reset, startUnloadingProcess }: Readonly<HumanAnimatorProps>) {
|
||||||
|
const { humanStore } = useSceneContext();
|
||||||
|
const { getHumanById } = humanStore();
|
||||||
|
const { isPaused } = usePauseButtonStore();
|
||||||
|
const { isPlaying } = usePlayButtonStore();
|
||||||
|
const { speed } = useAnimationPlaySpeed();
|
||||||
|
const { isReset, setReset } = useResetButtonStore();
|
||||||
|
const progressRef = useRef<number>(0);
|
||||||
|
const movingForward = useRef<boolean>(true);
|
||||||
|
const completedRef = useRef<boolean>(false);
|
||||||
|
const [objectRotation, setObjectRotation] = useState<[number, number, number] | null>(human.point?.action?.pickUpPoint?.rotation || [0, 0, 0])
|
||||||
|
const [restRotation, setRestingRotation] = useState<boolean>(true);
|
||||||
|
const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]);
|
||||||
|
const { scene } = useThree();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (currentPhase === 'init-pickup' && path.length > 0) {
|
||||||
|
setCurrentPath(path);
|
||||||
|
setObjectRotation(human.point.action.pickUpPoint?.rotation ?? null)
|
||||||
|
} else if (currentPhase === 'pickup-drop' && path.length > 0) {
|
||||||
|
setObjectRotation(human.point.action?.dropPoint?.rotation ?? null)
|
||||||
|
setCurrentPath(path);
|
||||||
|
} else if (currentPhase === 'drop-pickup' && path.length > 0) {
|
||||||
|
setObjectRotation(human.point.action?.pickUpPoint?.rotation ?? null)
|
||||||
|
setCurrentPath(path);
|
||||||
|
}
|
||||||
|
}, [currentPhase, path, objectRotation]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
completedRef.current = false;
|
||||||
|
}, [currentPath]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isReset || !isPlaying) {
|
||||||
|
reset();
|
||||||
|
setCurrentPath([]);
|
||||||
|
completedRef.current = false;
|
||||||
|
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) {
|
||||||
|
object.position.set(humanData.position[0], humanData.position[1], humanData.position[2]);
|
||||||
|
object.rotation.set(humanData.rotation[0], humanData.rotation[1], humanData.rotation[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isReset, isPlaying])
|
||||||
|
|
||||||
|
const lastTimeRef = useRef(performance.now());
|
||||||
|
|
||||||
|
useFrame(() => {
|
||||||
|
const now = performance.now();
|
||||||
|
const delta = (now - lastTimeRef.current) / 1000;
|
||||||
|
lastTimeRef.current = now;
|
||||||
|
|
||||||
|
const object = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||||
|
if (!object || currentPath.length < 2) return;
|
||||||
|
if (isPaused) return;
|
||||||
|
|
||||||
|
let totalDistance = 0;
|
||||||
|
const distances = [];
|
||||||
|
let accumulatedDistance = 0;
|
||||||
|
let index = 0;
|
||||||
|
const rotationSpeed = 1;
|
||||||
|
|
||||||
|
for (let i = 0; i < currentPath.length - 1; i++) {
|
||||||
|
const start = new THREE.Vector3(...currentPath[i]);
|
||||||
|
const end = new THREE.Vector3(...currentPath[i + 1]);
|
||||||
|
const segmentDistance = start.distanceTo(end);
|
||||||
|
distances.push(segmentDistance);
|
||||||
|
totalDistance += segmentDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (index < distances.length && progressRef.current > accumulatedDistance + distances[index]) {
|
||||||
|
accumulatedDistance += distances[index];
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < distances.length) {
|
||||||
|
const start = new THREE.Vector3(...currentPath[index]);
|
||||||
|
const end = new THREE.Vector3(...currentPath[index + 1]);
|
||||||
|
const segmentDistance = distances[index];
|
||||||
|
|
||||||
|
const currentDirection = new THREE.Vector3().subVectors(end, start).normalize();
|
||||||
|
const targetAngle = Math.atan2(currentDirection.x, currentDirection.z);
|
||||||
|
const currentAngle = object.rotation.y;
|
||||||
|
|
||||||
|
let angleDifference = targetAngle - currentAngle;
|
||||||
|
if (angleDifference > Math.PI) angleDifference -= 2 * Math.PI;
|
||||||
|
if (angleDifference < -Math.PI) angleDifference += 2 * Math.PI;
|
||||||
|
|
||||||
|
const maxRotationStep = (rotationSpeed * speed * human.speed) * delta;
|
||||||
|
object.rotation.y += Math.sign(angleDifference) * Math.min(Math.abs(angleDifference), maxRotationStep);
|
||||||
|
const isAligned = Math.abs(angleDifference) < 0.01;
|
||||||
|
|
||||||
|
if (isAligned) {
|
||||||
|
progressRef.current += delta * (speed * human.speed);
|
||||||
|
const t = (progressRef.current - accumulatedDistance) / segmentDistance;
|
||||||
|
const position = start.clone().lerp(end, t);
|
||||||
|
object.position.copy(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (progressRef.current >= totalDistance) {
|
||||||
|
if (restRotation && objectRotation) {
|
||||||
|
const targetEuler = new THREE.Euler(
|
||||||
|
objectRotation[0],
|
||||||
|
objectRotation[1] + Math.PI,
|
||||||
|
objectRotation[2]
|
||||||
|
);
|
||||||
|
const targetQuaternion = new THREE.Quaternion().setFromEuler(targetEuler);
|
||||||
|
object.quaternion.slerp(targetQuaternion, delta * (rotationSpeed * speed * human.speed));
|
||||||
|
if (object.quaternion.angleTo(targetQuaternion) < 0.01) {
|
||||||
|
object.quaternion.copy(targetQuaternion);
|
||||||
|
object.rotation.copy(targetEuler);
|
||||||
|
setRestingRotation(false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (progressRef.current >= totalDistance) {
|
||||||
|
setRestingRotation(true);
|
||||||
|
progressRef.current = 0;
|
||||||
|
movingForward.current = !movingForward.current;
|
||||||
|
setCurrentPath([]);
|
||||||
|
handleCallBack();
|
||||||
|
if (currentPhase === 'pickup-drop') {
|
||||||
|
requestAnimationFrame(startUnloadingProcess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{currentPath.length > 0 && (
|
||||||
|
// helper
|
||||||
|
<group >
|
||||||
|
<Line points={currentPath} color="blue" lineWidth={3} />
|
||||||
|
{currentPath.map((point, index) => (
|
||||||
|
<mesh key={index} position={point}>
|
||||||
|
<sphereGeometry args={[0.1, 16, 16]} />
|
||||||
|
<meshStandardMaterial color="red" />
|
||||||
|
</mesh>
|
||||||
|
))}
|
||||||
|
</group>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HumanAnimator
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
|
|
||||||
function HumanAnimator() {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default HumanAnimator
|
|
||||||
@@ -7,7 +7,7 @@ import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHa
|
|||||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||||
import { useProductContext } from '../../../products/productContext';
|
import { useProductContext } from '../../../products/productContext';
|
||||||
|
|
||||||
import HumanAnimator from './animator/humanAnimator';
|
import HumanAnimator from '../animator/humanAnimator';
|
||||||
|
|
||||||
function HumanInstance({ human }: { human: HumanStatus }) {
|
function HumanInstance({ human }: { human: HumanStatus }) {
|
||||||
const { navMesh } = useNavMesh();
|
const { navMesh } = useNavMesh();
|
||||||
@@ -66,12 +66,10 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
console.error("Failed to compute path");
|
console.error("Failed to compute path");
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
},
|
}, [navMesh]);
|
||||||
[navMesh]
|
|
||||||
);
|
|
||||||
|
|
||||||
function humanStatus(modelId: string, status: string) {
|
function humanStatus(modelId: string, status: string) {
|
||||||
// console.log(`${modelId} , ${status}`);
|
console.log(`${modelId} , ${status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
@@ -96,6 +94,25 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
|
if (!human.point.action.pickUpPoint || !human.point.action.dropPoint) return;
|
||||||
|
|
||||||
|
if (!human.isActive && human.state === 'idle' && currentPhase === 'init') {
|
||||||
|
const toPickupPath = computePath(
|
||||||
|
new THREE.Vector3(human?.position[0], human?.position[1], human?.position[2]),
|
||||||
|
new THREE.Vector3(
|
||||||
|
human?.point?.action?.pickUpPoint?.position?.[0] ?? 0,
|
||||||
|
human?.point?.action?.pickUpPoint?.position?.[1] ?? 0,
|
||||||
|
human?.point?.action?.pickUpPoint?.position?.[2] ?? 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
setPath(toPickupPath);
|
||||||
|
setCurrentPhase('init-pickup');
|
||||||
|
setHumanState(human.modelUuid, 'running');
|
||||||
|
setHumanPicking(human.modelUuid, false);
|
||||||
|
setHumanActive(human.modelUuid, true);
|
||||||
|
humanStatus(human.modelUuid, 'Started from init, heading to pickup');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -104,10 +121,28 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [human, currentPhase, path, isPlaying]);
|
}, [human, currentPhase, path, isPlaying]);
|
||||||
|
|
||||||
|
function handleCallBack() {
|
||||||
|
if (currentPhase === 'init-pickup') {
|
||||||
|
setCurrentPhase('picking');
|
||||||
|
} else if (currentPhase === 'pickup-drop') {
|
||||||
|
} else if (currentPhase === 'drop-pickup') {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function startUnloadingProcess() {
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
<HumanAnimator />
|
<HumanAnimator
|
||||||
|
path={path}
|
||||||
|
handleCallBack={handleCallBack}
|
||||||
|
currentPhase={currentPhase}
|
||||||
|
human={human}
|
||||||
|
reset={reset}
|
||||||
|
startUnloadingProcess={startUnloadingProcess}
|
||||||
|
/>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -60,35 +60,29 @@ function HumanUi() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!selectedEventSphere) return;
|
if (!selectedEventSphere) return;
|
||||||
|
|
||||||
const selectedHuman = getHumanById(selectedEventSphere.userData.modelUuid);
|
const selectedHuman = getHumanById(selectedEventSphere.userData.modelUuid);
|
||||||
|
if (!selectedHuman || !selectedHuman.point?.action) return;
|
||||||
|
|
||||||
if (selectedHuman) {
|
setSelectedHumanData({
|
||||||
setSelectedHumanData({
|
position: selectedHuman.position,
|
||||||
position: selectedHuman.position,
|
rotation: selectedHuman.rotation,
|
||||||
rotation: selectedHuman.rotation,
|
});
|
||||||
});
|
|
||||||
|
|
||||||
if (selectedHuman.point?.actions && selectedAction.actionId) {
|
const action = selectedHuman.point.action;
|
||||||
const action = selectedHuman.point.actions.find(a => a.actionUuid === selectedAction.actionId);
|
|
||||||
|
|
||||||
if (action?.animationSequences[0]) {
|
if (action.pickUpPoint?.position && outerGroup.current) {
|
||||||
const sequence = action.animationSequences[0];
|
const worldPos = new Vector3(...action.pickUpPoint.position);
|
||||||
|
const localPosition = outerGroup.current.worldToLocal(worldPos.clone());
|
||||||
|
setStartPosition([localPosition.x, 0.5, localPosition.z]);
|
||||||
|
setStartRotation(action.pickUpPoint.rotation || [0, 0, 0]);
|
||||||
|
}
|
||||||
|
|
||||||
if (sequence.startPoint?.position && outerGroup.current) {
|
if (action.dropPoint?.position && outerGroup.current) {
|
||||||
const worldPos = new Vector3(...sequence.startPoint.position);
|
const worldPos = new Vector3(...action.dropPoint.position);
|
||||||
const localPosition = outerGroup.current.worldToLocal(worldPos.clone());
|
const localPosition = outerGroup.current.worldToLocal(worldPos.clone());
|
||||||
setStartPosition([localPosition.x, 0.5, localPosition.z]);
|
setEndPosition([localPosition.x, 0.5, localPosition.z]);
|
||||||
setStartRotation(sequence.startPoint.rotation || [0, 0, 0]);
|
setEndRotation(action.dropPoint.rotation || [0, 0, 0]);
|
||||||
}
|
|
||||||
|
|
||||||
if (sequence.endPoint?.position && outerGroup.current) {
|
|
||||||
const worldPos = new Vector3(...sequence.endPoint.position);
|
|
||||||
const localPosition = outerGroup.current.worldToLocal(worldPos.clone());
|
|
||||||
setEndPosition([localPosition.x, 0.5, localPosition.z]);
|
|
||||||
setEndRotation(sequence.endPoint.rotation || [0, 0, 0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, [selectedEventSphere, outerGroup.current, selectedAction, humans]);
|
}, [selectedEventSphere, outerGroup.current, selectedAction, humans]);
|
||||||
|
|
||||||
@@ -126,29 +120,17 @@ function HumanUi() {
|
|||||||
const worldPosEnd = new Vector3(...endPosition);
|
const worldPosEnd = new Vector3(...endPosition);
|
||||||
const globalEndPosition = outerGroup.current.localToWorld(worldPosEnd.clone());
|
const globalEndPosition = outerGroup.current.localToWorld(worldPosEnd.clone());
|
||||||
|
|
||||||
const updatedActions = selectedHuman.point.actions.map(action => {
|
const updatedAction = {
|
||||||
if (action.actionUuid === selectedAction.actionId) {
|
...selectedHuman.point.action,
|
||||||
const updatedSequences = action.animationSequences.map(sequence => {
|
pickUpPoint: {
|
||||||
return {
|
position: [globalStartPosition.x, globalStartPosition.y, globalStartPosition.z] as [number, number, number],
|
||||||
...sequence,
|
rotation: startRotation
|
||||||
startPoint: {
|
},
|
||||||
position: [globalStartPosition.x, globalStartPosition.y, globalStartPosition.z] as [number, number, number],
|
dropPoint: {
|
||||||
rotation: startRotation
|
position: [globalEndPosition.x, globalEndPosition.y, globalEndPosition.z] as [number, number, number],
|
||||||
},
|
rotation: endRotation
|
||||||
endPoint: {
|
|
||||||
position: [globalEndPosition.x, globalEndPosition.y, globalEndPosition.z] as [number, number, number],
|
|
||||||
rotation: endRotation
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
...action,
|
|
||||||
animationSequences: updatedSequences
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
return action;
|
};
|
||||||
});
|
|
||||||
|
|
||||||
const event = updateEvent(
|
const event = updateEvent(
|
||||||
selectedProduct.productUuid,
|
selectedProduct.productUuid,
|
||||||
@@ -157,7 +139,7 @@ function HumanUi() {
|
|||||||
...selectedHuman,
|
...selectedHuman,
|
||||||
point: {
|
point: {
|
||||||
...selectedHuman.point,
|
...selectedHuman.point,
|
||||||
actions: updatedActions
|
action: updatedAction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -195,8 +177,7 @@ function HumanUi() {
|
|||||||
const currentPointerX = state.pointer.x;
|
const currentPointerX = state.pointer.x;
|
||||||
const deltaX = currentPointerX - prevMousePos.current.x;
|
const deltaX = currentPointerX - prevMousePos.current.x;
|
||||||
prevMousePos.current.x = currentPointerX;
|
prevMousePos.current.x = currentPointerX;
|
||||||
const marker =
|
const marker =isRotating === "start" ? startMarker.current : endMarker.current;
|
||||||
isRotating === "start" ? startMarker.current : endMarker.current;
|
|
||||||
if (marker) {
|
if (marker) {
|
||||||
const rotationSpeed = 10;
|
const rotationSpeed = 10;
|
||||||
marker.rotation.y += deltaX * rotationSpeed;
|
marker.rotation.y += deltaX * rotationSpeed;
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ export function useTriggerHandler() {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Handle current action using Event Manager
|
// Handle current action using Event Manager
|
||||||
addHumanToMonitor(human.modelUuid, triggeredAction.actionUuid, () => {
|
addHumanToMonitor(human.modelUuid, () => {
|
||||||
handleAction(action, materialId);
|
handleAction(action, materialId);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (currentPhase === 'stationed-pickup' && path.length > 0) {
|
if (currentPhase === 'stationed-pickup' && path.length > 0) {
|
||||||
// console.log('path: ', path);
|
|
||||||
setCurrentPath(path);
|
setCurrentPath(path);
|
||||||
setObjectRotation(agvDetail.point.action?.pickUpPoint?.rotation)
|
setObjectRotation(agvDetail.point.action?.pickUpPoint?.rotation)
|
||||||
} else if (currentPhase === 'pickup-drop' && path.length > 0) {
|
} else if (currentPhase === 'pickup-drop' && path.length > 0) {
|
||||||
@@ -66,84 +65,6 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
|
|||||||
}
|
}
|
||||||
}, [isReset, isPlaying])
|
}, [isReset, isPlaying])
|
||||||
|
|
||||||
// useFrame((_, delta) => {
|
|
||||||
// const object = scene.getObjectByProperty('uuid', agvUuid);
|
|
||||||
// if (!object || currentPath.length < 2) return;
|
|
||||||
// if (isPaused) return;
|
|
||||||
|
|
||||||
// let totalDistance = 0;
|
|
||||||
// const distances = [];
|
|
||||||
// let accumulatedDistance = 0;
|
|
||||||
// let index = 0;
|
|
||||||
// const rotationSpeed = 1;
|
|
||||||
|
|
||||||
// for (let i = 0; i < currentPath.length - 1; i++) {
|
|
||||||
// const start = new THREE.Vector3(...currentPath[i]);
|
|
||||||
// const end = new THREE.Vector3(...currentPath[i + 1]);
|
|
||||||
// const segmentDistance = start.distanceTo(end);
|
|
||||||
// distances.push(segmentDistance);
|
|
||||||
// totalDistance += segmentDistance;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// while (index < distances.length && progressRef.current > accumulatedDistance + distances[index]) {
|
|
||||||
// accumulatedDistance += distances[index];
|
|
||||||
// index++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (index < distances.length) {
|
|
||||||
// const start = new THREE.Vector3(...currentPath[index]);
|
|
||||||
// const end = new THREE.Vector3(...currentPath[index + 1]);
|
|
||||||
// const segmentDistance = distances[index];
|
|
||||||
|
|
||||||
// const currentDirection = new THREE.Vector3().subVectors(end, start).normalize();
|
|
||||||
// const targetAngle = Math.atan2(currentDirection.x, currentDirection.z);
|
|
||||||
|
|
||||||
// const currentAngle = object.rotation.y;
|
|
||||||
|
|
||||||
// let angleDifference = targetAngle - currentAngle;
|
|
||||||
// if (angleDifference > Math.PI) angleDifference -= 2 * Math.PI;
|
|
||||||
// if (angleDifference < -Math.PI) angleDifference += 2 * Math.PI;
|
|
||||||
|
|
||||||
// const maxRotationStep = (rotationSpeed * speed * agvDetail.speed) * delta;
|
|
||||||
// object.rotation.y += Math.sign(angleDifference) * Math.min(Math.abs(angleDifference), maxRotationStep);
|
|
||||||
// const isAligned = Math.abs(angleDifference) < 0.01;
|
|
||||||
|
|
||||||
// if (isAligned) {
|
|
||||||
// progressRef.current += delta * (speed * agvDetail.speed);
|
|
||||||
// const t = (progressRef.current - accumulatedDistance) / segmentDistance;
|
|
||||||
// const position = start.clone().lerp(end, t);
|
|
||||||
// object.position.copy(position);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (progressRef.current >= totalDistance) {
|
|
||||||
// if (restRotation && objectRotation) {
|
|
||||||
// const targetEuler = new THREE.Euler(
|
|
||||||
// objectRotation.x,
|
|
||||||
// objectRotation.y - (agvDetail.point.action.steeringAngle),
|
|
||||||
// objectRotation.z
|
|
||||||
// );
|
|
||||||
// const targetQuaternion = new THREE.Quaternion().setFromEuler(targetEuler);
|
|
||||||
// object.quaternion.slerp(targetQuaternion, delta * (rotationSpeed * speed * agvDetail.speed));
|
|
||||||
// if (object.quaternion.angleTo(targetQuaternion) < 0.01) {
|
|
||||||
// object.quaternion.copy(targetQuaternion);
|
|
||||||
// object.rotation.copy(targetEuler);
|
|
||||||
// setRestingRotation(false);
|
|
||||||
// }
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (progressRef.current >= totalDistance) {
|
|
||||||
// setRestingRotation(true);
|
|
||||||
// progressRef.current = 0;
|
|
||||||
// movingForward.current = !movingForward.current;
|
|
||||||
// setCurrentPath([]);
|
|
||||||
// handleCallBack();
|
|
||||||
// if (currentPhase === 'pickup-drop') {
|
|
||||||
// requestAnimationFrame(startUnloadingProcess);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
const lastTimeRef = useRef(performance.now());
|
const lastTimeRef = useRef(performance.now());
|
||||||
|
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
|
|||||||
@@ -104,6 +104,10 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||||||
new THREE.Vector3(agvDetail?.position[0], agvDetail?.position[1], agvDetail?.position[2]),
|
new THREE.Vector3(agvDetail?.position[0], agvDetail?.position[1], agvDetail?.position[2]),
|
||||||
agvDetail?.point?.action?.pickUpPoint?.position
|
agvDetail?.point?.action?.pickUpPoint?.position
|
||||||
);
|
);
|
||||||
|
// const toPickupPath = computePath(
|
||||||
|
// new THREE.Vector3(agvDetail?.position[0], agvDetail?.position[1], agvDetail?.position[2]),
|
||||||
|
// new THREE.Vector3(agvDetail?.position[0], agvDetail?.position[1], agvDetail?.position[2])
|
||||||
|
// );
|
||||||
setPath(toPickupPath);
|
setPath(toPickupPath);
|
||||||
setCurrentPhase('stationed-pickup');
|
setCurrentPhase('stationed-pickup');
|
||||||
setVehicleState(agvDetail.modelUuid, 'running');
|
setVehicleState(agvDetail.modelUuid, 'running');
|
||||||
@@ -193,7 +197,6 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||||||
};
|
};
|
||||||
}, [agvDetail, isPlaying]);
|
}, [agvDetail, isPlaying]);
|
||||||
|
|
||||||
|
|
||||||
function handleCallBack() {
|
function handleCallBack() {
|
||||||
if (currentPhase === 'stationed-pickup') {
|
if (currentPhase === 'stationed-pickup') {
|
||||||
setCurrentPhase('picking');
|
setCurrentPhase('picking');
|
||||||
|
|||||||
@@ -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['actions'][0]
|
action: ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action'] | HumanPointSchema['action']
|
||||||
) => 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['actions'][0]>
|
updates: Partial<ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action'] | HumanPointSchema['action']>
|
||||||
) => EventsSchema | undefined;
|
) => EventsSchema | undefined;
|
||||||
|
|
||||||
// Trigger-level actionss
|
// Trigger-level actionss
|
||||||
|
|||||||
12
app/src/types/simulationTypes.d.ts
vendored
12
app/src/types/simulationTypes.d.ts
vendored
@@ -73,14 +73,8 @@ interface HumanAction {
|
|||||||
actionUuid: string;
|
actionUuid: string;
|
||||||
actionName: string;
|
actionName: string;
|
||||||
actionType: "worker";
|
actionType: "worker";
|
||||||
animationSequences: {
|
pickUpPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; }
|
||||||
animationUuid: string;
|
dropPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; }
|
||||||
animationName: string;
|
|
||||||
animationType: "behaviour" | "animatedTravel";
|
|
||||||
animation: string | null;
|
|
||||||
startPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; }
|
|
||||||
endPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; }
|
|
||||||
}[]
|
|
||||||
loadCapacity: number;
|
loadCapacity: number;
|
||||||
triggers: TriggerSchema[];
|
triggers: TriggerSchema[];
|
||||||
}
|
}
|
||||||
@@ -127,7 +121,7 @@ interface HumanPointSchema {
|
|||||||
uuid: string;
|
uuid: string;
|
||||||
position: [number, number, number];
|
position: [number, number, number];
|
||||||
rotation: [number, number, number];
|
rotation: [number, number, number];
|
||||||
actions: HumanAction[];
|
action: HumanAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
type PointsScheme = | ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema | HumanPointSchema;
|
type PointsScheme = | ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema | HumanPointSchema;
|
||||||
|
|||||||
Reference in New Issue
Block a user