1093 lines
21 KiB
Markdown
1093 lines
21 KiB
Markdown
# MapLibreParticleLab 20_架构设计指令书 v1
|
||
|
||
## 1. 任务基本信息
|
||
|
||
- 项目:MapLibreParticleLab
|
||
- 大阶段:`20_架构设计`
|
||
- 当前基线分支:`particle/main`
|
||
- 前置阶段:`10_架构调查` 已完成
|
||
- 前置调查报告:`docs/20_调查/10_架构调查报告_v1.md`
|
||
- 前置完成报告:`docs/报告/10_架构调查_Codex完成报告_v1.md`
|
||
- 任务性质:架构设计
|
||
- 是否允许修改生产代码:否
|
||
- 是否允许实现粒子系统:否
|
||
- 是否允许安装或升级依赖:否
|
||
- 是否允许运行会修改工程状态的构建/测试:否
|
||
|
||
---
|
||
|
||
## 2. 任务目标
|
||
|
||
基于 `10_架构调查` 已确认的真实仓库结构、MapLibre Core / Android / iOS 渲染链、CustomLayer / CustomDrawable / gfx 扩展能力、Camera/Matrix、帧驱动和生命周期事实,完成 MapLibreParticleLab 第一版正式粒子系统总体架构设计。
|
||
|
||
本阶段必须完成的是:
|
||
|
||
> 从已经确认的候选扩展点中做出明确架构选择,冻结粒子系统的模块边界、数据边界、渲染边界、线程边界、平台边界、生命周期、Mask 机制和第一阶段离线 fixture 接口,并明确哪些内容必须进入后续最小技术验证。
|
||
|
||
本阶段不是实现阶段。
|
||
|
||
不得直接创建粒子 Shader、Renderer、Source、CustomLayerHost 实现或平台业务代码。
|
||
|
||
---
|
||
|
||
## 3. 必须先读取的现有文档
|
||
|
||
开始设计前必须完整读取并遵守:
|
||
|
||
1. 根目录 `AGENTS.md`
|
||
2. `PARTICLE_BASELINE.md`
|
||
3. `docs/00_项目总则/` 当前全部有效总则
|
||
4. `docs/00_项目规范/` 当前全部有效规范
|
||
5. `docs/20_调查/10_架构调查报告_v1.md`
|
||
6. `docs/报告/10_架构调查_Codex完成报告_v1.md`
|
||
7. `docs/10_架构/` 下当前已有架构文档
|
||
8. `粒子开发记录.md`
|
||
|
||
如果现有架构文档与本次真实调查结果有冲突:
|
||
|
||
- 不得静默覆盖;
|
||
- 必须在设计文档中明确指出冲突;
|
||
- 以当前有效总则、规范和 `10_架构调查报告_v1` 中的已确认事实作为设计输入;
|
||
- 旧文档仅作为历史参考。
|
||
|
||
---
|
||
|
||
## 4. 已冻结的调查事实
|
||
|
||
本任务不得重新把下列已确认事实当成“未知问题”反复调查。
|
||
|
||
### 4.1 仓库形态
|
||
|
||
当前仓库是 MapLibre Native monorepo,不是 React Native / Expo / Bare RN App。
|
||
|
||
当前不存在:
|
||
|
||
- RN 页面
|
||
- RN MapLibre binding
|
||
- Metro
|
||
- Babel
|
||
- NativeModule / TurboModule / Fabric 粒子宿主
|
||
- JS 每帧粒子运行时
|
||
|
||
因此当前架构设计必须先以 Native Core + Android/iOS 平台薄接入为事实基础。
|
||
|
||
### 4.2 Core 主渲染链
|
||
|
||
当前已确认主链:
|
||
|
||
`mbgl::Map`
|
||
→ `RendererFrontend`
|
||
→ `UpdateParameters`
|
||
→ `Renderer`
|
||
→ `RenderTree / RenderOrchestrator`
|
||
→ `RenderLayer / LayerGroup / Drawable`
|
||
→ `gfx`
|
||
→ 平台 GPU backend
|
||
|
||
### 4.3 当前候选扩展点
|
||
|
||
已确认候选包括:
|
||
|
||
1. Core `CustomLayerHost / RenderCustomLayer`
|
||
2. Core `CustomDrawableLayer`
|
||
3. 独立 Core particle render layer
|
||
4. 现有 Source / FileSource / tile / fixture 管线的薄接入
|
||
5. Android/iOS 仅负责必要的 backend 与生命周期薄适配
|
||
|
||
本任务必须在这些真实候选基础上做架构选择。
|
||
|
||
### 4.4 平台差异
|
||
|
||
- Android 当前存在 OpenGL / Vulkan backend。
|
||
- iOS 当前存在 OpenGL / Metal backend。
|
||
- 两个平台共享 Core,但高层 CustomLayer、context、encoder、surface 生命周期不完全对称。
|
||
- Android raw `CustomLayerHost` 业务侧稳定用法尚未经过运行时验证。
|
||
- iOS 最终目标构建采用 OpenGL 还是 Metal,需要以后结合目标工程确认。
|
||
|
||
### 4.5 当前粒子实现状态
|
||
|
||
当前仓库没有:
|
||
|
||
- 正式粒子运行时
|
||
- 速度场解析器
|
||
- 粒子 shader
|
||
- GPU ping-pong particle state
|
||
- trail render target
|
||
- 正式 Grid 数据模型
|
||
- 正式粒子数据 contract
|
||
|
||
`particle-fixtures/` 当前只有占位目录。
|
||
|
||
---
|
||
|
||
## 5. 架构设计原则
|
||
|
||
### 5.1 粒子系统必须高度隔离
|
||
|
||
不得把粒子逻辑散落到:
|
||
|
||
- RasterLayer
|
||
- 普通 Style Layer
|
||
- Map 主循环
|
||
- Camera
|
||
- Source 通用逻辑
|
||
- Android MapView
|
||
- iOS MLNMapView
|
||
|
||
粒子系统必须形成清晰、可独立关闭、可独立测试、可独立演进的模块边界。
|
||
|
||
### 5.2 不复制外部闭源或其他产品实现
|
||
|
||
不得复制:
|
||
|
||
- Windy APK 代码
|
||
- Mapbox 新版闭源实现
|
||
- 其他商业产品的反编译实现
|
||
|
||
允许参考当前仓库已有 MapLibre 结构和公开 API 形成自己的架构。
|
||
|
||
### 5.3 跨平台共用优先
|
||
|
||
尽量把:
|
||
|
||
- 粒子状态
|
||
- 场数据
|
||
- 坐标转换
|
||
- 粒子更新
|
||
- 渲染资源描述
|
||
- Shader contract
|
||
- Mask contract
|
||
- 生命周期状态机
|
||
|
||
放在 Core 层。
|
||
|
||
Android / iOS 只保留不可避免的:
|
||
|
||
- backend resource 接入
|
||
- surface/context/device 生命周期
|
||
- 平台 render callback 连接
|
||
- 平台能力探测
|
||
|
||
不得分别实现两套粒子系统。
|
||
|
||
### 5.4 设计必须支持 backend 差异
|
||
|
||
第一版架构不得假定所有平台永远使用同一种 GPU API。
|
||
|
||
设计必须至少能表达:
|
||
|
||
- Android OpenGL
|
||
- Android Vulkan
|
||
- iOS OpenGL
|
||
- iOS Metal
|
||
|
||
但本阶段不要求全部 backend 同时实现。
|
||
|
||
必须区分:
|
||
|
||
- 架构必须支持
|
||
- 第一阶段实际验证
|
||
- 后续扩展
|
||
|
||
---
|
||
|
||
## 6. 必须完成的核心架构决策
|
||
|
||
本任务最重要的输出不是列候选,而是明确选择。
|
||
|
||
必须对以下问题逐项给出:
|
||
|
||
- 推荐方案
|
||
- 为什么
|
||
- 为什么不选其他候选
|
||
- 风险
|
||
- 后续验证点
|
||
|
||
### 6.1 粒子渲染核心入口
|
||
|
||
必须在以下候选中做主路线选择:
|
||
|
||
- `CustomLayerHost / RenderCustomLayer`
|
||
- `CustomDrawableLayer`
|
||
- 新建独立 Core particle render layer
|
||
- 其他基于当前源码能够成立的方案
|
||
|
||
不得只写“都可以”。
|
||
|
||
必须明确:
|
||
|
||
> 第一阶段正式主路线是什么。
|
||
|
||
如果采用“两阶段方案”,例如先 CustomLayer 验证、后独立 RenderLayer 正式化,也必须说明每阶段退出条件,不能无限双轨。
|
||
|
||
### 6.2 与现有 MapLibre RenderTree 的关系
|
||
|
||
设计必须说明粒子模块:
|
||
|
||
- 是否进入 Style / Layer 系统
|
||
- 是否进入 RenderTree
|
||
- 是否属于 translucent pass
|
||
- 是否需要自己的 render target
|
||
- 是否需要 trail accumulation
|
||
- 是否参与 MapLibre repaint
|
||
- 是否需要主动 `triggerRepaint`
|
||
- Camera 更新时如何取得同帧 Transform
|
||
|
||
### 6.3 gfx 层使用边界
|
||
|
||
明确粒子系统可使用哪些现有 gfx 能力:
|
||
|
||
- Texture2D
|
||
- DynamicTexture
|
||
- Buffer
|
||
- UniformBuffer
|
||
- RenderTarget
|
||
- DrawableBuilder
|
||
- DrawableTweaker
|
||
- Shader registry
|
||
- UploadPass
|
||
- CommandEncoder
|
||
|
||
并明确哪些需要新增粒子专用抽象。
|
||
|
||
不得直接把 backend-specific OpenGL/Vulkan/Metal 调用散到公共粒子业务逻辑。
|
||
|
||
---
|
||
|
||
## 7. 模块划分
|
||
|
||
必须给出明确的模块图和建议源码目录。
|
||
|
||
至少考虑以下职责,名称可根据现有 MapLibre 目录风格调整:
|
||
|
||
### 7.1 Particle Field
|
||
|
||
职责:
|
||
|
||
- 描述风、浪、潮、海流等矢量场
|
||
- 范围
|
||
- 网格
|
||
- 时间片
|
||
- U/V 分量
|
||
- NoData
|
||
- 有效区
|
||
- 数据版本
|
||
|
||
### 7.2 Particle Data Adapter
|
||
|
||
职责:
|
||
|
||
- 从第一阶段 fixture 转为统一 Particle Field
|
||
- 后续可替换为真实数据源
|
||
- 不把真实天气 Server 协议耦合到 Renderer
|
||
|
||
### 7.3 Particle Simulation
|
||
|
||
职责:
|
||
|
||
- 粒子状态
|
||
- age
|
||
- seed
|
||
- advection
|
||
- respawn
|
||
- field sample
|
||
- timestep
|
||
|
||
必须明确哪些在 CPU,哪些预期在 GPU。
|
||
|
||
### 7.4 Particle Render
|
||
|
||
职责:
|
||
|
||
- 粒子绘制
|
||
- trail
|
||
- fade
|
||
- opacity
|
||
- viewport
|
||
- transform
|
||
- render pass
|
||
|
||
### 7.5 Particle GPU Resources
|
||
|
||
职责:
|
||
|
||
- velocity texture
|
||
- particle state
|
||
- trail target
|
||
- uniforms
|
||
- shader
|
||
- context loss / recreate
|
||
|
||
### 7.6 Particle Mask
|
||
|
||
职责:
|
||
|
||
- GLOBAL
|
||
- OCEAN_ONLY
|
||
- Land/Ocean Mask
|
||
- mask texture / geometry contract
|
||
- mask lifecycle
|
||
|
||
### 7.7 Particle Controller / Layer State
|
||
|
||
职责:
|
||
|
||
- enable/disable
|
||
- type
|
||
- data ready
|
||
- GPU ready
|
||
- map ready
|
||
- context lost
|
||
- renderable state
|
||
- repaint request
|
||
|
||
不得让 UI 直接管理 GPU resource。
|
||
|
||
---
|
||
|
||
## 8. WeatherColorLayer 与 RasterParticleLayer 边界
|
||
|
||
必须明确区分:
|
||
|
||
### WeatherColorLayer
|
||
|
||
用于:
|
||
|
||
- 颜色场
|
||
- 栅格填色
|
||
- 连续色带
|
||
- 不承担粒子动画
|
||
|
||
### RasterParticleLayer
|
||
|
||
用于:
|
||
|
||
- 风向/海流等动态粒子表现
|
||
- 粒子状态
|
||
- 动画
|
||
- trail
|
||
- GPU simulation/render
|
||
|
||
两者可以共享:
|
||
|
||
- 数据来源
|
||
- grid metadata
|
||
- mask
|
||
- time slice
|
||
|
||
但不得共享:
|
||
|
||
- RenderLayer 实例
|
||
- 粒子 GPU 状态
|
||
- 动画生命周期
|
||
|
||
设计文档必须明确二者不是一个 Layer 的两种开关模式。
|
||
|
||
---
|
||
|
||
## 9. Wind / Wave / Tide / Current 显示域
|
||
|
||
当前规则必须进入正式架构:
|
||
|
||
### Wind
|
||
|
||
`GLOBAL`
|
||
|
||
允许覆盖:
|
||
|
||
- 海洋
|
||
- 陆地
|
||
|
||
### Wave / Tide / Current
|
||
|
||
`OCEAN_ONLY`
|
||
|
||
只显示海洋部分。
|
||
|
||
不能要求每种海洋数据各自实现一套陆地裁剪。
|
||
|
||
必须设计统一可复用:
|
||
|
||
`Land/Ocean Mask`
|
||
|
||
机制。
|
||
|
||
---
|
||
|
||
## 10. Land/Ocean Mask 架构
|
||
|
||
必须给出独立设计。
|
||
|
||
至少明确:
|
||
|
||
- Mask 数据来源属于哪个模块
|
||
- Mask 是 CPU geometry 还是 GPU texture,或允许两级实现
|
||
- Mask 坐标系
|
||
- Mask 分辨率
|
||
- viewport / tile / world 范围
|
||
- zoom 时的行为
|
||
- wrap / antimeridian
|
||
- pitch / bearing 下如何与地图保持一致
|
||
- Mask 更新条件
|
||
- Mask 缓存
|
||
- 海岸边界 artifact 风险
|
||
- context loss 后如何恢复
|
||
|
||
Mask 必须可以被:
|
||
|
||
- Wave
|
||
- Tide
|
||
- Current
|
||
- 未来其他 OCEAN_ONLY 场
|
||
|
||
共享。
|
||
|
||
不得把 Mask 写死到某一种粒子 Layer 内。
|
||
|
||
---
|
||
|
||
## 11. 第一阶段离线 fixture contract
|
||
|
||
第一阶段仍然只使用离线 fixture。
|
||
|
||
架构设计必须冻结一个“最小 fixture contract”。
|
||
|
||
至少定义:
|
||
|
||
- fixture id
|
||
- field type
|
||
- bounds
|
||
- grid width / height
|
||
- coordinate reference
|
||
- U/V 分量
|
||
- NoData
|
||
- timestamp 或 timeIndex
|
||
- data version
|
||
- mask 信息
|
||
- endian / precision,如涉及二进制
|
||
- metadata 文件
|
||
- binary/data 文件
|
||
|
||
必须覆盖现有预留 fixture:
|
||
|
||
- `uniform-east`
|
||
- `uniform-north`
|
||
- `vortex`
|
||
- `shear`
|
||
- `coastal-mask`
|
||
|
||
本阶段可以设计格式,但不得生成真实天气数据下载器。
|
||
|
||
---
|
||
|
||
## 12. 数据流设计
|
||
|
||
必须画出完整数据链:
|
||
|
||
```text
|
||
Offline Fixture
|
||
→ Decode / Validate
|
||
→ Particle Field
|
||
→ CPU/GPU Resource Preparation
|
||
→ Velocity Resource
|
||
→ Simulation
|
||
→ Render
|
||
→ MapLibre Render Pass
|
||
→ GPU
|
||
```
|
||
|
||
同时说明:
|
||
|
||
### 哪些步骤低频
|
||
|
||
例如:
|
||
|
||
- fixture load
|
||
- data decode
|
||
- texture upload
|
||
|
||
### 哪些步骤每帧
|
||
|
||
例如:
|
||
|
||
- particle simulation
|
||
- trail update
|
||
- draw
|
||
|
||
### 哪些步骤 Camera 变化时更新
|
||
|
||
例如:
|
||
|
||
- transform uniform
|
||
- viewport
|
||
- visible bounds
|
||
|
||
不得让每帧流程重新解析 field 或重建 texture。
|
||
|
||
---
|
||
|
||
## 13. 线程模型设计
|
||
|
||
必须明确:
|
||
|
||
- Map / UI thread
|
||
- worker thread
|
||
- render thread
|
||
- GPU
|
||
|
||
各自负责什么。
|
||
|
||
至少回答:
|
||
|
||
### Field 解码在哪执行
|
||
|
||
### CPU 插值在哪执行
|
||
|
||
### GPU resource 创建在哪执行
|
||
|
||
### 每帧 Simulation 在哪里执行
|
||
|
||
### Camera Matrix 从哪里读取
|
||
|
||
### Data 更新如何安全交给 Render Thread
|
||
|
||
### 如何避免大数组频繁跨线程复制
|
||
|
||
### immutable snapshot 或 resource handle 如何使用
|
||
|
||
### context loss 时哪个线程负责恢复
|
||
|
||
---
|
||
|
||
## 14. Camera / Matrix 同步设计
|
||
|
||
必须基于当前调查确认的:
|
||
|
||
- `TransformState`
|
||
- `TransformParameters`
|
||
- `PaintParameters`
|
||
- `CustomLayerRenderParameters`
|
||
|
||
设计粒子同帧同步方式。
|
||
|
||
至少覆盖:
|
||
|
||
- pan
|
||
- zoom
|
||
- bearing
|
||
- pitch
|
||
- resize
|
||
- pixel ratio
|
||
- world wrap
|
||
- antimeridian
|
||
- projection/unprojection
|
||
|
||
必须明确:
|
||
|
||
> 粒子 Renderer 读取的是 MapLibre 当前 render frame 的 transform,而不是由另一个独立 UI/JS 动画循环猜 Camera。
|
||
|
||
---
|
||
|
||
## 15. 帧驱动与动画时钟
|
||
|
||
必须正式定义谁驱动粒子动画。
|
||
|
||
至少说明:
|
||
|
||
- 是否依赖 MapLibre render loop
|
||
- 粒子活动时如何持续请求下一帧
|
||
- 粒子关闭时如何停止额外 repaint
|
||
- 地图静止但粒子活动时如何继续帧
|
||
- App 后台如何暂停
|
||
- View 不可见如何暂停
|
||
- Map/Style 销毁如何停止
|
||
- context loss 如何停止并恢复
|
||
|
||
不得设计独立于 MapLibre Renderer 的第二套无同步动画循环作为正式主路线。
|
||
|
||
---
|
||
|
||
## 16. GPU 粒子状态模型
|
||
|
||
本阶段必须设计,但不实现。
|
||
|
||
至少定义:
|
||
|
||
- particle count
|
||
- position state
|
||
- age
|
||
- seed/random
|
||
- current / next state
|
||
- velocity sampling
|
||
- timestep
|
||
- respawn
|
||
- viewport clipping
|
||
- field bounds
|
||
- NoData 处理
|
||
|
||
如果采用 GPU simulation,需要明确:
|
||
|
||
- ping-pong resource
|
||
- compute 或 render-pass simulation
|
||
- backend capability gate
|
||
- 无 compute 时的 fallback 思路
|
||
|
||
如果第一阶段不使用 compute,也必须明确原因。
|
||
|
||
---
|
||
|
||
## 17. Trail 架构
|
||
|
||
必须说明是否第一阶段就包含 trail。
|
||
|
||
如果包含:
|
||
|
||
至少设计:
|
||
|
||
- accumulation target
|
||
- fade pass
|
||
- particle draw pass
|
||
- compositing
|
||
- resize
|
||
- camera movement
|
||
- zoom/bearing/pitch 改变时旧 trail 如何处理
|
||
- context loss
|
||
- clear conditions
|
||
|
||
如果第一阶段不包含 trail:
|
||
|
||
必须明确第一阶段视觉范围,并说明后续如何扩展。
|
||
|
||
---
|
||
|
||
## 18. 生命周期状态机
|
||
|
||
必须设计粒子 Layer/Renderer 状态机。
|
||
|
||
建议至少包含:
|
||
|
||
- DISABLED
|
||
- WAITING_MAP
|
||
- WAITING_FIELD
|
||
- PREPARING
|
||
- READY
|
||
- RENDERING
|
||
- PAUSED
|
||
- CONTEXT_LOST
|
||
- ERROR
|
||
|
||
可以调整名称,但必须覆盖:
|
||
|
||
- Map 创建
|
||
- Style reload
|
||
- 数据更新
|
||
- App background
|
||
- App foreground
|
||
- Surface recreation
|
||
- GPU context loss
|
||
- Layer removal
|
||
- Map destroy
|
||
|
||
必须明确资源释放和重新创建责任。
|
||
|
||
---
|
||
|
||
## 19. Android / iOS 薄接入
|
||
|
||
### 19.1 Android
|
||
|
||
架构必须说明:
|
||
|
||
- Java/Kotlin 业务 API 应保持多薄
|
||
- JNI 是否需要新增稳定 wrapper
|
||
- raw `long CustomLayerHost` 是否允许进入正式接口
|
||
- OpenGL / Vulkan backend 差异如何封装
|
||
- SurfaceView / TextureView 生命周期影响
|
||
- requestRender 如何连接
|
||
|
||
不得把 Android 平台代码变成第二套 particle engine。
|
||
|
||
### 19.2 iOS
|
||
|
||
必须说明:
|
||
|
||
- `MLNCustomStyleLayer`
|
||
- `MLNCustomDrawableStyleLayer`
|
||
- Metal / OpenGL resource
|
||
- CADisplayLink / MapLibre render callback
|
||
- backend resource
|
||
|
||
在正式架构中的位置。
|
||
|
||
不得因为 iOS 高层 CustomStyleLayer 比 Android 方便,就把 Core 共用逻辑放到 ObjC/Swift。
|
||
|
||
---
|
||
|
||
## 20. 公共 API 设计
|
||
|
||
本阶段需要设计未来供宿主使用的最小 API,但不实现。
|
||
|
||
例如需要能够表达:
|
||
|
||
- 创建/删除粒子 layer
|
||
- enable/disable
|
||
- 设置 field
|
||
- 设置 display domain
|
||
- 设置 particle options
|
||
- 设置 mask
|
||
- 数据更新
|
||
- 状态查询
|
||
|
||
必须遵循 MapLibre 当前 API 风格。
|
||
|
||
公共 API 不得暴露:
|
||
|
||
- GL texture id
|
||
- VkImage
|
||
- MTLTexture
|
||
- backend-specific command encoder
|
||
- raw native host pointer
|
||
|
||
除非是严格内部接口。
|
||
|
||
---
|
||
|
||
## 21. 配置与可调参数
|
||
|
||
架构设计应区分:
|
||
|
||
### 稳定业务参数
|
||
|
||
例如:
|
||
|
||
- particle count
|
||
- speed factor
|
||
- lifetime
|
||
- opacity
|
||
- trail fade
|
||
|
||
### 内部 backend 参数
|
||
|
||
例如:
|
||
|
||
- texture format
|
||
- buffer alignment
|
||
- workgroup size
|
||
- render target format
|
||
|
||
业务层不得直接依赖 backend 参数。
|
||
|
||
---
|
||
|
||
## 22. 错误与降级策略
|
||
|
||
设计必须定义:
|
||
|
||
- field 无效
|
||
- field 越界
|
||
- mask 无效
|
||
- GPU resource 创建失败
|
||
- backend 不支持
|
||
- context loss
|
||
- shader 创建失败
|
||
- memory pressure
|
||
|
||
发生时的行为。
|
||
|
||
原则:
|
||
|
||
- 地图本身不得因此崩溃
|
||
- 粒子层可以禁用或进入 ERROR
|
||
- 不得破坏其他 Style Layer
|
||
- 资源失败后必须可安全释放
|
||
- 是否自动重试必须明确
|
||
|
||
---
|
||
|
||
## 23. 性能预算
|
||
|
||
本阶段不要求真实性能测试,但必须建立设计预算。
|
||
|
||
至少定义需要后续验证的指标:
|
||
|
||
- FPS
|
||
- frame time
|
||
- CPU time
|
||
- GPU time
|
||
- particle count
|
||
- texture memory
|
||
- buffer memory
|
||
- field upload time
|
||
- context recreation time
|
||
|
||
并明确:
|
||
|
||
- 哪些属于第一阶段 gate
|
||
- 哪些属于后续优化
|
||
|
||
不得写未经测试的“能稳定 60 FPS”等结论。
|
||
|
||
---
|
||
|
||
## 24. 后续最小技术验证清单
|
||
|
||
架构设计完成后,必须给出“最少数量”的技术验证。
|
||
|
||
只列会影响实现路线的关键验证。
|
||
|
||
可能包括但不限于:
|
||
|
||
- Android CustomLayerHost 稳定生命周期
|
||
- Android OpenGL/Vulkan 中粒子资源能否共用 MapLibre render context
|
||
- iOS Metal / OpenGL CustomStyleLayer 同帧资源接入
|
||
- context loss / Surface recreate
|
||
- MapLibre transform 下的同帧矩阵同步
|
||
- trail render target
|
||
- OCEAN_ONLY mask
|
||
|
||
不得为了保险列几十个验证任务。
|
||
|
||
必须按:
|
||
|
||
1. 是否阻塞正式实现
|
||
2. 是否会改变架构
|
||
3. 最小验证方式
|
||
|
||
进行排序。
|
||
|
||
---
|
||
|
||
## 25. 必须明确拒绝的架构
|
||
|
||
设计报告必须专门列出“不采用的方案”。
|
||
|
||
至少评估:
|
||
|
||
- React Native / JS 每帧粒子
|
||
- MapView 外部 Overlay
|
||
- 每种海洋场各自一套 Mask
|
||
- 直接改造现有 RasterLayer 承担粒子
|
||
- Android/iOS 各写一套独立粒子引擎
|
||
- 每帧重新创建 field texture
|
||
- 每帧大数组跨 Java/ObjC/JS 边界
|
||
- backend-specific GPU API 暴露到公共业务 API
|
||
|
||
说明拒绝原因。
|
||
|
||
---
|
||
|
||
## 26. 必须生成的架构图
|
||
|
||
正式设计文档至少包含:
|
||
|
||
### 26.1 粒子系统总体架构图
|
||
|
||
### 26.2 Core 模块边界图
|
||
|
||
### 26.3 Offline Fixture → GPU 数据流图
|
||
|
||
### 26.4 每帧渲染链图
|
||
|
||
### 26.5 Camera / Matrix 同步图
|
||
|
||
### 26.6 Android 薄接入图
|
||
|
||
### 26.7 iOS 薄接入图
|
||
|
||
### 26.8 Land/Ocean Mask 共用图
|
||
|
||
### 26.9 生命周期状态机图
|
||
|
||
全部使用 Markdown / Mermaid / ASCII 均可。
|
||
|
||
图中不得补入当前不存在且未经设计定义的外部系统。
|
||
|
||
---
|
||
|
||
## 27. 正式设计结论必须冻结的内容
|
||
|
||
设计报告结尾必须列出“架构冻结项”。
|
||
|
||
至少包括:
|
||
|
||
- 主粒子渲染路线
|
||
- Core / Platform 分工
|
||
- Layer 边界
|
||
- WeatherColorLayer / RasterParticleLayer 边界
|
||
- Field 模型
|
||
- Fixture contract
|
||
- Wind GLOBAL
|
||
- Wave/Tide/Current OCEAN_ONLY
|
||
- Land/Ocean Mask
|
||
- Frame Driver
|
||
- Camera Matrix 来源
|
||
- GPU resource 生命周期
|
||
- Android/iOS 薄接入原则
|
||
- 第一阶段 backend 验证范围
|
||
- 第一阶段粒子视觉范围
|
||
- 后续最小技术验证项
|
||
|
||
冻结项是后续 `30_最小技术验证` 和实现任务的依据。
|
||
|
||
---
|
||
|
||
## 28. 不得在本阶段冻结的内容
|
||
|
||
以下如果没有运行时证据,不得假装已确定:
|
||
|
||
- 最终 FPS
|
||
- 最终最大 particle count
|
||
- 最终最佳 texture format
|
||
- 最终 Vulkan/Metal compute workgroup
|
||
- 具体 GPU 厂商优化
|
||
- 真实天气 Server 数据格式
|
||
- NavSea / RN 最终 Host API
|
||
- 最终生产设备能力矩阵
|
||
|
||
这些只能记录为后续验证项。
|
||
|
||
---
|
||
|
||
## 29. 禁止事项
|
||
|
||
本任务禁止:
|
||
|
||
- 修改生产源码
|
||
- 创建粒子 Renderer 实现
|
||
- 创建粒子 Shader
|
||
- 创建 GPU Buffer/Texture 实现
|
||
- 创建 CustomLayerHost 实现
|
||
- 创建 Android JNI 粒子模块
|
||
- 创建 iOS 粒子类
|
||
- 修改现有 MapLibre Renderer
|
||
- 修改 RasterLayer
|
||
- 修改 Style parser
|
||
- 安装/升级依赖
|
||
- 改 Gradle
|
||
- 改 Pod
|
||
- 改 CMake
|
||
- 改 package lock
|
||
- 运行会写入工程状态的自动构建
|
||
- 顺手修复无关问题
|
||
|
||
本任务只允许:
|
||
|
||
- 阅读
|
||
- 设计
|
||
- 生成/更新架构文档
|
||
- 生成 Codex 完成报告
|
||
- 追加 `粒子开发记录.md`
|
||
|
||
---
|
||
|
||
## 30. 必做输出
|
||
|
||
### 30.1 正式架构文档
|
||
|
||
生成:
|
||
|
||
`docs/10_架构/20_粒子系统总体架构设计_v1.md`
|
||
|
||
如果同名文件已经存在,不得覆盖,应递增版本号。
|
||
|
||
该文件是本阶段最主要的正式输出。
|
||
|
||
### 30.2 Codex 完成报告
|
||
|
||
生成:
|
||
|
||
`docs/报告/20_架构设计_Codex完成报告_v1.md`
|
||
|
||
如果同名文件已经存在,不得覆盖,应递增版本号。
|
||
|
||
### 30.3 开发记录
|
||
|
||
追加:
|
||
|
||
`粒子开发记录.md`
|
||
|
||
记录:
|
||
|
||
- `20_架构设计` 已执行
|
||
- 生成的架构文档
|
||
- 核心架构选择
|
||
- 是否需要进入最小技术验证
|
||
- 仍未确认的关键事项
|
||
|
||
不得重写历史记录。
|
||
|
||
---
|
||
|
||
## 31. 不主动创建 Step
|
||
|
||
本任务不主动新建或修改 `docs/50_Step记录/` 下的 Step 文件。
|
||
|
||
除非用户已有明确 Step 指令,否则只生成本任务规定的:
|
||
|
||
- 架构文档
|
||
- Codex 完成报告
|
||
- 开发记录追加
|
||
|
||
---
|
||
|
||
## 32. Codex 完成报告格式
|
||
|
||
必须逐项报告:
|
||
|
||
- `已完成`
|
||
- `未完成`
|
||
- `无法验证`
|
||
|
||
至少包括:
|
||
|
||
1. 读取前置文档
|
||
2. 候选渲染路线比较
|
||
3. 主路线选择
|
||
4. Core 模块设计
|
||
5. Data/Field contract
|
||
6. GPU resource 设计
|
||
7. Mask 设计
|
||
8. 线程模型
|
||
9. Camera/Matrix 同步
|
||
10. 帧驱动
|
||
11. Android 薄接入
|
||
12. iOS 薄接入
|
||
13. 生命周期
|
||
14. 错误/降级
|
||
15. 性能预算
|
||
16. 最小技术验证清单
|
||
17. 正式架构冻结项
|
||
18. 生成文件
|
||
19. 是否修改生产代码
|
||
20. 是否修改依赖或构建配置
|
||
|
||
---
|
||
|
||
## 33. 完成标准
|
||
|
||
本任务完成,不是指“列出几个可选方案”。
|
||
|
||
必须达到:
|
||
|
||
> 已经基于当前 MapLibreParticleLab 的真实 MapLibre Native 架构,为粒子系统选择唯一主架构路线,并冻结 Core / Platform 边界、Particle Field、Simulation、Render、GPU Resource、Mask、Frame Driver、Camera Matrix、生命周期和第一阶段 fixture contract,使下一阶段能够直接针对少量关键未知项做最小技术验证,而不再重新讨论总体架构。
|
||
|
||
如果仍然存在两个以上彼此冲突的主路线且没有选择,则本任务不能标记为完成。
|
||
|
||
---
|
||
|
||
## 34. 下一阶段判定
|
||
|
||
设计结束时必须明确选择:
|
||
|
||
### A. 直接进入实现
|
||
|
||
只有所有关键架构假设都已有运行时证据时才允许。
|
||
|
||
或:
|
||
|
||
### B. 进入 `30_最小技术验证`
|
||
|
||
如果仍存在会影响实现成败的 backend、CustomLayer、context、matrix、trail 或 Mask 等运行时未知项,应选择 B。
|
||
|
||
按照当前调查结果,预期大概率选择 B,但必须由本次设计结果最终判断。
|