fix: 贴合地面改为走第二步路径对齐定位,不再手工底边贴地

此前贴合地面自行手工定位"底边贴地"(Ground 语义),绕过了路径对齐,
Free 路径下物体中心未对齐路径点。改为:
- 第一步:计算姿态修正 + 上下偏移(路径无关)
- 第二步:ApplyObjectStartPlacementRequest 按路径语义定位起点
  (Ground → 底面贴地+lift;Free → 中心在路径点+lift)
移除手工原地旋转和底边贴地平移。
257 单测全过
This commit is contained in:
tian 2026-08-01 13:26:11 +08:00
parent 775c7b6fad
commit d1ab271578

View File

@ -2444,28 +2444,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
}
var center = item.BoundingBox().Center;
var tp = new Vector3((float)center.X, (float)center.Y, (float)center.Z);
var rtp = Vector3.Transform(tp, overrideQ);
var id = Transform3D.CreateTranslation(new Vector3D(0, 0, 0)).Factor();
id.Rotation = new Rotation3D(overrideQ.X, overrideQ.Y, overrideQ.Z, overrideQ.W);
id.Translation = new Vector3D(center.X - rtp.X, center.Y - rtp.Y, center.Z - rtp.Z);
doc.Models.OverridePermanentTransform(modelItems, id.Combine(), true);
// 旋转后平移:底边贴地 + 用户上下偏移
var hst = CoordinateSystemManager.Instance.ResolvedType;
var newBounds = item.BoundingBox();
var newCenter = newBounds.Center;
var ps = CurrentPathRoute?.Points?[0];
double objectBottom = hst == CoordinateSystemType.YUp ? newBounds.Min.Y : newBounds.Min.Z;
double groundLevel = (hst == CoordinateSystemType.YUp ? ps.Y : ps.Z)
+ UnitsConverter.ConvertFromMeters(_objectGroundLiftHeightInMeters);
var delta = new Vector3D(
ps.X - newCenter.X,
hst == CoordinateSystemType.YUp ? groundLevel - objectBottom : ps.Y - newCenter.Y,
hst == CoordinateSystemType.YUp ? ps.Z - newCenter.Z : groundLevel - objectBottom);
doc.Models.OverridePermanentTransform(modelItems, Transform3D.CreateTranslation(delta), false);
// 把绝对贴地姿态转成"相对于 baseline 的 host 欧拉修正"。
// PathAnimationManager 增量链从 CAD 姿态出发,需要扣除 CAD 自带 yaw + pathYaw。
LocalEulerRotationCorrection resultCorrection;
@ -2483,10 +2461,20 @@ namespace NavisworksTransport.UI.WPF.ViewModels
resultCorrection = ObjectPassageProjectionOptimizer.CanonicalQuaternionToHostEulerCorrection(
correctionCanonQ, adapter.HostType);
}
_pathAnimationManager?.SetObjectRotationCorrectionDirect(resultCorrection);
// ===== 第一步:调整物体的结果(姿态修正 + 上下偏移,路径无关)=====
_objectRotationCorrection = resultCorrection;
OnPropertyChanged(nameof(ObjectRotationCorrection));
// ===== 第二步:路径对齐(按路径语义定位到起点,各路径自己的处理)=====
// 不再手工"底边贴地"Ground 语义Free 不适用),改为走起点放置:
// Ground → 底面贴地+liftFree → 中心在路径点+lift
if (_pathAnimationManager != null)
{
_pathAnimationManager.ApplyObjectStartPlacementRequest(
ObjectStartPlacementRequest.CreateRotationCorrection(resultCorrection, _objectGroundLiftHeightInMeters));
}
// 回写上下偏移:贴地时用实际包围盒贴地,但确认/动画后用 correction 重建姿态,
// 旋转后物体底边位置会变。与自动调整同方法:应用 correction 重建→测量底边→算 lift
// 测量后用新 correction+lift 完整重建,使物体停留在贴地等价姿态。