"use client"
import { Canvas } from '@react-three/fiber'
import { Edges, Grid, OrbitControls } from '@react-three/drei'
import { Geometry, Base, Subtraction } from '@react-three/csg'
import { Leva, useControls } from 'leva'
import { StrictMode } from 'react'
import * as THREE from 'three'

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

export function Experience() {
  const { position } = useControls({ position: [0, 0, 0] })
  const { d, w } = useControls('Section', { d: { value: 8, min: 1, max: 24 }, w: { value: 6, min: 1, max: 24 } })
  const { N, B, tp, ex, ey, db } = useControls('Plate', { N: { value: 12, min: 2, max: 30 }, B: { value: 12, min: 2, max: 30 }, tp: { value: 0.5, min: 0.125, max: 4 }, ex: { value: 1, min: 0.125, max: 4 }, ey: { value: 1, min: 0.125, max: 4 }, db: { value: 0.5, min: 0.125, max: 4 }, })

  const Zs = 6;
  const tf = 0.5;
  const tw = 0.5

  const holes = {
    size: db / 2,
    locations: [[B / 2 - ex, N / 2 - ey], [-1 * (B / 2 - ex), (N / 2 - ey)], [-1 * (B / 2 - ex), -1 * (N / 2 - ey)], [(B / 2 - ex), -1 * (N / 2 - ey)]]
  }

  return <>
    <ambientLight intensity={0.5} />
    <pointLight position={[10, 10, 10]} />
    <OrbitControls />
    <Grid infiniteGrid position={[0, 0, 0]} cellColor={"#000000"} cellSize={1} sectionSize={12} />
    <group position={position}>
      <BasePlate N={N} B={B} tp={tp} holes={holes} />
      <Section w={w} d={d} tf={tf} Zs={Zs} tw={tw} />
      <Pressure scale={[B, 4, N / 2]} position={[0, -2 - tp / 2, -N / 4]} />
    </group>
  </>
}

export function Plate({ matProps, geomProps, ...props }) {
  return <mesh {...props}>
    <boxGeometry {...geomProps} />
    <meshStandardMaterial {...matProps} />
    <Edges lineWidth={1} color={"black"} />
  </mesh>
}

export function BoltHole({ r = 1, h = 1, position = [0, 0, 0], ...props }) {
  const cyl = new THREE.CylinderGeometry(1, 1, 1)

  return (
    <Subtraction position={position} scale={[r, h, r]} {...props}>
      <Geometry>
        <Base geometry={cyl}></Base>
      </Geometry>
    </Subtraction>
  )
}

export function BasePlate({ N, B, tp, color = "blue", holes }) {
  const box = new THREE.BoxGeometry(1, 1, 1);

  return (
    <mesh>
      <Geometry>
        <Base geometry={box} scale={[B, tp, N]} />
        {holes.locations.map((h, i) => <BoltHole key={i} r={holes.size} h={1.05 * tp} position={[h[0], 0, h[1]]} />)}
      </Geometry>
      <meshStandardMaterial color={color} />
    </mesh>
  )

}

export function Section({ w = 6, d = 6, tf = 1, tw = 1, Zs = 6, color = "crimson", position = [0, 0, 0] }) {
  return (<group position={position}>
    <Plate matProps={{ color: color }} scale={[w, Zs, tf]} position={[0, Zs / 2, (d - tf) / 2]} />
    <Plate matProps={{ color: color }} scale={[tw, Zs, d]} position={[0, Zs / 2, 0]} />
    <Plate matProps={{ color: color }} scale={[w, Zs, tf]} position={[0, Zs / 2, -(d - tf) / 2]} />
  </group>
  )
}

//make a 1x1 grid of arrows
export function Pressure({ position = [0, 0, 0], scale = [1, 1, 1], ...props }) {
  return (
    <group position={position} scale={scale} {...props}>
      <mesh >
        <boxGeometry args={[1, 1, 1]} />
        <meshStandardMaterial color={"black"} transparent opacity={0.5} />
      </mesh>
    </group>
  )
}

Comments (0)

Loading comments...