NavisworksTransport/doc/design/2026/free-path-design.md
tian 53ae232ebc refactor: 起点放置按两步架构分离(调整物体统一 + 路径对齐各自处理)
按架构原则重构 MoveObjectToPathStart 和 PreservingInitialPose:
- 第二步:路径起点位置对齐(各路径类型各自处理,不含 lift)
- 第一步:调整物体的上下偏移(统一应用,路径无关,无分支)
- Rail 因流程提前返回(三维姿态就地应用),lift 在其分支内应用
- 更新设计文档记录架构原则
257 单测全过
2026-08-01 12:56:11 +08:00

168 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 自由路径Free Path设计方案
> 分支:`feature/free-path`
> 创建日期2026-06-30
> 状态:实施中(详见下方"实施进度跟踪"
>
> **已确认决策**
> - 决策点1旋转姿态**最终改为 —— 自由路径保持物体原始姿态**,不自动对齐路径方向
> (真实物体/YUp 的自动姿态解析易出错;用户通过"调整物体"控制朝向)
> - 决策点2旧数据迁移方案A —— 自动转换 IsTwoPointVertical → Free
>
> **架构原则2026-08**"调整物体"只是调整物体的**姿态修正 + 上下偏移**
> 与路径对齐无关。物体在起点的姿态/位置由两个分离步骤决定:
> - **第一步(统一,路径无关,无分支)**:调整物体的结果(姿态修正 X/Y/Z + 上下偏移 lift
> - **第二步(各路径自己的处理逻辑)**:路径起点对齐(路径点→物体位置 + 基座姿态对齐)
> 所有路径都遵循此架构;只有第二步允许分支。
---
## 一、背景与问题
### 1.1 现状
当前路径类型 `PathType`
| 值 | 类型 | 说明 |
|----|------|------|
| 0 | Ground | 地面路径 |
| 1 | Rail | 空轨路径 |
| 2 | Hoisting | 吊装路径 |
**2点路径**:是 Hoisting 上的 `IsTwoPointVertical` 特殊标志,非独立类型。语义混乱:
| | 起点 | 终点 |
|----|------|------|
| 动画帧循环 | 底面中心对齐(`ResolveGroundTrackedCenter` | 几何中心(`p2` 原始点) |
| 终点诊断 | — | 底面中心对齐(又一种) |
**问题**:起点用底面中心对齐、终点用几何中心对齐,**对齐语义不一致**
且 2 点路径被绑死在吊装逻辑中,无法作为通用路径使用。
### 1.2 需求
1. 2 点路径改为**自由路径Free**,从吊装路径中剥离
2. 与地面、空轨、吊装等路径**并列**为一级路径类型
3. **统一包围盒中心对齐**:每个路径点 = 物体几何中心
4. 支持**任意多个自由路径点**
---
## 二、目标
1. 新增一级 `PathType.Free`
2. 统一包围盒中心对齐(轨迹即物体中心)
3. 支持任意多点自由路径
4. 从吊装剥离,废弃 `IsTwoPointVertical` 特殊逻辑
5. 温和迁移旧 2 点吊装路径数据
---
## 三、核心设计
### 3.1 PathType 枚举
```csharp
public enum PathType
{
Ground = 0,
Rail = 1,
Hoisting = 2,
Free = 3 // 新增
}
```
- `GetDisplayName()` 增加 `case PathType.Free: return "自由";`
- DB 存储为整数,**追加枚举值向后安全**,无需 schema 迁移
### 3.2 动画语义(关键)
自由路径的每个路径点**就是物体包围盒中心**
```csharp
framePosition = 路径点直接插值; // 不加任何半高偏移
```
- 起点/终点/中间点**统一**用几何中心对齐(无起点/终点不对称)
- 天然满足"矢量任意方向"——不依赖哪个面是底
### 3.3 旋转姿态策略决策点1 → 方案1
**方案1已确认**forward = 路径切线方向up = 世界 up 投影正交化。
- 复用 `RailPathPoseHelper` 的三维姿态计算
- 物体保持"上"朝世界,像车沿坡道走
- 通用且符合物流车语义
### 3.4 创建流程UI
- 新增"自由路径"创建模式,与地面/空轨/吊装并列
- 用户连续点击任意 3D 点(即物体中心轨迹)
- 无地面约束、无提升/下降段逻辑
- 支持任意点数,最后设终点完成
### 3.5 渲染
- 自由路径按普通多点线渲染(去掉吊装特殊逻辑)
- 通行空间以路径点为中心扩展
### 3.6 碰撞检测
framePosition 即物体中心,现有碰撞盒计算直接正确(无需改动)。
---
## 四、兼容与迁移
### 4.1 旧数据迁移决策点2 → 方案A
**方案A已确认自动转换**
加载旧库时,`IsTwoPointVertical=true` 的吊装路径:
- 转换为 `PathType.Free`
- 路径点坐标直接作为物体几何中心
- 注意:旧 2 点路径终点是"提升点"lift 高度),转换时作为物体中心需确认合理性
---
## 五、实施步骤与进度跟踪
| # | 步骤 | 状态 | 备注 |
|----|------|------|------|
| 1 | `PathType``Free` + `GetDisplayName` | ✅ | 枚举值3显示"自由" |
| 2 | 动画管理器:新增 Free 分支(统一中心对齐 + 方案1姿态 | ✅ | `TryCreateFreePathRotationForFrame/AtStart`,复用 CanonicalRailPoseBuilder |
| 3 | 渲染插件Free 普通渲染 | ✅ | 通行空间垂直偏移0路径=中心) |
| 4 | 路径管理器:`StartCreatingNewRoute`/`FinishEditing` 支持 Free | ✅ | 状态消息 + 设终点逻辑 |
| 5 | UI新增自由路径创建入口 | ✅ | PathEditingView 按钮 + `NewFreePathCommand` + `ExecuteNewFreePathAsync` |
| 6 | 数据库:枚举扩展(无 schema 变更) | ✅ | 存 intFree=3 自动映射 |
| 7 | 旧数据迁移方案A | ✅ | 加载时 IsTwoPointVertical→Free |
| 8 | 补单测(中心对齐 + 姿态 + 多点) | ✅ | 新增 FreePathTests6个 |
| 9 | 编译 + 单测 + 部署 + 手动验证 | 🔄 | 需部署后手动验证 |
> ✅ 附带修复:`CornerTurnCheckHelperTests` 6个 pre-existing 失败
> - 根因:代码正确,测试期望值与公式不符(`7e71387` 改算法时测试未同步)
> - 已修正测试期望值 + 补 maxLength 断言
> - 另将 `FreePathTests.cs` 显式加入 UnitTests.csproj此前未编译
> ✅ 自由路径起点姿态已正确(保持原始姿态,纯平移,排除平面旋转分支)
## 六、待办事项(明日处理)
### 6.1 "调整物体"窗口功能问题
**状态**:起点姿态、动画已正确;"调整物体"窗口功能在逐步修复。
**已修复**
-**X/Y/Z 角度调整**:根因是 `MoveObjectToPathStart` 的 Free 分支只做纯平移,
忽略了 `_objectRotationCorrection`。已改为先应用角度修正(围绕物体中心旋转)
再平移到起点;动画帧保留修正后姿态。
-**上下偏移lift**:泛化 `ApplyGroundPathObjectLiftOffset` 支持 Free
窗口对 Free 启用 lift 输入;起点和动画帧均应用偏移。
**待验证**
- ☐ 自动调整ObjectPassageProjectionOptimizer
- ☐ 贴合地面FaceInfer 流程)
- ☐ 平移到起点
> 进度图例:☐ 未开始 / 🔄 进行中 / ✅ 完成