| import { ContactShadows, Environment } from "@react-three/drei"; |
| import { Canvas } from "@react-three/fiber"; |
|
|
| import type { WorldSnapshot } from "../types"; |
| import { KeyboardOrbitControls } from "./KeyboardOrbitControls"; |
| import { WorldView } from "./WorldView"; |
|
|
| type WorldSimulatorSceneProps = { |
| snapshot: WorldSnapshot | null; |
| selectedId: string | null; |
| onSelectEntity: (id: string | null) => void; |
| }; |
|
|
| export function WorldSimulatorScene({ |
| snapshot, |
| selectedId, |
| onSelectEntity, |
| }: WorldSimulatorSceneProps) { |
| return ( |
| <Canvas |
| className="worldCanvas" |
| shadows |
| camera={{ position: [34, 38, 42], fov: 45, near: 0.1, far: 300 }} |
| dpr={[1, 1.75]} |
| gl={{ preserveDrawingBuffer: true }} |
| onPointerMissed={(event) => { |
| if (event.type === "click") { |
| onSelectEntity(null); |
| } |
| }} |
| > |
| <color attach="background" args={["#b9d7f2"]} /> |
| <fog attach="fog" args={["#b9d7f2", 70, 165]} /> |
| <ambientLight intensity={0.65} /> |
| <directionalLight |
| castShadow |
| position={[28, 42, 24]} |
| intensity={2.4} |
| shadow-mapSize={[2048, 2048]} |
| /> |
| <Environment preset="city" /> |
| |
| {snapshot ? ( |
| <WorldView |
| snapshot={snapshot} |
| selectedId={selectedId} |
| onSelectEntity={onSelectEntity} |
| /> |
| ) : ( |
| <LoadingTerrain /> |
| )} |
| |
| <ContactShadows position={[0, 0.03, 0]} opacity={0.32} scale={90} blur={2.6} far={32} /> |
| <KeyboardOrbitControls |
| terrainWidth={snapshot?.terrain.width ?? 80} |
| terrainDepth={snapshot?.terrain.depth ?? 80} |
| /> |
| </Canvas> |
| ); |
| } |
|
|
| function LoadingTerrain() { |
| return ( |
| <group> |
| <mesh position={[0, -0.3, 0]}> |
| <boxGeometry args={[80, 0.6, 80]} /> |
| <meshStandardMaterial color="#43a047" roughness={0.85} /> |
| </mesh> |
| <mesh position={[0, -1.3, 0]}> |
| <boxGeometry args={[80, 1.6, 80]} /> |
| <meshStandardMaterial color="#6b4a2c" roughness={0.95} /> |
| </mesh> |
| </group> |
| ); |
| } |
|
|