import { useEffect, useMemo } from 'react' import { Canvas } from '@react-three/fiber' import { OrbitControls } from '@react-three/drei' import * as THREE from 'three' import type { MeshData } from './mesh/types' import { VIEW_MODES } from './viewModes' import type { ViewMode } from './viewModes' const PLAIN_COLOR = '#8fb4d9' function MeshObject({ mesh, mode }: { mesh: MeshData; mode: ViewMode }) { const geometry = useMemo(() => { const g = new THREE.BufferGeometry() g.setAttribute('position', new THREE.Float32BufferAttribute(mesh.positions, 3)) g.setIndex(new THREE.Uint32BufferAttribute(mesh.indices, 1)) if (mesh.normals) { g.setAttribute('normal', new THREE.Float32BufferAttribute(mesh.normals, 3)) } else { g.computeVertexNormals() } if (mesh.colors) { g.setAttribute('color', new THREE.Float32BufferAttribute(mesh.colors, 3)) } // Center and scale to a consistent size so the fixed camera always frames it g.center() g.computeBoundingSphere() return g }, [mesh]) useEffect(() => () => geometry.dispose(), [geometry]) const scale = 1.6 / (geometry.boundingSphere?.radius || 1) const useVertexColors = !!mesh.colors // material settings are baked into the compiled shader; remount materials // when they change so three.js rebuilds the program const matKey = `${mode}-${useVertexColors ? 'vc' : 'plain'}` return ( {(mode === 'shaded' || mode === 'both') && ( )} {(mode === 'wire' || mode === 'both') && ( )} {mode === 'points' && ( )} ) } export function MeshView({ mesh, mode, onModeChange, }: { mesh: MeshData mode: ViewMode onModeChange: (mode: ViewMode) => void }) { return ( <>
{VIEW_MODES.map((m) => ( ))}
) }