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()