diff --git a/frontend/src/components/facility3d/FacilityScene.tsx b/frontend/src/components/facility3d/FacilityScene.tsx index e89f077..d229871 100644 --- a/frontend/src/components/facility3d/FacilityScene.tsx +++ b/frontend/src/components/facility3d/FacilityScene.tsx @@ -6,6 +6,9 @@ import { RoomObject } from './RoomObject'; import { Beacon } from './Beacon'; import { PlantPosition, VisMode } from './types'; +// Convert pixel coordinates to world units (same as RoomObject/SmartRack) +const SCALE = 0.1; + interface FacilitySceneProps { data: Floor3DData; visMode: VisMode; @@ -30,6 +33,12 @@ export function FacilityScene({ const controlsRef = useRef(null); const [keysPressed, setKeysPressed] = useState>({}); + // Scale floor dimensions for centering + const scaledFloor = { + width: data.floor.width * SCALE, + height: data.floor.height * SCALE, + }; + useEffect(() => { if (controlsRef.current) onControlsReady(controlsRef.current); }, [controlsRef.current, onControlsReady]); @@ -88,7 +97,7 @@ export function FacilityScene({ shadow-mapSize={[2048, 2048]} /> - + {data.rooms.map((room: Room3D) => ( { const hash = roomName.split('').reduce((a, b) => a + b.charCodeAt(0), 0); @@ -30,6 +33,14 @@ interface RoomObjectProps { export function RoomObject({ room, visMode, onPlantClick, highlightedTags, dimMode }: RoomObjectProps) { const env = getMockRoomEnv(room.name); + // Scale room dimensions to world units + const scaledRoom = { + posX: room.posX * SCALE, + posY: room.posY * SCALE, + width: room.width * SCALE, + height: room.height * SCALE, + }; + let floorColor: string = COLORS.ROOM_FLOOR; if (visMode === 'TEMP') { const t = (env.temp - 65) / 20; @@ -44,11 +55,11 @@ export function RoomObject({ room, visMode, onPlantClick, highlightedTags, dimMo } return ( - + )} - - + + - - + + diff --git a/frontend/src/components/facility3d/SmartRack.tsx b/frontend/src/components/facility3d/SmartRack.tsx index 8818b8a..084391f 100644 --- a/frontend/src/components/facility3d/SmartRack.tsx +++ b/frontend/src/components/facility3d/SmartRack.tsx @@ -5,6 +5,9 @@ import type { Section3D, Position3D } from '../../lib/layoutApi'; import { PlantPosition, VisMode } from './types'; import { PlantSystem } from './PlantSystem'; +// Convert pixel coordinates to world units (DB stores pixels, 3D uses meters/units) +const SCALE = 0.1; // 1 pixel = 0.1 world units (so 700px = 70 units) + interface SmartRackProps { section: Section3D; visMode: VisMode; @@ -14,27 +17,36 @@ interface SmartRackProps { } export function SmartRack({ section, visMode, onPlantClick, highlightedTags, dimMode }: SmartRackProps) { + // Scale section dimensions to world units + const scaledSection = { + posX: section.posX * SCALE, + posY: section.posY * SCALE, + width: section.width * SCALE, + height: section.height * SCALE, + }; + const positions: PlantPosition[] = useMemo(() => { - const spacing = 0.5; + const plantSpacing = 0.5; // Spacing between plants in world units return section.positions.map((pos: Position3D) => ({ ...pos, - x: section.posX + (pos.column * spacing), - z: section.posY + (pos.row * spacing), + // Position plants within the scaled section bounds + x: scaledSection.posX + (pos.column * plantSpacing), + z: scaledSection.posY + (pos.row * plantSpacing), y: 0.4 + (pos.tier * 0.6), })); - }, [section]); + }, [section, scaledSection]); const distinctTiers = [...new Set(positions.map(p => p.tier))].sort((a, b) => a - b); const distinctRows = [...new Set(positions.map(p => p.row))].sort((a, b) => a - b); const distinctCols = [...new Set(positions.map(p => p.column))].sort((a, b) => a - b); - const spacing = 0.5; + const plantSpacing = 0.5; return ( {visMode === 'STANDARD' && ( - + @@ -86,7 +98,7 @@ export function SmartRack({ section, visMode, onPlantClick, highlightedTags, dim {visMode === 'STANDARD' && distinctRows.map(row => ( (