Как создать нерегулярную 3D-многоугольную экструдированную форму React-Три волокна

#javascript #three.js #react-three-fiber

Вопрос:

До сих пор я создавал 3D-прямоугольники только с помощью инструкции useBox. Есть ли способ создать что-то вроде куска дерева «два на четыре», у которого два конца срезаны под некоторым углом, как на рисунке ниже?

введите описание изображения здесь

Код/демо-версию можно найти здесь: https://codesandbox.io/s/ragdoll-physics-forked-bntr9?file=/src/index.js

Я думаю, проблема в том, что я смешиваю различные образцы из Three.js и Реагируют-Три Волокна.

Из этого видео https://youtu.be/3eGeh_aJxMI?t=509, У меня возникла идея, что я, вероятно, мог бы создать 2D-форму многоугольника, а затем выдавливать ее в 3D. Если есть лучший подход, пожалуйста, дайте мне знать. Он использует «scene.add», но так как я нахожусь в react-three-fiber, я думаю, что мне нужно изменить эту часть, чтобы использовать существующий холст.

Приведенный ниже пример-это не та форма, которую я хочу, просто первая демонстрация с треугольником, вытянутым в 3D (в видео выше использовалась форма сердца).

Я не знаю, какой элемент использовать в инструкции return. Когда я пытаюсь «» или»», я получаю ошибки (я могу перечислить ошибки, но не уверен, что это правильные элементы для использования, поэтому пока не буду включать ошибки.) Строчный регистр «» позволяет запускать его без ошибок, но я не вижу на дисплее ни одного объекта, представляющего мой 3D-вытянутый треугольник.

 const Truss1 = () => {
  var trussPosition = [5, 5, 5];
  const trussBoard1FlatShap = new Shape();

  const x = 0;
  const y = 0;
  const moveSize = 40;
  trussBoard1FlatShap.moveTo(x - moveSize, y - moveSize);
  trussBoard1FlatShap.lineTo(x   moveSize, y - moveSize);
  trussBoard1FlatShap.lineTo(x, y   moveSize);

  var extrudeSettings = { amount: 30, bevelEnabled: false };
  var extrudeSettings2 = {steps: 2,
    depth: 16,
    bevelEnabled: true,
    bevelThickness: 1,
    bevelSize: 1,
    bevelOffset: 0,
    bevelSegments: 1}
  var material = new MeshLambertMaterial({ color: 'red'});

  var trussBoard1Extruded = new ExtrudeGeometry(trussBoard1FlatShap, extrudeSettings);  
   // I also tried extrudeSettings2 from above. 
  var trussBoard1Mesh = new Mesh(trussBoard1Extruded, material);
  trussBoard1Mesh.position.z = 55;
  
  const [cube] = useBox(() => ({ type: 'Static', position: [0, -3, -9.8], args: [0.25, 2, 0.25] }))

  return (
       <>
           <mesh scale={[8, 8, 8]} ref={trussBoard1Mesh} > 
           </mesh> 
           <Box scale={[1, 1, 1]} ref={cube} > 
           </Box> 
       </>
    )
}
    ...
    ReactDOM.render(
      <Canvas style={{ cursor: 'none' }} shadows orthographic camera={{ position: [-25, 20, 25], zoom: 25, near: 1, far: 100 }}>
        <CameraControls />
        <color attach="background" args={['#171720']} />
        <fog attach="fog" args={['#171720', 20, 70]} />
        <ambientLight intensity={0.2} />
        <pointLight position={[-10, -10, -10]} color="red" intensity={1.5} />
        <Physics iterations={15} gravity={[0, -200, 0]} allowSleep={false}>
          <Plane position={[0, -5, 0]} rotation={[-Math.PI / 2, 0, 0]} />
          <Lamp />
          <Table />
          <DynTable>{/* <texture  attach="map" image={'/images/wood_andrey-haimin-q2Fyzn-KJOQ-unsplash.jpg'} /> */}</DynTable>
          <DynShed />
          <Truss1 />
        </Physics>
      </Canvas>,
      document.getElementById('root')
    )
 

Ответ №1:

У меня есть фрилансер, чтобы придумать это:

 function Truss1() {
  var length = 14,
    width = 2,
    deg = 10,
    thickness = 0.3
  var rad = (deg * Math.PI) / 180
  var offset = Math.min(Math.tan(rad) * width, length / 2)
  var shape = new Shape()
  shape.moveTo(0, 0)
  shape.lineTo(offset, width)
  shape.lineTo(length - offset, width)
  shape.lineTo(length, 0)
  shape.lineTo(0, 0)
  const extrudeSettings = {
    curveSegments: 1,
    steps: 1,
    depth: thickness,
    bevelEnabled: false
  }

  return (
    <mesh>
      <extrudeBufferGeometry attach="geometry" args={[shape, extrudeSettings]} />
      <meshStandardMaterial color="red" side={DoubleSide} />
    </mesh>
  )
}
 

Пример Результата с одного угла:
введите описание изображения здесь