import { useEffect, useMemo } from 'react'
import { Canvas, useFrame, useThree } from '@react-three/fiber'
import { OrbitControls } from '@react-three/drei'
import * as THREE from 'three'
import { AnaglyphEffect } from 'three/addons/effects/AnaglyphEffect.js'
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 (