feat: upgrade 3d styling with environment, shadows, and physical materials
Some checks are pending
Deploy to Production / deploy (push) Waiting to run
Test / backend-test (push) Waiting to run
Test / frontend-test (push) Waiting to run

This commit is contained in:
fullsizemalt 2025-12-17 23:11:12 -08:00
parent 9ac0261a17
commit fa67f2d271

View file

@ -1,6 +1,6 @@
import { useEffect, useState, Suspense, useMemo, Component, ReactNode, useRef } from 'react'; import { useEffect, useState, Suspense, useMemo, Component, ReactNode, useRef } from 'react';
import { Canvas, useFrame } from '@react-three/fiber'; import { Canvas, useFrame } from '@react-three/fiber';
import { Text, Instances, Instance, Html, CameraControls } from '@react-three/drei'; import { Text, Instances, Instance, Html, CameraControls, Environment, ContactShadows } from '@react-three/drei';
import * as THREE from 'three'; import * as THREE from 'three';
import { layoutApi, Floor3DData } from '../lib/layoutApi'; import { layoutApi, Floor3DData } from '../lib/layoutApi';
import { Loader2, ArrowLeft, Maximize, MousePointer2, Layers, Thermometer, Droplets, Activity, Leaf } from 'lucide-react'; import { Loader2, ArrowLeft, Maximize, MousePointer2, Layers, Thermometer, Droplets, Activity, Leaf } from 'lucide-react';
@ -149,11 +149,11 @@ function PlantInstances({ positions, onPlantClick, visMode }: {
</Instances> </Instances>
)} )}
{/* Empty Slots */} {/* Empty Slots - Refined */}
{emptySlots.length > 0 && visMode === 'STANDARD' && ( {emptySlots.length > 0 && visMode === 'STANDARD' && (
<Instances range={emptySlots.length}> <Instances range={emptySlots.length}>
<cylinderGeometry args={[0.05, 0.05, 0.1, 8]} /> <cylinderGeometry args={[0.05, 0.05, 0.1, 8]} />
<meshStandardMaterial color={COLORS.EMPTY_SLOT} opacity={0.3} transparent /> <meshStandardMaterial color="#4b5563" roughness={0.8} />
{emptySlots.map((pos, i) => ( {emptySlots.map((pos, i) => (
<Instance <Instance
key={pos.id || i} key={pos.id || i}
@ -251,12 +251,13 @@ function FacilityScene({ data, onSelectPlant, targetView, setControls, visMode }
<mesh <mesh
rotation={[-Math.PI / 2, 0, 0]} rotation={[-Math.PI / 2, 0, 0]}
position={[room.width / 2, 0, room.height / 2]} position={[room.width / 2, 0, room.height / 2]}
receiveShadow
> >
<planeGeometry args={[room.width, room.height]} /> <planeGeometry args={[room.width, room.height]} />
<meshStandardMaterial <meshStandardMaterial
color={floorColor} color={floorColor}
metalness={0.2} roughness={0.9} // Concrete-like
roughness={0.8} metalness={0.1}
transparent={visMode !== 'STANDARD'} transparent={visMode !== 'STANDARD'}
opacity={visMode !== 'STANDARD' ? 0.8 : 1} opacity={visMode !== 'STANDARD' ? 0.8 : 1}
/> />
@ -306,9 +307,11 @@ function FacilityScene({ data, onSelectPlant, targetView, setControls, visMode }
section.posY + (section.height / 2) section.posY + (section.height / 2)
]} ]}
rotation={[-Math.PI / 2, 0, 0]} rotation={[-Math.PI / 2, 0, 0]}
castShadow
receiveShadow
> >
<planeGeometry args={[section.width, section.height]} /> <planeGeometry args={[section.width, section.height]} />
<meshStandardMaterial color="#374151" transparent opacity={0.5} side={THREE.DoubleSide} /> <meshStandardMaterial color="#64748b" roughness={0.2} metalness={0.8} side={THREE.DoubleSide} />
</mesh> </mesh>
))} ))}
@ -361,14 +364,29 @@ function FacilityScene({ data, onSelectPlant, targetView, setControls, visMode }
return ( return (
<> <>
<ambientLight intensity={1.5} /> <Environment preset="city" background={false} />
<pointLight position={[20, 30, 20]} intensity={2} /> <ambientLight intensity={0.5} />
<directionalLight position={[-10, 50, -10]} intensity={1} castShadow /> <directionalLight
position={[-10, 50, -10]}
intensity={1}
castShadow
shadow-mapSize={[2048, 2048]}
/>
<group position={[-data.floor.width / 2, 0, -data.floor.height / 2]}> <group position={[-data.floor.width / 2, 0, -data.floor.height / 2]}>
{roomMeshes} {roomMeshes}
</group> </group>
<ContactShadows
position={[0, -0.01, 0]}
opacity={0.4}
scale={100}
blur={2.5}
far={10}
resolution={512}
color="#000000"
/>
<CameraControls <CameraControls
ref={controlsRef} ref={controlsRef}
minDistance={5} minDistance={5}
@ -378,9 +396,6 @@ function FacilityScene({ data, onSelectPlant, targetView, setControls, visMode }
infinityDolly={false} infinityDolly={false}
makeDefault makeDefault
/> />
<gridHelper args={[200, 100, 0x444444, 0x111111]} position={[0, -0.1, 0]} />
<axesHelper args={[5]} />
</> </>
); );
} }