ThreeJS DOC CN

矩阵变换

Three.js 使矩阵来编码 3D 变换(包括位移、旋转、缩放等)。Object3D 的每个实例,有一个 matrix 属性,这个属性里保存着这个实例的位置、旋转角度和缩放比例等属性。这里主要介绍怎样更新一个实例的变换。

方便的属性更改和矩阵的自动更新

有两种方法来更新实例的变换

  1. 修改实例的位置(position)、四元数(quaternion)和缩放(scale)属性,然后告诉 Three.js 基于这些属性重新计算实例的 matrix
object.position = start_position;
object.quaternion = quaternion;
object.updateMatrix();

调用 updateMatrix 方法,是强制实例的 matrix 重新被计算。也可以设置

object.matrixAutoUpdate = true;

来替代 updateMatrix 方法的调用。上面这种写法每一帧都会强制计算 matrix 属性。因为,对于静物来说,我们应该像下面这样设置:

object.matrixAutoUpdate = false;
  1. 直接修改实例的 matrixMatrix4 这个类提供了许多修改它的方法。
object.matrix.setRotationFromQuaternion(quaternion);
object.matrix.setPosition(start_position);
object.matrixAutoUpdate = false;

注意:matrixAutoUpdate 这里必修设置为 false,还有必须保证不要调用 updateMatrix 方法。调用 updateMatrix 方法会与我们上面的手动修改产生冲突。

实例和全局矩阵

一个实例的 matrix 保存着相对于父实例的变换(类似于 CSS 中的 position: relativeposition: absolute?);要获取这个实例在全局坐标系中的变换,需要使用 Object3D.matrixWorld。当父实例或子实例改变变换的时候,我们可以调用 updateMatrixWorld() 来更新实例实例的 matrixWorld 属性。

旋转和四元数

Three.js 提供两种方法来呈现3D旋转:欧拉角(Euler angles) 和 四元数(Quaternion),当然还提供了它们两个之间的转换。欧拉角有个问题,叫做“万向节死锁(gimbal lock)”,问题就是他会丢失一个轴的自由度。因此,我们总是使用四元数。

先前的版本有一个属性 useQuaternion,当我们设置为 false 时,会使实例的 matrix 以欧拉角计算。现在,这种写法已经被弃用了,取而代之的是,可以使用 setRotationFromEuler 方法,来更新四元数。