Cocos引擎RenderScene模型管理

Cocos引擎RenderScene管理模型的方式

cocos 4.0.0之前的版本都是RenderScene管理Model数组,Model的变化矩阵数据从Node节点树获得,类图和时序图总结如下。

1 类图

classDiagram
    class Node {
        +_parent: Node
        -_children: Node[]
        -_worldMatrix: Mat4
        +isTransformDirty(): boolean
        +updateWorldTransform(): void
        +getWorldMatrix(): Mat4
    }
    class Model {
        #_type: ModelType
        #_scene: RenderScene
        #_subModels: SubModel[]
        #_modelBounds: AABB
        #_worldBounds: AABB
        #_node: Node
        #_transform: Node
        #_enabled: boolean
        #_visFlags: number
        #_priority: number
        #_castShadow: boolean
        #_receiveShadow: boolean
        #_updateStamp: number
        #_reflectionProbeId: number
        #_reflectionProbeBlendId: number
        #_tetrahedronIndex: number
        #_localBuffer: Buffer
        #_localSHBuffer: Buffer
        #_worldBoundBuffer: Buffer
        #_device: Device
        #_descriptorSetCount: number
        #_isDynamicBatching: Boolean
        #_worldBoundBuffer: Buffer
        #_lightmap: Texture2D
        #_lightmapUVParam: Vec4
        +initialize(): void
        +attachToScene(scene): void
        +detachFromScene(): void
        +updateTransform(stamp): void
        +updateWorldBound(): void
        +updateUBOs(stamp): void
    }
    
    class RenderScene {
        -_models: Model[]
        -_lodStateCache: LodStateCache
        +addModel(model): void
        +removeModel(model): void
        +update(stamp): void
    }
    class MorphModel {
        -_morphRenderingInstance: MorphRenderingInstance
        职责:形变(Morph)渲染
    }
    class SkinningModel {
        -_bufferIndices: number[]
        -_buffers: Buffer[]
        -_joints: JointInfo[]
        -_dataArray: float*
        -_realTimeTextureMode: boolean
        -_realTimeJointTexture: RealTimeJointTexture
        职责:实时骨骼蒙皮(GPU Skinning)
    }
    class BakedSkinningModel {
        -_jointsMedium: JointsInfo
        -_instAnimInfoIdx: number
        -_skeleton: Skeleton
        -_mesh: Mesh
        -_isUploadedAnim: boolean
        +uploadedAnim: AnimationClip
        职责:预烘焙骨骼动画(BakedSkinning)
    }
    RenderScene "1" *-- "0..*" Model
    Model --> Node
    Model <|-- MorphModel : 继承
    MorphModel <|-- SkinningModel : 继承(final)
    MorphModel <|-- BakedSkinningModel : 继承(final)

2 时序图

2.1 新增模型

sequenceDiagram
    participant C as MeshRenderer
    participant Root as Root
    participant N as Node
    participant M as Model
    participant RS as RenderScene

    Note over C: 节点激活 / onLoad 时触发
    C->>Root: createModel(ModelType)
    alt 池中有空闲
        Root-->>C: 复用 pooled Model
    else 无空闲
        Root-->>C: new Model()
    end
    C->>M: node = node, transform = node
    Note over N: Node 仅被引用,<br/>作为 Model 的变换来源
    C->>M: visFlags / priority 等初始化

    C->>RS: addModel(model)
    RS->>M: attachToScene(this)
    Note over M: scene = scene<br/>_localDataUpdated = true
    RS->>RS: _models.push(model)
    Note over RS: 模型进入待渲染列表

2.2 删除模型

sequenceDiagram
    participant C as MeshRenderer
    participant Root as Root
    participant M as Model
    participant RS as RenderScene

    Note over C: 组件 onDisable(禁用)时
    C->>C: _detachFromScene()
    C->>RS: scene.removeModel(model)
    RS->>RS: 查找到 index
    RS->>RS: _lodStateCache.removeModel(model)
    RS->>M: detachFromScene()
    Note over M: scene = null
    RS->>RS: _models.splice(index, 1)
    Note over RS: 模型退出渲染列表

    Note over C: 组件 onDestroy(销毁)时
    C->>Root: destroyModel(model)
    Root->>M: destroy()
    Root-->>C: 归还对象池(可选复用)
    C->>C: _model = null, _models.length = 0

2.3 每帧更新模型

sequenceDiagram
    participant Root as Root(每帧)
    participant RS as RenderScene
    participant M as Model
    participant N as Node

    Root->>RS: update(stamp)

    loop 遍历 _models
        alt model.enabled == true
            RS->>M: updateTransform(stamp)
            alt node.hasChangedFlags || node.isTransformDirty()
                M->>N: updateWorldTransform()
                Note over M: _modelBounds.transform
                Note over M: _localDataUpdated = true
            end

            RS->>M: updateUBOs(stamp)
            M->>M: subModels[i].update() / updateSHUBOs()
            M->>N: 读 node._mat
            Note over M: updateInstancedWorldMatrix()
        else enabled == false
            Note over RS: 跳过
        end
    end

    Note over RS: _lodStateCache.updateLodState()