自动调整: 回调内扣除路径 yaw,使 correction 成为绝对角度

优化器通过 OptimizeWithEvaluator 传回调函数,回调接收 correction 后
经真实动画链路评估。动画链路 targetYaw = pathYaw + correctionY,
导致 correction.Y 被错误地当成额外增量而非绝对角度。

修复: 回调内从 correction 的 up 轴角度扣除路径 yaw,
使 targetYaw = pathYaw + (correctionY - pathYaw) = correctionY。
优化器现在正确地将 correction 作为从 CAD 出发的总 yaw 角度搜索。
This commit is contained in:
tian 2026-05-27 13:10:15 +08:00
parent 7187bcf622
commit 3e43b20102

View File

@ -2244,8 +2244,22 @@ namespace NavisworksTransport.UI.WPF.ViewModels
request,
correction =>
{
// 从 correction 扣除路径 yaw动画链路会在起点再次加上
// 这样 targetYaw = pathYaw + (correctionY - pathYaw) = correctionY
// correction 成为「从 CAD 出发的总 yaw 角度」
CoordinateSystemType hst = CoordinateSystemManager.Instance.ResolvedType;
double pyAdj = 0;
if (PathTargetFrameResolver.TryResolvePlanarHostYaw(request.HostPathForward, hst, out double pyRad))
{
pyAdj = pyRad * 180.0 / Math.PI;
}
var corr = correction;
var baseAdjusted = new LocalEulerRotationCorrection(
corr.XDegrees,
hst == CoordinateSystemType.YUp ? corr.YDegrees - pyAdj : corr.YDegrees,
hst == CoordinateSystemType.ZUp ? corr.ZDegrees - pyAdj : corr.ZDegrees);
var placementRequest = ObjectStartPlacementRequest.CreateRotationCorrection(
correction,
baseAdjusted,
originalLiftInMeters);
_pathAnimationManager.ApplyObjectStartPlacementRequest(placementRequest);
BoundingBox3D bounds = animatedObject.BoundingBox();
@ -2290,30 +2304,30 @@ namespace NavisworksTransport.UI.WPF.ViewModels
double sizeZ;
Quaternion baselineHostRotation = Quaternion.Identity;
// 基线为路径方向 yaw动画系统已旋转到该方向
var hostType = CoordinateSystemManager.Instance.ResolvedType;
if (PathTargetFrameResolver.TryResolvePlanarHostYaw(hostPathForward, hostType, out double pathYawRad))
{
var upVec = hostType == CoordinateSystemType.YUp ? Vector3.UnitY : Vector3.UnitZ;
baselineHostRotation = Quaternion.CreateFromAxisAngle(upVec, (float)pathYawRad);
LogManager.Info($"[自动调整] 基线 yaw={pathYawRad * 180.0 / Math.PI:F1}°, 四元数=({baselineHostRotation.W:F4},{baselineHostRotation.X:F4},{baselineHostRotation.Y:F4},{baselineHostRotation.Z:F4})");
}
else
{
LogManager.Warning("[自动调整] 无法从路径方向计算 yaw基线保持恒等");
}
if (UseVirtualObject)
{
sizeX = VirtualObjectLengthInMeters * metersToUnits;
sizeY = VirtualObjectWidthInMeters * metersToUnits;
sizeZ = VirtualObjectHeightInMeters * metersToUnits;
var virtualObject = VirtualObjectManager.Instance.CurrentVirtualObject;
if (ModelItemTransformHelper.TryGetCurrentGeometryRotation(virtualObject, out var virtualRotation))
{
baselineHostRotation = Rotation3DToHostQuaternion(virtualRotation);
}
}
else if (SelectedAnimatedObject != null)
{
sizeX = _objectOriginalLength * metersToUnits;
sizeY = _objectOriginalWidth * metersToUnits;
sizeZ = _objectOriginalHeight * metersToUnits;
if (ModelItemTransformHelper.TryGetCurrentGeometryRotation(SelectedAnimatedObject, out var actualRotation))
{
baselineHostRotation = Rotation3DToHostQuaternion(actualRotation);
}
else if (_pathAnimationManager != null && _pathAnimationManager.HasTrackedRotation)
{
baselineHostRotation = Rotation3DToHostQuaternion(_pathAnimationManager.TrackedRotation);
}
}
else
{