threejs切割模型动画

76 阅读1分钟
import * as THREE from "three";
import { useEffect, useState } from "react";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
function App() {
  useEffect(() => {
    document.querySelector(".three-demo")?.appendChild(renderer.domElement);
  }, []);
  return (
    <div>
      <div className="three-demo"></div>
      <div style={{ position: "absolute", bottom: "20px" }}>
        <button onClick={c1}>聆听</button>
        <button onClick={c2}>思考</button>
        <button onClick={c3}>发呆</button>
        <button onClick={c4}>说话</button>
      </div>
    </div>
  );
}

function c1(){
  action.actionA.play();
  action.actionB.stop();
  action.actionC.stop();
  action.actionD.stop();
}

function c2(){
  action.actionB.play();
  action.actionA.stop();
  action.actionC.stop();
  action.actionD.stop();
}

function c3(){
  action.actionC.play();
  action.actionB.stop();
  action.actionA.stop();
  action.actionD.stop();
}

function c4(){
  action.actionD.play();
  action.actionB.stop();
  action.actionC.stop();
  action.actionA.stop();
}

// 1. 创建渲染器,指定渲染的分辨率和尺寸,然后添加到body中
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.pixelRatio = window.devicePixelRatio;
renderer.setSize(window.innerWidth, window.innerHeight);

// 2. 创建场景
const scene = new THREE.Scene();
scene.background = new THREE.Color("#f5f5f5"); // 将背景色设置为白色

// 3. 创建相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
camera.position.set(0, 10, 30);
camera.lookAt(0, 0, 0);

//给场景添加太阳光
let Sun = new THREE.DirectionalLight(0xffffff, 0.2);
Sun.position.set(20, 20, 20);
Sun.castShadow = true;
//设置相机渲染面积
Sun.shadow.camera.near = 0.01;
Sun.shadow.camera.far = 60;
Sun.shadow.camera.top = 22;
Sun.shadow.camera.bottom = -22;
Sun.shadow.camera.left = -35;
Sun.shadow.camera.right = 35;
// //设置阴影分辨率
Sun.shadow.mapSize.width = 2048; // default
Sun.shadow.mapSize.height = 2048; // default
//阴影限制
Sun.shadow.radius = 1;
scene.add(Sun);


var mixer: any = null; //声明一个混合器变量
var AnimationAction;
var loader = new GLTFLoader();
var action = {
  actionA: {},
  actionB: {},
  actionC: {},
  actionD: {},
};
loader.load(
  "scence_2.glb",
  function (model: any) {
    // console.log(model);
    model.scene.traverse(function (obj: any) {
      if (obj instanceof THREE.Mesh) {
        obj.material.emissive = new THREE.Color(1, 1, 1);
        obj.material.emissiveIntensity = 1;
        obj.material.emissiveMap = obj.material.map;
      }
    });
    scene.add(model.scene);
    mixer = new THREE.AnimationMixer(model.scene);
    var modelaction = model.animations[0];
    AnimationAction = mixer.clipAction(modelaction);
    action.actionA = mixer.clipAction(
      THREE.AnimationUtils.subclip(modelaction, 'A', 15,61)
    )
    action.actionB = mixer.clipAction(
      THREE.AnimationUtils.subclip(modelaction, 'B', 275,375)
    )
    action.actionC = mixer.clipAction(
      THREE.AnimationUtils.subclip(modelaction, 'C', 66,275)
    )
    action.actionD = mixer.clipAction(
      THREE.AnimationUtils.subclip(modelaction, 'D', 534,635)
    )
  },
  onSuccessCallback,
  onProgressCallback,
  onErrorCallback
);

function onSuccessCallback(e: any) {
  console.log("e1", e);
}
function onProgressCallback(e: any) {
  console.log("e2", e);
}
function onErrorCallback(e: any) {
  console.log("e3", e);
}

//轨道控制
var controls = new OrbitControls(camera, renderer.domElement);
var clock = new THREE.Clock();
// 5. 渲染
function render() {
  controls.update();
  requestAnimationFrame(render);
  renderer.render(scene, camera); //执行渲染操作

  if (mixer !== null) {
    // 更新混合器相关的时间
    mixer.update(clock.getDelta());
  }
}

render();

export default App;