name and schema chmage for assembly to manufacturer

This commit is contained in:
2025-08-23 10:24:21 +05:30
parent c86509e812
commit 69329dba7a
23 changed files with 327 additions and 353 deletions

View File

@@ -3,7 +3,7 @@ import InputRange from "../../../../../ui/inputs/InputRange";
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown"; import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
import SwapAction from "./SwapAction"; import SwapAction from "./SwapAction";
interface AssemblyActionProps { interface ManufactureActionProps {
processTime: { processTime: {
value: number; value: number;
min: number; min: number;
@@ -11,7 +11,7 @@ interface AssemblyActionProps {
disabled?: boolean, disabled?: boolean,
onChange: (value: number) => void; onChange: (value: number) => void;
}; };
assemblyCount: { manufactureCount: {
value: number; value: number;
min: number; min: number;
max: number; max: number;
@@ -26,9 +26,9 @@ interface AssemblyActionProps {
clearPoints: () => void; clearPoints: () => void;
} }
const AssemblyAction: React.FC<AssemblyActionProps> = ({ const ManufactureAction: React.FC<ManufactureActionProps> = ({
processTime, processTime,
assemblyCount, manufactureCount,
swapOptions, swapOptions,
swapDefaultOption, swapDefaultOption,
onSwapSelect, onSwapSelect,
@@ -46,18 +46,18 @@ const AssemblyAction: React.FC<AssemblyActionProps> = ({
onChange={processTime.onChange} onChange={processTime.onChange}
/> />
{assemblyCount && ( {manufactureCount && (
<InputWithDropDown <InputWithDropDown
label="Assembly Count" label="Manufacture Count"
value={assemblyCount.value.toString()} value={manufactureCount.value.toString()}
min={assemblyCount.min} min={manufactureCount.min}
max={assemblyCount.max} max={manufactureCount.max}
disabled={assemblyCount.disabled} disabled={manufactureCount.disabled}
defaultValue={assemblyCount.defaultValue} defaultValue={manufactureCount.defaultValue}
step={assemblyCount.step} step={manufactureCount.step}
activeOption="unit" activeOption="unit"
onClick={() => { }} onClick={() => { }}
onChange={(value) => assemblyCount.onChange(parseInt(value))} onChange={(value) => manufactureCount.onChange(parseInt(value))}
/> />
)} )}
<SwapAction <SwapAction
@@ -82,4 +82,4 @@ const AssemblyAction: React.FC<AssemblyActionProps> = ({
); );
}; };
export default AssemblyAction; export default ManufactureAction;

View File

@@ -7,7 +7,7 @@ import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import Trigger from "../trigger/Trigger"; import Trigger from "../trigger/Trigger";
import ActionsList from "../components/ActionsList"; import ActionsList from "../components/ActionsList";
import WorkerAction from "../actions/WorkerAction"; import WorkerAction from "../actions/WorkerAction";
import AssemblyAction from "../actions/AssemblyAction"; import ManufactureAction from "../actions/ManufactureAction";
import { useSelectedEventData, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore"; import { useSelectedEventData, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
@@ -17,10 +17,10 @@ import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
function HumanMechanics() { function HumanMechanics() {
const [activeOption, setActiveOption] = useState<"worker" | "assembly" | "operator">("worker"); const [activeOption, setActiveOption] = useState<"worker" | "manufacturer" | "operator">("worker");
const [speed, setSpeed] = useState("0.5"); const [speed, setSpeed] = useState("0.5");
const [loadCount, setLoadCount] = useState(0); const [loadCount, setLoadCount] = useState(0);
const [assemblyCount, setAssemblyCount] = useState(0); const [manufactureCount, setManufactureCount] = useState(0);
const [loadCapacity, setLoadCapacity] = useState("1"); const [loadCapacity, setLoadCapacity] = useState("1");
const [processTime, setProcessTime] = useState(10); const [processTime, setProcessTime] = useState(10);
const [swappedMaterial, setSwappedMaterial] = useState("Default material"); const [swappedMaterial, setSwappedMaterial] = useState("Default material");
@@ -58,7 +58,7 @@ function HumanMechanics() {
setLoadCapacity(firstAction.loadCapacity.toString()); setLoadCapacity(firstAction.loadCapacity.toString());
setActiveOption(firstAction.actionType); setActiveOption(firstAction.actionType);
setLoadCount(firstAction.loadCount || 0); setLoadCount(firstAction.loadCount || 0);
setAssemblyCount(firstAction.assemblyCount || 0); setManufactureCount(firstAction.manufactureCount || 0);
setProcessTime(firstAction.processTime || 10); setProcessTime(firstAction.processTime || 10);
setSwappedMaterial(firstAction.swapMaterial || "Default material"); setSwappedMaterial(firstAction.swapMaterial || "Default material");
} }
@@ -79,7 +79,7 @@ function HumanMechanics() {
const newCurrentAction = getActionByUuid(selectedProduct.productUuid, actionUuid); const newCurrentAction = getActionByUuid(selectedProduct.productUuid, actionUuid);
if (newCurrentAction && (newCurrentAction.actionType === 'assembly' || newCurrentAction?.actionType === 'worker' || newCurrentAction?.actionType === "operator")) { if (newCurrentAction && (newCurrentAction.actionType === 'manufacturer' || newCurrentAction?.actionType === 'worker' || newCurrentAction?.actionType === "operator")) {
if (!selectedAction.actionId) { if (!selectedAction.actionId) {
setSelectedAction(newCurrentAction.actionUuid, newCurrentAction.actionName); setSelectedAction(newCurrentAction.actionUuid, newCurrentAction.actionName);
} }
@@ -87,9 +87,9 @@ function HumanMechanics() {
setActiveOption(newCurrentAction.actionType); setActiveOption(newCurrentAction.actionType);
setLoadCapacity(newCurrentAction.loadCapacity.toString()); setLoadCapacity(newCurrentAction.loadCapacity.toString());
setLoadCount(newCurrentAction.loadCount || 0); setLoadCount(newCurrentAction.loadCount || 0);
setAssemblyCount(newCurrentAction.assemblyCount || 0); setManufactureCount(newCurrentAction.manufactureCount || 0);
if (newCurrentAction.actionType === 'assembly') { if (newCurrentAction.actionType === 'manufacturer') {
setProcessTime(newCurrentAction.processTime || 10); setProcessTime(newCurrentAction.processTime || 10);
setSwappedMaterial(newCurrentAction.swapMaterial || "Default material"); setSwappedMaterial(newCurrentAction.swapMaterial || "Default material");
} }
@@ -118,7 +118,7 @@ function HumanMechanics() {
const handleSelectActionType = (actionType: string) => { const handleSelectActionType = (actionType: string) => {
if (!selectedAction.actionId || !currentAction || !selectedPointData) return; if (!selectedAction.actionId || !currentAction || !selectedPointData) return;
const updatedAction = { ...currentAction, actionType: actionType as "worker" | "assembly" | "operator" }; const updatedAction = { ...currentAction, actionType: actionType as "worker" | "manufacturer" | "operator" };
const updatedActions = selectedPointData.actions.map(action => action.actionUuid === updatedAction.actionUuid ? updatedAction : action); const updatedActions = selectedPointData.actions.map(action => action.actionUuid === updatedAction.actionUuid ? updatedAction : action);
const updatedPoint = { ...selectedPointData, actions: updatedActions }; const updatedPoint = { ...selectedPointData, actions: updatedActions };
@@ -203,10 +203,10 @@ function HumanMechanics() {
setLoadCount(value); setLoadCount(value);
}; };
const handleAssemblyCountChange = (value: number) => { const handleManufactureCountChange = (value: number) => {
if (!currentAction || !selectedPointData || !selectedAction.actionId) return; if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
const updatedAction = { ...currentAction, assemblyCount: value }; const updatedAction = { ...currentAction, manufactureCount: value };
const updatedActions = selectedPointData.actions.map(action => action.actionUuid === updatedAction.actionUuid ? updatedAction : action); const updatedActions = selectedPointData.actions.map(action => action.actionUuid === updatedAction.actionUuid ? updatedAction : action);
const updatedPoint = { ...selectedPointData, actions: updatedActions }; const updatedPoint = { ...selectedPointData, actions: updatedActions };
@@ -222,7 +222,7 @@ function HumanMechanics() {
setCurrentAction(updatedAction); setCurrentAction(updatedAction);
setSelectedPointData(updatedPoint); setSelectedPointData(updatedPoint);
setAssemblyCount(value); setManufactureCount(value);
}; };
const handleProcessTimeChange = (value: number) => { const handleProcessTimeChange = (value: number) => {
@@ -274,8 +274,8 @@ function HumanMechanics() {
const updatedAction: HumanAction = JSON.parse(JSON.stringify(currentAction)); const updatedAction: HumanAction = JSON.parse(JSON.stringify(currentAction));
if (updatedAction.actionType === 'assembly') { if (updatedAction.actionType === 'manufacturer') {
updatedAction.assemblyPoint = { position: null, rotation: null, } updatedAction.manufacturePoint = { position: null, rotation: null, }
} else { } else {
updatedAction.pickUpPoint = { position: null, rotation: null, }; updatedAction.pickUpPoint = { position: null, rotation: null, };
updatedAction.dropPoint = { position: null, rotation: null, } updatedAction.dropPoint = { position: null, rotation: null, }
@@ -306,7 +306,7 @@ function HumanMechanics() {
actionName: `Action ${selectedPointData.actions.length + 1}`, actionName: `Action ${selectedPointData.actions.length + 1}`,
actionType: "worker", actionType: "worker",
loadCount: 1, loadCount: 1,
assemblyCount: 1, manufactureCount: 1,
loadCapacity: 1, loadCapacity: 1,
processTime: 10, processTime: 10,
triggers: [], triggers: [],
@@ -397,7 +397,7 @@ function HumanMechanics() {
<LabledDropdown <LabledDropdown
label="Action Type" label="Action Type"
defaultOption={activeOption} defaultOption={activeOption}
options={["worker", "assembly", "operator"]} options={["worker", "manufacture", "operator"]}
onSelect={handleSelectActionType} onSelect={handleSelectActionType}
disabled={false} disabled={false}
/> />
@@ -425,22 +425,22 @@ function HumanMechanics() {
clearPoints={handleClearPoints} clearPoints={handleClearPoints}
/> />
} }
{currentAction.actionType === 'assembly' && {currentAction.actionType === 'manufacturer' &&
<AssemblyAction <ManufactureAction
processTime={{ processTime={{
value: processTime, value: processTime,
min: 1, min: 1,
max: 60, max: 60,
onChange: handleProcessTimeChange, onChange: handleProcessTimeChange,
}} }}
assemblyCount={{ manufactureCount={{
value: assemblyCount, value: manufactureCount,
min: 1, min: 1,
max: 20, max: 20,
step: 1, step: 1,
defaultValue: "1", defaultValue: "1",
disabled: false, disabled: false,
onChange: handleAssemblyCountChange, onChange: handleManufactureCountChange,
}} }}
swapOptions={["Default material", "Material 1", "Material 2", "Material 3"]} swapOptions={["Default material", "Material 1", "Material 2", "Material 3"]}
swapDefaultOption={swappedMaterial} swapDefaultOption={swappedMaterial}

View File

@@ -271,7 +271,7 @@ function AssetsGroup({ plane }: { readonly plane: RefMesh }) {
actionName: "Action 1", actionName: "Action 1",
actionType: "worker", actionType: "worker",
loadCount: 1, loadCount: 1,
assemblyCount: 1, manufactureCount: 1,
loadCapacity: 1, loadCapacity: 1,
processTime: 10, processTime: 10,
triggers: [] triggers: []

View File

@@ -389,7 +389,7 @@ async function handleModelLoad(
actionName: "Action 1", actionName: "Action 1",
actionType: "worker", actionType: "worker",
loadCount: 1, loadCount: 1,
assemblyCount: 1, manufactureCount: 1,
loadCapacity: 1, loadCapacity: 1,
processTime: 10, processTime: 10,
triggers: [] triggers: []

View File

@@ -1,13 +1,5 @@
import { useMemo } from "react"; import { useMemo } from "react";
import { import { Shape, Vector2, DoubleSide, TextureLoader, RepeatWrapping, SRGBColorSpace, NoColorSpace, } from "three";
Shape,
Vector2,
DoubleSide,
TextureLoader,
RepeatWrapping,
SRGBColorSpace,
NoColorSpace,
} from "three";
import { useLoader } from "@react-three/fiber"; import { useLoader } from "@react-three/fiber";
import { Extrude } from "@react-three/drei"; import { Extrude } from "@react-three/drei";
import useModuleStore from "../../../../../store/useModuleStore"; import useModuleStore from "../../../../../store/useModuleStore";
@@ -36,212 +28,207 @@ import material4MetalicMap from "../../../../../assets/textures/floor/tex3/metal
import material4NormalMap from "../../../../../assets/textures/floor/tex3/metal_plate_nor_gl_1k.png"; import material4NormalMap from "../../../../../assets/textures/floor/tex3/metal_plate_nor_gl_1k.png";
function FloorInstance({ floor }: { floor: Floor }) { function FloorInstance({ floor }: { floor: Floor }) {
const { togglView } = useToggleView(); const { togglView } = useToggleView();
const { activeModule } = useModuleStore(); const { activeModule } = useModuleStore();
const { selectedFloor, setSelectedFloor, setSelectedDecal } = const { selectedFloor, setSelectedFloor, setSelectedDecal } =
useBuilderStore(); useBuilderStore();
const savedTheme = localStorage.getItem("theme"); const savedTheme = localStorage.getItem("theme");
const materials: Record< const materials: Record<
string, string,
{ {
map: string; map: string;
roughnessMap?: string; roughnessMap?: string;
metalnessMap?: string; metalnessMap?: string;
normalMap?: string; normalMap?: string;
textureTileScale?: [number, number]; textureTileScale?: [number, number];
}
> = {
"Default Material": {
map: savedTheme === "dark" ? texturePathDark : texturePath,
},
"Material 1": {
map: material1,
},
"Material 2": {
map: material2Map,
roughnessMap: material2MetalicRoughnessMap,
metalnessMap: material2MetalicRoughnessMap,
normalMap: material2NormalMap,
textureTileScale: [0.1, 0.1],
},
"Material 3": {
map: material3Map,
roughnessMap: material3MetalicRoughnessMap,
metalnessMap: material3MetalicRoughnessMap,
normalMap: material3NormalMap,
textureTileScale: [0.35, 0.5],
},
"Material 4": {
map: material4Map,
roughnessMap: material4RoughnessMap,
metalnessMap: material4MetalicMap,
normalMap: material4NormalMap,
},
};
const shape = useMemo(() => {
const shape = new Shape();
const points = floor.points.map(
(p) => new Vector2(p.position[0], p.position[2])
);
if (points.length < 3) return null;
shape.moveTo(points[0].x, points[0].y);
for (let i = 1; i < points.length; i++) {
shape.lineTo(points[i].x, points[i].y);
}
return shape;
}, [floor]);
const textureScale = Constants.floorConfig.textureScale;
// Helper function to handle texture maps and filter out null values
function getMaterialMaps(material: any, defaultMap: any) {
const materialMap = material.map || defaultMap;
const normalMap = material.normalMap || null;
const roughnessMap = material.roughnessMap || null;
const metalnessMap = material.metalnessMap || null;
return [materialMap, normalMap, roughnessMap, metalnessMap].filter(
(texture): texture is string => texture !== null
);
} }
> = {
"Default Material": {
map: savedTheme === "dark" ? texturePathDark : texturePath,
},
"Material 1": {
map: material1,
},
"Material 2": {
map: material2Map,
roughnessMap: material2MetalicRoughnessMap,
metalnessMap: material2MetalicRoughnessMap,
normalMap: material2NormalMap,
textureTileScale: [0.1, 0.1],
},
"Material 3": {
map: material3Map,
roughnessMap: material3MetalicRoughnessMap,
metalnessMap: material3MetalicRoughnessMap,
normalMap: material3NormalMap,
textureTileScale: [0.35, 0.5],
},
"Material 4": {
map: material4Map,
roughnessMap: material4RoughnessMap,
metalnessMap: material4MetalicMap,
normalMap: material4NormalMap,
},
};
const shape = useMemo(() => { // Default material map
const shape = new Shape(); const defaultMaterialMap = materials["Default Material"].map;
const points = floor.points.map(
(p) => new Vector2(p.position[0], p.position[2])
);
if (points.length < 3) return null;
shape.moveTo(points[0].x, points[0].y);
for (let i = 1; i < points.length; i++) {
shape.lineTo(points[i].x, points[i].y);
}
return shape;
}, [floor]);
const textureScale = Constants.floorConfig.textureScale; // Get top and side material maps
const topMaterial = materials[floor.topMaterial];
const sideMaterial = materials[floor.sideMaterial];
// Helper function to handle texture maps and filter out null values // Get the filtered lists for top and side textures
function getMaterialMaps(material: any, defaultMap: any) { const topTexturesList = getMaterialMaps(topMaterial, defaultMaterialMap);
const materialMap = material.map || defaultMap; const sideTexturesList = getMaterialMaps(sideMaterial, defaultMaterialMap);
const normalMap = material.normalMap || null;
const roughnessMap = material.roughnessMap || null;
const metalnessMap = material.metalnessMap || null;
return [materialMap, normalMap, roughnessMap, metalnessMap].filter( // Use loader to load top and side textures
(texture): texture is string => texture !== null const [topTexture, topNormalTexture, topRoughnessTexture, topMetalicTexture] = useLoader(TextureLoader, topTexturesList);
);
}
// Default material map const [
const defaultMaterialMap = materials["Default Material"].map;
// Get top and side material maps
const topMaterial = materials[floor.topMaterial];
const sideMaterial = materials[floor.sideMaterial];
// Get the filtered lists for top and side textures
const topTexturesList = getMaterialMaps(topMaterial, defaultMaterialMap);
const sideTexturesList = getMaterialMaps(sideMaterial, defaultMaterialMap);
// Use loader to load top and side textures
const [topTexture, topNormalTexture, topRoughnessTexture, topMetalicTexture] =
useLoader(TextureLoader, topTexturesList);
const [
sideTexture,
sideNormalTexture,
sideRoughnessTexture,
sideMetalicTexture,
] = useLoader(TextureLoader, sideTexturesList);
// Early exit if materials are missing
if (!materials[floor.topMaterial] || !materials[floor.sideMaterial])
return null;
// Combine and pair textures with their corresponding material
const textureMaterialMap = [
{
textures: [
topTexture,
topNormalTexture,
topRoughnessTexture,
topMetalicTexture,
],
materialKey: floor.topMaterial,
},
{
textures: [
sideTexture, sideTexture,
sideNormalTexture, sideNormalTexture,
sideRoughnessTexture, sideRoughnessTexture,
sideMetalicTexture, sideMetalicTexture,
], ] = useLoader(TextureLoader, sideTexturesList);
materialKey: floor.sideMaterial,
},
];
// Apply texture settings // Early exit if materials are missing
textureMaterialMap.forEach(({ textures, materialKey }) => { if (!materials[floor.topMaterial] || !materials[floor.sideMaterial])
const tileScale = materials[materialKey]?.textureTileScale ?? [ return null;
textureScale,
textureScale, // Combine and pair textures with their corresponding material
const textureMaterialMap = [
{
textures: [
topTexture,
topNormalTexture,
topRoughnessTexture,
topMetalicTexture,
],
materialKey: floor.topMaterial,
},
{
textures: [
sideTexture,
sideNormalTexture,
sideRoughnessTexture,
sideMetalicTexture,
],
materialKey: floor.sideMaterial,
},
]; ];
textures.forEach((tex, idx) => { // Apply texture settings
if (!tex) return; textureMaterialMap.forEach(({ textures, materialKey }) => {
tex.wrapS = tex.wrapT = RepeatWrapping; const tileScale = materials[materialKey]?.textureTileScale ?? [
tex.repeat.set(tileScale[0], tileScale[1]); textureScale,
tex.anisotropy = 16; textureScale,
// First texture is always the color map (use SRGB), others should be linear ];
tex.colorSpace = idx < 1 ? SRGBColorSpace : NoColorSpace;
textures.forEach((tex, idx) => {
if (!tex) return;
tex.wrapS = tex.wrapT = RepeatWrapping;
tex.repeat.set(tileScale[0], tileScale[1]);
tex.anisotropy = 16;
// First texture is always the color map (use SRGB), others should be linear
tex.colorSpace = idx < 1 ? SRGBColorSpace : NoColorSpace;
});
}); });
});
if (!shape) return null; if (!shape) return null;
return ( return (
<mesh <mesh
castShadow castShadow
receiveShadow receiveShadow
name={`Floor-${floor.floorUuid}`} name={`Floor-${floor.floorUuid}`}
rotation={[Math.PI / 2, 0, 0]} rotation={[Math.PI / 2, 0, 0]}
position={[ position={[0, !floor.isBeveled ? floor.floorDepth - 0.1 : floor.floorDepth - 0.2, 0,]}
0, userData={floor}
!floor.isBeveled ? floor.floorDepth - 0.1 : floor.floorDepth - 0.2, onDoubleClick={(e) => {
0, if (!togglView && activeModule === "builder") {
]} if (e.object.userData.floorUuid) {
userData={floor} e.stopPropagation();
onDoubleClick={(e) => { setSelectedFloor(e.object);
if (!togglView && activeModule === "builder") { setSelectedDecal(null);
if (e.object.userData.floorUuid) { }
e.stopPropagation(); }
setSelectedFloor(e.object); }}
setSelectedDecal(null); onPointerMissed={() => {
} if (
} selectedFloor &&
}} selectedFloor.userData.floorUuid === floor.floorUuid
onPointerMissed={() => { ) {
if ( setSelectedFloor(null);
selectedFloor && }
selectedFloor.userData.floorUuid === floor.floorUuid }}
) { >
setSelectedFloor(null); <Extrude
} name={`Floor-${floor.floorUuid}`}
}} args={[
> shape,
<Extrude {
name={`Floor-${floor.floorUuid}`} depth: !floor.isBeveled ? floor.floorDepth : floor.floorDepth - 0.1,
args={[ bevelEnabled: floor.isBeveled,
shape, bevelSegments: floor.bevelStrength,
{ bevelOffset: -0.1,
depth: !floor.isBeveled ? floor.floorDepth : floor.floorDepth - 0.1, bevelSize: 0.1,
bevelEnabled: floor.isBeveled, bevelThickness: 0.1,
bevelSegments: floor.bevelStrength, },
bevelOffset: -0.1, ]}
bevelSize: 0.1, userData={floor}
bevelThickness: 0.1, >
}, <meshPhysicalMaterial
]} attach="material-0"
userData={floor} color={Constants.floorConfig.defaultColor}
> map={topTexture}
<meshPhysicalMaterial roughnessMap={topRoughnessTexture}
attach="material-0" metalnessMap={topMetalicTexture}
color={Constants.floorConfig.defaultColor} normalMap={topNormalTexture}
map={topTexture} roughness={1.5}
roughnessMap={topRoughnessTexture} metalness={1.0}
metalnessMap={topMetalicTexture} side={DoubleSide}
normalMap={topNormalTexture} />
roughness={1.5} <meshStandardMaterial
metalness={1.0} attach="material-1"
side={DoubleSide} color={Constants.floorConfig.defaultColor}
/> map={sideTexture?.clone()}
<meshStandardMaterial roughnessMap={sideRoughnessTexture?.clone()}
attach="material-1" metalnessMap={sideMetalicTexture?.clone()}
color={Constants.floorConfig.defaultColor} normalMap={sideNormalTexture?.clone()}
map={sideTexture?.clone()} side={DoubleSide}
roughnessMap={sideRoughnessTexture?.clone()} />
metalnessMap={sideMetalicTexture?.clone()} </Extrude>
normalMap={sideNormalTexture?.clone()} </mesh>
side={DoubleSide} );
/>
</Extrude>
</mesh>
);
} }
export default FloorInstance; export default FloorInstance;

View File

@@ -10,7 +10,7 @@ import { useToggleView, useWallVisibility } from '../../../../../store/builder/s
import { useBuilderStore } from '../../../../../store/builder/useBuilderStore'; import { useBuilderStore } from '../../../../../store/builder/useBuilderStore';
import * as Constants from '../../../../../types/world/worldConstants'; import * as Constants from '../../../../../types/world/worldConstants';
// import DecalInstance from '../../../Decal/decalInstance'; import DecalInstance from '../../../Decal/decalInstance';
import defaultMaterial from '../../../../../assets/textures/floor/wall-tex.png'; import defaultMaterial from '../../../../../assets/textures/floor/wall-tex.png';
import material1 from '../../../../../assets/textures/floor/factory wall texture.jpg'; import material1 from '../../../../../assets/textures/floor/factory wall texture.jpg';
@@ -150,19 +150,6 @@ function Wall({ wall }: { readonly wall: Wall }) {
e.stopPropagation(); e.stopPropagation();
setSelectedWall(e.object); setSelectedWall(e.object);
setSelectedDecal(null); setSelectedDecal(null);
if (wall.decals.length > 0) return;
const decal: Decal = {
decalUuid: THREE.MathUtils.generateUUID(),
decalName: 'Decal',
decalId: 'Default Decal',
decalPosition: [0, 0, wall.wallThickness / 2 + 0.001],
decalRotation: 0,
decalScale: 1,
decalType: { type: 'Wall', wallUuid: wall.wallUuid }
}
addDecal(wall.wallUuid, decal);
} }
} }
}} }}
@@ -174,9 +161,9 @@ function Wall({ wall }: { readonly wall: Wall }) {
> >
<MeshDiscardMaterial /> <MeshDiscardMaterial />
{/* {wall.decals.map((decal) => ( {wall.decals.map((decal) => (
<DecalInstance zPosition={wall.wallThickness / 2 + 0.001} visible={visible} key={decal.decalUuid} decal={decal} /> <DecalInstance zPosition={wall.wallThickness / 2 + 0.001} visible={visible} key={decal.decalUuid} decal={decal} />
))} */} ))}
</mesh> </mesh>
</mesh> </mesh>
); );

View File

@@ -430,7 +430,7 @@ const CopyPasteControls3D = ({
actionName: "Action 1", actionName: "Action 1",
actionType: "worker", actionType: "worker",
loadCapacity: 1, loadCapacity: 1,
assemblyCount: 1, manufactureCount: 1,
loadCount: 1, loadCount: 1,
processTime: 10, processTime: 10,
triggers: [] triggers: []

View File

@@ -497,7 +497,7 @@ const DuplicationControls3D = ({
actionName: "Action 1", actionName: "Action 1",
actionType: "worker", actionType: "worker",
loadCapacity: 1, loadCapacity: 1,
assemblyCount: 1, manufactureCount: 1,
loadCount: 1, loadCount: 1,
processTime: 10, processTime: 10,
triggers: [] triggers: []

View File

@@ -2,7 +2,7 @@ import { useCallback } from "react";
import { useSceneContext } from "../../../../scene/sceneContext"; import { useSceneContext } from "../../../../scene/sceneContext";
import { useProductContext } from "../../../products/productContext"; import { useProductContext } from "../../../products/productContext";
export function useAssemblyHandler() { export function useManufacturerHandler() {
const { materialStore, humanStore, productStore } = useSceneContext(); const { materialStore, humanStore, productStore } = useSceneContext();
const { getMaterialById } = materialStore(); const { getMaterialById } = materialStore();
const { getModelUuidByActionUuid } = productStore(); const { getModelUuidByActionUuid } = productStore();
@@ -10,12 +10,12 @@ export function useAssemblyHandler() {
const { selectedProduct } = selectedProductStore(); const { selectedProduct } = selectedProductStore();
const { incrementHumanLoad, addCurrentMaterial, addCurrentAction } = humanStore(); const { incrementHumanLoad, addCurrentMaterial, addCurrentAction } = humanStore();
const assemblyLogStatus = (materialUuid: string, status: string) => { const manufactureLogStatus = (materialUuid: string, status: string) => {
echo.info(`${materialUuid}, ${status}`); echo.info(`${materialUuid}, ${status}`);
} }
const handleAssembly = useCallback((action: HumanAction, materialId?: string) => { const handleManufacturer = useCallback((action: HumanAction, materialId?: string) => {
if (!action || action.actionType !== 'assembly' || !materialId) return; if (!action || action.actionType !== 'manufacturer' || !materialId) return;
const material = getMaterialById(materialId); const material = getMaterialById(materialId);
if (!material) return; if (!material) return;
@@ -27,11 +27,11 @@ export function useAssemblyHandler() {
addCurrentAction(modelUuid, action.actionUuid); addCurrentAction(modelUuid, action.actionUuid);
addCurrentMaterial(modelUuid, material.materialType, material.materialId); addCurrentMaterial(modelUuid, material.materialType, material.materialId);
assemblyLogStatus(material.materialName, `performing assembly action`); manufactureLogStatus(material.materialName, `performing manufacturer action`);
}, [getMaterialById]); }, [getMaterialById]);
return { return {
handleAssembly, handleManufacturer,
}; };
} }

View File

@@ -1,18 +1,18 @@
import { useEffect, useCallback } from 'react'; import { useEffect, useCallback } from 'react';
import { useWorkerHandler } from './actionHandler/useWorkerHandler'; import { useWorkerHandler } from './actionHandler/useWorkerHandler';
import { useAssemblyHandler } from './actionHandler/useAssemblyHandler'; import { useManufacturerHandler } from './actionHandler/useManufacturerHandler';
export function useHumanActions() { export function useHumanActions() {
const { handleWorker } = useWorkerHandler(); const { handleWorker } = useWorkerHandler();
const { handleAssembly } = useAssemblyHandler(); const { handleManufacturer } = useManufacturerHandler();
const handleWorkerAction = useCallback((action: HumanAction, materialId: string) => { const handleWorkerAction = useCallback((action: HumanAction, materialId: string) => {
handleWorker(action, materialId); handleWorker(action, materialId);
}, [handleWorker]); }, [handleWorker]);
const handleAssemblyAction = useCallback((action: HumanAction, materialId: string) => { const handleManufactureAction = useCallback((action: HumanAction, materialId: string) => {
handleAssembly(action, materialId); handleManufacturer(action, materialId);
}, [handleAssembly]); }, [handleManufacturer]);
const handleHumanAction = useCallback((action: HumanAction, materialId: string) => { const handleHumanAction = useCallback((action: HumanAction, materialId: string) => {
if (!action) return; if (!action) return;
@@ -21,13 +21,13 @@ export function useHumanActions() {
case 'worker': case 'worker':
handleWorkerAction(action, materialId); handleWorkerAction(action, materialId);
break; break;
case 'assembly': case 'manufacturer':
handleAssemblyAction(action, materialId); handleManufactureAction(action, materialId);
break; break;
default: default:
console.warn(`Unknown Human action type: ${action.actionType}`); console.warn(`Unknown Human action type: ${action.actionType}`);
} }
}, [handleWorkerAction, handleAssemblyAction]); }, [handleWorkerAction, handleManufactureAction]);
const cleanup = useCallback(() => { const cleanup = useCallback(() => {
}, []); }, []);

View File

@@ -41,7 +41,7 @@ export function useActionHandler() {
case 'store': case 'retrieve': case 'store': case 'retrieve':
handleStorageAction(action as StorageAction, materialId as string); handleStorageAction(action as StorageAction, materialId as string);
break; break;
case 'worker': case 'assembly': case 'worker': case 'manufacturer':
handleHumanAction(action as HumanAction, materialId as string); handleHumanAction(action as HumanAction, materialId as string);
break; break;
case 'pickAndDrop': case 'pickAndDrop':

View File

@@ -25,7 +25,7 @@ export function useHumanEventManager() {
const addHumanToMonitor = (humanId: string, callback: () => void, actionUuid: string) => { const addHumanToMonitor = (humanId: string, callback: () => void, actionUuid: string) => {
const human = getHumanById(humanId); const human = getHumanById(humanId);
const action = getActionByUuid(selectedProduct.productUuid, actionUuid); const action = getActionByUuid(selectedProduct.productUuid, actionUuid);
if (!human || !action || (action.actionType !== 'assembly' && action.actionType !== 'worker' && action.actionType !== 'operator') || !humanEventManagerRef.current) return; if (!human || !action || (action.actionType !== 'manufacturer' && action.actionType !== 'worker' && action.actionType !== 'operator') || !humanEventManagerRef.current) return;
let state = humanEventManagerRef.current.humanStates.find(h => h.humanId === humanId); let state = humanEventManagerRef.current.humanStates.find(h => h.humanId === humanId);
if (!state) { if (!state) {
@@ -42,8 +42,8 @@ export function useHumanEventManager() {
existingAction.isMonitored = true; existingAction.isMonitored = true;
existingAction.isCompleted = false; existingAction.isCompleted = false;
} }
} else if (existingAction.actionType === 'assembly') { } else if (existingAction.actionType === 'manufacturer') {
if (currentCount < existingAction.maxAssemblyCount) { if (currentCount < existingAction.maxManufactureCount) {
existingAction.callback = callback; existingAction.callback = callback;
existingAction.isMonitored = true; existingAction.isMonitored = true;
existingAction.isCompleted = false; existingAction.isCompleted = false;
@@ -57,7 +57,7 @@ export function useHumanEventManager() {
actionUuid, actionUuid,
actionName: action.actionName, actionName: action.actionName,
maxLoadCount: action.loadCount ?? 0, maxLoadCount: action.loadCount ?? 0,
maxAssemblyCount: action.assemblyCount ?? 0, maxManufactureCount: action.manufactureCount ?? 0,
count: 0, count: 0,
isMonitored: true, isMonitored: true,
isCompleted: false, isCompleted: false,
@@ -101,11 +101,11 @@ export function useHumanEventManager() {
if (currentAction.actionType === 'worker' || currentAction.actionType === 'operator') { if (currentAction.actionType === 'worker' || currentAction.actionType === 'operator') {
if ((action.actionType === 'worker' || action.actionType === 'operator') && human.currentLoad < currentAction.loadCapacity) { if ((action.actionType === 'worker' || action.actionType === 'operator') && human.currentLoad < currentAction.loadCapacity) {
conditionMet = true; conditionMet = true;
} else if (action.actionType === 'assembly') { } else if (action.actionType === 'manufacturer') {
conditionMet = true; conditionMet = true;
} }
} else if (currentAction.actionType === 'assembly') { } else if (currentAction.actionType === 'manufacturer') {
if (action.actionType === 'assembly') { if (action.actionType === 'manufacturer') {
conditionMet = true; conditionMet = true;
} else if ((action.actionType === 'worker' || action.actionType === 'operator') && human.currentLoad < currentAction.loadCapacity) { } else if ((action.actionType === 'worker' || action.actionType === 'operator') && human.currentLoad < currentAction.loadCapacity) {
conditionMet = true; conditionMet = true;
@@ -122,7 +122,7 @@ export function useHumanEventManager() {
action.count = (action.count ?? 0) + 1; action.count = (action.count ?? 0) + 1;
action.isMonitored = false; action.isMonitored = false;
if (((action.actionType === 'worker' || action.actionType === 'operator') && action.count >= action.maxLoadCount) || if (((action.actionType === 'worker' || action.actionType === 'operator') && action.count >= action.maxLoadCount) ||
(action.actionType === 'assembly' && action.count >= action.maxAssemblyCount)) { (action.actionType === 'manufacturer' && action.count >= action.maxManufactureCount)) {
action.isCompleted = true; action.isCompleted = true;
} }
humanState.isCooldown = true; humanState.isCooldown = true;

View File

@@ -6,14 +6,14 @@ import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useRese
import { useSceneContext } from '../../../../scene/sceneContext'; import { useSceneContext } from '../../../../scene/sceneContext';
import { useProductContext } from '../../../products/productContext'; import { useProductContext } from '../../../products/productContext';
interface AssemblerAnimatorProps { interface ManufacturerAnimatorProps {
path: [number, number, number][]; path: [number, number, number][];
handleCallBack: () => void; handleCallBack: () => void;
reset: () => void; reset: () => void;
human: HumanStatus; human: HumanStatus;
} }
function AssemblerAnimator({ path, handleCallBack, human, reset }: Readonly<AssemblerAnimatorProps>) { function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<ManufacturerAnimatorProps>) {
const { humanStore, assetStore, productStore } = useSceneContext(); const { humanStore, assetStore, productStore } = useSceneContext();
const { getActionByUuid } = productStore(); const { getActionByUuid } = productStore();
const { selectedProductStore } = useProductContext(); const { selectedProductStore } = useProductContext();
@@ -27,16 +27,16 @@ function AssemblerAnimator({ path, handleCallBack, human, reset }: Readonly<Asse
const progressRef = useRef<number>(0); const progressRef = useRef<number>(0);
const completedRef = useRef<boolean>(false); const completedRef = useRef<boolean>(false);
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || ''); const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
const [objectRotation, setObjectRotation] = useState<[number, number, number] | null>((action as HumanAction)?.assemblyPoint?.rotation || [0, 0, 0]); const [objectRotation, setObjectRotation] = useState<[number, number, number] | null>((action as HumanAction)?.manufacturePoint?.rotation || [0, 0, 0]);
const [restRotation, setRestingRotation] = useState<boolean>(true); const [restRotation, setRestingRotation] = useState<boolean>(true);
const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]); const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]);
const { scene } = useThree(); const { scene } = useThree();
useEffect(() => { useEffect(() => {
if (!human.currentAction?.actionUuid) return; if (!human.currentAction?.actionUuid) return;
if (human.currentPhase === 'init-assembly' && path.length > 0) { if (human.currentPhase === 'init-manufacture' && path.length > 0) {
setCurrentPath(path); setCurrentPath(path);
setObjectRotation((action as HumanAction)?.assemblyPoint?.rotation ?? null); setObjectRotation((action as HumanAction)?.manufacturePoint?.rotation ?? null);
} }
}, [human.currentPhase, path, objectRotation, selectedProduct, human.currentAction?.actionUuid]); }, [human.currentPhase, path, objectRotation, selectedProduct, human.currentAction?.actionUuid]);
@@ -169,4 +169,4 @@ function AssemblerAnimator({ path, handleCallBack, human, reset }: Readonly<Asse
); );
} }
export default AssemblerAnimator; export default ManufacturerAnimator;

View File

@@ -50,7 +50,7 @@ const MaterialAnimator = ({ human }: { human: HumanStatus; }) => {
return ( return (
<> <>
{hasLoad && action && (action as HumanAction).actionType === 'worker' && human.currentMaterials.length > 0 && (human.currentPhase !== 'init-pickup' && human.currentPhase !== 'init-assembly' && human.currentPhase !== 'drop-pickup') && ( {hasLoad && action && (action as HumanAction).actionType === 'worker' && human.currentMaterials.length > 0 && (human.currentPhase !== 'init-pickup' && human.currentPhase !== 'init-manufacture' && human.currentPhase !== 'drop-pickup') && (
<MaterialModel <MaterialModel
matRef={meshRef} matRef={meshRef}
materialId={`human-${human.currentMaterials[0].materialId}` || ''} materialId={`human-${human.currentMaterials[0].materialId}` || ''}

View File

@@ -127,13 +127,13 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
const t = (progressRef.current - accumulatedDistance) / segmentDistance; const t = (progressRef.current - accumulatedDistance) / segmentDistance;
const position = start.clone().lerp(end, t); const position = start.clone().lerp(end, t);
object.position.copy(position); object.position.copy(position);
if (human.currentMaterials.length > 0 && (human.currentPhase !== 'init-pickup' && human.currentPhase !== 'init-assembly' && human.currentPhase !== 'drop-pickup')) { if (human.currentMaterials.length > 0 && (human.currentPhase !== 'init-pickup' && human.currentPhase !== 'init-manufacture' && human.currentPhase !== 'drop-pickup')) {
setCurrentAnimation(human.modelUuid, 'walk_with_box', true, true, true); setCurrentAnimation(human.modelUuid, 'walk_with_box', true, true, true);
} else { } else {
setCurrentAnimation(human.modelUuid, 'walking', true, true, true); setCurrentAnimation(human.modelUuid, 'walking', true, true, true);
} }
} else { } else {
if (human.currentMaterials.length > 0 && (human.currentPhase !== 'init-pickup' && human.currentPhase !== 'init-assembly' && human.currentPhase !== 'drop-pickup')) { if (human.currentMaterials.length > 0 && (human.currentPhase !== 'init-pickup' && human.currentPhase !== 'init-manufacture' && human.currentPhase !== 'drop-pickup')) {
setCurrentAnimation(human.modelUuid, 'idle_with_box', true, true, true); setCurrentAnimation(human.modelUuid, 'idle_with_box', true, true, true);
} else { } else {
setCurrentAnimation(human.modelUuid, 'idle', true, true, true); setCurrentAnimation(human.modelUuid, 'idle', true, true, true);

View File

@@ -8,9 +8,9 @@ import { useTriggerHandler } from '../../../../triggers/triggerHandler/useTrigge
import { useSceneContext } from '../../../../../scene/sceneContext'; import { useSceneContext } from '../../../../../scene/sceneContext';
import { useProductContext } from '../../../../products/productContext'; import { useProductContext } from '../../../../products/productContext';
import AssemblerAnimator from '../../animator/assemblerAnimator'; import ManufacturerAnimator from '../../animator/manufacturerAnimator';
function AssemblerInstance({ human }: { human: HumanStatus }) { function ManufacturerInstance({ human }: { human: HumanStatus }) {
const { navMesh } = useNavMesh(); const { navMesh } = useNavMesh();
const { isPlaying } = usePlayButtonStore(); const { isPlaying } = usePlayButtonStore();
const { scene } = useThree(); const { scene } = useThree();
@@ -99,24 +99,24 @@ function AssemblerInstance({ human }: { human: HumanStatus }) {
if (isPlaying) { if (isPlaying) {
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || ''); const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
if (!action || !(action as HumanAction).assemblyPoint || (action as HumanAction).actionType === 'worker') return; if (!action || !(action as HumanAction).manufacturePoint || (action as HumanAction).actionType === 'worker') return;
if (!human.isActive && human.state === 'idle' && human.currentPhase === 'init') { if (!human.isActive && human.state === 'idle' && human.currentPhase === 'init') {
const humanMesh = scene.getObjectByProperty('uuid', human.modelUuid); const humanMesh = scene.getObjectByProperty('uuid', human.modelUuid);
if (!humanMesh) return; if (!humanMesh) return;
const toPickupPath = computePath(humanMesh.position.toArray(), (action as HumanAction)?.assemblyPoint?.position || [0, 0, 0]); const toPickupPath = computePath(humanMesh.position.toArray(), (action as HumanAction)?.manufacturePoint?.position || [0, 0, 0]);
setPath(toPickupPath); setPath(toPickupPath);
setHumanState(human.modelUuid, 'idle'); setHumanState(human.modelUuid, 'idle');
setCurrentPhase(human.modelUuid, 'init-assembly'); setCurrentPhase(human.modelUuid, 'init-manufacture');
setHumanActive(human.modelUuid, false); setHumanActive(human.modelUuid, false);
setCurrentAnimation(human.modelUuid, 'idle', true, true, true); setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
humanStatus(human.modelUuid, 'Human is waiting for material in assembly'); humanStatus(human.modelUuid, 'Human is waiting for material in manufacture');
} else if (!human.isActive && human.state === 'idle' && human.currentPhase === 'waiting') { } else if (!human.isActive && human.state === 'idle' && human.currentPhase === 'waiting') {
if (human.currentMaterials.length > 0 && humanAsset && humanAsset.animationState?.current !== 'working_standing') { if (human.currentMaterials.length > 0 && humanAsset && humanAsset.animationState?.current !== 'working_standing') {
setCurrentAnimation(human.modelUuid, 'working_standing', true, true, false); setCurrentAnimation(human.modelUuid, 'working_standing', true, true, false);
setHumanState(human.modelUuid, 'running'); setHumanState(human.modelUuid, 'running');
setCurrentPhase(human.modelUuid, 'assembling'); setCurrentPhase(human.modelUuid, 'manufacturing');
setHumanActive(human.modelUuid, true); setHumanActive(human.modelUuid, true);
processStartTimeRef.current = performance.now(); processStartTimeRef.current = performance.now();
@@ -127,16 +127,16 @@ function AssemblerInstance({ human }: { human: HumanStatus }) {
hasLoggedCompleted.current = false; hasLoggedCompleted.current = false;
if (!processAnimationIdRef.current) { if (!processAnimationIdRef.current) {
processAnimationIdRef.current = requestAnimationFrame(trackAssemblyProcess); processAnimationIdRef.current = requestAnimationFrame(trackManufactureProcess);
} }
} }
} else if (human.isActive && human.state === 'running' && human.currentMaterials.length > 0 && humanAsset && humanAsset.animationState?.current === 'working_standing' && humanAsset.animationState?.isCompleted) { } else if (human.isActive && human.state === 'running' && human.currentMaterials.length > 0 && humanAsset && humanAsset.animationState?.current === 'working_standing' && humanAsset.animationState?.isCompleted) {
if ((action as HumanAction).assemblyPoint && human.currentPhase === 'assembling') { if ((action as HumanAction).manufacturePoint && human.currentPhase === 'manufacturing') {
setHumanState(human.modelUuid, 'idle'); setHumanState(human.modelUuid, 'idle');
setCurrentPhase(human.modelUuid, 'waiting'); setCurrentPhase(human.modelUuid, 'waiting');
setHumanActive(human.modelUuid, false); setHumanActive(human.modelUuid, false);
setCurrentAnimation(human.modelUuid, 'idle', true, true, true); setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
humanStatus(human.modelUuid, 'Human is waiting for material in assembly'); humanStatus(human.modelUuid, 'Human is waiting for material in manufacture');
decrementHumanLoad(human.modelUuid, 1); decrementHumanLoad(human.modelUuid, 1);
const material = removeLastMaterial(human.modelUuid); const material = removeLastMaterial(human.modelUuid);
@@ -150,7 +150,7 @@ function AssemblerInstance({ human }: { human: HumanStatus }) {
} }
}, [human, human.currentPhase, path, isPlaying, humanAsset?.animationState?.isCompleted]); }, [human, human.currentPhase, path, isPlaying, humanAsset?.animationState?.isCompleted]);
const trackAssemblyProcess = useCallback(() => { const trackManufactureProcess = useCallback(() => {
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || ''); const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
const now = performance.now(); const now = performance.now();
@@ -163,7 +163,7 @@ function AssemblerInstance({ human }: { human: HumanStatus }) {
if (!lastPauseTimeRef.current) { if (!lastPauseTimeRef.current) {
lastPauseTimeRef.current = now; lastPauseTimeRef.current = now;
} }
processAnimationIdRef.current = requestAnimationFrame(trackAssemblyProcess); processAnimationIdRef.current = requestAnimationFrame(trackManufactureProcess);
return; return;
} else if (lastPauseTimeRef.current) { } else if (lastPauseTimeRef.current) {
accumulatedPausedTimeRef.current += now - lastPauseTimeRef.current; accumulatedPausedTimeRef.current += now - lastPauseTimeRef.current;
@@ -178,7 +178,7 @@ function AssemblerInstance({ human }: { human: HumanStatus }) {
if (human.currentMaterials.length > 0) { if (human.currentMaterials.length > 0) {
setMaterial(human.currentMaterials[0].materialId, (action as HumanAction).swapMaterial || 'Default Material'); setMaterial(human.currentMaterials[0].materialId, (action as HumanAction).swapMaterial || 'Default Material');
} }
humanStatus(human.modelUuid, `🟡 Human ${human.modelUuid} reached halfway in assembly.`); humanStatus(human.modelUuid, `🟡 Human ${human.modelUuid} reached halfway in manufacture.`);
} }
if (elapsed >= totalProcessTimeMs && !hasLoggedCompleted.current) { if (elapsed >= totalProcessTimeMs && !hasLoggedCompleted.current) {
@@ -188,27 +188,27 @@ function AssemblerInstance({ human }: { human: HumanStatus }) {
cancelAnimationFrame(processAnimationIdRef.current); cancelAnimationFrame(processAnimationIdRef.current);
processAnimationIdRef.current = null; processAnimationIdRef.current = null;
} }
humanStatus(human.modelUuid, `✅ Human ${human.modelUuid} completed assembly process.`); humanStatus(human.modelUuid, `✅ Human ${human.modelUuid} completed manufacture process.`);
return; return;
} }
processAnimationIdRef.current = requestAnimationFrame(trackAssemblyProcess); processAnimationIdRef.current = requestAnimationFrame(trackManufactureProcess);
}, [human.modelUuid, human.currentMaterials]); }, [human.modelUuid, human.currentMaterials]);
function handleCallBack() { function handleCallBack() {
if (human.currentPhase === 'init-assembly') { if (human.currentPhase === 'init-manufacture') {
setCurrentPhase(human.modelUuid, 'waiting'); setCurrentPhase(human.modelUuid, 'waiting');
setHumanState(human.modelUuid, 'idle'); setHumanState(human.modelUuid, 'idle');
setHumanActive(human.modelUuid, false); setHumanActive(human.modelUuid, false);
setCurrentAnimation(human.modelUuid, 'idle', true, true, true); setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
humanStatus(human.modelUuid, 'Reached assembly point, waiting for material'); humanStatus(human.modelUuid, 'Reached manufacture point, waiting for material');
setPath([]); setPath([]);
} }
} }
return ( return (
<> <>
<AssemblerAnimator <ManufacturerAnimator
path={path} path={path}
handleCallBack={handleCallBack} handleCallBack={handleCallBack}
human={human} human={human}
@@ -218,4 +218,4 @@ function AssemblerInstance({ human }: { human: HumanStatus }) {
) )
} }
export default AssemblerInstance; export default ManufacturerInstance;

View File

@@ -4,7 +4,7 @@ import { useSceneContext } from '../../../../scene/sceneContext';
import { useProductContext } from '../../../products/productContext'; import { useProductContext } from '../../../products/productContext';
import MaterialAnimator from '../animator/materialAnimator'; import MaterialAnimator from '../animator/materialAnimator';
import AssemblerInstance from './actions/assemberInstance'; import ManufacturerInstance from './actions/manufacturerInstance';
import WorkerInstance from './actions/workerInstance'; import WorkerInstance from './actions/workerInstance';
import OperatorInstance from './actions/operatorInstance'; import OperatorInstance from './actions/operatorInstance';
@@ -84,8 +84,8 @@ function HumanInstance({ human }: { human: HumanStatus }) {
{action && action.actionType === 'worker' && {action && action.actionType === 'worker' &&
<WorkerInstance human={human} /> <WorkerInstance human={human} />
} }
{action && action.actionType === 'assembly' && {action && action.actionType === 'manufacturer' &&
<AssemblerInstance human={human} /> <ManufacturerInstance human={human} />
} }
{action && action.actionType === 'operator' && {action && action.actionType === 'operator' &&
<OperatorInstance human={human} /> <OperatorInstance human={human} />

View File

@@ -10,16 +10,16 @@ import { useVersionContext } from '../../../../builder/version/versionContext';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import startPoint from "../../../../../assets/gltf-glb/ui/human-ui-green.glb"; import startPoint from "../../../../../assets/gltf-glb/ui/human-ui-green.glb";
import startEnd from "../../../../../assets/gltf-glb/ui/human-ui-orange.glb"; import startEnd from "../../../../../assets/gltf-glb/ui/human-ui-orange.glb";
import assembly from "../../../../../assets/gltf-glb/ui/human-ui-assembly.glb"; import manufacture from "../../../../../assets/gltf-glb/ui/human-ui-manufacture.glb";
import { upsertProductOrEventApi } from '../../../../../services/simulation/products/UpsertProductOrEventApi'; import { upsertProductOrEventApi } from '../../../../../services/simulation/products/UpsertProductOrEventApi';
function HumanUi() { function HumanUi() {
const { scene: startScene } = useGLTF(startPoint) as any; const { scene: startScene } = useGLTF(startPoint) as any;
const { scene: endScene } = useGLTF(startEnd) as any; const { scene: endScene } = useGLTF(startEnd) as any;
const { scene: assemblyScene } = useGLTF(assembly) as any; const { scene: manufactureScene } = useGLTF(manufacture) as any;
const startMarker = useRef<Group>(null); const startMarker = useRef<Group>(null);
const endMarker = useRef<Group>(null); const endMarker = useRef<Group>(null);
const assemblyMarker = useRef<Group>(null); const manufactureMarker = useRef<Group>(null);
const outerGroup = useRef<Group>(null); const outerGroup = useRef<Group>(null);
const prevMousePos = useRef({ x: 0, y: 0 }); const prevMousePos = useRef({ x: 0, y: 0 });
const { controls, raycaster, camera } = useThree(); const { controls, raycaster, camera } = useThree();
@@ -31,9 +31,9 @@ function HumanUi() {
const { updateEvent, getActionByUuid } = productStore(); const { updateEvent, getActionByUuid } = productStore();
const [startPosition, setStartPosition] = useState<[number, number, number]>([0, 1, 0]); const [startPosition, setStartPosition] = useState<[number, number, number]>([0, 1, 0]);
const [endPosition, setEndPosition] = useState<[number, number, number]>([0, 1, 0]); const [endPosition, setEndPosition] = useState<[number, number, number]>([0, 1, 0]);
const [assemblyPosition, setAssemblyPosition] = useState<[number, number, number]>([0, 1, 0]); const [manufacturePosition, setManufacturePosition] = useState<[number, number, number]>([0, 1, 0]);
const [startRotation, setStartRotation] = useState<[number, number, number]>([0, Math.PI, 0]); const [startRotation, setStartRotation] = useState<[number, number, number]>([0, Math.PI, 0]);
const [assemblyRotation, setAssemblyRotation] = useState<[number, number, number]>([0, 0, 0]); const [manufactureRotation, setManufactureRotation] = useState<[number, number, number]>([0, 0, 0]);
const [endRotation, setEndRotation] = useState<[number, number, number]>([0, 0, 0]); const [endRotation, setEndRotation] = useState<[number, number, number]>([0, 0, 0]);
const { isDragging, setIsDragging } = useIsDragging(); const { isDragging, setIsDragging } = useIsDragging();
const { isRotating, setIsRotating } = useIsRotating(); const { isRotating, setIsRotating } = useIsRotating();
@@ -51,7 +51,7 @@ function HumanUi() {
const { projectId } = useParams(); const { projectId } = useParams();
const currentAction = getActionByUuid(selectedProduct.productUuid, selectedAction.actionId || ''); const currentAction = getActionByUuid(selectedProduct.productUuid, selectedAction.actionId || '');
const isAssembly = currentAction?.actionType === 'assembly'; const isManufacture = currentAction?.actionType === 'manufacturer';
const updateBackend = ( const updateBackend = (
productName: string, productName: string,
@@ -90,15 +90,15 @@ function HumanUi() {
const action = selectedHuman.point.actions.find(a => a.actionUuid === selectedAction.actionId); const action = selectedHuman.point.actions.find(a => a.actionUuid === selectedAction.actionId);
if (!action) return; if (!action) return;
if (isAssembly) { if (isManufacture) {
if (action.assemblyPoint?.position && outerGroup.current) { if (action.manufacturePoint?.position && outerGroup.current) {
const worldPos = new Vector3(...action.assemblyPoint.position); const worldPos = new Vector3(...action.manufacturePoint.position);
const localPosition = outerGroup.current.worldToLocal(worldPos.clone()); const localPosition = outerGroup.current.worldToLocal(worldPos.clone());
setAssemblyPosition([localPosition.x, 1, localPosition.z]); setManufacturePosition([localPosition.x, 1, localPosition.z]);
setAssemblyRotation(action.assemblyPoint.rotation || [0, 0, 0]); setManufactureRotation(action.manufacturePoint.rotation || [0, 0, 0]);
} else { } else {
setAssemblyPosition([0, 1, 0]); setManufacturePosition([0, 1, 0]);
setAssemblyRotation([0, 0, 0]); setManufactureRotation([0, 0, 0]);
} }
} else { } else {
if (action.pickUpPoint?.position && outerGroup.current) { if (action.pickUpPoint?.position && outerGroup.current) {
@@ -125,8 +125,8 @@ function HumanUi() {
const handlePointerDown = ( const handlePointerDown = (
e: any, e: any,
state: "start" | "end" | "assembly", state: "start" | "end" | "manufacture",
rotation: "start" | "end" | "assembly" rotation: "start" | "end" | "manufacture"
) => { ) => {
e.stopPropagation(); e.stopPropagation();
const intersection = new Vector3(); const intersection = new Vector3();
@@ -153,7 +153,7 @@ function HumanUi() {
const marker = const marker =
state === "start" ? startMarker.current : state === "start" ? startMarker.current :
state === "end" ? endMarker.current : state === "end" ? endMarker.current :
assemblyMarker.current; manufactureMarker.current;
if (marker && localPoint) { if (marker && localPoint) {
const markerPos = new Vector3().copy(marker.position); const markerPos = new Vector3().copy(marker.position);
dragOffset.current.copy(markerPos.sub(localPoint)); dragOffset.current.copy(markerPos.sub(localPoint));
@@ -176,17 +176,17 @@ function HumanUi() {
const updatedActions = selectedHuman.point.actions.map(action => { const updatedActions = selectedHuman.point.actions.map(action => {
if (action.actionUuid !== currentAction.actionUuid) return action; if (action.actionUuid !== currentAction.actionUuid) return action;
if (isAssembly) { if (isManufacture) {
if (!assemblyMarker.current || !outerGroup.current) return action; if (!manufactureMarker.current || !outerGroup.current) return action;
const worldPosAssembly = new Vector3(...assemblyPosition); const worldPosManufacture = new Vector3(...manufacturePosition);
const globalAssemblyPosition = outerGroup.current.localToWorld(worldPosAssembly.clone()); const globalManufacturePosition = outerGroup.current.localToWorld(worldPosManufacture.clone());
return { return {
...action, ...action,
assemblyPoint: { manufacturePoint: {
position: [globalAssemblyPosition.x, globalAssemblyPosition.y, globalAssemblyPosition.z] as [number, number, number], position: [globalManufacturePosition.x, globalManufacturePosition.y, globalManufacturePosition.z] as [number, number, number],
rotation: assemblyRotation rotation: manufactureRotation
}, },
}; };
} else { } else {
@@ -246,8 +246,8 @@ function HumanUi() {
setStartPosition([localPoint.x, 1, localPoint.z]); setStartPosition([localPoint.x, 1, localPoint.z]);
} else if (isDragging === "end") { } else if (isDragging === "end") {
setEndPosition([localPoint.x, 1, localPoint.z]); setEndPosition([localPoint.x, 1, localPoint.z]);
} else if (isDragging === "assembly") { } else if (isDragging === "manufacture") {
setAssemblyPosition([localPoint.x, 1, localPoint.z]); setManufacturePosition([localPoint.x, 1, localPoint.z]);
} }
}); });
@@ -260,7 +260,7 @@ function HumanUi() {
const marker = const marker =
isRotating === "start" ? startMarker.current : isRotating === "start" ? startMarker.current :
isRotating === "end" ? endMarker.current : isRotating === "end" ? endMarker.current :
assemblyMarker.current; manufactureMarker.current;
if (marker) { if (marker) {
const rotationSpeed = 10; const rotationSpeed = 10;
@@ -279,7 +279,7 @@ function HumanUi() {
marker.rotation.z, marker.rotation.z,
]); ]);
} else { } else {
setAssemblyRotation([ setManufactureRotation([
marker.rotation.x, marker.rotation.x,
marker.rotation.y, marker.rotation.y,
marker.rotation.z, marker.rotation.z,
@@ -303,7 +303,7 @@ function HumanUi() {
return () => { return () => {
window.removeEventListener("pointerup", handleGlobalPointerUp); window.removeEventListener("pointerup", handleGlobalPointerUp);
}; };
}, [isDragging, isRotating, startPosition, startRotation, endPosition, endRotation, assemblyPosition, assemblyRotation]); }, [isDragging, isRotating, startPosition, startRotation, endPosition, endRotation, manufacturePosition, manufactureRotation]);
return ( return (
<> <>
@@ -313,16 +313,16 @@ function HumanUi() {
ref={outerGroup} ref={outerGroup}
rotation={[0, Math.PI, 0]} rotation={[0, Math.PI, 0]}
> >
{isAssembly ? ( {isManufacture ? (
<MarkerPrimitive <MarkerPrimitive
name="assemblyMarker" name="manufactureMarker"
refProp={assemblyMarker} refProp={manufactureMarker}
object={assemblyScene} object={manufactureScene}
position={assemblyPosition} position={manufacturePosition}
rotation={assemblyRotation} rotation={manufactureRotation}
outerGroupRef={outerGroup} outerGroupRef={outerGroup}
type="assembly" type="manufacture"
subtype="assembly" subtype="manufacture"
color="#0f87f7" color="#0f87f7"
setIsDragging={setIsDragging} setIsDragging={setIsDragging}
setIsRotating={setIsRotating} setIsRotating={setIsRotating}

View File

@@ -1341,7 +1341,7 @@ export function useTriggerHandler() {
handleAction(action, material.materialId); handleAction(action, material.materialId);
} }
} else if (material && action.actionType === 'assembly') { } else if (material && action.actionType === 'manufacturer') {
setPreviousLocation(material.materialId, { setPreviousLocation(material.materialId, {
modelUuid: material.current.modelUuid, modelUuid: material.current.modelUuid,

View File

@@ -251,7 +251,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
} }
} else if (model.type === 'human') { } else if (model.type === 'human') {
const action = getActionByUuid(selectedProduct.productUuid, agvDetail.point.action.actionUuid); const action = getActionByUuid(selectedProduct.productUuid, agvDetail.point.action.actionUuid);
if (action && (triggeredAction?.actionType === 'assembly' || triggeredAction?.actionType === 'worker')) { if (action && (triggeredAction?.actionType === 'manufacturer' || triggeredAction?.actionType === 'worker')) {
handleMaterialDropToHuman(model, triggeredAction); handleMaterialDropToHuman(model, triggeredAction);
} }
} else if (model.type === 'crane') { } else if (model.type === 'crane') {

View File

@@ -203,8 +203,8 @@ export const useSelectedAnimation = create<SelectedAnimationState>()(
); );
interface IsDraggingState { interface IsDraggingState {
isDragging: "start" | "end" | "assembly" | null; isDragging: "start" | "end" | "manufacture" | null;
setIsDragging: (state: "start" | "end" | "assembly" | null) => void; setIsDragging: (state: "start" | "end" | "manufacture" | null) => void;
} }
export const useIsDragging = create<IsDraggingState>()( export const useIsDragging = create<IsDraggingState>()(
@@ -219,8 +219,8 @@ export const useIsDragging = create<IsDraggingState>()(
); );
interface IsRotatingState { interface IsRotatingState {
isRotating: "start" | "end" | "assembly" | null; isRotating: "start" | "end" | "manufacture" | null;
setIsRotating: (state: "start" | "end" | "assembly" | null) => void; setIsRotating: (state: "start" | "end" | "manufacture" | null) => void;
} }
export const useIsRotating = create<IsRotatingState>()( export const useIsRotating = create<IsRotatingState>()(

View File

@@ -96,14 +96,14 @@ interface StorageAction {
interface HumanAction { interface HumanAction {
actionUuid: string; actionUuid: string;
actionName: string; actionName: string;
actionType: "worker" | "assembly" | "operator"; actionType: "worker" | "manufacturer" | "operator";
processTime: number; processTime: number;
swapMaterial?: string; swapMaterial?: string;
assemblyPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; } manufacturePoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; }
pickUpPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; } pickUpPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; }
dropPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; } dropPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; }
loadCount: number; loadCount: number;
assemblyCount: number; manufactureCount: number;
loadCapacity: number; loadCapacity: number;
triggers: TriggerSchema[]; triggers: TriggerSchema[];
} }
@@ -324,11 +324,11 @@ interface CraneStatus extends CraneEventSchema {
type HumanEventState = { type HumanEventState = {
humanId: string; humanId: string;
actionQueue: { actionQueue: {
actionType: 'worker' | 'assembly' | 'operator'; actionType: 'worker' | 'manufacturer' | 'operator';
actionUuid: string; actionUuid: string;
actionName: string; actionName: string;
maxLoadCount: number; maxLoadCount: number;
maxAssemblyCount: number; maxManufactureCount: number;
count?: number; count?: number;
isMonitored: boolean; isMonitored: boolean;
isCompleted: boolean; isCompleted: boolean;