three.js 自制骨骼动画(二)
时间:2022-07-24
本文章向大家介绍three.js 自制骨骼动画(二),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
上一篇说了一下自制骨骼动画,这一篇郭先生使用帧动画让骨骼动画动起来。帧动画是一套比较完善的动画剪辑方法,详细我的api我们就不多说了,网上有很多例子,自行查找学习。在线案例请点击three.js自制骨骼动画。话不多说先上图
1. 初始化一些四元数
首先我们需要一些四元数,因为我们的动画里有很多旋转并且帧动画的旋转要求是四元数。
let q1 = this.getQuater(0,0,-Math.PI/4)
let q2 = this.getQuater(0,0,Math.PI/3)
let q3 = this.getQuater(0,0,-Math.PI/2)
let q4 = this.getQuater(0,0,0)
let q5 = this.getQuater(0,0,Math.PI/4)
let q6 = this.getQuater(0,0,Math.PI/3)
let q7 = this.getQuater(0,Math.PI/4,Math.PI/12)
let q8 = this.getQuater(0,0,-Math.PI/6)
let q9 = this.getQuater(0,-Math.PI/4,Math.PI/12)
let q10 = this.getQuater(0,Math.PI/12,0)
let q11 = this.getQuater(0,-Math.PI/12,0)
getQuater(x,y,z) {
return new THREE.Quaternion().setFromEuler(new THREE.Euler(x,y,z));
},
2. 创建关键帧轨道
关键帧轨道(KeyframeTrack)是关键帧(keyframes)的定时序列, 它由时间和相关值的列表组成, 用来让一个对象的某个特定属性动起来。这里预设好一些轨道,以便于我们是使用
let temp = new THREE.Mesh(new THREE.BoxGeometry(1), new THREE.MeshBasicMaterial());
let leg_l_t = new THREE.KeyframeTrack('temp.quaternion', [0,2,4], [q2.x,q2.y,q2.z,q2.w,q1.x,q1.y,q1.z,q1.w,q2.x,q2.y,q2.z,q2.w]);
let leg_r_t = new THREE.KeyframeTrack('temp.quaternion', [0,2,4], [q1.x,q1.y,q1.z,q1.w,q2.x,q2.y,q2.z,q2.w,q1.x,q1.y,q1.z,q1.w]);
let leg_l_b = new THREE.KeyframeTrack('temp.quaternion', [0,1.2,2,3.2,4], [q4.x,q4.y,q4.z,q4.w,q3.x,q3.y,q3.z,q3.w,q4.x,q4.y,q4.z,q4.w,q3.x,q3.y,q3.z,q3.w,q4.x,q4.y,q4.z,q4.w]);
let leg_r_b = new THREE.KeyframeTrack('temp.quaternion', [0,1.2,2,3.2,4], [q4.x,q4.y,q4.z,q4.w,q3.x,q3.y,q3.z,q3.w,q4.x,q4.y,q4.z,q4.w,q3.x,q3.y,q3.z,q3.w,q4.x,q4.y,q4.z,q4.w]);
let arm_l_t = new THREE.KeyframeTrack('temp.quaternion', [0,2,4], [q1.x,q1.y,q1.z,q1.w,q5.x,q5.y,q5.z,q5.w,q1.x,q1.y,q1.z,q1.w]);
let arm_r_t = new THREE.KeyframeTrack('temp.quaternion', [0,2,4], [q5.x,q5.y,q5.z,q5.w,q1.x,q1.y,q1.z,q1.w,q5.x,q5.y,q5.z,q5.w]);
let arm_l_b = new THREE.KeyframeTrack('temp.quaternion', [0,2,4], [q4.x,q4.y,q4.z,q4.w,q6.x,q6.y,q6.z,q6.w,q4.x,q4.y,q4.z,q4.w]);
let arm_r_b = new THREE.KeyframeTrack('temp.quaternion', [0,2,4], [q6.x,q6.y,q6.z,q6.w,q4.x,q4.y,q4.z,q4.w,q6.x,q6.y,q6.z,q6.w]);
let head = new THREE.KeyframeTrack('temp.quaternion', [0,1,2,3,4], [q7.x,q7.y,q7.z,q7.w,q8.x,q8.y,q8.z,q8.w,q9.x,q9.y,q9.z,q9.w,q8.x,q8.y,q8.z,q8.w,q7.x,q7.y,q7.z,q7.w]);
let body = new THREE.KeyframeTrack('temp.quaternion', [0,2,4], [q10.x,q10.y,q10.z,q10.w,q11.x,q11.y,q11.z,q11.w,q10.x,q10.y,q10.z,q10.w]);
3. 创建动画剪辑
动画剪辑(AnimationClip)是一个可重用的关键帧轨道集。这里为上面的关键帧轨道创建动画剪辑,并且剪辑的持续时间都是4秒
let duration = 4;
let clip_leg_l_t = new THREE.AnimationClip("default", duration, [leg_l_t]);
let clip_leg_r_t = new THREE.AnimationClip("default", duration, [leg_r_t]);
let clip_leg_l_b = new THREE.AnimationClip("default", duration, [leg_l_b]);
let clip_leg_r_b = new THREE.AnimationClip("default", duration, [leg_r_b]);
let clip_arm_l_t = new THREE.AnimationClip("default", duration, [arm_l_t]);
let clip_arm_r_t = new THREE.AnimationClip("default", duration, [arm_r_t]);
let clip_arm_l_b = new THREE.AnimationClip("default", duration, [arm_l_b]);
let clip_arm_r_b = new THREE.AnimationClip("default", duration, [arm_r_b]);
let clip_head = new THREE.AnimationClip("default", duration, [head]);
let clip_body = new THREE.AnimationClip("default", duration, [body]);
4. 创建动画混合器
动画混合器是用于场景中特定对象的动画的播放器。当场景中的多个对象独立动画时,每个对象都可以使用同一个动画混合器。
mixer[0] = new THREE.AnimationMixer(bone4);
mixer[1] = new THREE.AnimationMixer(bone5);
mixer[2] = new THREE.AnimationMixer(bone6);
mixer[3] = new THREE.AnimationMixer(bone7);
mixer[4] = new THREE.AnimationMixer(bone10);
mixer[5] = new THREE.AnimationMixer(bone11);
mixer[6] = new THREE.AnimationMixer(bone12);
mixer[7] = new THREE.AnimationMixer(bone13);
mixer[8] = new THREE.AnimationMixer(bone2);
mixer[9] = new THREE.AnimationMixer(bone3);
5. 创建动画控制器
它可以控制动画的播放、停止等功能
action[0] = mixer[0].clipAction(clip_leg_l_t);
action[1] = mixer[1].clipAction(clip_leg_r_t);
action[2] = mixer[2].clipAction(clip_leg_l_b);
action[3] = mixer[3].clipAction(clip_leg_r_b);
action[4] = mixer[4].clipAction(clip_arm_l_t);
action[5] = mixer[5].clipAction(clip_arm_r_t);
action[6] = mixer[6].clipAction(clip_arm_l_b);
action[7] = mixer[7].clipAction(clip_arm_r_b);
action[8] = mixer[8].clipAction(clip_head);
action[9] = mixer[9].clipAction(clip_body);
在需要播放动画的时候调用actionn.play()即可播放动画了,你看他跑的多high啊,是不是很简单。
最近文章有点难写,欢迎three.js的萌新提问,我会在下一期试着给出答案哦,如果没有,我就会在接下来的一段时间说一说three.js着色器材质,我相信这是一个十分有意思和具有挑战性的知识。
转载请注明地址:郭先生的博客
- TensorFlow 深度学习笔记 TensorFlow实现与优化深度神经网络
- ASP.NET的路由系统:路由映射
- ASP.NET Core的配置(3): 将配置绑定为对象[上篇]
- ASP.NET的路由系统:URL与物理文件的分离
- 使用Excel分析CloudStack使用记录
- 卷积神经网络初探索
- TensorFlow 深度学习笔记 逻辑回归 实践篇
- 黑客是如何实施暴力破解的?
- Python的初学者你现在可以自己“看”到代码的运行了!
- ASP.NET Core的配置(3): 将配置绑定为对象[下篇]
- TensorFlow 深度学习笔记 从线性分类器到深度神经网络
- 微信版12306来了!用12306微信小程序买票靠谱吗
- 无需写try/catch,也能正常处理异常
- “人工智能毁灭人类”是一种末世恐惧传染病
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Unrecognised tag: 'snapshotPolicy'
- spinrgboot缓存之缓存抽象(缓存初步体验)
- springboot之快速构建springboot应用
- NLP简报(Issue#4)
- LaTeX常用篇(一)---公式输入
- 几个Python“小伎俩”(续)
- Transformers Assemble(PART III)
- 【python-双指针】pair with target sum
- springboot开发之配置Servlet三大组件(Servlet、Filter、Listener)
- vuejs之v-html
- linux之解决使用VMWare安装centos7后无法联网问题
- c++之引用
- c++之函数的其它用法
- c++之函数重载
- c++面向对象之封装