# 地球3D可视化架构重构计划 ## 背景 当前 `frontend/public/earth` 3D地球可视化系统基于 Three.js 构建,未来需要迁移到 Unreal Engine (Cesium)。为降低迁移成本,需要提前做好**逻辑与渲染分离**的架构设计。 ## 目标 - 将线缆高亮逻辑与渲染实现分离 - 保持交互逻辑可复用,只需重写渲染层 - 为后续迁移到 UE/Cesium 做好准备 ## 已完成 ### 1. 状态枚举定义 (constants.js) ```javascript export const CABLE_STATE = { NORMAL: 'normal', HOVERED: 'hovered', LOCKED: 'locked' }; ``` ### 2. 线缆状态管理 (cables.js - 数据层) ```javascript const cableStates = new Map(); export function getCableState(cableId) { ... } export function setCableState(cableId, state) { ... } export function clearAllCableStates() { ... } export function getCableStateInfo() { ... } ``` ### 3. 逻辑层调用 (main.js) ```javascript // 悬停 setCableState(cable.userData.cableId, CABLE_STATE.HOVERED); // 锁定 setCableState(cableId, CABLE_STATE.LOCKED); // 恢复 setCableState(cableId, CABLE_STATE.NORMAL); clearAllCableStates(); // 清除锁定时 clearLockedObject() { hoveredCable = null; clearAllCableStates(); ... } ``` ### 4. 渲染层 (main.js - applyCableVisualState) ```javascript function applyCableVisualState() { const allCables = getCableLines(); const pulse = (Math.sin(Date.now() * CABLE_CONFIG.pulseSpeed) + 1) * 0.5; allCables.forEach(c => { const cableId = c.userData.cableId; const state = getCableState(cableId); switch (state) { case CABLE_STATE.LOCKED: // 呼吸效果 + 白色 c.material.opacity = CABLE_CONFIG.lockedOpacityMin + pulse * CABLE_CONFIG.pulseCoefficient; c.material.color.setRGB(1, 1, 1); break; case CABLE_STATE.HOVERED: // 白色高亮 c.material.opacity = 1; c.material.color.setRGB(1, 1, 1); break; case CABLE_STATE.NORMAL: default: if (lockedObjectType === 'cable' && lockedObject) { // 其他线缆变暗 c.material.opacity = CABLE_CONFIG.otherOpacity; ... } else { // 恢复原始 c.material.opacity = 1; c.material.color.setHex(c.userData.originalColor); } } }); } ``` ## 待完成 ### Phase 1: 完善状态配置 (constants.js) ```javascript export const CABLE_CONFIG = { lockedOpacityMin: 0.6, lockedOpacityMax: 1.0, otherOpacity: 0.5, otherBrightness: 0.6, pulseSpeed: 0.003, pulseCoefficient: 0.4, // 未来可扩展 // lockedLineWidth: 3, // normalLineWidth: 1, }; ``` ### Phase 2: 卫星状态管理 (satellites.js) 参考线缆状态管理,为卫星添加类似的状态枚举和状态管理函数: ```javascript export const SATELLITE_STATE = { NORMAL: 'normal', HOVERED: 'hovered', LOCKED: 'locked' }; ``` #### 卫星数据源说明 - **当前使用**: CelesTrak (https://celestrak.org) - 免费,无需认证 - **后续计划**: Space-Track.org (https://space-track.org) - 需要认证,数据更权威 - 迁移时只需修改 `satellites.js` 中的数据获取逻辑,状态管理和渲染逻辑不变 ### Phase 3: 统一渲染接口 将所有对象的渲染逻辑抽象为一个统一的渲染函数: ```javascript function applyObjectVisualState() { applyCableVisualState(); applySatelliteVisualState(); applyLandingPointVisualState(); } ``` ### Phase 4: UE 迁移准备 迁移到 Unreal Engine 时: 1. 保留 `constants.js` 中的枚举和配置 2. 保留 `cables.js` 中的数据层和状态管理 3. 保留 `main.js` 中的交互逻辑 4. **仅重写** `applyCableVisualState()` 等渲染函数 --- ## 架构原则 1. **状态与渲染分离** - 对象状态由数据层管理,渲染层只负责根据状态更新视觉效果 2. **逻辑可复用** - 交互逻辑(点击、悬停、锁定)在迁移时应直接复用 3. **渲染可替换** - 渲染实现可以针对不同引擎重写,不影响逻辑层 ## 文件变更记录 | 日期 | 文件 | 变更 | |------|------|------| | 2026-03-19 | constants.js | 新增 CABLE_STATE 枚举 | | 2026-03-19 | cables.js | 新增状态管理函数 | | 2026-03-19 | main.js | 使用状态管理,抽象 applyCableVisualState() |