3.8 KiB
3.8 KiB
VolumeField
命名空间: XCEngine::Resources
类型: class
头文件: XCEngine/Resources/Volume/VolumeField.h
源文件: engine/src/Resources/Volume/VolumeField.cpp
描述: 体积 payload 的运行时资源对象,保存存储类型、包围盒、体素尺寸、索引边界和原始字节负载。
角色概述
VolumeField 是当前体积资源在运行时的最小封装。它不直接解析体素内容,也不暴露采样级 API;它的职责是把 loader 或 artifact 读到的 payload 与元数据安全地装进统一资源对象,供后续缓存、组件和渲染系统消费。
当前状态模型
| 字段 | 说明 |
|---|---|
m_storageKind |
当前体积存储类型,现阶段主要是 NanoVDB |
m_bounds |
体积包围盒 |
m_voxelSize |
体素尺寸 |
m_indexBounds |
体素索引边界 |
m_gridType / m_gridClass |
体积格式元数据 |
m_payload |
原始 payload 字节数组 |
两条创建路径
Create
Create(...) 接收外部只读内存并执行一次拷贝。这条路径适合调用方只临时持有输入数据,或者数据源本身不可转移所有权的场景。
CreateOwned
这是本轮新增的重要接口:
bool CreateOwned(
VolumeStorageKind storageKind,
Containers::Array<Core::uint8>&& payload,
const Math::Bounds& bounds = Math::Bounds(),
const Math::Vector3& voxelSize = Math::Vector3::Zero(),
const VolumeIndexBounds& indexBounds = VolumeIndexBounds(),
Core::uint32 gridType = 0u,
Core::uint32 gridClass = 0u);
它允许调用方把已经拥有的 payload 直接移动进 VolumeField,避免再做一份内存复制。
为什么 CreateOwned 很重要
体积资源通常 payload 很大。对 .xcvol artifact 或 .nvdb 源文件来说,loader 往往已经先把整块数据读进了 Containers::Array<Core::uint8>。如果再走一次 Create(...),就会产生第二次大块拷贝。
CreateOwned(...) 的设计价值正是:
- loader 读入 payload 后可以直接转移所有权
VolumeField仍然保持统一的内部数据结构- 避免无意义的二次复制和额外峰值内存
这类“copy path + move path”双入口,在商业引擎资源系统里非常常见,尤其适合大块二进制资源。
当前实现行为
Create(...)payload == nullptr或payloadSize == 0时失败- 会复制整份 payload
- 成功后标记资源为 valid 并更新
memorySize
CreateOwned(...)payload.Empty()时失败- 会移动
payload,不再复制 - 同样会写入元数据、标记 valid 并更新
memorySize
- 两条路径现在共享内部元数据填充逻辑
ApplyMetadata(...) GetWorldBounds()当前仍然只是GetBounds()的别名Release()依旧执行delete this
当前调用链
LoadVolumeFieldArtifact()现在会把 artifact 中读出的 payload 通过CreateOwned(...)直接转移给资源LoadNanoVDBSourceFile()也会先组装Containers::Array<Core::uint8>,再通过CreateOwned(...)交给资源RenderResourceCache会继续把 payload 上传成体积相关 GPU 资源
这说明 CreateOwned(...) 已经不是预留接口,而是 loader 的真实生产路径。
当前边界
VolumeField仍然只保存 payload,不负责体素级查询- 它仍然是一次性初始化对象,没有增量修改协议
- 运行时世界空间语义目前没有超出
bounds本身