diff --git a/components/Structures/Mining/TopographicMap.tsx b/components/Structures/Mining/TopographicMap.tsx index 0170e189..55a31a83 100644 --- a/components/Structures/Mining/TopographicMap.tsx +++ b/components/Structures/Mining/TopographicMap.tsx @@ -1,7 +1,18 @@ 'use client'; -import { useEffect, useRef } from 'react'; +import { useEffect, useMemo, useRef, useState } from 'react'; import { motion } from 'framer-motion'; +import { Canvas, useFrame, useThree } from '@react-three/fiber'; +import { OrbitControls, PerspectiveCamera, Text, Line } from '@react-three/drei'; +import * as THREE from 'three'; +import { createNoise2D } from 'simplex-noise'; +import alea from 'alea'; +import { Card } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { Settings, X } from 'lucide-react'; export type MineralDeposit = { id: string; @@ -93,4 +104,377 @@ export function TopographicMap({ deposits = [], roverPosition, selectedDeposit } )} ); -} \ No newline at end of file +}; + +{/* const topographicVertexShader = ` + varying vec2 vUv; + varying float vElevation; + + void main() { + vUv = uv; + vElevation = position.z; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + } +` + +const topographicFragmentShader = ` + varying vec2 vUv; + varying float vElevation; + uniform vec3 uBaseColor; + uniform vec3 uContourColor; + uniform float uBands; + uniform float uContourWidth; + + void main() { + float elevation = vElevation; + float bandedElevation = floor(elevation * uBands) / uBands; + float nextBand = floor(elevation * uBands + 1.0) / uBands; + float mixFactor = smoothstep(bandedElevation, nextBand, elevation); + + float contourLine = 1.0 - smoothstep(0.0, uContourWidth, abs(mixFactor - 0.5)); + + vec3 finalColor = mix(uBaseColor, uContourColor, contourLine * 0.5); + + gl_FragColor = vec4(finalColor, 1.0); + } +` + +const atmosphericVertexShader = ` + varying vec2 vUv; + varying float vElevation; + + void main() { + vUv = uv; + vElevation = position.z; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + } +` + +const atmosphericFragmentShader = ` + varying vec2 vUv; + varying float vElevation; + uniform vec3 uLowColor; + uniform vec3 uMidColor; + uniform vec3 uHighColor; + + void main() { + float elevation = vElevation; + + vec3 color; + if (elevation < 0.33) { + color = mix(uLowColor, uMidColor, elevation * 3.0); + } else if (elevation < 0.66) { + color = mix(uMidColor, uHighColor, (elevation - 0.33) * 3.0); + } else { + color = uHighColor; + } + + gl_FragColor = vec4(color, 1.0); + } +` + +interface Landmark { + position: [number, number, number] + name: string + imageUrl: string +} + +interface Road { + points: [number, number, number][] + name: string +} + +const Landmark = ({ position, name, imageUrl, onClick }: Landmark & { onClick: () => void }) => { + const textRef = useRef() + const meshRef = useRef() + + useFrame(({ camera }) => { + if (textRef.current) { + textRef.current.lookAt(camera.position) + } + if (meshRef.current) { + meshRef.current.lookAt(camera.position) + } + }) + + return ( + + { + document.body.style.cursor = 'pointer' + e.stopPropagation() + }} + onPointerOut={(e) => { + document.body.style.cursor = 'default' + e.stopPropagation() + }} + > + + + + + {name} + + + ) +} + +const Road = ({ points, name }: Road) => { + return ( + + ) +} + +const Terrain = ({ config }) => { + const mesh = useRef() + const prng = useMemo(() => alea(config.seed), [config.seed]) + const noise2D = useMemo(() => createNoise2D(prng), [prng]) + + const geometry = useMemo(() => { + const geo = new THREE.PlaneGeometry(20, 20, 200, 200) + const positions = geo.attributes.position.array + + for (let i = 0; i < positions.length; i += 3) { + const x = positions[i] + const y = positions[i + 1] + const noise = noise2D(x * 0.05, y * 0.05) + positions[i + 2] = noise * config.heightScale + } + + geo.computeVertexNormals() + return geo + }, [noise2D, config.heightScale, config.seed]) + + const material = useMemo(() => { + const shader = config.viewMode === 'topographic' ? + { vertex: topographicVertexShader, fragment: topographicFragmentShader } : + { vertex: atmosphericVertexShader, fragment: atmosphericFragmentShader } + + return new THREE.ShaderMaterial({ + vertexShader: shader.vertex, + fragmentShader: shader.fragment, + uniforms: { + uBaseColor: { value: new THREE.Color(config.baseColor) }, + uContourColor: { value: new THREE.Color(config.contourColor) }, + uBands: { value: config.topographicBands }, + uContourWidth: { value: 0.1 }, + uLowColor: { value: new THREE.Color(config.lowColor) }, + uMidColor: { value: new THREE.Color(config.midColor) }, + uHighColor: { value: new THREE.Color(config.highColor) }, + }, + }) + }, [config]) + + useEffect(() => { + if (mesh.current) { + mesh.current.material.uniforms.uBaseColor.value.set(config.baseColor) + mesh.current.material.uniforms.uContourColor.value.set(config.contourColor) + mesh.current.material.uniforms.uBands.value = config.topographicBands + mesh.current.material.uniforms.uLowColor.value.set(config.lowColor) + mesh.current.material.uniforms.uMidColor.value.set(config.midColor) + mesh.current.material.uniforms.uHighColor.value.set(config.highColor) + } + }, [config]) + + return +} + +const Map = ({ config }) => { + const [selectedLandmark, setSelectedLandmark] = useState(null) + + const landmarks: Landmark[] = [ + { + position: [3, 3, 1], + name: "Mount Oberon", + imageUrl: "/placeholder.svg?height=300&width=400", + }, + { + position: [-2, -2, 0.5], + name: "Little Oberon", + imageUrl: "/placeholder.svg?height=300&width=400", + }, + ] + + const roads: Road[] = [ + { + points: [ + [-2, -2, 0.5], + [0, 0, 0.75], + [3, 3, 1], + ], + name: "Mountain Path", + }, + ] + + return ( + <> + + {landmarks.map((landmark, index) => ( + setSelectedLandmark(landmark)} + /> + ))} + {roads.map((road, index) => ( + + ))} + {selectedLandmark && ( + + + + {selectedLandmark.name} + setSelectedLandmark(null)} + > + + + + + + + )} + > + ) +} + +const ConfigPanel = ({ config, setConfig, onClose }) => { + return ( + + + Configuration + + + + + + + View Mode + setConfig({ ...config, viewMode: value })}> + + Topographic + Atmospheric + + + + {config.viewMode === 'topographic' && ( + <> + + Base Color + setConfig({ ...config, baseColor: e.target.value })} + /> + + + Contour Color + setConfig({ ...config, contourColor: e.target.value })} + /> + + > + )} + {config.viewMode === 'atmospheric' && ( + <> + + Low Elevation Color + setConfig({ ...config, lowColor: e.target.value })} + /> + + + Mid Elevation Color + setConfig({ ...config, midColor: e.target.value })} + /> + + + High Elevation Color + setConfig({ ...config, highColor: e.target.value })} + /> + + > + )} + + + ) +} + +export default function Component() { + const [config, setConfig] = useState({ + seed: 42, + heightScale: 1, + topographicBands: 40, + viewMode: 'topographic', + baseColor: '#F5F5DC', // Beige + contourColor: '#8B4513', // Saddle Brown + lowColor: '#0000FF', // Blue + midColor: '#00FF00', // Green + highColor: '#FF0000', // Red + }) + const [showConfig, setShowConfig] = useState(false) + + return ( + + + setShowConfig(!showConfig)} + aria-label="Toggle Configuration" + > + + + + {showConfig && ( + setShowConfig(false)} + /> + )} + + + + + + + + + ) +} */} \ No newline at end of file diff --git a/test.tsx b/test.tsx deleted file mode 100644 index e69de29b..00000000