feat: upgrade 3d styling with environment, shadows, and physical materials
This commit is contained in:
parent
9ac0261a17
commit
fa67f2d271
1 changed files with 27 additions and 12 deletions
|
|
@ -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]} />
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue