diff --git a/src/Core/Animation/PathAnimationManager.cs b/src/Core/Animation/PathAnimationManager.cs index 8665814..8f138e5 100644 --- a/src/Core/Animation/PathAnimationManager.cs +++ b/src/Core/Animation/PathAnimationManager.cs @@ -4372,7 +4372,13 @@ namespace NavisworksTransport.Core.Animation return false; } - ApplyPlanarNonUpAxisCorrectionsAtTrackedPosition(pathType, _trackedPosition, adapter.HostType); + // 提取非 up 轴修正角度 + double angleXRadians = _objectRotationCorrection.XDegrees * Math.PI / 180.0; + double angleNonUpRadians = (adapter.HostType == CoordinateSystemType.YUp + ? _objectRotationCorrection.ZDegrees + : _objectRotationCorrection.YDegrees) * Math.PI / 180.0; + var nonUpAxis = adapter.HostType == CoordinateSystemType.YUp + ? Vector3.UnitZ : Vector3.UnitY; double upAxisCorrectionRadians = ResolvePlanarHostUpCorrectionRadians( _objectRotationCorrection, @@ -4380,18 +4386,23 @@ namespace NavisworksTransport.Core.Animation targetYawRadians = NormalizeRadians(targetYawRadians + upAxisCorrectionRadians); double currentYawRadians = _currentYaw; double deltaYawRadians = NormalizeRadians(targetYawRadians - currentYawRadians); - LogManager.Info( - $"[{pathType.GetDisplayName()}纯增量起点] 当前Yaw={currentYawRadians * 180.0 / Math.PI:F2}°, " + - $"目标Yaw={targetYawRadians * 180.0 / Math.PI:F2}°, 增量Yaw={deltaYawRadians * 180.0 / Math.PI:F2}°, " + - $"当前跟踪点=({_trackedPosition.X:F3},{_trackedPosition.Y:F3},{_trackedPosition.Z:F3}), " + - $"目标跟踪点=({targetTrackedPosition.X:F3},{targetTrackedPosition.Y:F3},{targetTrackedPosition.Z:F3})"); - ModelItemTransformHelper.MoveItemIncrementallyByAxisRotationAndTranslation( - CurrentControlledObject, - _trackedPosition, - adapter.HostUpVector3, - deltaYawRadians, - targetTrackedPosition); + if (Math.Abs(angleXRadians) > 1e-9 || Math.Abs(angleNonUpRadians) > 1e-9 || Math.Abs(deltaYawRadians) > 1e-9) + { + LogManager.Info( + $"[{pathType.GetDisplayName()}纯增量起点] 当前Yaw={currentYawRadians * 180.0 / Math.PI:F2}°, " + + $"目标Yaw={targetYawRadians * 180.0 / Math.PI:F2}°, 增量Yaw={deltaYawRadians * 180.0 / Math.PI:F2}°, " + + $"当前跟踪点=({_trackedPosition.X:F3},{_trackedPosition.Y:F3},{_trackedPosition.Z:F3}), " + + $"目标跟踪点=({targetTrackedPosition.X:F3},{targetTrackedPosition.Y:F3},{targetTrackedPosition.Z:F3})"); + + ModelItemTransformHelper.MoveItemCombinedAxisRotationAndTranslation( + CurrentControlledObject, + _trackedPosition, + Vector3.UnitX, angleXRadians, + nonUpAxis, angleNonUpRadians, + adapter.HostUpVector3, deltaYawRadians, + targetTrackedPosition); + } _trackedPosition = targetTrackedPosition; diff --git a/src/Utils/ModelItemTransformHelper.cs b/src/Utils/ModelItemTransformHelper.cs index b167e38..84c8730 100644 --- a/src/Utils/ModelItemTransformHelper.cs +++ b/src/Utils/ModelItemTransformHelper.cs @@ -592,6 +592,48 @@ namespace NavisworksTransport.Utils LogIncrementalTransformActual(item, targetPosition, targetRotation); } + /// + /// 合并三次绕宿主轴的旋转 + 一次平移为单次 OverridePermanentTransform 调用。 + /// 等价于依次调用三次 MoveItemIncrementallyByAxisRotationAndTranslation,但 NW API 调用次数减少 66%。 + /// + public static void MoveItemCombinedAxisRotationAndTranslation( + ModelItem item, + Point3D trackedPosition, + Vector3 axis1, double angle1Radians, + Vector3 axis2, double angle2Radians, + Vector3 axis3, double angle3Radians, + Point3D targetPosition) + { + if (item == null) throw new ArgumentNullException(nameof(item)); + + // 用 System.Numerics 合成三个旋转 + var q1 = Quaternion.CreateFromAxisAngle(Vector3.Normalize(axis1), (float)angle1Radians); + var q2 = Quaternion.CreateFromAxisAngle(Vector3.Normalize(axis2), (float)angle2Radians); + var q3 = Quaternion.CreateFromAxisAngle(Vector3.Normalize(axis3), (float)angle3Radians); + // q3 * q2 * q1: apply q1 first, then q2, then q3(与 Override 左乘积累顺序一致) + var totalQ = Quaternion.Normalize(q3 * q2 * q1); + + // 计算旋后跟踪点位置 + var tp = new Vector3((float)trackedPosition.X, (float)trackedPosition.Y, (float)trackedPosition.Z); + var rotatedTp = Vector3.Transform(tp, totalQ); + + // 计算组合变换 + var doc = Application.ActiveDocument; + var modelItems = new ModelItemCollection { item }; + + doc.Models.ResetPermanentTransform(modelItems); + + var identity = Transform3D.CreateTranslation(new Vector3D(0, 0, 0)); + var components = identity.Factor(); + components.Rotation = new Rotation3D(totalQ.X, totalQ.Y, totalQ.Z, totalQ.W); + components.Translation = new Vector3D( + targetPosition.X - rotatedTp.X, + targetPosition.Y - rotatedTp.Y, + targetPosition.Z - rotatedTp.Z); + var combined = components.Combine(); + doc.Models.OverridePermanentTransform(modelItems, combined, false); + } + /// /// 直接对当前显示结果施加宿主轴旋转增量,再补一段平移把业务跟踪点拉回目标点。 /// 不先构造 targetRotation,也不从 current/target 姿态反推 deltaRotation。