From 823558628eb67c9af440cc7ff6ecb96092f6b102 Mon Sep 17 00:00:00 2001 From: Gizmotronn Date: Mon, 18 Nov 2024 19:31:44 +1100 Subject: [PATCH 01/14] =?UTF-8?q?=F0=9F=8E=99=EF=B8=8F=E2=9B=B8=EF=B8=8F?= =?UTF-8?q?=20=E2=86=9D=20[SSP-33=20SSC-40=20SSM-40]:=20Trying=20to=20buil?= =?UTF-8?q?d=20some=20shitty=20maps,=20but=20failing...about=20half?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/scenes/earth/page.tsx | 2 +- app/tests/page.tsx | 115 +++++++- components/Inventory.tsx | 57 ++++ components/Layout/Guide.tsx | 3 + components/Topo.tsx | 74 +++++ components/mining-component.tsx | 167 ++++++++++++ components/terrain-map.tsx | 211 +++++++++++++++ components/topographic-map.tsx | 465 ++++++++++++++++++++++++++++++++ package.json | 2 +- yarn.lock | 216 +++++++-------- 10 files changed, 1196 insertions(+), 116 deletions(-) create mode 100644 components/Inventory.tsx create mode 100644 components/Topo.tsx create mode 100644 components/mining-component.tsx create mode 100644 components/terrain-map.tsx create mode 100644 components/topographic-map.tsx diff --git a/app/scenes/earth/page.tsx b/app/scenes/earth/page.tsx index ebf17661..63507df2 100644 --- a/app/scenes/earth/page.tsx +++ b/app/scenes/earth/page.tsx @@ -13,7 +13,7 @@ import StructuresOnPlanet, { import AllAutomatonsOnActivePlanet from "@/components/Structures/Auto/AllAutomatons"; import InventoryPage from "@/components/Inventory/Grid/Grid"; import EnhancedWeatherEventsComponent from "@/components/enhanced-weather-events"; -import TopographicMap from "@/components/topographic-map"; +// import TopographicMap from "@/components/topographic-map"; const EarthView: React.FC = () => { const { activePlanet, updatePlanetLocation } = useActivePlanet(); diff --git a/app/tests/page.tsx b/app/tests/page.tsx index e3e3e7a0..2a6158a6 100644 --- a/app/tests/page.tsx +++ b/app/tests/page.tsx @@ -1,19 +1,16 @@ "use client"; -import React, { useEffect, useState } from "react"; +import React, { useEffect, useRef, useMemo, useState } from "react"; import StarnetLayout from "@/components/Layout/Starnet"; -import ImageAnnotation from "@/components/Projects/(classifications)/Annotation"; -import InventoryPage from "@/components/Inventory/Grid/Grid"; -import TelescopeComponent from "@/constants/Structures/Telescope"; -import ZoodexComponent from "@/constants/Structures/Zoodex"; -import { CreateStructure } from "@/components/Structures/Build/CreateDedicatedStructure"; -import AllClassifications from "@/content/Starnet/YourClassifications"; +// import { TopographicMap } from "@/components/topographic-map"; export default function TestPage() { return ( <> - +
+ +
); @@ -30,4 +27,104 @@ export default function TestPage() { }, ]} /> -*/ \ No newline at end of file +*/ + +import { Canvas } from "@react-three/fiber"; +import * as THREE from "three"; +import { createNoise2D } from "simplex-noise"; +import alea from "alea"; + +// Topographic shaders +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); + } +`; + +type TerrainProps = { + seed: number; + heightScale: number; + bands: number; + baseColor: string; + contourColor: string; +}; + +const Terrain: React.FC = ({ seed, heightScale, bands, baseColor, contourColor }) => { + const mesh = useRef(null); // Explicitly define mesh type + const prng = useMemo(() => alea(seed), [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 as Float32Array; + + 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 * heightScale; + } + + geo.computeVertexNormals(); + return geo; + }, [noise2D, heightScale]); + + const material = useMemo(() => { + return new THREE.ShaderMaterial({ + vertexShader: topographicVertexShader, + fragmentShader: topographicFragmentShader, + uniforms: { + uBaseColor: { value: new THREE.Color(baseColor) }, + uContourColor: { value: new THREE.Color(contourColor) }, + uBands: { value: bands }, + uContourWidth: { value: 0.1 }, + }, + }); + }, [baseColor, contourColor, bands]); + + return ( + + ); +}; + +const TopographicMap = () => { + return ( + + + + + ); +}; \ No newline at end of file diff --git a/components/Inventory.tsx b/components/Inventory.tsx new file mode 100644 index 00000000..446cae05 --- /dev/null +++ b/components/Inventory.tsx @@ -0,0 +1,57 @@ +import { useState } from 'react' +import { Diamond, Zap, Gem, Rocket, Crown } from 'lucide-react' + +type InventoryItem = { + id: string + name: string + amount: number +} + +type Props = { + inventory: InventoryItem[] +} + +export function Inventory({ inventory = [] }: Props) { + const [hoveredItem, setHoveredItem] = useState(null) + + const getIcon = (name: string) => { + switch (name) { + case 'Iron': + return + case 'Copper': + return + case 'Gold': + return + case 'Titanium': + return + case 'Platinum': + return + default: + return + } + } + + return ( +
+

Inventory

+
+ {inventory.map(item => ( +
setHoveredItem(item.id)} + onMouseLeave={() => setHoveredItem(null)} + > + {getIcon(item.name)} + {item.amount} + {hoveredItem === item.id && ( +
+ {item.name} +
+ )} +
+ ))} +
+
+ ) +} \ No newline at end of file diff --git a/components/Layout/Guide.tsx b/components/Layout/Guide.tsx index 1305db6e..0bd3d527 100644 --- a/components/Layout/Guide.tsx +++ b/components/Layout/Guide.tsx @@ -294,6 +294,9 @@ const StructureMissionGuide = () => {

{mission.description}

+ {mission.modalContent && ( + + )} diff --git a/components/Topo.tsx b/components/Topo.tsx new file mode 100644 index 00000000..d8b19f7b --- /dev/null +++ b/components/Topo.tsx @@ -0,0 +1,74 @@ +import { useEffect, useRef } from 'react' +import { motion } from 'framer-motion' + +type MineralDeposit = { + id: string + name: string + amount: number + position: { x: number; y: number } +} + +type Props = { + deposits: MineralDeposit[] + roverPosition: { x: number; y: number } | null + selectedDeposit: MineralDeposit | null +} + +export function TopographicMap({ deposits = [], roverPosition, selectedDeposit }: Props) { + const canvasRef = useRef(null) + + useEffect(() => { + const canvas = canvasRef.current + if (!canvas) return + + const ctx = canvas.getContext('2d') + if (!ctx) return + + // Draw topographic map (simplified version) + ctx.fillStyle = '#f0f0f0' + ctx.fillRect(0, 0, canvas.width, canvas.height) + + // Draw contour lines + ctx.strokeStyle = '#d0d0d0' + for (let i = 0; i < canvas.height; i += 20) { + ctx.beginPath() + ctx.moveTo(0, i) + ctx.lineTo(canvas.width, i) + ctx.stroke() + } + + // Draw deposits + deposits.forEach(deposit => { + ctx.fillStyle = deposit.name === 'Iron' ? '#FFE3BA' : '#5FCBC3' + ctx.beginPath() + ctx.arc(deposit.position.x, deposit.position.y, Math.sqrt(deposit.amount) / 2, 0, 2 * Math.PI) + ctx.fill() + + // Add deposit name + ctx.fillStyle = '#2C4F64' + ctx.font = '12px Arial' + ctx.textAlign = 'center' + ctx.fillText(deposit.name, deposit.position.x, deposit.position.y + Math.sqrt(deposit.amount) / 2 + 20) + }) + }, [deposits]) + + return ( +
+ + {roverPosition && ( + + )} + {selectedDeposit && ( +
+ )} +
+ ) +} \ No newline at end of file diff --git a/components/mining-component.tsx b/components/mining-component.tsx new file mode 100644 index 00000000..1702cea9 --- /dev/null +++ b/components/mining-component.tsx @@ -0,0 +1,167 @@ +import { useState, useEffect } from 'react'; +import { MineralDepositList } from './Structures/Mining/Deposits'; +import { ControlPanel } from './Structures/Mining/ControlPanel'; +import { TopographicMap } from './Topo'; +// import { TerrainMap } from './terrain-map'; +import { Inventory } from './Inventory'; + +type MineralDeposit = { + id: string + name: string + amount: number + availableAmount: number + level: number + uses: string[] + position: { x: number; y: number } +} + +type Rover = { + id: string + name: string + speed: number + efficiency: number + miningLevel: number +} + +type InventoryItem = { + id: string + name: string + amount: number +} + +export function MiningComponentComponent() { + const [mineralDeposits, setMineralDeposits] = useState([]) + const [rovers, setRovers] = useState([]) + const [selectedDeposit, setSelectedDeposit] = useState(null) + const [selectedRover, setSelectedRover] = useState(null) + const [roverPosition, setRoverPosition] = useState<{ x: number; y: number } | null>(null) + const [inventory, setInventory] = useState([]) + const [isMining, setIsMining] = useState(false) + const [activeMap, setActiveMap] = useState<'2D' | '3D'>('2D') + + useEffect(() => { + setMineralDeposits([ + { id: '1', name: 'Iron', amount: 1000, availableAmount: 500, level: 1, uses: ['Construction', 'Tools'], position: { x: 200, y: 150 } }, + { id: '2', name: 'Copper', amount: 800, availableAmount: 400, level: 2, uses: ['Electronics', 'Wiring'], position: { x: 400, y: 300 } }, + { id: '3', name: 'Gold', amount: 500, availableAmount: 200, level: 3, uses: ['Electronics', 'Jewelry'], position: { x: 300, y: 200 } }, + { id: '4', name: 'Titanium', amount: 600, availableAmount: 300, level: 2, uses: ['Aerospace', 'Medical'], position: { x: 500, y: 250 } }, + { id: '5', name: 'Platinum', amount: 400, availableAmount: 150, level: 4, uses: ['Catalysts', 'Electronics'], position: { x: 150, y: 350 } }, + ]) + setRovers([ + { id: '1', name: 'Rover A', speed: 10, efficiency: 0.8, miningLevel: 1 }, + { id: '2', name: 'Rover B', speed: 15, efficiency: 0.7, miningLevel: 2 }, + { id: '3', name: 'Rover C', speed: 12, efficiency: 0.9, miningLevel: 3 }, + { id: '4', name: 'Rover D', speed: 18, efficiency: 0.6, miningLevel: 4 }, + ]) + setInventory([ + { id: '1', name: 'Iron', amount: 0 }, + { id: '2', name: 'Copper', amount: 0 }, + { id: '3', name: 'Gold', amount: 0 }, + { id: '4', name: 'Titanium', amount: 0 }, + { id: '5', name: 'Platinum', amount: 0 }, + ]) + }, []) + + const handleDepositSelect = (deposit: MineralDeposit) => { + setSelectedDeposit(deposit) + } + + const handleRoverSelect = (rover: Rover) => { + setSelectedRover(rover) + } + + const handleStartMining = () => { + if (selectedDeposit && selectedRover) { + setIsMining(true) + setRoverPosition({ x: 50, y: 50 }) // Start position + + const duration = 5000 // 5 seconds to reach deposit + const startTime = Date.now() + + const animateRover = () => { + const elapsedTime = Date.now() - startTime + const progress = Math.min(elapsedTime / duration, 1) + + setRoverPosition({ + x: 50 + (selectedDeposit.position.x - 50) * progress, + y: 50 + (selectedDeposit.position.y - 50) * progress + }) + + if (progress < 1) { + requestAnimationFrame(animateRover) + } else { + // At deposit, start mining + setTimeout(() => { + setRoverPosition({ x: 50, y: 50 }) // Return to base + setIsMining(false) + updateInventory(selectedDeposit.name, 50) // Add mined resources to inventory + }, 5000) // 5 seconds at deposit + } + } + + requestAnimationFrame(animateRover) + } + } + + const updateInventory = (resourceName: string, amount: number) => { + setInventory(prev => prev.map(item => + item.name === resourceName ? { ...item, amount: item.amount + amount } : item + )) + } + + const toggleMap = () => { + setActiveMap(prev => prev === '2D' ? '3D' : '2D') + } + + return ( +
+
+
+
+

Mars Mining Operation

+ +
+ {/* {activeMap === '2D' ? ( + + ) : ( + + )} */} +
+
+ {/*
+ +
+
+ +
*/} +
+
+
+ +
+
+ ) +} \ No newline at end of file diff --git a/components/terrain-map.tsx b/components/terrain-map.tsx new file mode 100644 index 00000000..0baa92d5 --- /dev/null +++ b/components/terrain-map.tsx @@ -0,0 +1,211 @@ +"use client" + +import React, { useRef, useState, useEffect, useMemo } from 'react' +import { Canvas, useFrame, useThree } from '@react-three/fiber' +import { OrbitControls, PerspectiveCamera, Html } from '@react-three/drei' +import * as THREE from 'three' +import { createNoise2D } from 'simplex-noise' +import alea from 'alea' +import { Button } from "@/components/ui/button" +import { Settings, Play } from 'lucide-react' + +const terrainVertexShader = ` + varying vec2 vUv; + varying float vElevation; + + void main() { + vUv = uv; + vElevation = position.z; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + } +` + +const terrainFragmentShader = ` + varying vec2 vUv; + varying float vElevation; + uniform vec3 uLowColor; + uniform vec3 uHighColor; + uniform float uBands; + + void main() { + float bandedElevation = floor(vElevation * uBands) / uBands; + vec3 color = mix(uLowColor, uHighColor, bandedElevation); + gl_FragColor = vec4(color, 1.0); + } +` + +interface TerrainConfig { + seed: number; + heightScale: number; + lowColor: string; + highColor: string; + topographicBands: number; +}; + +export function Ignore(){ + return ( + <> + ) +} + +// const Terrain = ({ config }: { config: TerrainConfig }) => { +// 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(() => { +// return new THREE.ShaderMaterial({ +// vertexShader: terrainVertexShader, +// fragmentShader: terrainFragmentShader, +// uniforms: { +// uLowColor: { value: new THREE.Color(config.lowColor) }, +// uHighColor: { value: new THREE.Color(config.highColor) }, +// uBands: { value: config.topographicBands }, +// }, +// }) +// }, [config.lowColor, config.highColor, config.topographicBands]) + +// useFrame(() => { +// if (mesh.current) { +// mesh.current.material.uniforms.uLowColor.value.set(config.lowColor) +// mesh.current.material.uniforms.uHighColor.value.set(config.highColor) +// mesh.current.material.uniforms.uBands.value = config.topographicBands +// } +// }) + +// return +// } + +// const Deposit = ({ position, name, selected }) => { +// const mesh = useRef(null); + +// useFrame(({ camera }) => { +// if (mesh.current) { +// mesh.current.lookAt(camera.position) +// } +// }) + +// return ( +// +// +// +// +// +// +//
{name}
+// +//
+// ) +// } + +// const Rover = ({ position }) => { +// return ( +// +// +// +// +// ) +// } + +// const Map = ({ config, deposits, roverPosition, selectedDeposit }) => { +// return ( +// <> +// +// {deposits.map((deposit) => ( +// +// ))} +// {roverPosition && ( +// +// )} +// +// ) +// } + +// const CameraController = () => { +// const { camera } = useThree() +// useEffect(() => { +// camera.position.set(0, 15, 0.01) +// camera.lookAt(0, 0, 0) +// }, [camera]) + +// return null +// } + +// type MineralDeposit = { +// id: string +// name: string +// amount: number +// position: { x: number; y: number } +// } + +// type Props = { +// deposits: MineralDeposit[] +// roverPosition: { x: number; y: number } | null +// selectedDeposit: MineralDeposit | null +// } + +// export function TerrainMap({ deposits = [], roverPosition, selectedDeposit }: Props) { +// const [config, setConfig] = useState({ +// seed: 42, +// heightScale: 1, +// topographicBands: 20, +// lowColor: '#1e3a8a', +// highColor: '#60a5fa', +// }) +// const [showConfig, setShowConfig] = useState(false) + +// const handleGenerate = () => { +// setConfig({ ...config, seed: Math.floor(Math.random() * 1000) }) +// } + +// return ( +//
+//
+// +// +//
+// +// +// +// +// +// +// +// +//
+// ) +// } \ No newline at end of file diff --git a/components/topographic-map.tsx b/components/topographic-map.tsx new file mode 100644 index 00000000..626179ad --- /dev/null +++ b/components/topographic-map.tsx @@ -0,0 +1,465 @@ +import React, { useRef, useState, useEffect, useMemo } from 'react' +import { Canvas, useFrame, useThree } from '@react-three/fiber' +import { OrbitControls, PerspectiveCamera } 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' +import { Slider } from "@/components/ui/slider"; +import { ThreeEvent } from "@react-three/fiber"; + +// Shader code remains the same +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 atmosphericFragmentShader = ` + varying vec2 vUv; + varying float vElevation; + uniform vec3 uLowColor; + uniform vec3 uMidColor; + uniform vec3 uHighColor; + uniform float uBands; + uniform float uContourWidth; + + 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; + } + + 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)); + + color = mix(color, vec3(0.0), contourLine * 0.5); + + gl_FragColor = vec4(color, 1.0); + } +` + +interface Landmark { + position: [number, number, number] + name: string + imageUrl: string + description: string +} + +const createStarShape = () => { + const shape = new THREE.Shape() + const points = 5 + const innerRadius = 0.2 + const outerRadius = 0.5 + + for (let i = 0; i < points * 2; i++) { + const angle = (i / (points * 2)) * Math.PI * 2 + const radius = i % 2 === 0 ? outerRadius : innerRadius + const x = Math.sin(angle) * radius + const y = Math.cos(angle) * radius + if (i === 0) { + shape.moveTo(x, y) + } else { + shape.lineTo(x, y) + } + } + shape.closePath() + return shape +} + +type LandmarkMarkerProps = { + position: [number, number, number]; + onClick: (e: ThreeEvent) => void; // Use ThreeEvent here +}; + +const LandmarkMarker: React.FC = ({ position, onClick }) => { + const meshRef = useRef(null); + const starShape = useMemo(() => createStarShape(), []); + + useFrame(({ camera }) => { + if (meshRef.current) { + meshRef.current.lookAt(camera.position); + } + }); + + return ( + + + + + ); +}; + +interface TerrainConfig { + seed: string + heightScale: number + viewMode: 'topographic' | 'atmospheric' + baseColor: string + contourColor: string + lowColor: string + midColor: string + highColor: string + topographicBands: number +} + +interface TerrainProps { + config: TerrainConfig +} + +const terrainConfig: TerrainConfig = { + seed: "example-seed", + heightScale: 5, + viewMode: "topographic", + baseColor: "#F5F5DC", + contourColor: "#000000", + lowColor: "#0000ff", + midColor: "#00ff00", + highColor: "#ff0000", + topographicBands: 10, +}; + +const Terrain: React.FC = ({ config }) => { + // Explicitly type the mesh ref as THREE.Mesh + const mesh = useRef(null) + + // Memoized PRNG and noise generator + const prng = useMemo(() => alea(config.seed), [config.seed]) + const noise2D = useMemo(() => createNoise2D(prng), [prng]) + + // Create the geometry with noise-based elevation + const geometry = useMemo(() => { + const geo = new THREE.PlaneGeometry(20, 20, 200, 200) + const positions = geo.attributes.position.array as Float32Array + + 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]) + + // Create the ShaderMaterial + const material = useMemo(() => { + const shader = + config.viewMode === 'topographic' + ? { + vertex: topographicVertexShader, + fragment: topographicFragmentShader, + } + : { + vertex: topographicVertexShader, + 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) }, + uLowColor: { value: new THREE.Color(config.lowColor) }, + uMidColor: { value: new THREE.Color(config.midColor) }, + uHighColor: { value: new THREE.Color(config.highColor) }, + uBands: { value: config.topographicBands }, + uContourWidth: { value: 0.1 }, + }, + }) + }, [config]) + + // Update the ShaderMaterial uniforms on each frame + useFrame(() => { + if (mesh.current) { + const mat = mesh.current.material as THREE.ShaderMaterial + mat.uniforms.uBaseColor.value.set(config.baseColor) + mat.uniforms.uContourColor.value.set(config.contourColor) + mat.uniforms.uLowColor.value.set(config.lowColor) + mat.uniforms.uMidColor.value.set(config.midColor) + mat.uniforms.uHighColor.value.set(config.highColor) + mat.uniforms.uBands.value = config.topographicBands + } + }) + + return ( + + ) +} + +interface MapSceneProps { + config: unknown + onSelectLandmark: (landmark: Landmark) => void +} + +const MapScene: React.FC = ({ config, onSelectLandmark }) => { + const landmarks: Landmark[] = [ + { + position: [3, 3, 1], + name: "Mount Oberon", + imageUrl: "/placeholder.svg?height=300&width=400", + description: + "The highest peak in the region, known for its unique crystalline formations.", + }, + { + position: [-2, -2, 0.5], + name: "Little Oberon", + imageUrl: "/placeholder.svg?height=300&width=400", + description: + "A smaller peak with abundant vegetation and rare mineral deposits.", + }, + ]; + + return ( + <> + + {landmarks.map((landmark, index) => ( + ) => { + e.stopPropagation(); + onSelectLandmark(landmark); + }} + /> + ))} + + ); +}; + +interface LandmarkModalProps { + landmark: Landmark | null; + onClose: () => void; +} + +const LandmarkModal: React.FC = ({ landmark, onClose }) => { + if (!landmark) return null + + return ( +
+ +
+
+

{landmark.name}

+ +
+
+ {landmark.name} +

{landmark.description}

+
+
+
+
+ ); +}; + +// const ConfigPanel = ({ config, setConfig, onClose }) => { +// return ( +// +//
+//

Configuration

+// +//
+//
+//
+// +// setConfig({ ...config, viewMode: value })}> +// +// Topographic +// Atmospheric +// +// +//
+// {config.viewMode === 'topographic' && ( +// <> +//
+// +// setConfig({ ...config, baseColor: e.target.value })} +// /> +//
+//
+// +// setConfig({ ...config, contourColor: e.target.value })} +// /> +//
+// +// )} +// {config.viewMode === 'atmospheric' && ( +// <> +//
+// +// setConfig({ ...config, lowColor: e.target.value })} +// /> +//
+//
+// +// setConfig({ ...config, midColor: e.target.value })} +// /> +//
+//
+// +// setConfig({ ...config, highColor: e.target.value })} +// /> +//
+// +// )} +//
+// +// setConfig({ ...config, topographicBands: value[0] })} +// /> +//
+//
+//
+// ) +// } + +export function TopographicMap() { + const [config, setConfig] = useState({ + seed: 42, + heightScale: 1, + topographicBands: 40, + viewMode: 'topographic', + baseColor: '#F5F5DC', // Beige + contourColor: '#8B4513', // Saddle Brown + lowColor: '#0000FF', // Blue + midColor: '#8B4513', // Green + highColor: '#FF0000', // Red + }); + const [showConfig, setShowConfig] = useState(false); + const [selectedLandmark, setSelectedLandmark] = useState(null); + const [key, setKey] = useState(0); + + const handleConfigChange = (newConfig: typeof config) => { + setConfig(newConfig); + setKey((prevKey) => prevKey + 1); + }; + + return ( +
+
+ +
+ + {showConfig && ( +
+ + +
+ )} + + + + + + + + + {selectedLandmark && ( + setSelectedLandmark(null)} + /> + )} +
+ ); +} \ No newline at end of file diff --git a/package.json b/package.json index e51ea443..ff3a8f21 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@radix-ui/react-toggle": "^1.1.0", "@radix-ui/react-toggle-group": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.2", - "@react-three/drei": "^9.115.0", + "@react-three/drei": "^9.117.0", "@react-three/fiber": "^8.17.10", "@supabase/auth-helpers-nextjs": "^0.10.0", "@supabase/auth-helpers-react": "^0.5.0", diff --git a/yarn.lock b/yarn.lock index 0bb1b050..1bc68144 100644 --- a/yarn.lock +++ b/yarn.lock @@ -841,7 +841,7 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/runtime@^7", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.7", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.0", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.5", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.6", "@babel/runtime@^7.23.9", "@babel/runtime@^7.24.1", "@babel/runtime@^7.24.4", "@babel/runtime@^7.24.7", "@babel/runtime@^7.24.8", "@babel/runtime@^7.25.6", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.7", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.0", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.5", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.6", "@babel/runtime@^7.23.9", "@babel/runtime@^7.24.1", "@babel/runtime@^7.24.4", "@babel/runtime@^7.24.7", "@babel/runtime@^7.24.8", "@babel/runtime@^7.25.6", "@babel/runtime@^7.26.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.26.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1" integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw== @@ -1150,12 +1150,12 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@mediapipe/tasks-vision@0.10.8": - version "0.10.8" - resolved "https://registry.yarnpkg.com/@mediapipe/tasks-vision/-/tasks-vision-0.10.8.tgz#a78e137018a19933b7a1d0e887d553d4ab833d10" - integrity sha512-Rp7ll8BHrKB3wXaRFKhrltwZl1CiXGdibPxuWXvqGnKTnv8fqa/nvftYNuSbf+pbJWKYCXdBtYTITdAUTGGh0Q== +"@mediapipe/tasks-vision@0.10.17": + version "0.10.17" + resolved "https://registry.yarnpkg.com/@mediapipe/tasks-vision/-/tasks-vision-0.10.17.tgz#2c1c73ed81902b21d37336a587b96183bb6882d5" + integrity sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg== -"@monogrid/gainmap-js@^3.0.5": +"@monogrid/gainmap-js@^3.0.6": version "3.0.6" resolved "https://registry.yarnpkg.com/@monogrid/gainmap-js/-/gainmap-js-3.0.6.tgz#21e4a7188ce9845527a480e8c7ac7894323095bc" integrity sha512-ireqJg7cw0tUn/JePDG8rAL7RyXgUKSDbjYdiygkrnye1WuKGLAWDBwF/ICwCwJ9iZBAF5caU8gSu+c34HLGdQ== @@ -2015,78 +2015,77 @@ rc-resize-observer "^1.3.1" rc-util "^5.38.0" -"@react-spring/animated@~9.6.1": - version "9.6.1" - resolved "https://registry.yarnpkg.com/@react-spring/animated/-/animated-9.6.1.tgz#ccc626d847cbe346f5f8815d0928183c647eb425" - integrity sha512-ls/rJBrAqiAYozjLo5EPPLLOb1LM0lNVQcXODTC1SMtS6DbuBCPaKco5svFUQFMP2dso3O+qcC4k9FsKc0KxMQ== - dependencies: - "@react-spring/shared" "~9.6.1" - "@react-spring/types" "~9.6.1" - -"@react-spring/core@~9.6.1": - version "9.6.1" - resolved "https://registry.yarnpkg.com/@react-spring/core/-/core-9.6.1.tgz#ebe07c20682b360b06af116ea24e2b609e778c10" - integrity sha512-3HAAinAyCPessyQNNXe5W0OHzRfa8Yo5P748paPcmMowZ/4sMfaZ2ZB6e5x5khQI8NusOHj8nquoutd6FRY5WQ== - dependencies: - "@react-spring/animated" "~9.6.1" - "@react-spring/rafz" "~9.6.1" - "@react-spring/shared" "~9.6.1" - "@react-spring/types" "~9.6.1" - -"@react-spring/rafz@~9.6.1": - version "9.6.1" - resolved "https://registry.yarnpkg.com/@react-spring/rafz/-/rafz-9.6.1.tgz#d71aafb92b78b24e4ff84639f52745afc285c38d" - integrity sha512-v6qbgNRpztJFFfSE3e2W1Uz+g8KnIBs6SmzCzcVVF61GdGfGOuBrbjIcp+nUz301awVmREKi4eMQb2Ab2gGgyQ== - -"@react-spring/shared@~9.6.1": - version "9.6.1" - resolved "https://registry.yarnpkg.com/@react-spring/shared/-/shared-9.6.1.tgz#4e2e4296910656c02bd9fd54c559702bc836ac4e" - integrity sha512-PBFBXabxFEuF8enNLkVqMC9h5uLRBo6GQhRMQT/nRTnemVENimgRd+0ZT4yFnAQ0AxWNiJfX3qux+bW2LbG6Bw== - dependencies: - "@react-spring/rafz" "~9.6.1" - "@react-spring/types" "~9.6.1" - -"@react-spring/three@~9.6.1": - version "9.6.1" - resolved "https://registry.yarnpkg.com/@react-spring/three/-/three-9.6.1.tgz#095fcd1dc6509127c33c14486d88289b89baeb9d" - integrity sha512-Tyw2YhZPKJAX3t2FcqvpLRb71CyTe1GvT3V+i+xJzfALgpk10uPGdGaQQ5Xrzmok1340DAeg2pR/MCfaW7b8AA== - dependencies: - "@react-spring/animated" "~9.6.1" - "@react-spring/core" "~9.6.1" - "@react-spring/shared" "~9.6.1" - "@react-spring/types" "~9.6.1" - -"@react-spring/types@~9.6.1": - version "9.6.1" - resolved "https://registry.yarnpkg.com/@react-spring/types/-/types-9.6.1.tgz#913d3a68c5cbc1124fdb18eff919432f7b6abdde" - integrity sha512-POu8Mk0hIU3lRXB3bGIGe4VHIwwDsQyoD1F394OK7STTiX9w4dG3cTLljjYswkQN+hDSHRrj4O36kuVa7KPU8Q== - -"@react-three/drei@^9.115.0": - version "9.115.0" - resolved "https://registry.yarnpkg.com/@react-three/drei/-/drei-9.115.0.tgz#48d3effe00c67c3c8bccfb35c3b6106bf2cebc17" - integrity sha512-VQN/AdTwLFAXEeZCCLhxGLaL5pUWt/qBOJEyr/CCgs4j/RIw1cS1CvRJsMdihFNGgc0yAgjdZlyNUa8IxUfxLw== - dependencies: - "@babel/runtime" "^7.11.2" - "@mediapipe/tasks-vision" "0.10.8" - "@monogrid/gainmap-js" "^3.0.5" - "@react-spring/three" "~9.6.1" - "@use-gesture/react" "^10.2.24" - camera-controls "^2.4.2" +"@react-spring/animated@~9.7.5": + version "9.7.5" + resolved "https://registry.yarnpkg.com/@react-spring/animated/-/animated-9.7.5.tgz#eb0373aaf99b879736b380c2829312dae3b05f28" + integrity sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg== + dependencies: + "@react-spring/shared" "~9.7.5" + "@react-spring/types" "~9.7.5" + +"@react-spring/core@~9.7.5": + version "9.7.5" + resolved "https://registry.yarnpkg.com/@react-spring/core/-/core-9.7.5.tgz#72159079f52c1c12813d78b52d4f17c0bf6411f7" + integrity sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w== + dependencies: + "@react-spring/animated" "~9.7.5" + "@react-spring/shared" "~9.7.5" + "@react-spring/types" "~9.7.5" + +"@react-spring/rafz@~9.7.5": + version "9.7.5" + resolved "https://registry.yarnpkg.com/@react-spring/rafz/-/rafz-9.7.5.tgz#ee7959676e7b5d6a3813e8c17d5e50df98b95df9" + integrity sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw== + +"@react-spring/shared@~9.7.5": + version "9.7.5" + resolved "https://registry.yarnpkg.com/@react-spring/shared/-/shared-9.7.5.tgz#6d513622df6ad750bbbd4dedb4ca0a653ec92073" + integrity sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw== + dependencies: + "@react-spring/rafz" "~9.7.5" + "@react-spring/types" "~9.7.5" + +"@react-spring/three@~9.7.5": + version "9.7.5" + resolved "https://registry.yarnpkg.com/@react-spring/three/-/three-9.7.5.tgz#46bcd22354afa873a809f1c6d7e07b59600b4d08" + integrity sha512-RxIsCoQfUqOS3POmhVHa1wdWS0wyHAUway73uRLp3GAL5U2iYVNdnzQsep6M2NZ994BlW8TcKuMtQHUqOsy6WA== + dependencies: + "@react-spring/animated" "~9.7.5" + "@react-spring/core" "~9.7.5" + "@react-spring/shared" "~9.7.5" + "@react-spring/types" "~9.7.5" + +"@react-spring/types@~9.7.5": + version "9.7.5" + resolved "https://registry.yarnpkg.com/@react-spring/types/-/types-9.7.5.tgz#e5dd180f3ed985b44fd2cd2f32aa9203752ef3e8" + integrity sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g== + +"@react-three/drei@^9.117.0": + version "9.117.0" + resolved "https://registry.yarnpkg.com/@react-three/drei/-/drei-9.117.0.tgz#325dc954faaf572604044716eab27a1d2ae2ca05" + integrity sha512-UuYnM/qNiP+37R2dVR68R9ufGrWI/OdtDxfJRxtHaXyHWWfj7muEy4vbLZRe95a4fGEfaKy0gdplbG2BFedHtg== + dependencies: + "@babel/runtime" "^7.26.0" + "@mediapipe/tasks-vision" "0.10.17" + "@monogrid/gainmap-js" "^3.0.6" + "@react-spring/three" "~9.7.5" + "@use-gesture/react" "^10.3.1" + camera-controls "^2.9.0" cross-env "^7.0.3" - detect-gpu "^5.0.28" + detect-gpu "^5.0.56" glsl-noise "^0.0.0" hls.js "^1.5.17" - maath "^0.10.7" - meshline "^3.1.6" + maath "^0.10.8" + meshline "^3.3.1" react-composer "^5.0.3" - stats-gl "^2.0.0" + stats-gl "^2.2.8" stats.js "^0.17.0" suspend-react "^0.1.3" three-mesh-bvh "^0.7.8" - three-stdlib "^2.29.9" - troika-three-text "^0.49.0" + three-stdlib "^2.34.0" + troika-three-text "^0.52.0" tunnel-rat "^0.1.2" - utility-types "^3.10.0" + utility-types "^3.11.0" uuid "^9.0.1" zustand "^3.7.1" @@ -2285,7 +2284,7 @@ "@swc/counter" "^0.1.3" tslib "^2.4.0" -"@tweenjs/tween.js@~23.1.1": +"@tweenjs/tween.js@~23.1.3": version "23.1.3" resolved "https://registry.yarnpkg.com/@tweenjs/tween.js/-/tween.js-23.1.3.tgz#eff0245735c04a928bb19c026b58c2a56460539d" integrity sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA== @@ -2455,14 +2454,15 @@ resolved "https://registry.yarnpkg.com/@types/stats.js/-/stats.js-0.17.3.tgz#705446e12ce0fad618557dd88236f51148b7a935" integrity sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ== -"@types/three@^0.163.0": - version "0.163.0" - resolved "https://registry.yarnpkg.com/@types/three/-/three-0.163.0.tgz#96f5440fcd39452d2c84dfe0c9b7a9cf0247b9e6" - integrity sha512-uIdDhsXRpQiBUkflBS/i1l3JX14fW6Ot9csed60nfbZNXHDTRsnV2xnTVwXcgbvTiboAR4IW+t+lTL5f1rqIqA== +"@types/three@*": + version "0.170.0" + resolved "https://registry.yarnpkg.com/@types/three/-/three-0.170.0.tgz#1fe17693e4e08dd6fd8662542af4c9cba9671620" + integrity sha512-CUm2uckq+zkCY7ZbFpviRttY+6f9fvwm6YqSqPfA5K22s9w7R4VnA3rzJse8kHVvuzLcTx+CjNCs2NYe0QFAyg== dependencies: - "@tweenjs/tween.js" "~23.1.1" + "@tweenjs/tween.js" "~23.1.3" "@types/stats.js" "*" "@types/webxr" "*" + "@webgpu/types" "*" fflate "~0.8.2" meshoptimizer "~0.18.1" @@ -2579,7 +2579,7 @@ resolved "https://registry.yarnpkg.com/@use-gesture/core/-/core-10.3.1.tgz#976c9421e905f0079d49822cfd5c2e56b808fc56" integrity sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw== -"@use-gesture/react@^10.2.24": +"@use-gesture/react@^10.3.1": version "10.3.1" resolved "https://registry.yarnpkg.com/@use-gesture/react/-/react-10.3.1.tgz#17a743a894d9bd9a0d1980c618f37f0164469867" integrity sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g== @@ -2593,6 +2593,11 @@ dependencies: server-only "^0.0.1" +"@webgpu/types@*": + version "0.1.51" + resolved "https://registry.yarnpkg.com/@webgpu/types/-/types-0.1.51.tgz#a4c5a12d0554032bb3cdfad632123e736b9de943" + integrity sha512-ktR3u64NPjwIViNCck+z9QeyN0iPkQCUOQ07ZCV1RzlkfP+olLTeEZ95O1QHS+v4w9vJeY9xj/uJuSphsHy5rQ== + acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -3094,7 +3099,7 @@ camelcase-css@^2.0.1: resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== -camera-controls@^2.4.2: +camera-controls@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/camera-controls/-/camera-controls-2.9.0.tgz#c3f67e702c2b68ae87418ca047c867e6494be2e8" integrity sha512-TpCujnP0vqPppTXXJRYpvIy0xq9Tro6jQf2iYUxlDpPCNxkvE/XGaTuwIxnhINOkVP/ob2CRYXtY3iVYXeMEzA== @@ -3523,10 +3528,10 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -detect-gpu@^5.0.28: - version "5.0.54" - resolved "https://registry.yarnpkg.com/detect-gpu/-/detect-gpu-5.0.54.tgz#4e637def92a49537f72a5c3b73d5bdcc16524b2d" - integrity sha512-mPfxFyfiJraOkxtDe/oaSzCt21QAmNmFtcaN7te41SwAZ2UbBsC526kAaSY6EosniNUL/K0pzh1cjqgZ3fN45A== +detect-gpu@^5.0.56: + version "5.0.57" + resolved "https://registry.yarnpkg.com/detect-gpu/-/detect-gpu-5.0.57.tgz#b032977b2cbddc464e592bd7af64684cc966aa35" + integrity sha512-iHfsCCAyxYTE0S4ULs52/DhV2W4l+VT9sTnnYLMwgdNlXKks6PSZleZRDmTCLvPXS4Lt30JI/M5QjhUPwwnZfQ== dependencies: webgl-constants "^1.1.1" @@ -5078,7 +5083,7 @@ lucide-react@^0.394.0: resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.394.0.tgz#ea496bcdb0a1295219936766f70b48235624e1ef" integrity sha512-PzTbJ0bsyXRhH59k5qe7MpTd5MxlpYZUcM9kGSwvPGAfnn0J6FElDwu2EX6Vuh//F7y60rcVJiFQ7EK9DCMgfw== -maath@^0.10.7: +maath@^0.10.8: version "0.10.8" resolved "https://registry.yarnpkg.com/maath/-/maath-0.10.8.tgz#cf647544430141bf6982da6e878abb6c4b804e24" integrity sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g== @@ -5117,7 +5122,7 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -meshline@^3.1.6: +meshline@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/meshline/-/meshline-3.3.1.tgz#20decfd5cdd25c8469e862ddf0ab1ad167759734" integrity sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ== @@ -6622,12 +6627,13 @@ sourcemap-codec@^1.4.8: resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== -stats-gl@^2.0.0: - version "2.2.8" - resolved "https://registry.yarnpkg.com/stats-gl/-/stats-gl-2.2.8.tgz#72566abc8e4a66e91c26b7d9abf659d032379d68" - integrity sha512-94G5nZvduDmzxBS7K0lYnynYwreZpkknD8g5dZmU6mpwIhy3caCrjAm11Qm1cbyx7mqix7Fp00RkbsonzKWnoQ== +stats-gl@^2.2.8: + version "2.4.2" + resolved "https://registry.yarnpkg.com/stats-gl/-/stats-gl-2.4.2.tgz#28a6c869fc3a36a8be608ef21df63c0aad99d1ba" + integrity sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ== dependencies: - "@types/three" "^0.163.0" + "@types/three" "*" + three "^0.170.0" stats.js@^0.17.0: version "0.17.0" @@ -6953,7 +6959,7 @@ three-mesh-bvh@^0.7.8: resolved "https://registry.yarnpkg.com/three-mesh-bvh/-/three-mesh-bvh-0.7.8.tgz#83156e4d3945734db076de1c94809331481b3fdd" integrity sha512-BGEZTOIC14U0XIRw3tO4jY7IjP7n7v24nv9JXS1CyeVRWOCkcOMhRnmENUjuV39gktAw4Ofhr0OvIAiTspQrrw== -three-stdlib@^2.29.9: +three-stdlib@^2.34.0: version "2.34.0" resolved "https://registry.yarnpkg.com/three-stdlib/-/three-stdlib-2.34.0.tgz#bc191d92037ddcc3e4d5a4ae1bd46a199a857b5b" integrity sha512-U5qJYWgUKBFJqr1coMSbczA964uvouzBjQbtJlaI9LfMwy7hr+kc1Mfh0gqi/2872KmGu9utgff6lj8Oti8+VQ== @@ -7026,25 +7032,25 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== -troika-three-text@^0.49.0: - version "0.49.1" - resolved "https://registry.yarnpkg.com/troika-three-text/-/troika-three-text-0.49.1.tgz#1aaa75337e507ea4120103fb69a5e4687fff97dd" - integrity sha512-lXGWxgjJP9kw4i4Wh+0k0Q/7cRfS6iOME4knKht/KozPu9GcFA9NnNpRvehIhrUawq9B0ZRw+0oiFHgRO+4Wig== +troika-three-text@^0.52.0: + version "0.52.0" + resolved "https://registry.yarnpkg.com/troika-three-text/-/troika-three-text-0.52.0.tgz#08a6e5dbbdab994be2c512d313404498f52cdaba" + integrity sha512-4rywfbPxayE5ktmdkCMdnq5BZl5LPVgNElQnJZ9/DAW6JYnY2ft9teCqof4qwdzLMZ7QaIS5NziJRs2XRsQpDg== dependencies: bidi-js "^1.0.2" - troika-three-utils "^0.49.0" - troika-worker-utils "^0.49.0" + troika-three-utils "^0.52.0" + troika-worker-utils "^0.52.0" webgl-sdf-generator "1.1.1" -troika-three-utils@^0.49.0: - version "0.49.0" - resolved "https://registry.yarnpkg.com/troika-three-utils/-/troika-three-utils-0.49.0.tgz#3fbdbf8783740ce3c1f7acac642e7e957ea4f090" - integrity sha512-umitFL4cT+Fm/uONmaQEq4oZlyRHWwVClaS6ZrdcueRvwc2w+cpNQ47LlJKJswpqtMFWbEhOLy0TekmcPZOdYA== +troika-three-utils@^0.52.0: + version "0.52.0" + resolved "https://registry.yarnpkg.com/troika-three-utils/-/troika-three-utils-0.52.0.tgz#54f6fafcef58901bddd5749dee0ab0ddd09f1179" + integrity sha512-00oxqIIehtEKInOTQekgyknBuRUj1POfOUE2q1OmL+Xlpp4gIu+S0oA0schTyXsDS4d9DkR04iqCdD40rF5R6w== -troika-worker-utils@^0.49.0: - version "0.49.0" - resolved "https://registry.yarnpkg.com/troika-worker-utils/-/troika-worker-utils-0.49.0.tgz#e5e200a09d2e0e4eb9fe818a83effa912e2ec4b4" - integrity sha512-1xZHoJrG0HFfCvT/iyN41DvI/nRykiBtHqFkGaGgJwq5iXfIZFBiPPEHFpPpgyKM3Oo5ITHXP5wM2TNQszYdVg== +troika-worker-utils@^0.52.0: + version "0.52.0" + resolved "https://registry.yarnpkg.com/troika-worker-utils/-/troika-worker-utils-0.52.0.tgz#ba5525fc444345006ebab0bc9cabdd66f1561e66" + integrity sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw== ts-api-utils@^1.3.0: version "1.4.0" @@ -7276,7 +7282,7 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -utility-types@^3.10.0: +utility-types@^3.11.0: version "3.11.0" resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.11.0.tgz#607c40edb4f258915e901ea7995607fdf319424c" integrity sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw== From a42d5e537e6c3a1eded5c56330d21d9c13e137a2 Mon Sep 17 00:00:00 2001 From: Gizmotronn Date: Tue, 19 Nov 2024 21:31:42 +1100 Subject: [PATCH 02/14] =?UTF-8?q?=F0=9F=A4=BD=F0=9F=8F=BB=F0=9F=91=A8?= =?UTF-8?q?=E2=80=8D=F0=9F=91=A8=E2=80=8D=F0=9F=91=A7=E2=80=8D=F0=9F=91=A6?= =?UTF-8?q?=20=E2=86=9D=20[SSG-69]:=20Removing=20a=20bit=20of=20superflous?= =?UTF-8?q?=20content=20&=20functionality=20that=20isn't=20being=20utilise?= =?UTF-8?q?d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/auth/onlineUsers.tsx | 49 -- app/metadata.tsx | 4 - components/Missions/CommunityMissions.tsx | 192 ------ .../Structures/Auto/deployAndReturn.tsx | 181 ------ components/Topo.tsx | 74 --- components/mining-component.tsx | 7 +- components/terrain-map.tsx | 211 ------- components/topographic-map.jsx | 313 ---------- components/topographic-map.tsx | 465 --------------- .../(planets)/classificationsGenerated.tsx | 1 + context/Inventory/UserStructures.tsx | 61 -- package.json | 18 - yarn.lock | 554 +----------------- 13 files changed, 19 insertions(+), 2111 deletions(-) delete mode 100644 app/auth/onlineUsers.tsx delete mode 100644 app/metadata.tsx delete mode 100644 components/Missions/CommunityMissions.tsx delete mode 100644 components/Structures/Auto/deployAndReturn.tsx delete mode 100644 components/Topo.tsx delete mode 100644 components/terrain-map.tsx delete mode 100644 components/topographic-map.jsx delete mode 100644 components/topographic-map.tsx delete mode 100644 context/Inventory/UserStructures.tsx diff --git a/app/auth/onlineUsers.tsx b/app/auth/onlineUsers.tsx deleted file mode 100644 index 8c40caae..00000000 --- a/app/auth/onlineUsers.tsx +++ /dev/null @@ -1,49 +0,0 @@ -'use client'; - -import React, { useState, useEffect } from "react"; -import { useSupabaseClient, useSession } from "@supabase/auth-helpers-react"; - -export default function OnlineUserList() { - const supabase = useSupabaseClient(); - const session = useSession(); // Session must be loaded first - const [onlineUsers, setOnlineUsers] = useState(0); - - useEffect(() => { - // Wait until session is ready - if (!session?.user?.id) return; - - const roomOne = supabase.channel('room_01', { - config: { - presence: { - key: session.user.id, // Ensure session user id is used correctly - }, - }, - }); - - roomOne - .on('presence', { event: 'sync' }, () => { - const currentPresenceState = roomOne.presenceState(); - const onlineUsersCount = Object.keys(currentPresenceState).length; - setOnlineUsers(onlineUsersCount); - }) - .on('presence', { event: 'join' }, ({ key, newPresences }) => { - console.log('User joined:', key, newPresences); - }) - .on('presence', { event: 'leave' }, ({ key, leftPresences }) => { - console.log('User left:', key, leftPresences); - }) - .subscribe(); - - // Clean up the subscription on unmount - return () => { - roomOne.unsubscribe(); - }; - }, [session?.user?.id, supabase]); - - return ( -
-
-

{onlineUsers} Online

-
- ); -}; \ No newline at end of file diff --git a/app/metadata.tsx b/app/metadata.tsx deleted file mode 100644 index e171f90e..00000000 --- a/app/metadata.tsx +++ /dev/null @@ -1,4 +0,0 @@ -export const metadata = { - title: 'Star Sailors', - description: 'Collect the stars', -}; \ No newline at end of file diff --git a/components/Missions/CommunityMissions.tsx b/components/Missions/CommunityMissions.tsx deleted file mode 100644 index 6757bba3..00000000 --- a/components/Missions/CommunityMissions.tsx +++ /dev/null @@ -1,192 +0,0 @@ -import { useEffect, useState } from "react"; -import { Button } from "@/components/ui/button"; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; -import { MapPin, Rocket, Navigation } from "lucide-react"; -import Link from "next/link"; -import { useActivePlanet } from "@/context/ActivePlanet"; -import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react"; -import CommunityMissionList from "./Requests"; - -const missions = [ - { id: 1, title: "Clean up Space Debris", location: "Orbit", reward: "500 credits" }, - { id: 2, title: "Alien Flora Survey", location: "Jungle", reward: "300 credits" }, - { id: 3, title: "Mineral Extraction", location: "Mountains", reward: "600 credits" }, - { id: 4, title: "Atmospheric Data Collection", location: "Sky City", reward: "400 credits" }, -]; - -const stations = [ - { id: 31011, name: "Greenhouse" }, - { id: 31012, name: "Weather balloon" }, - { id: 31013, name: "Space telescope" }, -]; - -export default function CommunityMissions() { - const supabase = useSupabaseClient(); - const session = useSession(); - const { activePlanet } = useActivePlanet(); - - const [stationStatus, setStationStatus] = useState>({}); - - useEffect(() => { - const fetchStationData = async () => { - try { - if (!activePlanet?.id) return; - - const { data, error } = await supabase - .from("inventory") - .select("item") - .eq("anomaly", activePlanet?.id) - .in("item", stations.map((station) => station.id)); - - if (error) throw error; - - const existingStationIds = new Set(data.map((row: { item: number }) => row.item)); - const statusMap: Record = {}; - - stations.forEach((station) => { - statusMap[station.id] = existingStationIds.has(station.id); - }); - - setStationStatus(statusMap); - } catch (error) { - console.error("Error fetching station data:", error); - } - }; - - fetchStationData(); - }, [activePlanet, supabase]); - - const handleBuildClick = async (stationName: string) => { - await addSpecificStructure(stationName); - }; - - async function addSpecificStructure(structureType: string) { - if (!session || !activePlanet) { - return; - } - - const structureItem = stations.find((station) => station.name === structureType); - - if (!structureItem) { - console.error("Invalid structure type"); - return; - } - - try { - const { error: inventoryError } = await supabase - .from("inventory") - .insert([ - { - owner: session?.user.id, - anomaly: activePlanet?.id, - item: structureItem.id, - quantity: 1, - configuration: { Uses: 5 }, - }, - ]); - - if (inventoryError) { - throw inventoryError; - } - - // Update the status to reflect that the station is now built - setStationStatus((prev) => ({ - ...prev, - [structureItem.id]: true, - })); - } catch (error: any) { - console.error("Error adding structure to inventory", error.message); - } - } - - return ( -
-
-

- Available community missions -

- - - - - - Community Stations - - - Community stations are facilities where users can add and collate new data, collaborate on combined missions and pool resources. If your planet or area doesn't have a station you need, you can create one for free. - - - -
    - {stations.map((station) => ( -
  • - - - {station.name} - - - {stationStatus[station.id] ? ( - - ) : ( - - )} - - -
  • - ))} -
-
-
- - {/* - - - - Available Missions - - - Complete missions to earn rewards - - - -
    - {missions.map((mission) => ( -
  • - - - {mission.title} - - Location: {mission.location} - - - -

    Reward: {mission.reward}

    - -
    -
    -
  • - ))} -
-
-
*/} -
-
- ); -}; \ No newline at end of file diff --git a/components/Structures/Auto/deployAndReturn.tsx b/components/Structures/Auto/deployAndReturn.tsx deleted file mode 100644 index adfcc2ba..00000000 --- a/components/Structures/Auto/deployAndReturn.tsx +++ /dev/null @@ -1,181 +0,0 @@ -import { useEffect, useState } from "react"; -import { - Card, - CardHeader, - CardTitle, - CardDescription, - CardContent, -} from "@/components/ui/card"; -import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar"; -import { Button } from "@/components/ui/button"; -import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react"; -import { useActivePlanet } from "@/context/ActivePlanet"; -import { RooverFromAppeears } from "@/components/Projects/Auto/Mars-Photos"; - -interface RoverData { - photos: string[]; - resourceSites: { name: string; deposits: string[] }[]; -}; - -export default function DeployRooversInitial() { - const supabase = useSupabaseClient(); - const session = useSession(); - - const { activePlanet } = useActivePlanet(); - - const newRoverToInventoryData = { - item: 23, - owner: session?.user?.id, - quantity: 1, - notes: "Created for mission 1370104", - parentItem: null, - time_of_deploy: null, - anomaly: activePlanet?.id, - configuration: '{"Uses": 8}', - }; - - const researchStructureToInventoryData = { - item: 3106, - owner: session?.user.id, - quantity: 1, - notes: "Created for introductory mission group", - anomaly: activePlanet?.id, - configuration: '{"Uses": 8}', - } - - const [isDeployed, setIsDeployed] = useState(false); - const [roverData, setRoverData] = useState(null); - const [dialogueStep, setDialogueStep] = useState(1); - - const deployRover = () => { - console.log("Deploying rover..."); - setIsDeployed(true); - setDialogueStep(2); - setTimeout(() => { - setRoverData({ - photos: Array(6).fill("/placeholder.svg?height=200&width=200"), - resourceSites: [ - { name: "Site A", deposits: ["Iron", "Copper"] }, - { name: "Site B", deposits: ["Titanium", "Aluminum"] }, - { name: "Site C", deposits: ["Silicon", "Rare Earth"] }, - ], - }); - setDialogueStep(3); - }, 5000); - }; - - useEffect(() => { - const fetchInventoryItems = async () => { - try { - const { data, error } = await supabase - .from("inventory") - .select("*") - .eq("item", 23) - .eq("owner", session?.user?.id); - - if (error) { - console.error("Error fetching inventory items: ", error); - return; - }; - - if (data && data.length > 0) { - console.log(`Rover already in inventory with ID: ${data[0].id}`); - } else { - const { error: insertError } = await supabase - .from("inventory") - .insert(newRoverToInventoryData); - - if (insertError) { - console.error("Error creating rover in inventory: ", insertError); - } else { - console.log("New rover added to inventory."); - }; - - const { error: insertResearchError } = await supabase - .from("inventory") - .insert(researchStructureToInventoryData); - - if (insertResearchError) { - console.error("Error creating research structure in inventory: ", insertResearchError); - } else { - console.log("Research structure added to inventory."); - }; - }; - } catch (error) { - console.error("Unexpected error: ", error); - } - }; - - if (session?.user?.id) { - fetchInventoryItems(); - } - }, [session, supabase, newRoverToInventoryData]); - - return ( -
- - {/* -
-
- - Deploy and monitor your automated Mars rovers. - -
-
-
*/} - -
- {dialogueStep === 1 && !isDeployed && ( -
- - - -
-
- Now that we've discovered a planet, let's deploy a rover to get a closer look! -
-
- )} - {dialogueStep === 2 && isDeployed && !roverData && ( -
-
- Now let's analyze your rover photos... -
- )} - {dialogueStep === 3 && roverData && ( - <> - -
-
- Select from the available options based on what you can see in the photo. -
- - )} - {!isDeployed && ( -
- {["Rover"].map((rover, index) => ( - - ))} -
- )} -
-
-
-
- ); -}; \ No newline at end of file diff --git a/components/Topo.tsx b/components/Topo.tsx deleted file mode 100644 index d8b19f7b..00000000 --- a/components/Topo.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { useEffect, useRef } from 'react' -import { motion } from 'framer-motion' - -type MineralDeposit = { - id: string - name: string - amount: number - position: { x: number; y: number } -} - -type Props = { - deposits: MineralDeposit[] - roverPosition: { x: number; y: number } | null - selectedDeposit: MineralDeposit | null -} - -export function TopographicMap({ deposits = [], roverPosition, selectedDeposit }: Props) { - const canvasRef = useRef(null) - - useEffect(() => { - const canvas = canvasRef.current - if (!canvas) return - - const ctx = canvas.getContext('2d') - if (!ctx) return - - // Draw topographic map (simplified version) - ctx.fillStyle = '#f0f0f0' - ctx.fillRect(0, 0, canvas.width, canvas.height) - - // Draw contour lines - ctx.strokeStyle = '#d0d0d0' - for (let i = 0; i < canvas.height; i += 20) { - ctx.beginPath() - ctx.moveTo(0, i) - ctx.lineTo(canvas.width, i) - ctx.stroke() - } - - // Draw deposits - deposits.forEach(deposit => { - ctx.fillStyle = deposit.name === 'Iron' ? '#FFE3BA' : '#5FCBC3' - ctx.beginPath() - ctx.arc(deposit.position.x, deposit.position.y, Math.sqrt(deposit.amount) / 2, 0, 2 * Math.PI) - ctx.fill() - - // Add deposit name - ctx.fillStyle = '#2C4F64' - ctx.font = '12px Arial' - ctx.textAlign = 'center' - ctx.fillText(deposit.name, deposit.position.x, deposit.position.y + Math.sqrt(deposit.amount) / 2 + 20) - }) - }, [deposits]) - - return ( -
- - {roverPosition && ( - - )} - {selectedDeposit && ( -
- )} -
- ) -} \ No newline at end of file diff --git a/components/mining-component.tsx b/components/mining-component.tsx index 1702cea9..17727840 100644 --- a/components/mining-component.tsx +++ b/components/mining-component.tsx @@ -1,7 +1,6 @@ import { useState, useEffect } from 'react'; import { MineralDepositList } from './Structures/Mining/Deposits'; import { ControlPanel } from './Structures/Mining/ControlPanel'; -import { TopographicMap } from './Topo'; // import { TerrainMap } from './terrain-map'; import { Inventory } from './Inventory'; @@ -13,7 +12,7 @@ type MineralDeposit = { level: number uses: string[] position: { x: number; y: number } -} +}; type Rover = { id: string @@ -21,13 +20,13 @@ type Rover = { speed: number efficiency: number miningLevel: number -} +}; type InventoryItem = { id: string name: string amount: number -} +}; export function MiningComponentComponent() { const [mineralDeposits, setMineralDeposits] = useState([]) diff --git a/components/terrain-map.tsx b/components/terrain-map.tsx deleted file mode 100644 index 0baa92d5..00000000 --- a/components/terrain-map.tsx +++ /dev/null @@ -1,211 +0,0 @@ -"use client" - -import React, { useRef, useState, useEffect, useMemo } from 'react' -import { Canvas, useFrame, useThree } from '@react-three/fiber' -import { OrbitControls, PerspectiveCamera, Html } from '@react-three/drei' -import * as THREE from 'three' -import { createNoise2D } from 'simplex-noise' -import alea from 'alea' -import { Button } from "@/components/ui/button" -import { Settings, Play } from 'lucide-react' - -const terrainVertexShader = ` - varying vec2 vUv; - varying float vElevation; - - void main() { - vUv = uv; - vElevation = position.z; - gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); - } -` - -const terrainFragmentShader = ` - varying vec2 vUv; - varying float vElevation; - uniform vec3 uLowColor; - uniform vec3 uHighColor; - uniform float uBands; - - void main() { - float bandedElevation = floor(vElevation * uBands) / uBands; - vec3 color = mix(uLowColor, uHighColor, bandedElevation); - gl_FragColor = vec4(color, 1.0); - } -` - -interface TerrainConfig { - seed: number; - heightScale: number; - lowColor: string; - highColor: string; - topographicBands: number; -}; - -export function Ignore(){ - return ( - <> - ) -} - -// const Terrain = ({ config }: { config: TerrainConfig }) => { -// 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(() => { -// return new THREE.ShaderMaterial({ -// vertexShader: terrainVertexShader, -// fragmentShader: terrainFragmentShader, -// uniforms: { -// uLowColor: { value: new THREE.Color(config.lowColor) }, -// uHighColor: { value: new THREE.Color(config.highColor) }, -// uBands: { value: config.topographicBands }, -// }, -// }) -// }, [config.lowColor, config.highColor, config.topographicBands]) - -// useFrame(() => { -// if (mesh.current) { -// mesh.current.material.uniforms.uLowColor.value.set(config.lowColor) -// mesh.current.material.uniforms.uHighColor.value.set(config.highColor) -// mesh.current.material.uniforms.uBands.value = config.topographicBands -// } -// }) - -// return -// } - -// const Deposit = ({ position, name, selected }) => { -// const mesh = useRef(null); - -// useFrame(({ camera }) => { -// if (mesh.current) { -// mesh.current.lookAt(camera.position) -// } -// }) - -// return ( -// -// -// -// -// -// -//
{name}
-// -//
-// ) -// } - -// const Rover = ({ position }) => { -// return ( -// -// -// -// -// ) -// } - -// const Map = ({ config, deposits, roverPosition, selectedDeposit }) => { -// return ( -// <> -// -// {deposits.map((deposit) => ( -// -// ))} -// {roverPosition && ( -// -// )} -// -// ) -// } - -// const CameraController = () => { -// const { camera } = useThree() -// useEffect(() => { -// camera.position.set(0, 15, 0.01) -// camera.lookAt(0, 0, 0) -// }, [camera]) - -// return null -// } - -// type MineralDeposit = { -// id: string -// name: string -// amount: number -// position: { x: number; y: number } -// } - -// type Props = { -// deposits: MineralDeposit[] -// roverPosition: { x: number; y: number } | null -// selectedDeposit: MineralDeposit | null -// } - -// export function TerrainMap({ deposits = [], roverPosition, selectedDeposit }: Props) { -// const [config, setConfig] = useState({ -// seed: 42, -// heightScale: 1, -// topographicBands: 20, -// lowColor: '#1e3a8a', -// highColor: '#60a5fa', -// }) -// const [showConfig, setShowConfig] = useState(false) - -// const handleGenerate = () => { -// setConfig({ ...config, seed: Math.floor(Math.random() * 1000) }) -// } - -// return ( -//
-//
-// -// -//
-// -// -// -// -// -// -// -// -//
-// ) -// } \ No newline at end of file diff --git a/components/topographic-map.jsx b/components/topographic-map.jsx deleted file mode 100644 index 2c993297..00000000 --- a/components/topographic-map.jsx +++ /dev/null @@ -1,313 +0,0 @@ -"use client" - -import React, { useRef, useState, useEffect, useMemo } from 'react' -import { Canvas, useFrame, useThree } from '@react-three/fiber' -import { OrbitControls, PerspectiveCamera } from '@react-three/drei' -import * as THREE from 'three' -import { createNoise2D } from 'simplex-noise' -import alea from 'alea' -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" -import { Label } from "@/components/ui/label" -import { Input } from "@/components/ui/input" -import { Button } from "@/components/ui/button" -import { Slider } from "@/components/ui/slider" -import { Textarea } from "@/components/ui/textarea" -import { Settings, Play, X } from 'lucide-react' - -const terrainVertexShader = ` - varying vec2 vUv; - varying float vElevation; - - void main() { - vUv = uv; - vElevation = position.z; - gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); - } -` - -const terrainFragmentShader = ` - varying vec2 vUv; - varying float vElevation; - uniform vec3 uLowColor; - uniform vec3 uHighColor; - uniform float uBands; - - void main() { - float bandedElevation = floor(vElevation * uBands) / uBands; - vec3 color = mix(uLowColor, uHighColor, bandedElevation); - gl_FragColor = vec4(color, 1.0); - } -` - -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(() => { - return new THREE.ShaderMaterial({ - vertexShader: terrainVertexShader, - fragmentShader: terrainFragmentShader, - uniforms: { - uLowColor: { value: new THREE.Color(config.lowColor) }, - uHighColor: { value: new THREE.Color(config.highColor) }, - uBands: { value: config.topographicBands }, - }, - }) - }, [config.lowColor, config.highColor, config.topographicBands]) - - useFrame(() => { - if (mesh.current) { - mesh.current.material.uniforms.uLowColor.value.set(config.lowColor) - mesh.current.material.uniforms.uHighColor.value.set(config.highColor) - mesh.current.material.uniforms.uBands.value = config.topographicBands - } - }) - - return -} - -const Structure = ({ position }) => { - const mesh = useRef() - - useFrame(({ camera }) => { - if (mesh.current) { - mesh.current.lookAt(camera.position) - } - }) - - return ( - - - - - ) -} - -const Map = ({ config }) => { - const [structures, setStructures] = useState([]) - - useEffect(() => { - const newStructures = [] - const prng = alea(config.seed + 'structures') - for (let i = 0; i < config.structureCount; i++) { - const x = (prng() - 0.5) * 20 - const y = (prng() - 0.5) * 20 - const noise2D = createNoise2D(prng) - const z = (noise2D(x * 0.05, y * 0.05) + 1) * 0.5 * config.heightScale - newStructures.push({ position: [x, y, z] }) - } - setStructures(newStructures) - }, [config.seed, config.structureCount, config.heightScale]) - - return ( - <> - - {structures.map((structure, index) => ( - - ))} - - ) -} - -const CameraController = () => { - const { camera } = useThree() - useEffect(() => { - camera.position.set(0, 15, 0.01) - camera.lookAt(0, 0, 0) - }, [camera]) - - return null -} - -const Configurator = ({ config, setConfig, onGenerate, onClose }) => { - const [configText, setConfigText] = useState(JSON.stringify(config, null, 2)) - - const handleExport = () => { - setConfigText(JSON.stringify(config, null, 2)) - } - - const handleImport = () => { - try { - const importedConfig = JSON.parse(configText) - setConfig(importedConfig) - } catch (error) { - console.error("Invalid JSON:", error) - } - } - - return ( - - - Map Configuration - - - -
-
- - setConfig({ ...config, seed: parseInt(e.target.value) })} - /> -
-
- - setConfig({ ...config, heightScale: value[0] })} - /> -
-
- - setConfig({ ...config, topographicBands: value[0] })} - /> -
-
- - setConfig({ ...config, structureCount: value[0] })} - /> -
-
- - setConfig({ ...config, lowColor: e.target.value })} - /> -
-
- - setConfig({ ...config, highColor: e.target.value })} - /> -
-
- -