1、骨骼动画原理
骨骼包括骨架和骨头,在three.js
中,骨骼模型是SkinnedMesh
就是具有骨架Skeleton
和骨头bones
的网格Mesh
,骨骼网格可以控制几何体Geometry
的顶点生成骨骼动画。
因此,要实现骨骼动画就需要先创建骨架和骨头,这一般可以通过3D建模软件自动生成,因此three.js
只需要负责解析即可,但是也需要了解骨架和骨头所组成的数据结构。
1.1、创建一个手臂
1.1.1、Bone骨头对象
THREE.Bone
是骨头关节,是骨骼Skeleton
的一部分,THREE.Bone
继承自Object3D
对象,因此可以完全等同于THREE.Object3D
对象,仅仅是语义上的区别,通过THREE.Bone
对象可以构建一个树结构,用来描述骨骼的各个关节的联系。一个父关节可以有多个子关节,父关节vertex
的变化,可以带动子关节的变化。
如下面的代码创建各个骨关节,然后创建一个骨骼系统:
var bones = []
// 肩膀
var shoulder = new THREE.Bone();
// 胳膊
var elbow = new THREE.Bone();
// 手臂
var hand = new THREE.Bone()
shoulder.add(elbow)
elbow.add(hand)
bones.push(shoulder, elbow, hand);
// 设置相对位置
elbow.position.y = 60;//胳膊相对于肩膀的位置
hand.position.y = 40;//手臂相对于胳膊的位置
var armSkeleton = new THREE.Skeleton(bones);
1.1.2、设置皮肤索引skinIndices
皮肤权重skinWeight
首先,需要创建一个几何体Geometry
然后对几何体的顶点进行皮肤索引和皮肤权重设置。
1、创建一个圆柱几何体
var geometry = new THREE.CylinderBufferGeometry(3, 7, 120, 50, 10);
2、设置皮肤索引和权重
通过遍历几何体顶点为每一个顶点设置皮肤索引和权重,Geometry
具有两个方法skinWeights
和skinIndices
,
skinWeights是一个权重值数组,对应于几何体中顶点的顺序,因此第一个skinWeight
对应于几何体中的第一个顶点由于每个顶点可以被4
个骨骼Bone
修改,因此,使用THREE.Vector4()
来表示顶点皮肤的权重,也就是第四个参数w
。
skinIndices同样对应于几何体的顶点,每个顶点最多可以有四个与之关联的骨骼,skinIndices
同样是一个THREE.Vector4
,对应骨架对象Skeleton
的属性bones
。
//根据y来分段,0~60一段、60~100一段、100~120一段
for (var i = 0; i < geometry.vertices.length; i++) {
var vertex = geometry.vertices[i]; //第i个顶点
if (vertex.y <= 60) {
// 设置每个顶点蒙皮索引属性 受根关节Bone1影响
geometry.skinIndices.push(new THREE.Vector4(0, 0, 0, 0));
// 设置每个顶点蒙皮权重属性
// 影响该顶点关节Bone1对应权重是1-vertex.y/60
geometry.skinWeights.push(new THREE.Vector4(1 - vertex.y / 60, 0, 0, 0));
} else if (60 < vertex.y && vertex.y <= 60 + 40) {
// Vector4(1, 0, 0, 0)表示对应顶点受关节Bone2影响
geometry.skinIndices.push(new THREE.Vector4(1, 0, <