name and schema chmage for assembly to manufacturer
This commit is contained in:
@@ -3,7 +3,7 @@ import InputRange from "../../../../../ui/inputs/InputRange";
|
||||
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
|
||||
import SwapAction from "./SwapAction";
|
||||
|
||||
interface AssemblyActionProps {
|
||||
interface ManufactureActionProps {
|
||||
processTime: {
|
||||
value: number;
|
||||
min: number;
|
||||
@@ -11,7 +11,7 @@ interface AssemblyActionProps {
|
||||
disabled?: boolean,
|
||||
onChange: (value: number) => void;
|
||||
};
|
||||
assemblyCount: {
|
||||
manufactureCount: {
|
||||
value: number;
|
||||
min: number;
|
||||
max: number;
|
||||
@@ -26,9 +26,9 @@ interface AssemblyActionProps {
|
||||
clearPoints: () => void;
|
||||
}
|
||||
|
||||
const AssemblyAction: React.FC<AssemblyActionProps> = ({
|
||||
const ManufactureAction: React.FC<ManufactureActionProps> = ({
|
||||
processTime,
|
||||
assemblyCount,
|
||||
manufactureCount,
|
||||
swapOptions,
|
||||
swapDefaultOption,
|
||||
onSwapSelect,
|
||||
@@ -46,18 +46,18 @@ const AssemblyAction: React.FC<AssemblyActionProps> = ({
|
||||
onChange={processTime.onChange}
|
||||
/>
|
||||
|
||||
{assemblyCount && (
|
||||
{manufactureCount && (
|
||||
<InputWithDropDown
|
||||
label="Assembly Count"
|
||||
value={assemblyCount.value.toString()}
|
||||
min={assemblyCount.min}
|
||||
max={assemblyCount.max}
|
||||
disabled={assemblyCount.disabled}
|
||||
defaultValue={assemblyCount.defaultValue}
|
||||
step={assemblyCount.step}
|
||||
label="Manufacture Count"
|
||||
value={manufactureCount.value.toString()}
|
||||
min={manufactureCount.min}
|
||||
max={manufactureCount.max}
|
||||
disabled={manufactureCount.disabled}
|
||||
defaultValue={manufactureCount.defaultValue}
|
||||
step={manufactureCount.step}
|
||||
activeOption="unit"
|
||||
onClick={() => { }}
|
||||
onChange={(value) => assemblyCount.onChange(parseInt(value))}
|
||||
onChange={(value) => manufactureCount.onChange(parseInt(value))}
|
||||
/>
|
||||
)}
|
||||
<SwapAction
|
||||
@@ -82,4 +82,4 @@ const AssemblyAction: React.FC<AssemblyActionProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default AssemblyAction;
|
||||
export default ManufactureAction;
|
||||
@@ -7,7 +7,7 @@ import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
|
||||
import Trigger from "../trigger/Trigger";
|
||||
import ActionsList from "../components/ActionsList";
|
||||
import WorkerAction from "../actions/WorkerAction";
|
||||
import AssemblyAction from "../actions/AssemblyAction";
|
||||
import ManufactureAction from "../actions/ManufactureAction";
|
||||
|
||||
import { useSelectedEventData, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
@@ -17,10 +17,10 @@ import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
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 [loadCount, setLoadCount] = useState(0);
|
||||
const [assemblyCount, setAssemblyCount] = useState(0);
|
||||
const [manufactureCount, setManufactureCount] = useState(0);
|
||||
const [loadCapacity, setLoadCapacity] = useState("1");
|
||||
const [processTime, setProcessTime] = useState(10);
|
||||
const [swappedMaterial, setSwappedMaterial] = useState("Default material");
|
||||
@@ -58,7 +58,7 @@ function HumanMechanics() {
|
||||
setLoadCapacity(firstAction.loadCapacity.toString());
|
||||
setActiveOption(firstAction.actionType);
|
||||
setLoadCount(firstAction.loadCount || 0);
|
||||
setAssemblyCount(firstAction.assemblyCount || 0);
|
||||
setManufactureCount(firstAction.manufactureCount || 0);
|
||||
setProcessTime(firstAction.processTime || 10);
|
||||
setSwappedMaterial(firstAction.swapMaterial || "Default material");
|
||||
}
|
||||
@@ -79,7 +79,7 @@ function HumanMechanics() {
|
||||
|
||||
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) {
|
||||
setSelectedAction(newCurrentAction.actionUuid, newCurrentAction.actionName);
|
||||
}
|
||||
@@ -87,9 +87,9 @@ function HumanMechanics() {
|
||||
setActiveOption(newCurrentAction.actionType);
|
||||
setLoadCapacity(newCurrentAction.loadCapacity.toString());
|
||||
setLoadCount(newCurrentAction.loadCount || 0);
|
||||
setAssemblyCount(newCurrentAction.assemblyCount || 0);
|
||||
setManufactureCount(newCurrentAction.manufactureCount || 0);
|
||||
|
||||
if (newCurrentAction.actionType === 'assembly') {
|
||||
if (newCurrentAction.actionType === 'manufacturer') {
|
||||
setProcessTime(newCurrentAction.processTime || 10);
|
||||
setSwappedMaterial(newCurrentAction.swapMaterial || "Default material");
|
||||
}
|
||||
@@ -118,7 +118,7 @@ function HumanMechanics() {
|
||||
const handleSelectActionType = (actionType: string) => {
|
||||
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 updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
@@ -203,10 +203,10 @@ function HumanMechanics() {
|
||||
setLoadCount(value);
|
||||
};
|
||||
|
||||
const handleAssemblyCountChange = (value: number) => {
|
||||
const handleManufactureCountChange = (value: number) => {
|
||||
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 updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
@@ -222,7 +222,7 @@ function HumanMechanics() {
|
||||
|
||||
setCurrentAction(updatedAction);
|
||||
setSelectedPointData(updatedPoint);
|
||||
setAssemblyCount(value);
|
||||
setManufactureCount(value);
|
||||
};
|
||||
|
||||
const handleProcessTimeChange = (value: number) => {
|
||||
@@ -274,8 +274,8 @@ function HumanMechanics() {
|
||||
|
||||
const updatedAction: HumanAction = JSON.parse(JSON.stringify(currentAction));
|
||||
|
||||
if (updatedAction.actionType === 'assembly') {
|
||||
updatedAction.assemblyPoint = { position: null, rotation: null, }
|
||||
if (updatedAction.actionType === 'manufacturer') {
|
||||
updatedAction.manufacturePoint = { position: null, rotation: null, }
|
||||
} else {
|
||||
updatedAction.pickUpPoint = { position: null, rotation: null, };
|
||||
updatedAction.dropPoint = { position: null, rotation: null, }
|
||||
@@ -306,7 +306,7 @@ function HumanMechanics() {
|
||||
actionName: `Action ${selectedPointData.actions.length + 1}`,
|
||||
actionType: "worker",
|
||||
loadCount: 1,
|
||||
assemblyCount: 1,
|
||||
manufactureCount: 1,
|
||||
loadCapacity: 1,
|
||||
processTime: 10,
|
||||
triggers: [],
|
||||
@@ -397,7 +397,7 @@ function HumanMechanics() {
|
||||
<LabledDropdown
|
||||
label="Action Type"
|
||||
defaultOption={activeOption}
|
||||
options={["worker", "assembly", "operator"]}
|
||||
options={["worker", "manufacture", "operator"]}
|
||||
onSelect={handleSelectActionType}
|
||||
disabled={false}
|
||||
/>
|
||||
@@ -425,22 +425,22 @@ function HumanMechanics() {
|
||||
clearPoints={handleClearPoints}
|
||||
/>
|
||||
}
|
||||
{currentAction.actionType === 'assembly' &&
|
||||
<AssemblyAction
|
||||
{currentAction.actionType === 'manufacturer' &&
|
||||
<ManufactureAction
|
||||
processTime={{
|
||||
value: processTime,
|
||||
min: 1,
|
||||
max: 60,
|
||||
onChange: handleProcessTimeChange,
|
||||
}}
|
||||
assemblyCount={{
|
||||
value: assemblyCount,
|
||||
manufactureCount={{
|
||||
value: manufactureCount,
|
||||
min: 1,
|
||||
max: 20,
|
||||
step: 1,
|
||||
defaultValue: "1",
|
||||
disabled: false,
|
||||
onChange: handleAssemblyCountChange,
|
||||
onChange: handleManufactureCountChange,
|
||||
}}
|
||||
swapOptions={["Default material", "Material 1", "Material 2", "Material 3"]}
|
||||
swapDefaultOption={swappedMaterial}
|
||||
|
||||
@@ -271,7 +271,7 @@ function AssetsGroup({ plane }: { readonly plane: RefMesh }) {
|
||||
actionName: "Action 1",
|
||||
actionType: "worker",
|
||||
loadCount: 1,
|
||||
assemblyCount: 1,
|
||||
manufactureCount: 1,
|
||||
loadCapacity: 1,
|
||||
processTime: 10,
|
||||
triggers: []
|
||||
|
||||
@@ -389,7 +389,7 @@ async function handleModelLoad(
|
||||
actionName: "Action 1",
|
||||
actionType: "worker",
|
||||
loadCount: 1,
|
||||
assemblyCount: 1,
|
||||
manufactureCount: 1,
|
||||
loadCapacity: 1,
|
||||
processTime: 10,
|
||||
triggers: []
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
import { useMemo } from "react";
|
||||
import {
|
||||
Shape,
|
||||
Vector2,
|
||||
DoubleSide,
|
||||
TextureLoader,
|
||||
RepeatWrapping,
|
||||
SRGBColorSpace,
|
||||
NoColorSpace,
|
||||
} from "three";
|
||||
import { Shape, Vector2, DoubleSide, TextureLoader, RepeatWrapping, SRGBColorSpace, NoColorSpace, } from "three";
|
||||
import { useLoader } from "@react-three/fiber";
|
||||
import { Extrude } from "@react-three/drei";
|
||||
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";
|
||||
|
||||
function FloorInstance({ floor }: { floor: Floor }) {
|
||||
const { togglView } = useToggleView();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { selectedFloor, setSelectedFloor, setSelectedDecal } =
|
||||
useBuilderStore();
|
||||
const savedTheme = localStorage.getItem("theme");
|
||||
const { togglView } = useToggleView();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { selectedFloor, setSelectedFloor, setSelectedDecal } =
|
||||
useBuilderStore();
|
||||
const savedTheme = localStorage.getItem("theme");
|
||||
|
||||
const materials: Record<
|
||||
string,
|
||||
{
|
||||
map: string;
|
||||
roughnessMap?: string;
|
||||
metalnessMap?: string;
|
||||
normalMap?: string;
|
||||
textureTileScale?: [number, number];
|
||||
const materials: Record<
|
||||
string,
|
||||
{
|
||||
map: string;
|
||||
roughnessMap?: string;
|
||||
metalnessMap?: string;
|
||||
normalMap?: string;
|
||||
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(() => {
|
||||
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]);
|
||||
// Default material map
|
||||
const defaultMaterialMap = materials["Default Material"].map;
|
||||
|
||||
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
|
||||
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;
|
||||
// Get the filtered lists for top and side textures
|
||||
const topTexturesList = getMaterialMaps(topMaterial, defaultMaterialMap);
|
||||
const sideTexturesList = getMaterialMaps(sideMaterial, defaultMaterialMap);
|
||||
|
||||
return [materialMap, normalMap, roughnessMap, metalnessMap].filter(
|
||||
(texture): texture is string => texture !== null
|
||||
);
|
||||
}
|
||||
// Use loader to load top and side textures
|
||||
const [topTexture, topNormalTexture, topRoughnessTexture, topMetalicTexture] = useLoader(TextureLoader, topTexturesList);
|
||||
|
||||
// Default material map
|
||||
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: [
|
||||
const [
|
||||
sideTexture,
|
||||
sideNormalTexture,
|
||||
sideRoughnessTexture,
|
||||
sideMetalicTexture,
|
||||
],
|
||||
materialKey: floor.sideMaterial,
|
||||
},
|
||||
];
|
||||
] = useLoader(TextureLoader, sideTexturesList);
|
||||
|
||||
// Apply texture settings
|
||||
textureMaterialMap.forEach(({ textures, materialKey }) => {
|
||||
const tileScale = materials[materialKey]?.textureTileScale ?? [
|
||||
textureScale,
|
||||
textureScale,
|
||||
// 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,
|
||||
sideNormalTexture,
|
||||
sideRoughnessTexture,
|
||||
sideMetalicTexture,
|
||||
],
|
||||
materialKey: floor.sideMaterial,
|
||||
},
|
||||
];
|
||||
|
||||
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;
|
||||
// Apply texture settings
|
||||
textureMaterialMap.forEach(({ textures, materialKey }) => {
|
||||
const tileScale = materials[materialKey]?.textureTileScale ?? [
|
||||
textureScale,
|
||||
textureScale,
|
||||
];
|
||||
|
||||
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 (
|
||||
<mesh
|
||||
castShadow
|
||||
receiveShadow
|
||||
name={`Floor-${floor.floorUuid}`}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
position={[
|
||||
0,
|
||||
!floor.isBeveled ? floor.floorDepth - 0.1 : floor.floorDepth - 0.2,
|
||||
0,
|
||||
]}
|
||||
userData={floor}
|
||||
onDoubleClick={(e) => {
|
||||
if (!togglView && activeModule === "builder") {
|
||||
if (e.object.userData.floorUuid) {
|
||||
e.stopPropagation();
|
||||
setSelectedFloor(e.object);
|
||||
setSelectedDecal(null);
|
||||
}
|
||||
}
|
||||
}}
|
||||
onPointerMissed={() => {
|
||||
if (
|
||||
selectedFloor &&
|
||||
selectedFloor.userData.floorUuid === floor.floorUuid
|
||||
) {
|
||||
setSelectedFloor(null);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Extrude
|
||||
name={`Floor-${floor.floorUuid}`}
|
||||
args={[
|
||||
shape,
|
||||
{
|
||||
depth: !floor.isBeveled ? floor.floorDepth : floor.floorDepth - 0.1,
|
||||
bevelEnabled: floor.isBeveled,
|
||||
bevelSegments: floor.bevelStrength,
|
||||
bevelOffset: -0.1,
|
||||
bevelSize: 0.1,
|
||||
bevelThickness: 0.1,
|
||||
},
|
||||
]}
|
||||
userData={floor}
|
||||
>
|
||||
<meshPhysicalMaterial
|
||||
attach="material-0"
|
||||
color={Constants.floorConfig.defaultColor}
|
||||
map={topTexture}
|
||||
roughnessMap={topRoughnessTexture}
|
||||
metalnessMap={topMetalicTexture}
|
||||
normalMap={topNormalTexture}
|
||||
roughness={1.5}
|
||||
metalness={1.0}
|
||||
side={DoubleSide}
|
||||
/>
|
||||
<meshStandardMaterial
|
||||
attach="material-1"
|
||||
color={Constants.floorConfig.defaultColor}
|
||||
map={sideTexture?.clone()}
|
||||
roughnessMap={sideRoughnessTexture?.clone()}
|
||||
metalnessMap={sideMetalicTexture?.clone()}
|
||||
normalMap={sideNormalTexture?.clone()}
|
||||
side={DoubleSide}
|
||||
/>
|
||||
</Extrude>
|
||||
</mesh>
|
||||
);
|
||||
return (
|
||||
<mesh
|
||||
castShadow
|
||||
receiveShadow
|
||||
name={`Floor-${floor.floorUuid}`}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
position={[0, !floor.isBeveled ? floor.floorDepth - 0.1 : floor.floorDepth - 0.2, 0,]}
|
||||
userData={floor}
|
||||
onDoubleClick={(e) => {
|
||||
if (!togglView && activeModule === "builder") {
|
||||
if (e.object.userData.floorUuid) {
|
||||
e.stopPropagation();
|
||||
setSelectedFloor(e.object);
|
||||
setSelectedDecal(null);
|
||||
}
|
||||
}
|
||||
}}
|
||||
onPointerMissed={() => {
|
||||
if (
|
||||
selectedFloor &&
|
||||
selectedFloor.userData.floorUuid === floor.floorUuid
|
||||
) {
|
||||
setSelectedFloor(null);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Extrude
|
||||
name={`Floor-${floor.floorUuid}`}
|
||||
args={[
|
||||
shape,
|
||||
{
|
||||
depth: !floor.isBeveled ? floor.floorDepth : floor.floorDepth - 0.1,
|
||||
bevelEnabled: floor.isBeveled,
|
||||
bevelSegments: floor.bevelStrength,
|
||||
bevelOffset: -0.1,
|
||||
bevelSize: 0.1,
|
||||
bevelThickness: 0.1,
|
||||
},
|
||||
]}
|
||||
userData={floor}
|
||||
>
|
||||
<meshPhysicalMaterial
|
||||
attach="material-0"
|
||||
color={Constants.floorConfig.defaultColor}
|
||||
map={topTexture}
|
||||
roughnessMap={topRoughnessTexture}
|
||||
metalnessMap={topMetalicTexture}
|
||||
normalMap={topNormalTexture}
|
||||
roughness={1.5}
|
||||
metalness={1.0}
|
||||
side={DoubleSide}
|
||||
/>
|
||||
<meshStandardMaterial
|
||||
attach="material-1"
|
||||
color={Constants.floorConfig.defaultColor}
|
||||
map={sideTexture?.clone()}
|
||||
roughnessMap={sideRoughnessTexture?.clone()}
|
||||
metalnessMap={sideMetalicTexture?.clone()}
|
||||
normalMap={sideNormalTexture?.clone()}
|
||||
side={DoubleSide}
|
||||
/>
|
||||
</Extrude>
|
||||
</mesh>
|
||||
);
|
||||
}
|
||||
|
||||
export default FloorInstance;
|
||||
|
||||
@@ -10,7 +10,7 @@ import { useToggleView, useWallVisibility } from '../../../../../store/builder/s
|
||||
import { useBuilderStore } from '../../../../../store/builder/useBuilderStore';
|
||||
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 material1 from '../../../../../assets/textures/floor/factory wall texture.jpg';
|
||||
@@ -150,19 +150,6 @@ function Wall({ wall }: { readonly wall: Wall }) {
|
||||
e.stopPropagation();
|
||||
setSelectedWall(e.object);
|
||||
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 />
|
||||
|
||||
{/* {wall.decals.map((decal) => (
|
||||
{wall.decals.map((decal) => (
|
||||
<DecalInstance zPosition={wall.wallThickness / 2 + 0.001} visible={visible} key={decal.decalUuid} decal={decal} />
|
||||
))} */}
|
||||
))}
|
||||
</mesh>
|
||||
</mesh>
|
||||
);
|
||||
|
||||
@@ -430,7 +430,7 @@ const CopyPasteControls3D = ({
|
||||
actionName: "Action 1",
|
||||
actionType: "worker",
|
||||
loadCapacity: 1,
|
||||
assemblyCount: 1,
|
||||
manufactureCount: 1,
|
||||
loadCount: 1,
|
||||
processTime: 10,
|
||||
triggers: []
|
||||
|
||||
@@ -497,7 +497,7 @@ const DuplicationControls3D = ({
|
||||
actionName: "Action 1",
|
||||
actionType: "worker",
|
||||
loadCapacity: 1,
|
||||
assemblyCount: 1,
|
||||
manufactureCount: 1,
|
||||
loadCount: 1,
|
||||
processTime: 10,
|
||||
triggers: []
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useCallback } from "react";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
|
||||
export function useAssemblyHandler() {
|
||||
export function useManufacturerHandler() {
|
||||
const { materialStore, humanStore, productStore } = useSceneContext();
|
||||
const { getMaterialById } = materialStore();
|
||||
const { getModelUuidByActionUuid } = productStore();
|
||||
@@ -10,12 +10,12 @@ export function useAssemblyHandler() {
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { incrementHumanLoad, addCurrentMaterial, addCurrentAction } = humanStore();
|
||||
|
||||
const assemblyLogStatus = (materialUuid: string, status: string) => {
|
||||
const manufactureLogStatus = (materialUuid: string, status: string) => {
|
||||
echo.info(`${materialUuid}, ${status}`);
|
||||
}
|
||||
|
||||
const handleAssembly = useCallback((action: HumanAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== 'assembly' || !materialId) return;
|
||||
const handleManufacturer = useCallback((action: HumanAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== 'manufacturer' || !materialId) return;
|
||||
|
||||
const material = getMaterialById(materialId);
|
||||
if (!material) return;
|
||||
@@ -27,11 +27,11 @@ export function useAssemblyHandler() {
|
||||
addCurrentAction(modelUuid, action.actionUuid);
|
||||
addCurrentMaterial(modelUuid, material.materialType, material.materialId);
|
||||
|
||||
assemblyLogStatus(material.materialName, `performing assembly action`);
|
||||
manufactureLogStatus(material.materialName, `performing manufacturer action`);
|
||||
|
||||
}, [getMaterialById]);
|
||||
|
||||
return {
|
||||
handleAssembly,
|
||||
handleManufacturer,
|
||||
};
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
import { useEffect, useCallback } from 'react';
|
||||
import { useWorkerHandler } from './actionHandler/useWorkerHandler';
|
||||
import { useAssemblyHandler } from './actionHandler/useAssemblyHandler';
|
||||
import { useManufacturerHandler } from './actionHandler/useManufacturerHandler';
|
||||
|
||||
export function useHumanActions() {
|
||||
const { handleWorker } = useWorkerHandler();
|
||||
const { handleAssembly } = useAssemblyHandler();
|
||||
const { handleManufacturer } = useManufacturerHandler();
|
||||
|
||||
const handleWorkerAction = useCallback((action: HumanAction, materialId: string) => {
|
||||
handleWorker(action, materialId);
|
||||
}, [handleWorker]);
|
||||
|
||||
const handleAssemblyAction = useCallback((action: HumanAction, materialId: string) => {
|
||||
handleAssembly(action, materialId);
|
||||
}, [handleAssembly]);
|
||||
const handleManufactureAction = useCallback((action: HumanAction, materialId: string) => {
|
||||
handleManufacturer(action, materialId);
|
||||
}, [handleManufacturer]);
|
||||
|
||||
const handleHumanAction = useCallback((action: HumanAction, materialId: string) => {
|
||||
if (!action) return;
|
||||
@@ -21,13 +21,13 @@ export function useHumanActions() {
|
||||
case 'worker':
|
||||
handleWorkerAction(action, materialId);
|
||||
break;
|
||||
case 'assembly':
|
||||
handleAssemblyAction(action, materialId);
|
||||
case 'manufacturer':
|
||||
handleManufactureAction(action, materialId);
|
||||
break;
|
||||
default:
|
||||
console.warn(`Unknown Human action type: ${action.actionType}`);
|
||||
}
|
||||
}, [handleWorkerAction, handleAssemblyAction]);
|
||||
}, [handleWorkerAction, handleManufactureAction]);
|
||||
|
||||
const cleanup = useCallback(() => {
|
||||
}, []);
|
||||
|
||||
@@ -41,7 +41,7 @@ export function useActionHandler() {
|
||||
case 'store': case 'retrieve':
|
||||
handleStorageAction(action as StorageAction, materialId as string);
|
||||
break;
|
||||
case 'worker': case 'assembly':
|
||||
case 'worker': case 'manufacturer':
|
||||
handleHumanAction(action as HumanAction, materialId as string);
|
||||
break;
|
||||
case 'pickAndDrop':
|
||||
|
||||
@@ -25,7 +25,7 @@ export function useHumanEventManager() {
|
||||
const addHumanToMonitor = (humanId: string, callback: () => void, actionUuid: string) => {
|
||||
const human = getHumanById(humanId);
|
||||
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);
|
||||
if (!state) {
|
||||
@@ -42,8 +42,8 @@ export function useHumanEventManager() {
|
||||
existingAction.isMonitored = true;
|
||||
existingAction.isCompleted = false;
|
||||
}
|
||||
} else if (existingAction.actionType === 'assembly') {
|
||||
if (currentCount < existingAction.maxAssemblyCount) {
|
||||
} else if (existingAction.actionType === 'manufacturer') {
|
||||
if (currentCount < existingAction.maxManufactureCount) {
|
||||
existingAction.callback = callback;
|
||||
existingAction.isMonitored = true;
|
||||
existingAction.isCompleted = false;
|
||||
@@ -57,7 +57,7 @@ export function useHumanEventManager() {
|
||||
actionUuid,
|
||||
actionName: action.actionName,
|
||||
maxLoadCount: action.loadCount ?? 0,
|
||||
maxAssemblyCount: action.assemblyCount ?? 0,
|
||||
maxManufactureCount: action.manufactureCount ?? 0,
|
||||
count: 0,
|
||||
isMonitored: true,
|
||||
isCompleted: false,
|
||||
@@ -101,11 +101,11 @@ export function useHumanEventManager() {
|
||||
if (currentAction.actionType === 'worker' || currentAction.actionType === 'operator') {
|
||||
if ((action.actionType === 'worker' || action.actionType === 'operator') && human.currentLoad < currentAction.loadCapacity) {
|
||||
conditionMet = true;
|
||||
} else if (action.actionType === 'assembly') {
|
||||
} else if (action.actionType === 'manufacturer') {
|
||||
conditionMet = true;
|
||||
}
|
||||
} else if (currentAction.actionType === 'assembly') {
|
||||
if (action.actionType === 'assembly') {
|
||||
} else if (currentAction.actionType === 'manufacturer') {
|
||||
if (action.actionType === 'manufacturer') {
|
||||
conditionMet = true;
|
||||
} else if ((action.actionType === 'worker' || action.actionType === 'operator') && human.currentLoad < currentAction.loadCapacity) {
|
||||
conditionMet = true;
|
||||
@@ -122,7 +122,7 @@ export function useHumanEventManager() {
|
||||
action.count = (action.count ?? 0) + 1;
|
||||
action.isMonitored = false;
|
||||
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;
|
||||
}
|
||||
humanState.isCooldown = true;
|
||||
|
||||
@@ -6,14 +6,14 @@ import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useRese
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
|
||||
interface AssemblerAnimatorProps {
|
||||
interface ManufacturerAnimatorProps {
|
||||
path: [number, number, number][];
|
||||
handleCallBack: () => void;
|
||||
reset: () => void;
|
||||
human: HumanStatus;
|
||||
}
|
||||
|
||||
function AssemblerAnimator({ path, handleCallBack, human, reset }: Readonly<AssemblerAnimatorProps>) {
|
||||
function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<ManufacturerAnimatorProps>) {
|
||||
const { humanStore, assetStore, productStore } = useSceneContext();
|
||||
const { getActionByUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
@@ -27,16 +27,16 @@ function AssemblerAnimator({ path, handleCallBack, human, reset }: Readonly<Asse
|
||||
const progressRef = useRef<number>(0);
|
||||
const completedRef = useRef<boolean>(false);
|
||||
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 [currentPath, setCurrentPath] = useState<[number, number, number][]>([]);
|
||||
const { scene } = useThree();
|
||||
|
||||
useEffect(() => {
|
||||
if (!human.currentAction?.actionUuid) return;
|
||||
if (human.currentPhase === 'init-assembly' && path.length > 0) {
|
||||
if (human.currentPhase === 'init-manufacture' && path.length > 0) {
|
||||
setCurrentPath(path);
|
||||
setObjectRotation((action as HumanAction)?.assemblyPoint?.rotation ?? null);
|
||||
setObjectRotation((action as HumanAction)?.manufacturePoint?.rotation ?? null);
|
||||
}
|
||||
}, [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;
|
||||
@@ -50,7 +50,7 @@ const MaterialAnimator = ({ human }: { human: HumanStatus; }) => {
|
||||
|
||||
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
|
||||
matRef={meshRef}
|
||||
materialId={`human-${human.currentMaterials[0].materialId}` || ''}
|
||||
|
||||
@@ -127,13 +127,13 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
|
||||
const t = (progressRef.current - accumulatedDistance) / segmentDistance;
|
||||
const position = start.clone().lerp(end, t);
|
||||
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);
|
||||
} else {
|
||||
setCurrentAnimation(human.modelUuid, 'walking', true, true, true);
|
||||
}
|
||||
} 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);
|
||||
} else {
|
||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||
|
||||
@@ -8,9 +8,9 @@ import { useTriggerHandler } from '../../../../triggers/triggerHandler/useTrigge
|
||||
import { useSceneContext } from '../../../../../scene/sceneContext';
|
||||
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 { isPlaying } = usePlayButtonStore();
|
||||
const { scene } = useThree();
|
||||
@@ -99,24 +99,24 @@ function AssemblerInstance({ human }: { human: HumanStatus }) {
|
||||
if (isPlaying) {
|
||||
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') {
|
||||
const humanMesh = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||
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);
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
setCurrentPhase(human.modelUuid, 'init-assembly');
|
||||
setCurrentPhase(human.modelUuid, 'init-manufacture');
|
||||
setHumanActive(human.modelUuid, false);
|
||||
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') {
|
||||
if (human.currentMaterials.length > 0 && humanAsset && humanAsset.animationState?.current !== 'working_standing') {
|
||||
setCurrentAnimation(human.modelUuid, 'working_standing', true, true, false);
|
||||
setHumanState(human.modelUuid, 'running');
|
||||
setCurrentPhase(human.modelUuid, 'assembling');
|
||||
setCurrentPhase(human.modelUuid, 'manufacturing');
|
||||
setHumanActive(human.modelUuid, true);
|
||||
|
||||
processStartTimeRef.current = performance.now();
|
||||
@@ -127,16 +127,16 @@ function AssemblerInstance({ human }: { human: HumanStatus }) {
|
||||
hasLoggedCompleted.current = false;
|
||||
|
||||
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) {
|
||||
if ((action as HumanAction).assemblyPoint && human.currentPhase === 'assembling') {
|
||||
if ((action as HumanAction).manufacturePoint && human.currentPhase === 'manufacturing') {
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
setCurrentPhase(human.modelUuid, 'waiting');
|
||||
setHumanActive(human.modelUuid, false);
|
||||
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);
|
||||
const material = removeLastMaterial(human.modelUuid);
|
||||
@@ -150,7 +150,7 @@ function AssemblerInstance({ human }: { human: HumanStatus }) {
|
||||
}
|
||||
}, [human, human.currentPhase, path, isPlaying, humanAsset?.animationState?.isCompleted]);
|
||||
|
||||
const trackAssemblyProcess = useCallback(() => {
|
||||
const trackManufactureProcess = useCallback(() => {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
|
||||
const now = performance.now();
|
||||
@@ -163,7 +163,7 @@ function AssemblerInstance({ human }: { human: HumanStatus }) {
|
||||
if (!lastPauseTimeRef.current) {
|
||||
lastPauseTimeRef.current = now;
|
||||
}
|
||||
processAnimationIdRef.current = requestAnimationFrame(trackAssemblyProcess);
|
||||
processAnimationIdRef.current = requestAnimationFrame(trackManufactureProcess);
|
||||
return;
|
||||
} else if (lastPauseTimeRef.current) {
|
||||
accumulatedPausedTimeRef.current += now - lastPauseTimeRef.current;
|
||||
@@ -178,7 +178,7 @@ function AssemblerInstance({ human }: { human: HumanStatus }) {
|
||||
if (human.currentMaterials.length > 0) {
|
||||
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) {
|
||||
@@ -188,27 +188,27 @@ function AssemblerInstance({ human }: { human: HumanStatus }) {
|
||||
cancelAnimationFrame(processAnimationIdRef.current);
|
||||
processAnimationIdRef.current = null;
|
||||
}
|
||||
humanStatus(human.modelUuid, `✅ Human ${human.modelUuid} completed assembly process.`);
|
||||
humanStatus(human.modelUuid, `✅ Human ${human.modelUuid} completed manufacture process.`);
|
||||
return;
|
||||
}
|
||||
|
||||
processAnimationIdRef.current = requestAnimationFrame(trackAssemblyProcess);
|
||||
processAnimationIdRef.current = requestAnimationFrame(trackManufactureProcess);
|
||||
}, [human.modelUuid, human.currentMaterials]);
|
||||
|
||||
function handleCallBack() {
|
||||
if (human.currentPhase === 'init-assembly') {
|
||||
if (human.currentPhase === 'init-manufacture') {
|
||||
setCurrentPhase(human.modelUuid, 'waiting');
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
setHumanActive(human.modelUuid, false);
|
||||
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([]);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<AssemblerAnimator
|
||||
<ManufacturerAnimator
|
||||
path={path}
|
||||
handleCallBack={handleCallBack}
|
||||
human={human}
|
||||
@@ -218,4 +218,4 @@ function AssemblerInstance({ human }: { human: HumanStatus }) {
|
||||
)
|
||||
}
|
||||
|
||||
export default AssemblerInstance;
|
||||
export default ManufacturerInstance;
|
||||
@@ -4,7 +4,7 @@ import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
|
||||
import MaterialAnimator from '../animator/materialAnimator';
|
||||
import AssemblerInstance from './actions/assemberInstance';
|
||||
import ManufacturerInstance from './actions/manufacturerInstance';
|
||||
import WorkerInstance from './actions/workerInstance';
|
||||
import OperatorInstance from './actions/operatorInstance';
|
||||
|
||||
@@ -84,8 +84,8 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
||||
{action && action.actionType === 'worker' &&
|
||||
<WorkerInstance human={human} />
|
||||
}
|
||||
{action && action.actionType === 'assembly' &&
|
||||
<AssemblerInstance human={human} />
|
||||
{action && action.actionType === 'manufacturer' &&
|
||||
<ManufacturerInstance human={human} />
|
||||
}
|
||||
{action && action.actionType === 'operator' &&
|
||||
<OperatorInstance human={human} />
|
||||
|
||||
@@ -10,16 +10,16 @@ import { useVersionContext } from '../../../../builder/version/versionContext';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import startPoint from "../../../../../assets/gltf-glb/ui/human-ui-green.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';
|
||||
|
||||
function HumanUi() {
|
||||
const { scene: startScene } = useGLTF(startPoint) 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 endMarker = useRef<Group>(null);
|
||||
const assemblyMarker = useRef<Group>(null);
|
||||
const manufactureMarker = useRef<Group>(null);
|
||||
const outerGroup = useRef<Group>(null);
|
||||
const prevMousePos = useRef({ x: 0, y: 0 });
|
||||
const { controls, raycaster, camera } = useThree();
|
||||
@@ -31,9 +31,9 @@ function HumanUi() {
|
||||
const { updateEvent, getActionByUuid } = productStore();
|
||||
const [startPosition, setStartPosition] = 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 [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 { isDragging, setIsDragging } = useIsDragging();
|
||||
const { isRotating, setIsRotating } = useIsRotating();
|
||||
@@ -51,7 +51,7 @@ function HumanUi() {
|
||||
const { projectId } = useParams();
|
||||
|
||||
const currentAction = getActionByUuid(selectedProduct.productUuid, selectedAction.actionId || '');
|
||||
const isAssembly = currentAction?.actionType === 'assembly';
|
||||
const isManufacture = currentAction?.actionType === 'manufacturer';
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
@@ -90,15 +90,15 @@ function HumanUi() {
|
||||
const action = selectedHuman.point.actions.find(a => a.actionUuid === selectedAction.actionId);
|
||||
if (!action) return;
|
||||
|
||||
if (isAssembly) {
|
||||
if (action.assemblyPoint?.position && outerGroup.current) {
|
||||
const worldPos = new Vector3(...action.assemblyPoint.position);
|
||||
if (isManufacture) {
|
||||
if (action.manufacturePoint?.position && outerGroup.current) {
|
||||
const worldPos = new Vector3(...action.manufacturePoint.position);
|
||||
const localPosition = outerGroup.current.worldToLocal(worldPos.clone());
|
||||
setAssemblyPosition([localPosition.x, 1, localPosition.z]);
|
||||
setAssemblyRotation(action.assemblyPoint.rotation || [0, 0, 0]);
|
||||
setManufacturePosition([localPosition.x, 1, localPosition.z]);
|
||||
setManufactureRotation(action.manufacturePoint.rotation || [0, 0, 0]);
|
||||
} else {
|
||||
setAssemblyPosition([0, 1, 0]);
|
||||
setAssemblyRotation([0, 0, 0]);
|
||||
setManufacturePosition([0, 1, 0]);
|
||||
setManufactureRotation([0, 0, 0]);
|
||||
}
|
||||
} else {
|
||||
if (action.pickUpPoint?.position && outerGroup.current) {
|
||||
@@ -125,8 +125,8 @@ function HumanUi() {
|
||||
|
||||
const handlePointerDown = (
|
||||
e: any,
|
||||
state: "start" | "end" | "assembly",
|
||||
rotation: "start" | "end" | "assembly"
|
||||
state: "start" | "end" | "manufacture",
|
||||
rotation: "start" | "end" | "manufacture"
|
||||
) => {
|
||||
e.stopPropagation();
|
||||
const intersection = new Vector3();
|
||||
@@ -153,7 +153,7 @@ function HumanUi() {
|
||||
const marker =
|
||||
state === "start" ? startMarker.current :
|
||||
state === "end" ? endMarker.current :
|
||||
assemblyMarker.current;
|
||||
manufactureMarker.current;
|
||||
if (marker && localPoint) {
|
||||
const markerPos = new Vector3().copy(marker.position);
|
||||
dragOffset.current.copy(markerPos.sub(localPoint));
|
||||
@@ -176,17 +176,17 @@ function HumanUi() {
|
||||
const updatedActions = selectedHuman.point.actions.map(action => {
|
||||
if (action.actionUuid !== currentAction.actionUuid) return action;
|
||||
|
||||
if (isAssembly) {
|
||||
if (!assemblyMarker.current || !outerGroup.current) return action;
|
||||
if (isManufacture) {
|
||||
if (!manufactureMarker.current || !outerGroup.current) return action;
|
||||
|
||||
const worldPosAssembly = new Vector3(...assemblyPosition);
|
||||
const globalAssemblyPosition = outerGroup.current.localToWorld(worldPosAssembly.clone());
|
||||
const worldPosManufacture = new Vector3(...manufacturePosition);
|
||||
const globalManufacturePosition = outerGroup.current.localToWorld(worldPosManufacture.clone());
|
||||
|
||||
return {
|
||||
...action,
|
||||
assemblyPoint: {
|
||||
position: [globalAssemblyPosition.x, globalAssemblyPosition.y, globalAssemblyPosition.z] as [number, number, number],
|
||||
rotation: assemblyRotation
|
||||
manufacturePoint: {
|
||||
position: [globalManufacturePosition.x, globalManufacturePosition.y, globalManufacturePosition.z] as [number, number, number],
|
||||
rotation: manufactureRotation
|
||||
},
|
||||
};
|
||||
} else {
|
||||
@@ -246,8 +246,8 @@ function HumanUi() {
|
||||
setStartPosition([localPoint.x, 1, localPoint.z]);
|
||||
} else if (isDragging === "end") {
|
||||
setEndPosition([localPoint.x, 1, localPoint.z]);
|
||||
} else if (isDragging === "assembly") {
|
||||
setAssemblyPosition([localPoint.x, 1, localPoint.z]);
|
||||
} else if (isDragging === "manufacture") {
|
||||
setManufacturePosition([localPoint.x, 1, localPoint.z]);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -260,7 +260,7 @@ function HumanUi() {
|
||||
const marker =
|
||||
isRotating === "start" ? startMarker.current :
|
||||
isRotating === "end" ? endMarker.current :
|
||||
assemblyMarker.current;
|
||||
manufactureMarker.current;
|
||||
|
||||
if (marker) {
|
||||
const rotationSpeed = 10;
|
||||
@@ -279,7 +279,7 @@ function HumanUi() {
|
||||
marker.rotation.z,
|
||||
]);
|
||||
} else {
|
||||
setAssemblyRotation([
|
||||
setManufactureRotation([
|
||||
marker.rotation.x,
|
||||
marker.rotation.y,
|
||||
marker.rotation.z,
|
||||
@@ -303,7 +303,7 @@ function HumanUi() {
|
||||
return () => {
|
||||
window.removeEventListener("pointerup", handleGlobalPointerUp);
|
||||
};
|
||||
}, [isDragging, isRotating, startPosition, startRotation, endPosition, endRotation, assemblyPosition, assemblyRotation]);
|
||||
}, [isDragging, isRotating, startPosition, startRotation, endPosition, endRotation, manufacturePosition, manufactureRotation]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -313,16 +313,16 @@ function HumanUi() {
|
||||
ref={outerGroup}
|
||||
rotation={[0, Math.PI, 0]}
|
||||
>
|
||||
{isAssembly ? (
|
||||
{isManufacture ? (
|
||||
<MarkerPrimitive
|
||||
name="assemblyMarker"
|
||||
refProp={assemblyMarker}
|
||||
object={assemblyScene}
|
||||
position={assemblyPosition}
|
||||
rotation={assemblyRotation}
|
||||
name="manufactureMarker"
|
||||
refProp={manufactureMarker}
|
||||
object={manufactureScene}
|
||||
position={manufacturePosition}
|
||||
rotation={manufactureRotation}
|
||||
outerGroupRef={outerGroup}
|
||||
type="assembly"
|
||||
subtype="assembly"
|
||||
type="manufacture"
|
||||
subtype="manufacture"
|
||||
color="#0f87f7"
|
||||
setIsDragging={setIsDragging}
|
||||
setIsRotating={setIsRotating}
|
||||
|
||||
@@ -1341,7 +1341,7 @@ export function useTriggerHandler() {
|
||||
handleAction(action, material.materialId);
|
||||
}
|
||||
|
||||
} else if (material && action.actionType === 'assembly') {
|
||||
} else if (material && action.actionType === 'manufacturer') {
|
||||
|
||||
setPreviousLocation(material.materialId, {
|
||||
modelUuid: material.current.modelUuid,
|
||||
|
||||
@@ -251,7 +251,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
}
|
||||
} else if (model.type === 'human') {
|
||||
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);
|
||||
}
|
||||
} else if (model.type === 'crane') {
|
||||
|
||||
@@ -203,8 +203,8 @@ export const useSelectedAnimation = create<SelectedAnimationState>()(
|
||||
);
|
||||
|
||||
interface IsDraggingState {
|
||||
isDragging: "start" | "end" | "assembly" | null;
|
||||
setIsDragging: (state: "start" | "end" | "assembly" | null) => void;
|
||||
isDragging: "start" | "end" | "manufacture" | null;
|
||||
setIsDragging: (state: "start" | "end" | "manufacture" | null) => void;
|
||||
}
|
||||
|
||||
export const useIsDragging = create<IsDraggingState>()(
|
||||
@@ -219,8 +219,8 @@ export const useIsDragging = create<IsDraggingState>()(
|
||||
);
|
||||
|
||||
interface IsRotatingState {
|
||||
isRotating: "start" | "end" | "assembly" | null;
|
||||
setIsRotating: (state: "start" | "end" | "assembly" | null) => void;
|
||||
isRotating: "start" | "end" | "manufacture" | null;
|
||||
setIsRotating: (state: "start" | "end" | "manufacture" | null) => void;
|
||||
}
|
||||
|
||||
export const useIsRotating = create<IsRotatingState>()(
|
||||
|
||||
10
app/src/types/simulationTypes.d.ts
vendored
10
app/src/types/simulationTypes.d.ts
vendored
@@ -96,14 +96,14 @@ interface StorageAction {
|
||||
interface HumanAction {
|
||||
actionUuid: string;
|
||||
actionName: string;
|
||||
actionType: "worker" | "assembly" | "operator";
|
||||
actionType: "worker" | "manufacturer" | "operator";
|
||||
processTime: number;
|
||||
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; }
|
||||
dropPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; }
|
||||
loadCount: number;
|
||||
assemblyCount: number;
|
||||
manufactureCount: number;
|
||||
loadCapacity: number;
|
||||
triggers: TriggerSchema[];
|
||||
}
|
||||
@@ -324,11 +324,11 @@ interface CraneStatus extends CraneEventSchema {
|
||||
type HumanEventState = {
|
||||
humanId: string;
|
||||
actionQueue: {
|
||||
actionType: 'worker' | 'assembly' | 'operator';
|
||||
actionType: 'worker' | 'manufacturer' | 'operator';
|
||||
actionUuid: string;
|
||||
actionName: string;
|
||||
maxLoadCount: number;
|
||||
maxAssemblyCount: number;
|
||||
maxManufactureCount: number;
|
||||
count?: number;
|
||||
isMonitored: boolean;
|
||||
isCompleted: boolean;
|
||||
|
||||
Reference in New Issue
Block a user