使用GLTF格式文件动画创建动画
1.demo效果2. 实现要点2.1 加载GLTF文件2.2 创建AnimationMixer动画2.3 render中更新动画 3. demo代码1.demo效果
2. 实现要点
2.1 加载GLTF文件
加载gltf文件,首先要引入GLTF加载器,需要在vue文件中显示引入
import {GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
加载模型代码如下
// 创建模型createModels() {const THIS = thisconst publicPath = process.env.BASE_URLconst loader = new GLTFLoader()loader.load(`${publicPath}models/gltf/hand.gltf`, model => {//加载完成回调处理...})}
2.2 创建AnimationMixer动画
动画混合器(AnimationMixer) 相当于场景中不同对象的动画的调度器。当场景中的多个对象独立动画时,所有动画都可以通过动画混合器来控制何时启用动画何时停止动画
// 新建一个AnimationMixerthis.mixer = new THREE.AnimationMixer(model.scene)const clip = model.animations[0] //将第1帧动画设置为动画剪辑对象const action = this.mixer.clipAction(clip) //使用动画剪辑对象创建AnimationAction对象this.mixer.timeScale = 0.5 //默认1,可以调节播放速度action.setDuration(2).play() //设置单此循环的持续时间(setDuration也可以调节播放速度)并开始动画
2.3 render中更新动画
render() {if (this.mixer) {const delta = this.clock.getDelta() // 获取自上次调用的时间差this.mixer.update(delta)}this.renderer.render(this.scene, this.camera)requestAnimationFrame(this.render)}
3. demo代码
<template><div><div id="container" /></div></template><script>import * as THREE from 'three'import {GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'export default {data() {return {clock: new THREE.Clock(),mixer: null,camera: null,scene: null,renderer: null}},mounted() {this.init()},methods: {formatTooltip(val) {return val},// 初始化init() {this.createScene() // 创建场景this.createModels() // 创建模型this.createLight() // 创建光源this.createCamera() // 创建相机this.createRender() // 创建渲染器this.render() // 渲染},// 创建场景createScene() {this.scene = new THREE.Scene()},// 创建模型createModels() {const THIS = thisconst publicPath = process.env.BASE_URLconst loader = new GLTFLoader()loader.load(`${publicPath}models/gltf/hand.gltf`, model => {THIS.scene.add(model.scene)// 新建一个AnimationMixerthis.mixer = new THREE.AnimationMixer(model.scene)const clip = model.animations[0] //将第1帧动画设置为动画剪辑对象const action = this.mixer.clipAction(clip) //使用动画剪辑对象创建AnimationAction对象this.mixer.timeScale = 0.5 //默认1,可以调节播放速度action.setDuration(2).play() //设置单此循环的持续时间(setDuration也可以调节播放速度)并开始动画})},// 创建光源createLight() {// 环境光const ambientLight = new THREE.AmbientLight(0x111111) // 创建环境光this.scene.add(ambientLight) // 将环境光添加到场景const directionLight = new THREE.DirectionalLight(0xffffff)directionLight.position.set(300, 200, 300)directionLight.intensity = 1.5this.scene.add(directionLight)},// 创建相机createCamera() {const element = document.getElementById('container')const width = element.clientWidth // 窗口宽度const height = element.clientHeight // 窗口高度const k = width / height // 窗口宽高比// PerspectiveCamera( fov, aspect, near, far )this.camera = new THREE.PerspectiveCamera(45, k, 0.1, 1000)this.camera.position.set(5, 5, 5) // 设置相机位置this.camera.lookAt(new THREE.Vector3(0, 0, 0)) // 设置相机方向this.scene.add(this.camera)},// 创建渲染器createRender() {const element = document.getElementById('container')this.renderer = new THREE.WebGLRenderer({antialias: true, alpha: true })this.renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸this.renderer.setClearColor(0xeeeeee, 1) // 设置背景颜色element.appendChild(this.renderer.domElement)},render() {if (this.mixer) {const delta = this.clock.getDelta() // 获取自上次调用的时间差this.mixer.update(delta)}this.renderer.render(this.scene, this.camera)requestAnimationFrame(this.render)}}}</script><style>#container {position: absolute;width: 100%;height: 100%;}</style>