seto-hp

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

Model.tsx (2942B)


      1 // Model.tsx
      2 import { FC, useState, useEffect } from "react"
      3 import { Html} from "@react-three/drei"
      4 import { GLTFLoader, GLTF } from "three/examples/jsm/loaders/GLTFLoader"
      5 import { VRMLoaderPlugin } from "@pixiv/three-vrm"
      6 import { VRMAnimationLoaderPlugin } from "@pixiv/three-vrm-animation"
      7 
      8 
      9 
     10 const Model: FC = () => {
     11   const [gltf, setGltf] = useState<GLTF>()
     12   const [progress, setProgress] = useState<number>(0)
     13 
     14   useEffect(() => {
     15     if (!gltf) {
     16       const loader = new GLTFLoader()
     17       loader.register((parser) => {
     18         return new VRMLoaderPlugin(parser)
     19       });
     20       loader.register((parser) => {
     21         return new VRMAnimationLoaderPlugin(parser)
     22       });
     23 
     24       loader.load(
     25         "/models/Setok.vrm",
     26         (tmpGltf) => {
     27           setGltf(tmpGltf)
     28           console.log("loaded")
     29         },
     30         // called as loading progresses
     31         (xhr) => {
     32           setProgress((xhr.loaded / xhr.total) * 100)
     33           console.log((xhr.loaded / xhr.total) * 100 + "% loaded")
     34         },
     35         // called when loading has errors
     36         (error) => {
     37           console.log("An error happened")
     38           console.log(error)
     39         }
     40       )
     41       let currentVrm: any = undefined;
     42       let currentVrmAnimation: any = undefined;
     43       let currentMixer:any = undefined;
     44       function load(url: string) {
     45         loader.load(
     46             url,
     47             // ロード時に呼ばれる
     48             (gltf) => {
     49                 tryInitVRM(gltf);
     50                 tryInitVRMA(gltf);
     51             },
     52             // プログレス時に呼ばれる
     53             (progress) => console.log( 
     54               "Loading model...", 
     55               100.0 * (progress.loaded / progress.total), "%" 
     56             ),
     57             // エラー時に呼ばれる
     58             (error) => console.error(error)
     59         );
     60       }
     61       function tryInitVRM(gltf: any) {
     62         const vrm = gltf.userData.vrm;
     63         if ( vrm == null ) {
     64             return;
     65         }
     66         currentVrm = vrm;
     67         scene.add(vrm.scene);
     68         initAnimationClip();
     69       }
     70 
     71       // VRMAの読み込み
     72       function tryInitVRMA(gltf: any) {
     73         const vrmAnimations = gltf.userData.vrmAnimations;
     74         if (vrmAnimations == null) {
     75             return;
     76         }
     77         currentVrmAnimation = vrmAnimations[0] ?? null;
     78         initAnimationClip();
     79       }
     80       function initAnimationClip() {
     81         if (currentVrm && currentVrmAnimation) {
     82             currentMixer = new THREE.AnimationMixer(currentVrm.scene);
     83             const clip = createVRMAnimationClip(currentVrmAnimation, currentVrm);
     84             currentMixer.clipAction(clip).play();
     85         }
     86       }
     87       // https://note.com/npaka/n/nf632f283f89a
     88       load("/animations/VRMA_01.vrma")
     89     }
     90   }, [gltf])
     91 
     92   return (
     93     <>
     94       {gltf ? (
     95         <primitive object={gltf.scene} />
     96       ) : (
     97         <Html center>{progress} % loaded</Html>
     98       )}
     99     </>
    100   )
    101 }
    102 
    103 export default Model