added ui and integerated ui for the vehicle mechanics
This commit is contained in:
parent
1ce24a64f1
commit
13732a5679
|
@ -109,7 +109,7 @@ const SideBarRight: React.FC = () => {
|
||||||
{subModule === "mechanics" && selectedActionSphere && selectedActionSphere.path.type === "Vehicle" && (
|
{subModule === "mechanics" && selectedActionSphere && selectedActionSphere.path.type === "Vehicle" && (
|
||||||
<div className="sidebar-right-container">
|
<div className="sidebar-right-container">
|
||||||
<div className="sidebar-right-content-container">
|
<div className="sidebar-right-content-container">
|
||||||
{/* <VehicleMechanics /> */}
|
<VehicleMechanics />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -8,9 +8,7 @@ import {
|
||||||
import RenameInput from "../../../ui/inputs/RenameInput";
|
import RenameInput from "../../../ui/inputs/RenameInput";
|
||||||
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||||
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
|
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
|
||||||
import RegularDropDown from "../../../ui/inputs/RegularDropDown";
|
|
||||||
import { handleResize } from "../../../../functions/handleResizePannel";
|
import { handleResize } from "../../../../functions/handleResizePannel";
|
||||||
import EyeDropInput from "../../../ui/inputs/EyeDropInput";
|
|
||||||
import { useSelectedActionSphere, useSelectedPath, useSimulationPaths } from "../../../../store/store";
|
import { useSelectedActionSphere, useSelectedPath, useSimulationPaths } from "../../../../store/store";
|
||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
import * as Types from '../../../../types/world/worldTypes';
|
import * as Types from '../../../../types/world/worldTypes';
|
||||||
|
@ -428,9 +426,18 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="machine-mechanics-container">
|
<div className="machine-mechanics-container">
|
||||||
<div className="machine-mechanics-header">
|
{!selectedPath &&
|
||||||
{selectedActionSphere?.path?.modelName || "point name not found"}
|
<div className="machine-mechanics-header">
|
||||||
</div>
|
{selectedActionSphere?.path?.modelName || "point name not found"}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
{selectedPath &&
|
||||||
|
|
||||||
|
<div className="machine-mechanics-header">
|
||||||
|
{selectedPath.path.modelName || "path name not found"}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<div className="machine-mechanics-content-container">
|
<div className="machine-mechanics-content-container">
|
||||||
{!selectedPath &&
|
{!selectedPath &&
|
||||||
|
@ -632,10 +639,18 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="footer">
|
{!selectedPath && (
|
||||||
<InfoIcon />
|
<div className="footer">
|
||||||
By selecting points, you can create events and triggers.
|
<InfoIcon />
|
||||||
</div>
|
Configure the point's action and trigger properties.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{selectedPath && (
|
||||||
|
<div className="footer">
|
||||||
|
<InfoIcon />
|
||||||
|
Configure the path properties.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,562 +1,128 @@
|
||||||
import React, { useRef, useState, useMemo, useEffect } from "react";
|
import React, { useRef, useMemo } from "react";
|
||||||
import {
|
import { InfoIcon } from "../../../icons/ExportCommonIcons";
|
||||||
AddIcon,
|
|
||||||
InfoIcon,
|
|
||||||
RemoveIcon,
|
|
||||||
ResizeHeightIcon,
|
|
||||||
} from "../../../icons/ExportCommonIcons";
|
|
||||||
import RenameInput from "../../../ui/inputs/RenameInput";
|
|
||||||
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||||
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
|
|
||||||
import RegularDropDown from "../../../ui/inputs/RegularDropDown";
|
|
||||||
import { handleResize } from "../../../../functions/handleResizePannel";
|
|
||||||
import EyeDropInput from "../../../ui/inputs/EyeDropInput";
|
import EyeDropInput from "../../../ui/inputs/EyeDropInput";
|
||||||
import { useSelectedActionSphere, useSelectedPath, useSimulationPaths } from "../../../../store/store";
|
import { useSelectedActionSphere, useSimulationPaths } from "../../../../store/store";
|
||||||
import * as THREE from 'three';
|
|
||||||
import * as Types from '../../../../types/world/worldTypes';
|
import * as Types from '../../../../types/world/worldTypes';
|
||||||
import InputToggle from "../../../ui/inputs/InputToggle";
|
|
||||||
|
|
||||||
const VehicleMechanics: React.FC = () => {
|
const VehicleMechanics: React.FC = () => {
|
||||||
const { selectedActionSphere } = useSelectedActionSphere();
|
const { selectedActionSphere } = useSelectedActionSphere();
|
||||||
const { selectedPath, setSelectedPath } = useSelectedPath();
|
|
||||||
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
|
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
|
||||||
|
|
||||||
const actionsContainerRef = useRef<HTMLDivElement>(null);
|
const propertiesContainerRef = useRef<HTMLDivElement>(null);
|
||||||
const triggersContainerRef = useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
const selectedPoint = useMemo(() => {
|
const selectedPoint = useMemo(() => {
|
||||||
if (!selectedActionSphere) return null;
|
if (!selectedActionSphere?.point?.uuid) return null;
|
||||||
return simulationPaths
|
|
||||||
.filter((path): path is Types.ConveyorEventsSchema => path.type === "Conveyor")
|
|
||||||
.flatMap((path) => path.points)
|
|
||||||
.find((point) => point.uuid === selectedActionSphere.point.uuid);
|
|
||||||
}, [selectedActionSphere, simulationPaths]);
|
|
||||||
|
|
||||||
const handleAddAction = () => {
|
const vehiclePaths = simulationPaths.filter(
|
||||||
if (!selectedActionSphere) return;
|
(path): path is Types.VehicleEventsSchema => path.type === "Vehicle"
|
||||||
|
);
|
||||||
|
|
||||||
|
return vehiclePaths.find(
|
||||||
|
(path) => path.point.uuid === selectedActionSphere.point.uuid
|
||||||
|
)?.point;
|
||||||
|
}, [selectedActionSphere, simulationPaths, selectedActionSphere?.point?.uuid]);
|
||||||
|
|
||||||
|
const handleActionUpdate = React.useCallback((updatedAction: Partial<Types.VehicleEventsSchema['point']['actions']>) => {
|
||||||
|
if (!selectedActionSphere?.point?.uuid) return;
|
||||||
|
|
||||||
const updatedPaths = simulationPaths.map((path) => {
|
const updatedPaths = simulationPaths.map((path) => {
|
||||||
if (path.type === "Conveyor") {
|
if (path.type === "Vehicle" && path.point.uuid === selectedActionSphere.point.uuid) {
|
||||||
return {
|
return {
|
||||||
...path,
|
...path,
|
||||||
points: path.points.map((point) => {
|
point: {
|
||||||
if (point.uuid === selectedActionSphere.point.uuid) {
|
...path.point,
|
||||||
const actionIndex = point.actions.length;
|
actions: {
|
||||||
const newAction = {
|
...path.point.actions,
|
||||||
uuid: THREE.MathUtils.generateUUID(),
|
...updatedAction
|
||||||
name: `Action ${actionIndex + 1}`,
|
|
||||||
type: 'Inherit',
|
|
||||||
material: 'Inherit',
|
|
||||||
delay: 'Inherit',
|
|
||||||
spawnInterval: 'Inherit',
|
|
||||||
isUsed: false
|
|
||||||
};
|
|
||||||
|
|
||||||
return { ...point, actions: [...point.actions, newAction] };
|
|
||||||
}
|
}
|
||||||
return point;
|
}
|
||||||
}),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
});
|
});
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
setSimulationPaths(updatedPaths);
|
||||||
};
|
}, [selectedActionSphere?.point?.uuid, simulationPaths, setSimulationPaths]);
|
||||||
|
|
||||||
const handleDeleteAction = (uuid: string) => {
|
const handleStartPositionChange = React.useCallback((position: string) => {
|
||||||
if (!selectedActionSphere) return;
|
handleActionUpdate({ start: position });
|
||||||
|
}, [handleActionUpdate]);
|
||||||
|
|
||||||
const updatedPaths = simulationPaths.map((path) =>
|
const handleEndPositionChange = React.useCallback((position: string) => {
|
||||||
path.type === "Conveyor"
|
handleActionUpdate({ end: position });
|
||||||
? {
|
}, [handleActionUpdate]);
|
||||||
...path,
|
|
||||||
points: path.points.map((point) =>
|
|
||||||
point.uuid === selectedActionSphere.point.uuid
|
|
||||||
? { ...point, actions: point.actions.filter(action => action.uuid !== uuid) }
|
|
||||||
: point
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: path
|
|
||||||
);
|
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
const handleHitCountChange = React.useCallback((hitCount: number) => {
|
||||||
};
|
handleActionUpdate({ hitCount });
|
||||||
|
}, [handleActionUpdate]);
|
||||||
|
|
||||||
const handleActionSelect = (uuid: string, actionType: string) => {
|
const handleBufferChange = React.useCallback((buffer: number) => {
|
||||||
if (!selectedActionSphere) return;
|
handleActionUpdate({ buffer });
|
||||||
|
}, [handleActionUpdate]);
|
||||||
|
|
||||||
const updatedPaths = simulationPaths.map((path) =>
|
const handleSpeedChange = React.useCallback((speed: number) => {
|
||||||
path.type === "Conveyor"
|
|
||||||
? {
|
}, [selectedActionSphere?.point?.uuid, simulationPaths, setSimulationPaths]);
|
||||||
...path,
|
|
||||||
points: path.points.map((point) =>
|
|
||||||
point.uuid === selectedActionSphere.point.uuid
|
|
||||||
? {
|
|
||||||
...point,
|
|
||||||
actions: point.actions.map((action) =>
|
|
||||||
action.uuid === uuid
|
|
||||||
? {
|
|
||||||
...action,
|
|
||||||
type: actionType,
|
|
||||||
material: actionType === 'Spawn' || actionType === 'Swap' ? 'Inherit' : action.material,
|
|
||||||
delay: actionType === 'Delay' ? 'Inherit' : action.delay,
|
|
||||||
spawnInterval: actionType === 'Spawn' ? 'Inherit' : action.spawnInterval
|
|
||||||
}
|
|
||||||
: action
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: point
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: path
|
|
||||||
);
|
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
|
||||||
|
|
||||||
// Update the selected item to reflect changes
|
|
||||||
if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
|
|
||||||
const updatedAction = updatedPaths
|
|
||||||
.filter((path): path is Types.ConveyorEventsSchema => path.type === "Conveyor")
|
|
||||||
.flatMap(path => path.points)
|
|
||||||
.find(p => p.uuid === selectedActionSphere.point.uuid)
|
|
||||||
?.actions.find(a => a.uuid === uuid);
|
|
||||||
|
|
||||||
if (updatedAction) {
|
|
||||||
setSelectedItem({
|
|
||||||
type: "action",
|
|
||||||
item: updatedAction
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Modified handleMaterialSelect to ensure it only applies to relevant action types
|
|
||||||
const handleMaterialSelect = (uuid: string, material: string) => {
|
|
||||||
if (!selectedActionSphere) return;
|
|
||||||
|
|
||||||
const updatedPaths = simulationPaths.map((path) =>
|
|
||||||
path.type === "Conveyor"
|
|
||||||
? {
|
|
||||||
...path,
|
|
||||||
points: path.points.map((point) =>
|
|
||||||
point.uuid === selectedActionSphere.point.uuid
|
|
||||||
? {
|
|
||||||
...point,
|
|
||||||
actions: point.actions.map((action) =>
|
|
||||||
action.uuid === uuid &&
|
|
||||||
(action.type === 'Spawn' || action.type === 'Swap')
|
|
||||||
? { ...action, material }
|
|
||||||
: action
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: point
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: path
|
|
||||||
);
|
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
|
||||||
|
|
||||||
// Update selected item if it's the current action
|
|
||||||
if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
|
|
||||||
setSelectedItem({
|
|
||||||
...selectedItem,
|
|
||||||
item: {
|
|
||||||
...selectedItem.item,
|
|
||||||
material
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDelayChange = (uuid: string, delay: number | string) => {
|
|
||||||
if (!selectedActionSphere) return;
|
|
||||||
|
|
||||||
const updatedPaths = simulationPaths.map((path) =>
|
|
||||||
path.type === "Conveyor"
|
|
||||||
? {
|
|
||||||
...path,
|
|
||||||
points: path.points.map((point) =>
|
|
||||||
point.uuid === selectedActionSphere.point.uuid
|
|
||||||
? {
|
|
||||||
...point,
|
|
||||||
actions: point.actions.map((action) =>
|
|
||||||
action.uuid === uuid ? { ...action, delay } : action
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: point
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: path
|
|
||||||
);
|
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSpawnIntervalChange = (uuid: string, spawnInterval: number | string) => {
|
|
||||||
if (!selectedActionSphere) return;
|
|
||||||
|
|
||||||
const updatedPaths = simulationPaths.map((path) =>
|
|
||||||
path.type === "Conveyor"
|
|
||||||
? {
|
|
||||||
...path,
|
|
||||||
points: path.points.map((point) =>
|
|
||||||
point.uuid === selectedActionSphere.point.uuid
|
|
||||||
? {
|
|
||||||
...point,
|
|
||||||
actions: point.actions.map((action) =>
|
|
||||||
action.uuid === uuid ? { ...action, spawnInterval } : action
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: point
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: path
|
|
||||||
);
|
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSpeedChange = (speed: number) => {
|
|
||||||
if (!selectedPath) return;
|
|
||||||
|
|
||||||
const updatedPaths = simulationPaths.map((path) =>
|
|
||||||
path.modeluuid === selectedPath.path.modeluuid ? { ...path, speed } : path
|
|
||||||
);
|
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
|
||||||
setSelectedPath({ ...selectedPath, path: { ...selectedPath.path, speed } });
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleAddTrigger = () => {
|
|
||||||
if (!selectedActionSphere) return;
|
|
||||||
|
|
||||||
const updatedPaths = simulationPaths.map((path) =>
|
|
||||||
path.type === "Conveyor"
|
|
||||||
? {
|
|
||||||
...path,
|
|
||||||
points: path.points.map((point) => {
|
|
||||||
if (point.uuid === selectedActionSphere.point.uuid) {
|
|
||||||
const triggerIndex = point.triggers.length;
|
|
||||||
const newTrigger = {
|
|
||||||
uuid: THREE.MathUtils.generateUUID(),
|
|
||||||
name: `Trigger ${triggerIndex + 1}`,
|
|
||||||
type: '',
|
|
||||||
bufferTime: 0,
|
|
||||||
isUsed: false
|
|
||||||
};
|
|
||||||
|
|
||||||
return { ...point, triggers: [...point.triggers, newTrigger] };
|
|
||||||
}
|
|
||||||
return point;
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
: path
|
|
||||||
);
|
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDeleteTrigger = (uuid: string) => {
|
|
||||||
if (!selectedActionSphere) return;
|
|
||||||
|
|
||||||
const updatedPaths = simulationPaths.map((path) =>
|
|
||||||
path.type === "Conveyor"
|
|
||||||
? {
|
|
||||||
...path,
|
|
||||||
points: path.points.map((point) =>
|
|
||||||
point.uuid === selectedActionSphere.point.uuid
|
|
||||||
? { ...point, triggers: point.triggers.filter(trigger => trigger.uuid !== uuid) }
|
|
||||||
: point
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: path
|
|
||||||
);
|
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleTriggerSelect = (uuid: string, triggerType: string) => {
|
|
||||||
if (!selectedActionSphere) return;
|
|
||||||
|
|
||||||
const updatedPaths = simulationPaths.map((path) =>
|
|
||||||
path.type === "Conveyor"
|
|
||||||
? {
|
|
||||||
...path,
|
|
||||||
points: path.points.map((point) =>
|
|
||||||
point.uuid === selectedActionSphere.point.uuid
|
|
||||||
? {
|
|
||||||
...point,
|
|
||||||
triggers: point.triggers.map((trigger) =>
|
|
||||||
trigger.uuid === uuid ? { ...trigger, type: triggerType } : trigger
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: point
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: path
|
|
||||||
);
|
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update the toggle handlers to immediately update the selected item
|
|
||||||
const handleActionToggle = (uuid: string) => {
|
|
||||||
if (!selectedActionSphere) return;
|
|
||||||
const updatedPaths = simulationPaths.map((path) =>
|
|
||||||
path.type === "Conveyor"
|
|
||||||
? {
|
|
||||||
...path,
|
|
||||||
points: path.points.map((point) =>
|
|
||||||
point.uuid === selectedActionSphere.point.uuid
|
|
||||||
? {
|
|
||||||
...point,
|
|
||||||
actions: point.actions.map((action) => ({
|
|
||||||
...action,
|
|
||||||
isUsed: action.uuid === uuid ? !action.isUsed : false,
|
|
||||||
})),
|
|
||||||
}
|
|
||||||
: point
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: path
|
|
||||||
);
|
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
|
||||||
|
|
||||||
// Immediately update the selected item if it's the one being toggled
|
|
||||||
if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
|
|
||||||
setSelectedItem({
|
|
||||||
...selectedItem,
|
|
||||||
item: {
|
|
||||||
...selectedItem.item,
|
|
||||||
isUsed: !selectedItem.item.isUsed
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Do the same for trigger toggle
|
|
||||||
const handleTriggerToggle = (uuid: string) => {
|
|
||||||
if (!selectedActionSphere) return;
|
|
||||||
|
|
||||||
const updatedPaths = simulationPaths.map((path) =>
|
|
||||||
path.type === "Conveyor"
|
|
||||||
? {
|
|
||||||
...path,
|
|
||||||
points: path.points.map((point) =>
|
|
||||||
point.uuid === selectedActionSphere.point.uuid
|
|
||||||
? {
|
|
||||||
...point,
|
|
||||||
triggers: point.triggers.map((trigger) => ({
|
|
||||||
...trigger,
|
|
||||||
isUsed: trigger.uuid === uuid ? !trigger.isUsed : false,
|
|
||||||
})),
|
|
||||||
}
|
|
||||||
: point
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: path
|
|
||||||
);
|
|
||||||
|
|
||||||
setSimulationPaths(updatedPaths);
|
|
||||||
|
|
||||||
// Immediately update the selected item if it's the one being toggled
|
|
||||||
if (selectedItem?.type === "trigger" && selectedItem.item.uuid === uuid) {
|
|
||||||
setSelectedItem({
|
|
||||||
...selectedItem,
|
|
||||||
item: {
|
|
||||||
...selectedItem.item,
|
|
||||||
isUsed: !selectedItem.item.isUsed
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const [selectedItem, setSelectedItem] = useState<{ type: "action" | "trigger"; item: any; } | null>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setSelectedItem(null); // Reset selectedItem when selectedActionSphere changes
|
|
||||||
}, [selectedActionSphere]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="machine-mechanics-container">
|
<div className="machine-mechanics-container" key={selectedPoint?.uuid}>
|
||||||
<div className="machine-mechanics-header">
|
<div className="machine-mechanics-header">
|
||||||
{selectedActionSphere?.path?.modelName || "point name not found"}
|
{selectedActionSphere?.path?.modelName || "Vehicle point not found"}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="machine-mechanics-content-container">
|
<div className="machine-mechanics-content-container">
|
||||||
<div className="actions">
|
<div className="selected-properties-container" ref={propertiesContainerRef}>
|
||||||
<div className="header">
|
<div className="properties-header">Vehicle Properties</div>
|
||||||
<div className="header-value">Actions</div>
|
|
||||||
<div className="add-button" onClick={handleAddAction}>
|
{selectedPoint && (
|
||||||
<AddIcon /> Add
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="lists-main-container"
|
|
||||||
ref={actionsContainerRef}
|
|
||||||
style={{ height: "120px" }}
|
|
||||||
>
|
|
||||||
<div className="list-container">
|
|
||||||
<>
|
|
||||||
{console.log(selectedPoint)}
|
|
||||||
</>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="resize-icon"
|
|
||||||
id="action-resize"
|
|
||||||
onMouseDown={(e) => handleResize(e, actionsContainerRef)}
|
|
||||||
>
|
|
||||||
<ResizeHeightIcon />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="triggers">
|
|
||||||
<div className="header">
|
|
||||||
<div className="header-value">Triggers</div>
|
|
||||||
<div className="add-button" onClick={handleAddTrigger}>
|
|
||||||
<AddIcon /> Add
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="lists-main-container"
|
|
||||||
ref={triggersContainerRef}
|
|
||||||
style={{ height: "120px" }}
|
|
||||||
>
|
|
||||||
<div className="list-container">
|
|
||||||
{selectedPoint?.triggers.map((trigger) => (
|
|
||||||
<div
|
|
||||||
key={trigger.uuid}
|
|
||||||
className={`list-item ${selectedItem?.type === "trigger" &&
|
|
||||||
selectedItem.item?.uuid === trigger.uuid
|
|
||||||
? "active"
|
|
||||||
: ""
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="value"
|
|
||||||
onClick={() => setSelectedItem({ type: "trigger", item: trigger })}
|
|
||||||
>
|
|
||||||
<RenameInput value={trigger.name} />
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="remove-button"
|
|
||||||
onClick={() => handleDeleteTrigger(trigger.uuid)}
|
|
||||||
>
|
|
||||||
<RemoveIcon />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="resize-icon"
|
|
||||||
id="trigger-resize"
|
|
||||||
onMouseDown={(e) => handleResize(e, triggersContainerRef)}
|
|
||||||
>
|
|
||||||
<ResizeHeightIcon />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="selected-properties-container">
|
|
||||||
{selectedItem && (
|
|
||||||
<>
|
<>
|
||||||
<div className="properties-header">{selectedItem.item.name}</div>
|
<EyeDropInput
|
||||||
|
key={`start-${selectedPoint.uuid}`}
|
||||||
|
label="Start Position"
|
||||||
|
value={selectedPoint.actions.start}
|
||||||
|
onChange={handleStartPositionChange}
|
||||||
|
/>
|
||||||
|
|
||||||
{selectedItem.type === "action" && (
|
<EyeDropInput
|
||||||
<>
|
key={`end-${selectedPoint.uuid}`}
|
||||||
<InputToggle
|
label="End Position"
|
||||||
inputKey="enableTrigger"
|
value={selectedPoint.actions.end}
|
||||||
label="Enable Trigger"
|
onChange={handleEndPositionChange}
|
||||||
value={selectedItem.item.isUsed}
|
/>
|
||||||
onClick={() => handleActionToggle(selectedItem.item.uuid)}
|
|
||||||
/>
|
|
||||||
<LabledDropdown
|
|
||||||
defaultOption={selectedItem.item.type}
|
|
||||||
options={["Inherit", "Spawn", "Swap", "Despawn", "Delay"]}
|
|
||||||
onSelect={(option) => handleActionSelect(selectedItem.item.uuid, option)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Only show material dropdown for Spawn/Swap actions */}
|
<InputWithDropDown
|
||||||
{(selectedItem.item.type === 'Spawn' || selectedItem.item.type === 'Swap') && (
|
key={`hitcount-${selectedPoint.uuid}`}
|
||||||
<LabledDropdown
|
label="Hit Count"
|
||||||
label={selectedItem.item.type === 'Spawn' ? 'Spawn Material' : 'Swap Material'}
|
value={selectedPoint.actions.hitCount.toString()}
|
||||||
defaultOption={selectedItem.item.material}
|
onChange={(value) => handleHitCountChange(parseInt(value))}
|
||||||
options={["Inherit", "Crate", "Box"]}
|
/>
|
||||||
onSelect={(option) => handleMaterialSelect(selectedItem.item.uuid, option)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Only show delay input for Delay actions */}
|
<InputWithDropDown
|
||||||
{selectedItem.item.type === 'Delay' && (
|
key={`buffer-${selectedPoint.uuid}`}
|
||||||
<InputWithDropDown
|
label="Buffer Time"
|
||||||
label="Delay Time"
|
value={selectedPoint.actions.buffer.toString()}
|
||||||
value={selectedItem.item.delay === 'Inherit'
|
onChange={(value) => handleBufferChange(parseInt(value))}
|
||||||
? undefined
|
/>
|
||||||
: selectedItem.item.delay}
|
|
||||||
onChange={(value) => {
|
|
||||||
const numValue = parseInt(value);
|
|
||||||
handleDelayChange(
|
|
||||||
selectedItem.item.uuid,
|
|
||||||
!value ? 'Inherit' : numValue
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Only show spawn interval for Spawn actions */}
|
<InputWithDropDown
|
||||||
{selectedItem.item.type === 'Spawn' && (
|
key={`speed-${selectedPoint.uuid}`}
|
||||||
<InputWithDropDown
|
label="Vehicle Speed"
|
||||||
label="Spawn Interval"
|
value={selectedPoint.speed.toString()}
|
||||||
min={0}
|
onChange={(value) => handleSpeedChange(parseFloat(value))}
|
||||||
defaultValue={selectedItem.item.spawnInterval === "Inherit" ? "" : selectedItem.item.spawnInterval.toString()}
|
/>
|
||||||
value={selectedItem.item.spawnInterval === "Inherit" ? "" : selectedItem.item.spawnInterval.toString()}
|
|
||||||
onChange={(value) => {
|
|
||||||
handleSpawnIntervalChange(selectedItem.item.uuid, (value === "") ? "Inherit" : parseInt(value));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{selectedItem.type === "trigger" && (
|
|
||||||
<>
|
|
||||||
<InputToggle
|
|
||||||
inputKey="enableTrigger"
|
|
||||||
label="Enable Trigger"
|
|
||||||
value={selectedItem.item.isUsed}
|
|
||||||
onClick={() => handleTriggerToggle(selectedItem.item.uuid)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<LabledDropdown
|
|
||||||
defaultOption={selectedItem.item.type || "Select Trigger Type"}
|
|
||||||
options={["On-Hit", "Buffer"]}
|
|
||||||
onSelect={(option) => handleTriggerSelect(selectedItem.item.uuid, option)}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{selectedPath && !selectedItem && (
|
|
||||||
<div className="speed-control">
|
|
||||||
<InputWithDropDown
|
|
||||||
label="ConveyorEventsSchema Speed"
|
|
||||||
value={selectedPath.path.speed.toString()}
|
|
||||||
onChange={(value) => handleSpeedChange(parseFloat(value))}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="footer">
|
<div className="footer">
|
||||||
<InfoIcon />
|
<InfoIcon />
|
||||||
By selecting points, you can create events and triggers.
|
Configure vehicle's movement and interaction properties.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default VehicleMechanics;
|
export default React.memo(VehicleMechanics);
|
|
@ -23,6 +23,7 @@ import {
|
||||||
useDeleteModels,
|
useDeleteModels,
|
||||||
useDeletePointOrLine,
|
useDeletePointOrLine,
|
||||||
useMovePoint,
|
useMovePoint,
|
||||||
|
useRefTextUpdate,
|
||||||
useSelectedWallItem,
|
useSelectedWallItem,
|
||||||
useToggleView,
|
useToggleView,
|
||||||
useToolMode,
|
useToolMode,
|
||||||
|
@ -53,6 +54,7 @@ const Tools: React.FC = () => {
|
||||||
const { movePoint, setMovePoint } = useMovePoint();
|
const { movePoint, setMovePoint } = useMovePoint();
|
||||||
const { toolMode, setToolMode } = useToolMode();
|
const { toolMode, setToolMode } = useToolMode();
|
||||||
const { activeTool, setActiveTool } = useActiveTool();
|
const { activeTool, setActiveTool } = useActiveTool();
|
||||||
|
const { refTextupdate, setRefTextUpdate } = useRefTextUpdate();
|
||||||
|
|
||||||
// Reset activeTool whenever activeModule changes
|
// Reset activeTool whenever activeModule changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -103,6 +105,7 @@ const Tools: React.FC = () => {
|
||||||
setTransformMode(null);
|
setTransformMode(null);
|
||||||
setMovePoint(false);
|
setMovePoint(false);
|
||||||
setDeletePointOrLine(false);
|
setDeletePointOrLine(false);
|
||||||
|
setRefTextUpdate((prevUpdate) => prevUpdate - 1);
|
||||||
|
|
||||||
switch (activeTool) {
|
switch (activeTool) {
|
||||||
case "Move":
|
case "Move":
|
||||||
|
|
|
@ -1,18 +1,30 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import RegularDropDown from "./RegularDropDown";
|
|
||||||
import { EyeDroperIcon } from "../../icons/ExportCommonIcons";
|
import { EyeDroperIcon } from "../../icons/ExportCommonIcons";
|
||||||
|
|
||||||
const EyeDropInput: React.FC = () => {
|
interface EyeDropInputProps {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
options?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const EyeDropInput: React.FC<EyeDropInputProps> = ({
|
||||||
|
label = "Object",
|
||||||
|
onChange,
|
||||||
|
}) => {
|
||||||
|
const handleEyeDropClick = () => {
|
||||||
|
// Here you would typically implement the eye dropper functionality
|
||||||
|
// For now, we'll just simulate selecting a value
|
||||||
|
const simulatedValue = "picked_value"; // Replace with actual eye dropper logic
|
||||||
|
onChange(simulatedValue);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="eye-dropper-input-container">
|
<div className="eye-dropper-input-container">
|
||||||
<div className="label">Object</div>
|
<div className="label">{label}</div>
|
||||||
<div className="input-container">
|
<div className="input-container">
|
||||||
<RegularDropDown
|
<input disabled type="text" />
|
||||||
header="select object"
|
<div className="eye-picker-button" onClick={handleEyeDropClick}>
|
||||||
options={[]}
|
|
||||||
onSelect={() => {}}
|
|
||||||
/>
|
|
||||||
<div className="eye-picker-button">
|
|
||||||
<EyeDroperIcon isActive={false} />
|
<EyeDroperIcon isActive={false} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,4 +32,4 @@ const EyeDropInput: React.FC = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EyeDropInput;
|
export default EyeDropInput;
|
|
@ -17,7 +17,7 @@ async function Draw(
|
||||||
floorPlanGroup: Types.RefGroup,
|
floorPlanGroup: Types.RefGroup,
|
||||||
ReferenceLineMesh: Types.RefMesh,
|
ReferenceLineMesh: Types.RefMesh,
|
||||||
LineCreated: Types.RefBoolean,
|
LineCreated: Types.RefBoolean,
|
||||||
setRefTextUpdate: Types.NumberIncrementState,
|
setRefTextUpdate: any,
|
||||||
Tube: Types.RefTubeGeometry,
|
Tube: Types.RefTubeGeometry,
|
||||||
anglesnappedPoint: Types.RefVector3,
|
anglesnappedPoint: Types.RefVector3,
|
||||||
isAngleSnapped: Types.RefBoolean,
|
isAngleSnapped: Types.RefBoolean,
|
||||||
|
|
|
@ -36,7 +36,7 @@ const MeasurementTool = () => {
|
||||||
isLeftMouseDown = false;
|
isLeftMouseDown = false;
|
||||||
if (evt.button === 0 && !drag) {
|
if (evt.button === 0 && !drag) {
|
||||||
raycaster.setFromCamera(pointer, camera);
|
raycaster.setFromCamera(pointer, camera);
|
||||||
const intersects = raycaster.intersectObjects(scene.children, true).filter(intersect => !intersect.object.name.includes("Roof") && !intersect.object.name.includes("MeasurementReference") && !(intersect.object.type === "GridHelper"));
|
const intersects = raycaster.intersectObjects(scene.children, true).filter(intersect => !intersect.object.name.includes("Roof") && !intersect.object.name.includes("MeasurementReference") && !intersect.object.name.includes("agv-collider") && !(intersect.object.type === "GridHelper"));
|
||||||
|
|
||||||
if (intersects.length > 0) {
|
if (intersects.length > 0) {
|
||||||
const intersectionPoint = intersects[0].point.clone();
|
const intersectionPoint = intersects[0].point.clone();
|
||||||
|
@ -83,7 +83,7 @@ const MeasurementTool = () => {
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
if (points.length === 1) {
|
if (points.length === 1) {
|
||||||
raycaster.setFromCamera(pointer, camera);
|
raycaster.setFromCamera(pointer, camera);
|
||||||
const intersects = raycaster.intersectObjects(scene.children, true).filter(intersect => !intersect.object.name.includes("Roof") && !intersect.object.name.includes("MeasurementReference") && !(intersect.object.type === "GridHelper"));
|
const intersects = raycaster.intersectObjects(scene.children, true).filter(intersect => !intersect.object.name.includes("Roof") && !intersect.object.name.includes("MeasurementReference") && !intersect.object.name.includes("agv-collider") && !(intersect.object.type === "GridHelper"));
|
||||||
|
|
||||||
if (intersects.length > 0) {
|
if (intersects.length > 0) {
|
||||||
updateMeasurement(points[0], intersects[0].point);
|
updateMeasurement(points[0], intersects[0].point);
|
||||||
|
|
|
@ -29,6 +29,7 @@ import {
|
||||||
useUpdateScene,
|
useUpdateScene,
|
||||||
useWalls,
|
useWalls,
|
||||||
useToolMode,
|
useToolMode,
|
||||||
|
useRefTextUpdate,
|
||||||
} from "../../../store/store";
|
} from "../../../store/store";
|
||||||
|
|
||||||
////////// 3D Function Imports //////////
|
////////// 3D Function Imports //////////
|
||||||
|
@ -118,7 +119,7 @@ export default function World() {
|
||||||
const { shadows, setShadows } = useShadows();
|
const { shadows, setShadows } = useShadows();
|
||||||
const { updateScene, setUpdateScene } = useUpdateScene();
|
const { updateScene, setUpdateScene } = useUpdateScene();
|
||||||
const { walls, setWalls } = useWalls();
|
const { walls, setWalls } = useWalls();
|
||||||
const [RefTextupdate, setRefTextUpdate] = useState(-1000);
|
const { refTextupdate, setRefTextUpdate } = useRefTextUpdate();
|
||||||
|
|
||||||
// const loader = new GLTFLoader();
|
// const loader = new GLTFLoader();
|
||||||
// const dracoLoader = new DRACOLoader();
|
// const dracoLoader = new DRACOLoader();
|
||||||
|
@ -158,7 +159,7 @@ export default function World() {
|
||||||
////////// All Toggle's //////////
|
////////// All Toggle's //////////
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setRefTextUpdate((prevUpdate) => prevUpdate - 1);
|
setRefTextUpdate((prevUpdate: number) => prevUpdate - 1);
|
||||||
if (dragPointControls.current) {
|
if (dragPointControls.current) {
|
||||||
dragPointControls.current.enabled = false;
|
dragPointControls.current.enabled = false;
|
||||||
}
|
}
|
||||||
|
@ -241,7 +242,7 @@ export default function World() {
|
||||||
<DistanceText key={toggleView} />
|
<DistanceText key={toggleView} />
|
||||||
|
|
||||||
<ReferenceDistanceText
|
<ReferenceDistanceText
|
||||||
key={RefTextupdate}
|
key={refTextupdate}
|
||||||
line={ReferenceLineMesh.current}
|
line={ReferenceLineMesh.current}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -67,12 +67,11 @@ function Behaviour() {
|
||||||
point: {
|
point: {
|
||||||
uuid: pointUUID,
|
uuid: pointUUID,
|
||||||
position: [pointPosition.x, pointPosition.y, pointPosition.z],
|
position: [pointPosition.x, pointPosition.y, pointPosition.z],
|
||||||
actions: [{ uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Start', start: '', hitCount: 1, end: '', buffer: 0, isUsed: false }],
|
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: 'Start', start: '', hitCount: 1, end: '', buffer: 0 },
|
||||||
triggers: [],
|
|
||||||
connections: { source: { pathUUID: item.modeluuid, pointUUID: pointUUID }, targets: [] },
|
connections: { source: { pathUUID: item.modeluuid, pointUUID: pointUUID }, targets: [] },
|
||||||
|
speed: 2,
|
||||||
},
|
},
|
||||||
assetPosition: [...item.position],
|
assetPosition: [...item.position],
|
||||||
speed: 2,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
newPaths.push(newVehiclePath);
|
newPaths.push(newVehiclePath);
|
||||||
|
|
|
@ -93,6 +93,7 @@ const PathCreator = ({ simulationPaths, setSimulationPaths, connections, setConn
|
||||||
intersects = intersects.filter(
|
intersects = intersects.filter(
|
||||||
(intersect) =>
|
(intersect) =>
|
||||||
!intersect.object.name.includes("Roof") &&
|
!intersect.object.name.includes("Roof") &&
|
||||||
|
!intersect.object.name.includes("agv-collider") &&
|
||||||
!intersect.object.name.includes("MeasurementReference") &&
|
!intersect.object.name.includes("MeasurementReference") &&
|
||||||
!intersect.object.userData.isPathObject &&
|
!intersect.object.userData.isPathObject &&
|
||||||
!(intersect.object.type === "GridHelper")
|
!(intersect.object.type === "GridHelper")
|
||||||
|
@ -146,6 +147,7 @@ const PathCreator = ({ simulationPaths, setSimulationPaths, connections, setConn
|
||||||
const intersects = raycaster.intersectObjects(scene.children, true).filter(
|
const intersects = raycaster.intersectObjects(scene.children, true).filter(
|
||||||
(intersect) =>
|
(intersect) =>
|
||||||
!intersect.object.name.includes("Roof") &&
|
!intersect.object.name.includes("Roof") &&
|
||||||
|
!intersect.object.name.includes("agv-collider") &&
|
||||||
!intersect.object.name.includes("MeasurementReference") &&
|
!intersect.object.name.includes("MeasurementReference") &&
|
||||||
!intersect.object.userData.isPathObject &&
|
!intersect.object.userData.isPathObject &&
|
||||||
!(intersect.object.type === "GridHelper")
|
!(intersect.object.type === "GridHelper")
|
||||||
|
@ -262,6 +264,7 @@ const PathCreator = ({ simulationPaths, setSimulationPaths, connections, setConn
|
||||||
const intersects = raycaster.intersectObjects(scene.children, true).filter(
|
const intersects = raycaster.intersectObjects(scene.children, true).filter(
|
||||||
(intersect) =>
|
(intersect) =>
|
||||||
!intersect.object.name.includes("Roof") &&
|
!intersect.object.name.includes("Roof") &&
|
||||||
|
!intersect.object.name.includes("agv-collider") &&
|
||||||
!intersect.object.name.includes("MeasurementReference") &&
|
!intersect.object.name.includes("MeasurementReference") &&
|
||||||
!intersect.object.userData.isPathObject &&
|
!intersect.object.userData.isPathObject &&
|
||||||
!(intersect.object.type === "GridHelper")
|
!(intersect.object.type === "GridHelper")
|
||||||
|
|
|
@ -203,6 +203,20 @@ export const useActiveLayer = create<any>((set: any) => ({
|
||||||
setActiveLayer: (x: any) => set({ activeLayer: x }),
|
setActiveLayer: (x: any) => set({ activeLayer: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
interface RefTextUpdateState {
|
||||||
|
refTextupdate: number;
|
||||||
|
setRefTextUpdate: (callback: (currentValue: number) => number | number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useRefTextUpdate = create<RefTextUpdateState>((set) => ({
|
||||||
|
refTextupdate: -1000,
|
||||||
|
setRefTextUpdate: (callback) =>
|
||||||
|
set((state) => ({
|
||||||
|
refTextupdate:
|
||||||
|
typeof callback === "function" ? callback(state.refTextupdate) : callback,
|
||||||
|
})),
|
||||||
|
}));
|
||||||
|
|
||||||
export const useResetCamera = create<any>((set: any) => ({
|
export const useResetCamera = create<any>((set: any) => ({
|
||||||
resetCamera: false,
|
resetCamera: false,
|
||||||
setResetCamera: (x: any) => set({ resetCamera: x }),
|
setResetCamera: (x: any) => set({ resetCamera: x }),
|
||||||
|
|
|
@ -310,10 +310,9 @@ interface VehicleEventsSchema {
|
||||||
point: {
|
point: {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
position: [number, number, number];
|
position: [number, number, number];
|
||||||
actions: { uuid: string; name: string; type: string; start: string, hitCount: number, end: string, buffer: number; isUsed: boolean }[] | [];
|
actions: { uuid: string; name: string; type: string; start: string, hitCount: number, end: string, buffer: number };
|
||||||
triggers: { uuid: string; name: string; type: string; isUsed: boolean }[] | [];
|
|
||||||
connections: { source: { pathUUID: string; pointUUID: string }; targets: { pathUUID: string; pointUUID: string }[] };
|
connections: { source: { pathUUID: string; pointUUID: string }; targets: { pathUUID: string; pointUUID: string }[] };
|
||||||
|
speed: number;
|
||||||
};
|
};
|
||||||
assetPosition: [number, number, number];
|
assetPosition: [number, number, number];
|
||||||
speed: number;
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue