fix: 路径切换保留 lift 避免物体浮空,物体参数同步优先读 AABB 缓存

路径切换问题:
- 切换路径时 lift 被重置为 0,GetAnimatedObjectGroundContactHeight
  用 correction 投影算出错误高度(~4.27m),物体浮空
- 改为保留 lift(离地高度不变),路径切换后物体保持正确位置

可视化宽度问题:
- 路径切换后物体参数同步(SyncAnimationViewObjectParameters)
  调用 TryGetCurrentRouteRealObjectPlanarProjectedExtents,
  用 correction 投影算失真尺寸覆盖正确值
- 改为优先读 AnimationControlViewModel 的 _autoAabbSx 缓存
  (由 MeasureXAlignedAabbAndSetCache 实测得到)
- 新增 TryGetCachedAabbSizes 公开缓存给外部
This commit is contained in:
tian 2026-06-28 12:50:28 +08:00
parent da6b6cb481
commit 6ef866d1dc
2 changed files with 80 additions and 37 deletions

View File

@ -619,7 +619,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 注意只有路径真正改变时才移动避免初始设置null时的不必要移动
if (value != null && oldRoute != value)
{
// 保留 lift物体姿态不变离地高度保持不变
// 保留 _autoAabbSx 缓存(物理尺寸与路径方向无关)。
// 保留 _objectRotationCorrection物体姿态不变
MoveAnimatedObjectToPathStart();
// 用现有缓存刷新路径可视化和通行空间,不走 CalculateRotatedDimensions
UpdatePassageSpaceVisualization();
}
}
}
@ -2224,6 +2229,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
_pathAnimationManager?.ApplyObjectStartPlacementRequest(placementRequest);
ObjectRotationCorrection = placementRequest.RotationCorrection;
// 手动改角度后实测AABB缓存与自动调整/贴地一致
var manualAdapter = CoordinateSystemManager.Instance.CreateHostAdapter();
var manualDoc = Autodesk.Navisworks.Api.Application.ActiveDocument;
var manualItems = new ModelItemCollection { SelectedAnimatedObject };
MeasureXAlignedAabbAndSetCache(SelectedAnimatedObject, manualItems, manualAdapter, manualDoc);
}
if (isAutoAdjusted)
{
@ -5128,6 +5138,23 @@ namespace NavisworksTransport.UI.WPF.ViewModels
return result;
}
/// <summary>
/// 暴露实测 AABB 缓存给外部(如 PathEditingViewModel 的物体参数同步),
/// 避免它们走 correction 投影导致失真。
/// </summary>
public bool TryGetCachedAabbSizes(out double forward, out double side, out double up)
{
if (_autoAabbSx.HasValue)
{
forward = _autoAabbSx.Value;
side = _autoAabbSz.Value;
up = _autoAabbSy.Value;
return true;
}
forward = side = up = 0;
return false;
}
/// <summary>
/// 根据路径类型更新通行空间可视化
/// 空轨和吊装路径默认打开通行空间(物体通行空间模式),地面路径不打开

View File

@ -6364,48 +6364,64 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
else if (animationVm.SelectedAnimatedObject != null)
{
var animationManager = NavisworksTransport.Core.Animation.PathAnimationManager.GetInstance();
if ((pathType == PathType.Ground || pathType == PathType.Hoisting) &&
animationManager != null &&
animationManager.TryGetCurrentRouteRealObjectPlanarProjectedExtents(
out double resolvedPlanarForward,
out double resolvedPlanarSide,
out double resolvedPlanarUp))
// 优先使用 AnimationControlViewModel 的实测 AABB 缓存
// (贴合地面/自动调整后设置),避免 correction 投影失真
if (animationVm.TryGetCachedAabbSizes(out double cachedFwd, out double cachedSide, out double cachedUp))
{
objectLengthModel = resolvedPlanarForward;
objectWidthModel = resolvedPlanarSide;
objectHeightModel = resolvedPlanarUp;
objectLengthModel = cachedFwd;
objectWidthModel = cachedSide;
objectHeightModel = cachedUp;
LogManager.Debug(
$"[物体参数同步] 使用真实物体平面路径最终姿态尺寸: " +
$"沿路径={resolvedPlanarForward / metersToUnits:F2}m, " +
$"垂直路径={resolvedPlanarSide / metersToUnits:F2}m, " +
$"法线={resolvedPlanarUp / metersToUnits:F2}m");
}
else if (pathType == PathType.Rail &&
animationManager != null &&
animationManager.TryGetCurrentRouteRealObjectRailProjectedExtents(
out double resolvedRailForward,
out double resolvedRailSide,
out double resolvedRailUp))
{
objectLengthModel = resolvedRailForward;
objectWidthModel = resolvedRailSide;
objectHeightModel = resolvedRailUp;
LogManager.Debug(
$"[物体参数同步] 使用真实物体 Rail 最终姿态尺寸: " +
$"沿路径={resolvedRailForward / metersToUnits:F2}m, " +
$"垂直路径={resolvedRailSide / metersToUnits:F2}m, " +
$"法线={resolvedRailUp / metersToUnits:F2}m");
$"[物体参数同步] 复用贴合地面/自动调整实测AABB: " +
$"沿路径={cachedFwd / metersToUnits:F2}m, " +
$"垂直路径={cachedSide / metersToUnits:F2}m, " +
$"法线={cachedUp / metersToUnits:F2}m");
}
else
{
// 回退:使用选择物体时保存的原始尺寸(米)
objectLengthModel = animationVm.ObjectOriginalLength * metersToUnits;
objectWidthModel = animationVm.ObjectOriginalWidth * metersToUnits;
objectHeightModel = animationVm.ObjectOriginalHeight * metersToUnits;
LogManager.Debug(
$"[物体参数同步] 回退使用选择物体保存的原始尺寸: " +
$"{animationVm.ObjectOriginalLength:F2}m x {animationVm.ObjectOriginalWidth:F2}m x {animationVm.ObjectOriginalHeight:F2}m");
var animationManager = NavisworksTransport.Core.Animation.PathAnimationManager.GetInstance();
if ((pathType == PathType.Ground || pathType == PathType.Hoisting) &&
animationManager != null &&
animationManager.TryGetCurrentRouteRealObjectPlanarProjectedExtents(
out double resolvedPlanarForward,
out double resolvedPlanarSide,
out double resolvedPlanarUp))
{
objectLengthModel = resolvedPlanarForward;
objectWidthModel = resolvedPlanarSide;
objectHeightModel = resolvedPlanarUp;
LogManager.Debug(
$"[物体参数同步] 使用真实物体平面路径最终姿态尺寸: " +
$"沿路径={resolvedPlanarForward / metersToUnits:F2}m, " +
$"垂直路径={resolvedPlanarSide / metersToUnits:F2}m, " +
$"法线={resolvedPlanarUp / metersToUnits:F2}m");
}
else if (pathType == PathType.Rail &&
animationManager != null &&
animationManager.TryGetCurrentRouteRealObjectRailProjectedExtents(
out double resolvedRailForward,
out double resolvedRailSide,
out double resolvedRailUp))
{
objectLengthModel = resolvedRailForward;
objectWidthModel = resolvedRailSide;
objectHeightModel = resolvedRailUp;
LogManager.Debug(
$"[物体参数同步] 使用真实物体 Rail 最终姿态尺寸: " +
$"沿路径={resolvedRailForward / metersToUnits:F2}m, " +
$"垂直路径={resolvedRailSide / metersToUnits:F2}m, " +
$"法线={resolvedRailUp / metersToUnits:F2}m");
}
else
{
// 回退:使用选择物体时保存的原始尺寸(米)
objectLengthModel = animationVm.ObjectOriginalLength * metersToUnits;
objectWidthModel = animationVm.ObjectOriginalWidth * metersToUnits;
objectHeightModel = animationVm.ObjectOriginalHeight * metersToUnits;
LogManager.Debug(
$"[物体参数同步] 回退使用选择物体保存的原始尺寸: " +
$"{animationVm.ObjectOriginalLength:F2}m x {animationVm.ObjectOriginalWidth:F2}m x {animationVm.ObjectOriginalHeight:F2}m");
}
}
}
else