Hello all, I em new to three.js, I created a React component to render 3D model, my issue is that i want to give the glb file path as props so outside the models component i can choose witch 3D model i want to render and when this path is changed, the scene and the 3D model will rerender so I will see new animation model which i provided.
Hope i explained correctly
My code
import React, { FC, useEffect, useRef, useState } from ‘react’;
import * as THREE from ‘three’;
import { OrbitControls } from ‘three/examples/jsm/controls/OrbitControls’;
import { GLTFLoader } from ‘three/examples/jsm/loaders/GLTFLoader’
import { DRACOLoader } from ‘three/examples/jsm/loaders/DRACOLoader’;
interface PenguinProps {
modelSrc: string
}
const Penguin: FC = (props) => {
const refBody = useRef(null);
const [scene] = useState(new THREE.Scene());
const [camera] = useState( new THREE.PerspectiveCamera(23, 177 / 230, 0.01, 1000))
const [initialCameraPosition] = useState(
new THREE.Vector3(15, 3, 4)
);
const [modelSrc, setModelSrc] = useState(props.modelSrc)
const [target] = useState(new THREE.Vector3(0, 0, 0));
scene.receiveShadow = true
scene.background = new THREE.Color('#1B212B');
const assetLoader = new GLTFLoader()
useEffect(() => {
setModelSrc(props.modelSrc);
assetLoader.load(
// '/penguin.glb',
modelSrc,
gltf => {
const model = gltf.scene
scene.add(model)
model.position.set(0.5, -0.2, 0)
model.rotateY(Math.PI / 2)
model.traverse(node => {
node.castShadow = true
})
},undefined, (error) => {
console.error(error)
})
}, [props.modelSrc])
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('https://www.gstatic.com/draco/v1/decoders/');
assetLoader.setDRACOLoader( dracoLoader );
dracoLoader.preload()
useEffect(()=> {
const { current: container } = refBody;
if (container) {
const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(177, 230)
container.appendChild(renderer.domElement);
camera.position.copy(initialCameraPosition);
camera.lookAt(target);
renderer.setClearColor(0xA3A3A3)
renderer.shadowMap.enabled = true
const orbit = new OrbitControls(camera, renderer.domElement)
orbit.enableZoom = false
orbit.update()
const animate = () => {
renderer.render(scene, camera);
}
renderer.setAnimationLoop(animate)
}
}, [])
const ambientLight = new THREE.HemisphereLight('#1B212B', 1)
scene.add(ambientLight)
const rectLight = new THREE.RectAreaLight( 0xffffff, 1, 20, 20 );
rectLight.position.set( 2, 0, 0 );
rectLight.lookAt( 1, 0, 0 );
scene.add( rectLight )
const pl = new THREE.PointLight(0xFFFFFF, 0.3, 20)
pl.position.set(3, 5, -0.5)
pl.castShadow = true
scene.add(pl)
const planeGeo = new THREE.PlaneGeometry(50, 50)
const planeMat = new THREE.MeshPhongMaterial(
{
dithering: true,
})
const plane = new THREE.Mesh(planeGeo, planeMat)
plane.position.set(-2, -2.5, 0)
scene.add(plane)
plane.rotateX(-0.5 * Math.PI)
plane.receiveShadow = true
return (
<div ref={refBody} ></div>
)
}
export default Penguin