Threejs源码系列- Object3D

Object3D

three.js核心类

js 复制代码
const _v1 = /*@__PURE__*/ new Vector3();
const _q1 = /*@__PURE__*/ new Quaternion();
const _m1 = /*@__PURE__*/ new Matrix4();
const _target = /*@__PURE__*/ new Vector3();

const _position = /*@__PURE__*/ new Vector3();
const _scale = /*@__PURE__*/ new Vector3();
const _quaternion = /*@__PURE__*/ new Quaternion();

const _xAxis = /*@__PURE__*/ new Vector3( 1, 0, 0 );
const _yAxis = /*@__PURE__*/ new Vector3( 0, 1, 0 );
const _zAxis = /*@__PURE__*/ new Vector3( 0, 0, 1 );
  • _v1:V通用向量临时存储,例如在 translateOnAxis 方法中计算平移向量,或在坐标转换时临时存储中间结果。
  • _q1:临时存储旋转四元数,例如在 rotateOnAxis 和 rotateOnWorldAxis 方法中生成旋转四元数,避免每次调用时新建对象。
  • _m1:临时存储变换矩阵,例如在 worldToLocal 方法中计算逆矩阵,或在 lookAt 方法中生成视图矩阵。
  • _target:在 lookAt 方法中存储目标点坐标(世界空间中的注视点),统一处理参数为向量或单独坐标的情况。
  • _position:临时存储位置信息,例如在 lookAt 方法中从世界矩阵提取当前对象的位置。
  • _scale:临时存储缩放信息,主要在矩阵分解(如 applyMatrix4 中从矩阵提取缩放分量)时使用。
  • _quaternion:临时存储旋转信息,例如在矩阵分解或父对象旋转提取时使用(如 lookAt 中处理父对象旋转)。
  • _xAxis_yAxis_zAxis:预定义的 X、Y、Z 轴单位向量((1,0,0)、(0,1,0)、(0,0,1)),在 rotateX/rotateY/rotateZ 等方法中作为旋转轴使用,避免重复创建轴向量。
js 复制代码
class Object3D extends EventDispatcher {
    constructor() {}

    onBeforeShadow() {}
    onAfterShadow() {}
    onBeforeRender() {}
    onAfterRender() {}

    applyMatrix4(matrix) {}
    applyQuaternion(q) {}

    setRotationFromAxisAngle(axis, angle) {}
    setRotationFromEuler(euler) {}
    setRotationFromMatrix(m) {}
    setRotationFromQuaternion(q) {}

    rotateOnAxis(axis, angle) {}
    rotateOnWorldAxis(axis, angle) {}
    rotateX(angle) {}
    rotateY(angle) {}
    rotateZ(angle) {}

    translateOnAxis(axis, distance) {}
    translateX(distance) {}
    translateY(distance) {}
    translateZ(distance) {}

    localToWorld(vector) {}
    worldToLocal(vector) {}

    lookAt(x,y,z) {}

    add(object) {}
    remove(object) {}
    removeFromParent() {}
    clear() {}
    attach(object) {}

    getObjectById(id) {}
    getObjectByName(name) {}
    getObjectByProperty(name, value) {}
    getObjectsByProperty(name, value, result=[]) {}
    getWorldPosition(target) {}
    getWorldQuaternion(target) {}
    getWorldScale(target) {}
    getWorldDirection(target) {}

    raycast() {}

    traverse(callback) {}
    traverseVisible(callback) {}
    traverseAncestors(callback) {}

    updateMatrix() {}
    updateMatrixWorld(force) {}
    updateWorldMatrix(updateParents, updateChildren){}

    toJSON(meta) {}
    clone(recursive) {}
    copy(source, recursive=true) {}

}

updateMatrixWorld 函数、updateWorldMatrix 函数对比

相同点

  • 核心目标一致

    最终都是为了计算对象的世界矩阵(matrixWorld),该矩阵表示对象在全局坐标系中的位置、旋转和缩放的综合变换,计算公式相同:

    • 若对象无父级(parent === null),则 matrixWorld 直接等于本地矩阵(matrix)。
    • 若有父级,则 matrixWorld 是父级世界矩阵与自身本地矩阵的乘积(parent.matrixWorld × matrix)。
  • 依赖本地矩阵更新

    两者都会先检查 matrixAutoUpdate 标志,若为 true,则先调用 updateMatrix() 确保本地矩阵(matrix)是最新的(基于当前 position、rotation、scale 计算)。

  • 支持层级更新

    都能触发子对象(或父对象)的矩阵更新,确保整个层级结构的世界矩阵保持一致。

不同点

维度 updateMatrixWorld(force) updateWorldMatrix(updateParents, updateChildren)
更新方向 从当前对象向下递归更新(子对象)。 可灵活控制:向上更新父对象(updateParents)、向下更新子对象(updateChildren)。
触发条件 仅当 matrixWorldNeedsUpdatetrueforcetrue 时,才更新自身 matrixWorld 无条件计算自身 matrixWorld(只要 matrixWorldAutoUpdatetrue),不受 matrixWorldNeedsUpdate 影响。
参数作用 force:强制更新自身及所有子对象的世界矩阵(忽略 matrixWorldNeedsUpdate)。 updateParents:是否先更新所有父对象的世界矩阵;updateChildren:是否更新所有子对象的世界矩阵。
递归逻辑 自身更新后,强制子对象以 force = true 递归更新(若自身被更新过)。 仅在 updateChildrentrue 时,才递归更新子对象(子对象的 updateParents 固定为 false)。
典型使用场景 自动更新流程(如渲染前触发),依赖 matrixWorldNeedsUpdate 标志优化性能。 手动精确控制更新范围(如获取世界位置前,确保父级矩阵已更新)。

总结

  • updateMatrixWorld自动更新管道的核心 ,依赖状态标志(matrixWorldNeedsUpdate)优化性能,适合渲染循环等自动触发的场景。
  • updateWorldMatrix手动控制工具,允许精确指定更新范围(父级/子级),适合需要手动同步矩阵的场景(如获取世界位置、姿态前)。
相关推荐
答案answer1 天前
three.js着色器(Shader)实现数字孪生项目中常见的特效
前端·three.js
猪哥帅过吴彦祖1 天前
第 3 篇:让图形动起来 - WebGL 2D 变换
前端·javascript·webgl
ssshooter2 天前
WebGL 整个运行流程是怎样的?shader 是怎么从内存取到值?
前端·webgl
温宇飞6 天前
如何渲染出一个字
webgl·字体
KallkaGo6 天前
threejs复刻原神渲染(三)
前端·webgl·three.js
刘皇叔code8 天前
如何给Three.js中ExtrudeGeometry的不同面设置不同材质
webgl·three.js
vivo互联网技术8 天前
拥抱新一代 Web 3D 引擎,Three.js 项目快速升级 Galacean 指南
前端·three.js
Nicander11 天前
上帝视角看 GPU 学习笔记
webgl·gpu