การเพิ่มโมเดลให้กับฉาก (Models to a Scene)

การเพิ่มโมเดลให้กับฉาก three.js

ในบทความที่แล้ว เราตั้งค่าฟิสิกส์ จากนั้นในบทความนี้ เราจะพูดถึงการโหลดโมเดล 3 มิติ สิ่งนี้มีประโยชน์จริง ๆ เนื่องจากเราเห็นว่าการสร้างวัตถุ 3 มิติใน reactor five

ข้อกำหนดเบื้องต้น


ข้อกำหนดสำหรับบทความนี้คือ คุณควรได้ทำตามบทความ การใช้ไลบรารี่ฟิสิกส์ (Adding Physics) มาก่อน

sketchfab.com

จริงๆ แล้ว วิธีที่ดีที่สุดในการนำวัตถุเข้ามาในฉากของคุณคือสร้างมันขึ้นมาด้วยแอปพลิเคชั่นอย่าง Blender เพียงดาวน์โหลดจากอินเทอร์เน็ตแล้วอัปโหลดโมเดลที่สร้างสรรค์ของคุณไปยังฉากของคุณโดยตรง ดังนั้นฉันจะใช้เว็บไซต์นี้ที่ชื่อว่า sketchfab.com และพวกเขามีโมเดลมากมายที่นี่ บางอย่างคุณต้องจ่าย บางอย่างฟรี และ อีกหนึ่งทางเลือก คือ คุณสามารถดาวน์โหลดแอปพลิเคชันอย่าง Blender ซึ่งฟรี แล้วสร้างแบบจำลองของคุณเองแล้วส่งออก

แต่เพื่อความรวดเร็ว และเพื่อประโยชน์ของเวลา เราจะดาวน์โหลดจากอินเทอร์เน็ต เราไปค้นหาคำว่า Tesla บางส่วนมีเครื่องหมายดอลลาร์อยู่ที่มุม นี่คือสิ่งที่คุณต้องจ่ายเกี่ยวกับ สิ่งที่เรากำลังมองหาคือรุ่นที่มีสัญลักษณ์ดาวน์โหลดอยู่ที่นี่ ดังนั้นสิ่งเหล่านั้นจะเป็นสิ่งที่คุณสามารถดาวน์โหลดได้ฟรี

และเราะใช้โมเดลนี้ที่อื่นจากนายคนนี้ Steven ถ้าฉันคลิก โมเดลนี้จะปรากฏขึ้น และคุณสามารถตรวจสอบโมเดลได้ จากนั้นจะมีปุ่ม ดังนั้นะดาวน์โหลดสิ่งนั้น

สร้างไฟล์ Model.jsx

สร้างไฟล์ Model.jsx ภายในโฟลเดอร์ components เขียนโค้ดดังนี้

import { useLoader } from 'react-three-fiber';
import {
    GLTFLoader
} from 'three/examples/jsm/loaders/GLTFLoader';


const Model = props => {
    const model = useLoader(
        GLTFLoader,
        props.path
    )
    console.log(model)
    return (
        <primitive
        object={model.scene}
        {...props}    
    />
    )
}

export default Model;

ไฟล์ App.js

เพิ่มโค้ดนำเข้า Model ที่ไฟล์ App.js

import Model from './components/Model';
            <Suspense fallback={null}>
              <Model
                path='/tesla_model_3/scene.gltf'
                scale={new Array(3).fill(0.01)}
                position={[0,0.6,0]}
              />
            </Suspense>

โค้ดไฟล์ App.js

import './App.css';
import {
  Canvas, useFrame
} from 'react-three-fiber';
import { Physics } from 'use-cannon';
import { Suspense } from 'react';
import Orbit from './components/Orbit';
import Box from './components/Box';
import Background from './components/Background';
import Floor from './components/Floor';
import Bulb from './components/Bulb';
import Draggable from './components/Draggable';
import ColorPicker from './components/ColorPicker';
import Model from './components/Model';

function App() {

  return (
    <div style={{ height: '100vh', width: '100vw' }}>
      < ColorPicker />
      <Canvas
        shadowMap
        style={{ background: 'black' }}
        camera={{ position: [7, 7, 7] }}
      >
        <ambientLight intensity={0.2} />
        <Orbit />
        <axesHelper args={[5]} />
        <Physics>
          <Draggable>
            <Bulb position={[0, 3, 0]} />
            <Suspense fallback={null}>
              <Model
                path='/tesla_model_3/scene.gltf'
                scale={new Array(3).fill(0.01)}
                position={[0,0.6,0]}
              />
            </Suspense>
            <Suspense fallback={null}>
              <Box position={[-4, 1, 0]} />
            </Suspense>
            <Suspense fallback={null}>
              <Box position={[4, 1, 0]} />
            </Suspense>
          </Draggable>
          <Suspense fallback={null}>
            <Background />
          </Suspense>
          <Floor position={[0, -0.5, 0]} />
        </Physics>
      </Canvas>
    </div>
  );
}

export default App;


เพิ่ม Model


ลบโค้ดการแสดง Box ออกไป

เพิ่ม Model

              <Model
                path='/tesla_model_3/scene.gltf'
                scale={new Array(3).fill(0.01)}
                position={[4, 0.6, 0]}
              />
              <Model
                path='/tesla_model_s/scene.gltf'
                scale={new Array(3).fill(0.013)}
                position={[-4, 0.2, 0]}
              />

แก้ไขโค้ดไฟล์ Draggable.jsx

import {
    DragControls
} from 'three/examples/jsm/controls/DragControls';
import { useRef, useEffect, useState } from 'react';
import { useThree, extend } from 'react-three-fiber';
extend({ DragControls });

const Draggable = props => {
    const groupRef = useRef();
    const controlsRef = useRef();
    const [children, setChildren] = useState([])
    const { camera, gl, scene } = useThree();

    useEffect(() => {
        setChildren(groupRef.current.children)     
    }, [])

    useEffect(() => {
        controlsRef.current.addEventListener(
            'hoveron',
            e => scene.orbitControls.enabled = false
        ) 
        controlsRef.current.addEventListener(
            'hoveroff',
            e => scene.orbitControls.enabled = true
        ) 
        controlsRef.current.addEventListener(
            'dragstart',
            e => e.object.api?.mass.set(0)
        )
        controlsRef.current.addEventListener(
            'dragend',
            e => e.object.api?.mass.set(1)
        )
        controlsRef.current.addEventListener(
            'drag',
            e => {
                e.object.api.position.copy(e.object.position)
                e.object.api.velocity.set(0,0,0)
            }
        )      
    }, [children])


    return (
        <group ref={groupRef}>
            <dragControls
                transformGroup={props.transformGroup}
                ref={controlsRef}
                args={[children, camera, gl.domElement]}
            />
            {props.children}
        </group>
    )
}

export default Draggable;


แก้โค้ดไฟล์ App.js

import "./App.css";
import { Canvas, useFrame } from "react-three-fiber";
import { Physics } from "use-cannon";
import { Suspense } from "react";
import Orbit from "./components/Orbit";
import Background from "./components/Background";
import Floor from "./components/Floor";
import Bulb from "./components/Bulb";
import Draggable from "./components/Draggable";
import ColorPicker from "./components/ColorPicker";
import Model from "./components/Model";

function App() {
  return (
    <div style={{ height: "100vh", width: "100vw" }}>
      <ColorPicker />
      <Canvas
        shadowMap
        style={{ background: "black" }}
        camera={{ position: [7, 7, 7] }}
      >
        <ambientLight intensity={0.2} />
        <Orbit />
        <axesHelper args={[5]} />
        <Bulb position={[0, 3, 0]} />
        <Physics>
          <Suspense fallback={null}>
            <Draggable transformGroup>
              <Model
                path="/tesla_model_3/scene.gltf"
                scale={new Array(3).fill(0.01)}
                position={[4, 0.6, 0]}
              />
            </Draggable>
            <Draggable transformGroup>
              <Model
                path="/tesla_model_s/scene.gltf"
                scale={new Array(3).fill(0.013)}
                position={[-4, 0.2, 0]}
              />
            </Draggable>
          </Suspense>
          <Suspense fallback={null}>
            <Background />
          </Suspense>
          <Floor position={[0, -0.5, 0]} />
        </Physics>
      </Canvas>
    </div>
  );
}

export default App;

ผลลัพธ์การทำงาน


ดูผ่านเว็บไซต์ได้ที่

Leave a Reply

Your email address will not be published. Required fields are marked *