feat: Implement human simulation features

- Added human event handling in the simulation, including the ability to add, update, and remove human instances.
- Introduced a new Human store to manage human states and actions.
- Updated the simulation context to include human management.
- Enhanced the Points and TriggerConnector components to support human interactions.
- Refactored existing components to integrate human-related functionalities.
- Added HumanInstance and HumanInstances components for rendering human entities in the simulation.
- Updated TypeScript definitions to include human-related types and actions.
This commit is contained in:
2025-07-02 15:07:31 +05:30
parent 3f59f5d2dd
commit 7519aa90c6
22 changed files with 706 additions and 144 deletions

View File

@@ -1,19 +1,15 @@
import React, { useEffect } from 'react'
import { useEffect } from 'react'
import { useInputValues, useProductionCapacityData, useThroughPutData } from '../../../../store/builder/store'
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
import { useProductContext } from '../../products/productContext';
export default function ProductionCapacityData() {
const { throughputData } = useThroughPutData()
const { productionCapacityData, setProductionCapacityData } = useProductionCapacityData()
const { setProductionCapacityData } = useProductionCapacityData()
const { inputValues } = useInputValues();
const { isPlaying } = usePlayButtonStore();
const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
useEffect(() => {
if (!isPlaying) {
setProductionCapacityData(0);
}
}, [isPlaying]);
@@ -26,8 +22,6 @@ export default function ProductionCapacityData() {
const Monthly_working_days = workingDaysPerYear / 12;
const Production_capacity_per_month = throughputData * Monthly_working_days;
setProductionCapacityData(Number(Production_capacity_per_month.toFixed(2)));
}
}, [throughputData, inputValues, isPlaying]);

View File

@@ -1,18 +1,9 @@
import React, { useEffect } from 'react'
import { usePlayButtonStore } from '../../../store/usePlayButtonStore'
import ProductionCapacityData from './productionCapacity/productionCapacityData'
import ThroughPutData from './throughPut/throughPutData'
import ROIData from './ROI/roiData'
function SimulationAnalysis() {
const { isPlaying } = usePlayButtonStore()
// useEffect(()=>{
// if (isPlaying) {
//
// } else {
//
// }
// },[isPlaying])
return (
<>
<ThroughPutData />

View File

@@ -352,6 +352,37 @@ function PointsCreator() {
</mesh>
</group>
);
} else if (usedEvent.type === "human") {
const point = usedEvent.point;
return (
<group
key={`${index}-${usedEvent.modelUuid}`}
position={usedEvent.position}
rotation={usedEvent.rotation}
>
<mesh
name="Event-Sphere"
uuid={point.uuid}
ref={(el) => (sphereRefs.current[point.uuid] = el!)}
onClick={(e) => {
e.stopPropagation();
if (toolMode === 'cursor') {
setSelectedEventSphere(
sphereRefs.current[point.uuid]
);
}
}}
position={new THREE.Vector3(...point.position)}
userData={{
modelUuid: usedEvent.modelUuid,
pointUuid: point.uuid,
}}
>
<sphereGeometry args={[0.1, 16, 16]} />
<meshStandardMaterial color="white" />
</mesh>
</group>
);
} else {
return null;
}

View File

@@ -1,4 +1,3 @@
import React from 'react'
import PointsCreator from './creator/pointsCreator'
function Points() {

View File

@@ -152,6 +152,22 @@ function TriggerConnector() {
});
}
}
// Handle Human point
else if (event.type === "human" && 'point' in event) {
const point = event.point;
point.actions?.forEach(action => {
action.triggers?.forEach(trigger => {
if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint) {
newConnections.push({
id: `${point.uuid}-${trigger.triggeredAsset.triggeredPoint.pointUuid}-${trigger.triggerUuid}`,
startPointUuid: point.uuid,
endPointUuid: trigger.triggeredAsset.triggeredPoint.pointUuid,
trigger
});
}
});
});
}
});
setConnections(newConnections);

View File

@@ -0,0 +1,13 @@
import HumanInstances from './instances/humanInstances'
function Human() {
return (
<>
<HumanInstances />
</>
)
}
export default Human

View File

@@ -0,0 +1,20 @@
import React from 'react'
import HumanInstance from './instance/humanInstance';
import { useSceneContext } from '../../../scene/sceneContext';
function HumanInstances() {
const { humanStore } = useSceneContext();
const { humans } = humanStore();
return (
<>
{humans.map((human: HumanStatus) => (
<React.Fragment key={human.modelUuid}>
<HumanInstance human={human} />
</React.Fragment>
))}
</>
)
}
export default HumanInstances

View File

@@ -0,0 +1,15 @@
import { useEffect } from 'react'
function HumanInstance({ human }: { human: HumanStatus }) {
useEffect(() => {
console.log('human: ', human);
}, [human])
return (
<>
</>
)
}
export default HumanInstance

View File

@@ -10,7 +10,7 @@ import { useParams } from 'react-router-dom';
import { useVersionContext } from '../../builder/version/versionContext';
function Products() {
const { armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, layout, productStore } = useSceneContext();
const { armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, humanStore, layout, productStore } = useSceneContext();
const { products, getProductById, addProduct, setProducts } = productStore();
const { selectedProductStore } = useProductContext();
const { setMainProduct } = useMainProduct();
@@ -20,6 +20,7 @@ function Products() {
const { addMachine, clearMachines } = machineStore();
const { addConveyor, clearConveyors } = conveyorStore();
const { setCurrentMaterials, clearStorageUnits, updateCurrentLoad, addStorageUnit } = storageUnitStore();
const { addHuman, clearHumans } = humanStore();
const { isReset } = useResetButtonStore();
const { isPlaying } = usePlayButtonStore();
const { mainProduct } = useMainProduct();
@@ -153,6 +154,20 @@ function Products() {
}
}, [selectedProduct, products, isReset, isPlaying]);
useEffect(() => {
if (selectedProduct.productUuid) {
const product = getProductById(selectedProduct.productUuid);
if (product) {
clearHumans();
product.eventDatas.forEach(events => {
if (events.type === 'human') {
addHuman(selectedProduct.productUuid, events);
}
});
}
}
}, [selectedProduct, products, isReset, isPlaying]);
return (
<>

View File

@@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import { useEffect } from 'react';
import Vehicles from './vehicle/vehicles';
import Points from './events/points/points';
import Conveyor from './conveyor/conveyor';
@@ -6,6 +6,7 @@ import RoboticArm from './roboticArm/roboticArm';
import Materials from './materials/materials';
import Machine from './machine/machine';
import StorageUnit from './storageUnit/storageUnit';
import Human from './human/human';
import Simulator from './simulator/simulator';
import Products from './products/products';
import Trigger from './triggers/trigger';
@@ -52,6 +53,8 @@ function Simulation() {
<StorageUnit />
<Human />
<Simulator />
<SimulationAnalysis />

View File

@@ -4,7 +4,6 @@ import { usePlayButtonStore, useResetButtonStore } from '../../../store/usePlayB
import { determineExecutionOrder } from './functions/determineExecutionOrder';
import { useProductContext } from '../products/productContext';
import { useSceneContext } from '../../scene/sceneContext';
import { useCompareProductDataStore } from '../../../store/builder/store';
function Simulator() {
const { selectedProductStore } = useProductContext();

View File

@@ -5,20 +5,20 @@ import { useSceneContext } from "../../../scene/sceneContext";
import { useViewSceneStore } from "../../../../store/builder/store";
function VehicleInstances() {
const { vehicleStore } = useSceneContext();
const { vehicles } = vehicleStore();
const { viewSceneLabels } = useViewSceneStore();
const { vehicleStore } = useSceneContext();
const { vehicles } = vehicleStore();
const { viewSceneLabels } = useViewSceneStore();
return (
<>
{vehicles.map((vehicle: VehicleStatus) => (
<React.Fragment key={vehicle.modelUuid}>
<VehicleInstance agvDetail={vehicle} />
{viewSceneLabels && <VehicleContentUi vehicle={vehicle} />}
</React.Fragment>
))}
</>
);
return (
<>
{vehicles.map((vehicle: VehicleStatus) => (
<React.Fragment key={vehicle.modelUuid}>
<VehicleInstance agvDetail={vehicle} />
{viewSceneLabels && <VehicleContentUi vehicle={vehicle} />}
</React.Fragment>
))}
</>
);
}
export default VehicleInstances;