add useHeatMapStore for managing monitoring of vehicles and humans in HeatMap component
This commit is contained in:
@@ -6,6 +6,7 @@ import { useSceneContext } from "../../modules/scene/sceneContext";
|
||||
import * as CONSTANTS from "../../types/world/worldConstants";
|
||||
import { determineExecutionMachineSequences } from "../../modules/simulation/simulator/functions/determineExecutionMachineSequences";
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from "../../store/usePlayButtonStore";
|
||||
import { useHeatMapStore } from "../../store/simulation/useHeatMapStore";
|
||||
|
||||
const DECAY_RATE = 0.01;
|
||||
const GROWTH_TIME_MULTIPLIER = 20;
|
||||
@@ -32,6 +33,7 @@ const HeatMap = () => {
|
||||
const { getProductById, products } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { hasHuman, hasVehicle, monitoringHuman, monitoringVehicle, addMonitoringHuman, addMonitoringVehicle } = useHeatMapStore();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { isReset } = useResetButtonStore();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
@@ -62,6 +64,11 @@ const HeatMap = () => {
|
||||
}
|
||||
}, [isReset, isPlaying]);
|
||||
|
||||
useEffect(() => {
|
||||
addMonitoringVehicle("26770368-55e8-4d40-87f7-8eacb48dc236");
|
||||
addMonitoringHuman("264a51e7-d8b9-4093-95ac-fa7e2dc49cfa");
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const selectedProductData = getProductById(selectedProduct.productUuid);
|
||||
const newEvents: EventsSchema[] = [];
|
||||
@@ -70,21 +77,26 @@ const HeatMap = () => {
|
||||
determineExecutionMachineSequences([selectedProductData]).then((sequences) => {
|
||||
sequences.forEach((sequence) => {
|
||||
sequence.forEach((event) => {
|
||||
if (event.type === "human" || event.type === "vehicle") {
|
||||
newEvents.push(event);
|
||||
if (event.type === "human") {
|
||||
if (hasHuman(event.modelUuid)) {
|
||||
newEvents.push(event);
|
||||
}
|
||||
} else if (event.type === "vehicle") {
|
||||
if (hasVehicle(event.modelUuid)) {
|
||||
newEvents.push(event);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
setEvents(newEvents);
|
||||
});
|
||||
}
|
||||
}, [selectedProduct, products]);
|
||||
}, [selectedProduct, products, monitoringHuman, monitoringVehicle]);
|
||||
|
||||
useFrame((state) => {
|
||||
if (!scene || !isPlaying || isReset) return;
|
||||
|
||||
const now = state.clock.elapsedTime;
|
||||
|
||||
if (isPaused || speed === 0) {
|
||||
lastFrameTime.current = now;
|
||||
return;
|
||||
@@ -95,16 +107,13 @@ const HeatMap = () => {
|
||||
delta = now - lastFrameTime.current;
|
||||
}
|
||||
lastFrameTime.current = now;
|
||||
|
||||
|
||||
if (delta <= 0) return;
|
||||
|
||||
const updateInterval = UPDATE_INTERVAL / Math.max(speed, 0.1);
|
||||
|
||||
if (now - lastUpdateTime.current < updateInterval) return;
|
||||
lastUpdateTime.current = now;
|
||||
|
||||
const scaledDelta = delta * speed;
|
||||
|
||||
let updatedPoints = [...points];
|
||||
|
||||
events.forEach((event) => {
|
||||
@@ -113,35 +122,23 @@ const HeatMap = () => {
|
||||
|
||||
const pos = isUsingBBOX
|
||||
? (() => {
|
||||
const box = new THREE.Box3().setFromObject(model);
|
||||
const { min, max } = box;
|
||||
return new THREE.Vector3((min.x + max.x) / 2, 0, (min.z + max.z) / 2);
|
||||
})()
|
||||
const box = new THREE.Box3().setFromObject(model);
|
||||
const { min, max } = box;
|
||||
return new THREE.Vector3((min.x + max.x) / 2, 0, (min.z + max.z) / 2);
|
||||
})()
|
||||
: model.position;
|
||||
|
||||
updatedPoints.push({
|
||||
x: pos.x,
|
||||
y: pos.z,
|
||||
strength: 0.3,
|
||||
lastUpdated: now,
|
||||
});
|
||||
updatedPoints.push({ x: pos.x, y: pos.z, strength: 0.3, lastUpdated: now });
|
||||
});
|
||||
|
||||
updatedPoints = updatedPoints
|
||||
.map((p) => ({
|
||||
...p,
|
||||
strength: Math.max(0, p.strength - DECAY_RATE * scaledDelta),
|
||||
}))
|
||||
.filter((p) => p.strength > 0.01);
|
||||
updatedPoints = updatedPoints.map((p) => ({ ...p, strength: Math.max(0, p.strength - DECAY_RATE * scaledDelta) })).filter((p) => p.strength > 0.01);
|
||||
|
||||
setPoints(updatedPoints);
|
||||
});
|
||||
|
||||
const pointTexture = useMemo(() => {
|
||||
if (points.length === 0) return null;
|
||||
|
||||
const data = new Float32Array(points.length * 4);
|
||||
|
||||
points.forEach((p, i) => {
|
||||
const index = i * 4;
|
||||
data[index] = (p.x + width / 2) / width;
|
||||
@@ -150,13 +147,7 @@ const HeatMap = () => {
|
||||
data[index + 3] = 0.0;
|
||||
});
|
||||
|
||||
const texture = new THREE.DataTexture(
|
||||
data,
|
||||
points.length,
|
||||
1,
|
||||
THREE.RGBAFormat,
|
||||
THREE.FloatType
|
||||
);
|
||||
const texture = new THREE.DataTexture(data, points.length, 1, THREE.RGBAFormat, THREE.FloatType);
|
||||
texture.needsUpdate = true;
|
||||
return texture;
|
||||
}, [points, width, height]);
|
||||
@@ -234,7 +225,7 @@ const HeatMap = () => {
|
||||
float adjustedIntensity = intensity * u_growthRate;
|
||||
|
||||
// Normalize intensity between 0-1
|
||||
float normalized = clamp(intensity / max(u_growthRate, 0.0001), 0.0, 1.0);
|
||||
float normalized = clamp(intensity / max(u_growthRate, 0.0001), 0.0, 1.0);
|
||||
|
||||
vec3 color = vec3(0.0);
|
||||
if (normalized < 0.33) {
|
||||
@@ -254,4 +245,4 @@ const HeatMap = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default HeatMap;
|
||||
export default HeatMap;
|
||||
|
||||
100
app/src/store/simulation/useHeatMapStore.ts
Normal file
100
app/src/store/simulation/useHeatMapStore.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import { create } from "zustand";
|
||||
import { immer } from "zustand/middleware/immer";
|
||||
|
||||
interface HeatMapState {
|
||||
monitoringVehicle: string[];
|
||||
monitoringHuman: string[];
|
||||
|
||||
setMonitoringVehicle: (vehiclesUuid: string[]) => void;
|
||||
addMonitoringVehicle: (vehicleUuid: string) => void;
|
||||
removeMonitoringVehicle: (vehicleUuid: string) => void;
|
||||
clearMonitoringVehicle: () => void;
|
||||
|
||||
setMonitoringHuman: (humansUuid: string[]) => void;
|
||||
addMonitoringHuman: (humanUuid: string) => void;
|
||||
removeMonitoringHuman: (humanUuid: string) => void;
|
||||
clearMonitoringHuman: () => void;
|
||||
|
||||
clearAllMonitors: () => void;
|
||||
|
||||
hasVehicle: (vehicleUuid: string) => boolean;
|
||||
hasHuman: (humanUuid: string) => boolean;
|
||||
}
|
||||
|
||||
export const useHeatMapStore = create<HeatMapState>()(
|
||||
immer((set, get) => ({
|
||||
monitoringVehicle: [],
|
||||
monitoringHuman: [],
|
||||
|
||||
setMonitoringVehicle: (vehiclesUuid) =>
|
||||
set((state) => {
|
||||
state.monitoringVehicle = vehiclesUuid;
|
||||
}),
|
||||
|
||||
addMonitoringVehicle: (vehicleUuid) =>
|
||||
set((state) => {
|
||||
if (!state.monitoringVehicle.includes(vehicleUuid)) {
|
||||
state.monitoringVehicle.push(vehicleUuid);
|
||||
}
|
||||
}),
|
||||
|
||||
removeMonitoringVehicle: (vehicleUuid) =>
|
||||
set((state) => {
|
||||
state.monitoringVehicle = state.monitoringVehicle.filter((v) => v !== vehicleUuid);
|
||||
}),
|
||||
|
||||
clearMonitoringVehicle: () =>
|
||||
set((state) => {
|
||||
state.monitoringVehicle = [];
|
||||
}),
|
||||
|
||||
setMonitoringHuman: (humansUuid) =>
|
||||
set((state) => {
|
||||
state.monitoringHuman = humansUuid;
|
||||
}),
|
||||
|
||||
addMonitoringHuman: (humanUuid) =>
|
||||
set((state) => {
|
||||
if (!state.monitoringHuman.includes(humanUuid)) {
|
||||
state.monitoringHuman.push(humanUuid);
|
||||
}
|
||||
}),
|
||||
|
||||
removeMonitoringHuman: (humanUuid) =>
|
||||
set((state) => {
|
||||
state.monitoringHuman = state.monitoringHuman.filter((h) => h !== humanUuid);
|
||||
}),
|
||||
|
||||
clearMonitoringHuman: () =>
|
||||
set((state) => {
|
||||
state.monitoringHuman = [];
|
||||
}),
|
||||
|
||||
clearAllMonitors: () =>
|
||||
set((state) => {
|
||||
state.monitoringVehicle = [];
|
||||
state.monitoringHuman = [];
|
||||
}),
|
||||
|
||||
hasVehicle: (vehicleUuid) => get().monitoringVehicle.includes(vehicleUuid),
|
||||
hasHuman: (humanUuid) => get().monitoringHuman.includes(humanUuid),
|
||||
}))
|
||||
);
|
||||
|
||||
// useEffect(() => {
|
||||
// const selectedProductData = getProductById(selectedProduct.productUuid);
|
||||
// const newEvents: EventsSchema[] = [];
|
||||
|
||||
// if (selectedProductData) {
|
||||
// determineExecutionMachineSequences([selectedProductData]).then((sequences) => {
|
||||
// sequences.forEach((sequence) => {
|
||||
// sequence.forEach((event) => {
|
||||
// if (event.type === "human" || event.type === "vehicle") {
|
||||
// newEvents.push(event);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// setEvents(newEvents);
|
||||
// });
|
||||
// }
|
||||
// }, [selectedProduct, products, monitoringHuman, monitoringVehicle]);
|
||||
Reference in New Issue
Block a user