"use client"
import { Canvas } from '@react-three/fiber'
import { OrbitControls, Sky } from '@react-three/drei'
import { Leva, useControls } from 'leva'
import { StrictMode, useMemo } from 'react'
import * as THREE from 'three'

export default function Page() {
  return (
    <StrictMode>
      <Leva flat />
      <Canvas camera={{ fov: 50, near: 0.1, far: 200, position: [- 50, 50, 50] }} shadows>
        <Experience />
      </Canvas>
    </StrictMode>
  )
}

export function Experience() {
  const { B, H, a, depth } = useControls('Geometry', { B: { value: 40, min: 1 }, H: { value: 12, min: 0 }, a: { value: 15, min: 0, max: 75 }, depth: { value: 50, min: 0 } })

  const Hpeak = H + B / 2 * Math.tan(a * Math.PI / 180)
  const path = [[B, 0], [B, H], [B / 2, Hpeak], [0, H], [0, 0]]
  const position = [-B / 2, 0, -depth / 2]

  return <>
    <OrbitControls makeDefault />
    <directionalLight position={[1, 2, 3]} intensity={1.5} />
    <ambientLight intensity={0.5} />
    <Sky />
    <Extrusion start={[0, 0]} paths={path} position={position} depth={depth} bevelEnabled={false} />
    <axesHelper />

    <mesh rotation-x={- Math.PI * 0.5} scale={1}>
      <planeGeometry args={[B + 10, depth + 10, 1, 1]} />
      <meshStandardMaterial color="greenyellow" />
    </mesh>

  </>
}

export function Extrusion({ start = [0, 0], paths, position = [0, 0, 0], ...props }) {
  const shape = useMemo(() => {
    const shape = new THREE.Shape()
    shape.moveTo(...start)
    paths.forEach(path => shape.lineTo(...path))
    return shape
  }, [start, paths])

  return (
    <mesh position={position}>
      <extrudeGeometry args={[shape, props]} />
      <meshStandardMaterial />
    </mesh>
  )
}

Comments (0)

Loading comments...