# STEP-055 Android 真实 WeatherV2 风场综合可视化 v4 状态:**IMPLEMENTED / WAITING_ANDROID_VALIDATION** Starting HEAD:`97aa019f6ff07d1b91e17c46ad0e6e6c0cd339d5` ## 已确认问题 Float State 已使真实粒子恢复运动,但旧正式路径会在无效或越界时回固定 seed;同时 particle draw 以固定 world `streakLength` 构造短棍,viewport-sized Trail 又按全球 world 坐标使用。结果是密度向边缘集中、缩放后出现粗短线与闪烁,且每帧固定 fade 受 FPS 影响。 ## 本轮修复 - State A/B 保持 Float,Trail A/B 保持 UnsignedByte。 - State B 保存 simulation age;越界、无效、零速或 `3600` simulation seconds 到期时,在当前有效 Field bounds 内以 particle texel/旧位置哈希进行最多三次确定性重生。State A=0 作为 respawn 标记,下一次正常 advection 才设回 A=1。 - 正式 particle segment 改为 `StateRead.previousPosition → StateWrite.currentPosition`;respawn 标记帧丢弃 segment,避免跨屏连线。REAL WEATHER 中 `streakLength` 保留兼容 UI/API,不再决定真实 segment 长度。 - particle segment 通过当前 `matrixForTile()` 投影进入 viewport Trail;正式 Composite 改为一次 fullscreen view-space Trail 合成,而非把 viewport texture 当作全球 world texture。 - 相机 pan/zoom/rotate/pitch/resize 变化时只释放并重建 Trail A/B,记录 `ParticleTrail: event=CAMERA_RESET`;State、Field、Timeline、Runtime Window 均保留。正常 T0/T1 forecast boundary 不触发该路径。 - `trailFade` 保持“60 FPS 每帧保留率”UI 含义,实际每帧 fade 为 `pow(trailFade, wallDeltaSeconds * 60)`,因此以 wall time 一致衰减。 - visual clock 从 `6000` 改为 `1200` simulation seconds / real second;60 FPS 时约为 20 simulation seconds / frame。5 m/s≈100 m/frame(z9≈0.65 px),30 m/s≈3.9 px,避免旧 6000 的高风速离散跳跃。 ## 冻结边界 未修改 canonical Field、WeatherV2 assets、Host submission、Timeline、Runtime Field Window、WeatherColorLayer 或 Android UI。Timeline Pause 仍仅冻结 forecast;Particle State 在当前 Field 内继续更新。正常 window advance 仍维持 reuse、only NEW_T1 upload、`simulationRebuild=false` 与 `trailCleared=false`。 ## 验证与待验收 已执行 shader generator、Linux OpenGL 受影响 C++ 精确编译、既有非 Jest `style_layer.test.cpp` 精确编译和 `git diff --check`。未执行 Android Gradle、APK、ADB、设备测试或 Jest。 下一步:由用户按 v5 指令进行一次 Android 综合验收,重点观察 Pause 下 2–3 分钟密度、缩放后的连续轨迹、相机 Trail reset、time-based fade、T0→T3 boundary 与 Rotation。