Skip to content

架构总览 ​

Engine 3.0 的目标不是包住 Three.js,而是在其原生对象之上增加三个领域能力:ECS binding、渲染计划与鼠标事件。

唯一事实来源 ​

领域唯一事实业务入口
设备Engine 创建的 Canvas 与原生 WebGLRendererengine.canvas、engine.renderer
场景层级Object3D scene graphEntity 层级方法
ECS 身份Entity/Object3D 一对一 bindingcreateEntity、getEntity
World membershipEngine-owned Scene ancestryentity.world、world.createQuery
表现RenderView 的 World/Camera/viewport/orderengine.pipeline.addView
渲染扩展Pass Definition 的 stage/order/enabledcreatePass、engine.pipeline
交互当前 View snapshot + Raycaster 命中entity.onPointer、engine.pointer
跨模块消息EngineEvent token identitycreateEvent、onEvent、emitEvent
Undo/Redo独立 History 双栈@tripo3d/engine/history

Engine 不维护第二棵 Entity 树,也不提供 Camera、Scene、Renderer、Pass wrapper identity。

组合关系 ​

  • Engine唯一组合根与 mutation authority
    • Canvas deviceCanvas、WebGLRenderer、ResizeObserver、DPR 与 RAF/Three Timer
    • ECSWorld、Entity/Object3D binding、Component presence、System 与 Script owners
    • PipelineRenderView、两阶段 Pass Definition、固定 main/OutputPass 与私有 EffectComposer
    • Pointer原生鼠标输入、topmost View、Raycaster 与 Entity route
    • Eventsopaque token 驱动的同步 Engine-local 事件
    • Plugins仅构造期静态安装的 setup/dispose 扩展

History 不属于 Engine core。应用可创建 standalone History,并用 createHistoryPlugin(history) 在 Engine dispose 时自动清栈。Vue 也只存在于 @tripo3d/engine/vue 子入口。

Entity 与 Object3D ​

engine.createEntity(root) 对一个 parentless raw Object3D 子树执行全量 binding。每个 Object3D 恰有一个同 Engine Entity;以后使用 engine.getEntity(object) 反查。

接纳后的层级 mutation 必须走 Entity facade:

  • parent.add(child):采用 Three.js add 的世界变换语义;
  • parent.attach(child):采用 Three.js attach,尽量保持世界变换;
  • parent.remove(child)、child.removeFromParent()、parent.clear()。

Object3D scene graph 仍是层级事实,但 Engine 需要在同一 mutation 边界同步 World membership、Query、Script 与 Pointer 派生状态,因此业务不能绕过 Entity 直接改 scene graph。

帧顺序 ​

每帧入口只捕获一次有效 RenderView snapshot,System、Script、Pipeline 与 Pointer 共用该 identity:

  • frame entry捕获 time、size 与 ViewSnapshot
  • Pointer flush消费离散 FIFO 与最新 pointermove
  • System update按 Definition order 与注册顺序
  • Script update按当前 World enrollment
  • Script lateUpdateEntity-local late phase
  • System lateUpdate场景级 late phase
  • Pipeline prepare + render复用同一 views/size/time
  • frame complete结束同步帧并调度下一次 RAF

Engine 使用浏览器 requestAnimationFrame 和 Three.js Timer。首帧、resume 后首帧以及可见性中断后的首帧 delta = 0。

正向 enrollment 在 active frame 中延后到下一帧,负向 enabled/remove/destroy 事实立即阻止后续回调。World 和 Pipeline topology mutation 在 active frame 中直接拒绝,避免同一帧出现两套事实。

生命周期与所有权 ​

  • Engine 创建:Canvas、renderer、默认 World/View/Camera、内部 Composer 与默认 Pass;
  • Engine 释放:上述对象、所有 Entity 子树及其标准资源;
  • 业务创建:额外 Camera、借入的原生 Three Pass、custom RenderTarget 与非标准资源;
  • 业务释放:自己的 Camera 附属资源、原生 Pass、uniform/userData/custom material 等 Engine 不知道的边。

dispose() 先发布终态,再对所有 owner 做 best-effort 清理;单错原样抛出,多错按发生顺序形成 AggregateError,renderer 固定最后尝试释放。普通帧回调仍 fail-fast,不引入 recovery 或 retry 状态机。

如何选择扩展点 ​

需求选择
Entity-local 状态建立与资源 cleanupComponent setup Definition
单个 Entity 的局部行为Script
跨实体或场景级能力System
渲染链贡献Pass Definition + 原生 Three Pass
World/Camera/viewport 的表现绑定RenderView
同步解耦消息EngineEvent
构造期横切安装与最终清理Plugin
Undo/Redostandalone History
Vue DOM 生命周期Canvas

下一步 ​

基于 MIT 协议发布(内部使用)