diff --git a/src/Core/Animation/PathAnimationManager.cs b/src/Core/Animation/PathAnimationManager.cs index f795b29..82ca6c1 100644 --- a/src/Core/Animation/PathAnimationManager.cs +++ b/src/Core/Animation/PathAnimationManager.cs @@ -5079,7 +5079,6 @@ namespace NavisworksTransport.Core.Animation return TryCreateRealObjectPlanarRotationFromHostForward(hostForward, out rotation); } - var convention = GetCurrentModelAxisConvention(); Vector3 canonicalPrevious = ToNumerics(adapter.ToCanonicalPoint(previousPoint)); Vector3 canonicalCurrent = ToNumerics(adapter.ToCanonicalPoint(currentPoint)); Vector3 canonicalNext = ToNumerics(adapter.ToCanonicalPoint(nextPoint)); @@ -5090,19 +5089,7 @@ namespace NavisworksTransport.Core.Animation forward = canonicalNext - canonicalCurrent; } - Quaternion correctionQuaternion = adapter.CreateCanonicalRotationCorrection(_objectRotationCorrection); - if (!CanonicalPlanarPoseBuilder.TryCreateQuaternionFromForward( - forward, - HostCoordinateAdapter.CanonicalUpVector3, - convention, - correctionQuaternion, - out var quaternion)) - { - return false; - } - - rotation = adapter.FromCanonicalRotation(quaternion); - return true; + return TryResolvePlanarVirtualObjectRotation(forward, out rotation); } private double GetAnimatedObjectRailNormalExtent( @@ -5126,6 +5113,50 @@ namespace NavisworksTransport.Core.Animation return GetAnimatedObjectHeight(); } + /// + /// 平面虚拟物体姿态:路径对齐(可选)+ 角度修正(始终应用,与路径无关)。 + /// 路径方向有水平分量时对齐路径;无水平分量(纯垂直)时保持当前姿态, + /// 仅把角度修正叠加到当前姿态上,避免修正因路径几何而丢失。 + /// + private bool TryResolvePlanarVirtualObjectRotation(Vector3 canonicalForward, out Rotation3D rotation) + { + rotation = Rotation3D.Identity; + var adapter = CoordinateSystemManager.Instance.CreateHostAdapter(); + var convention = GetCurrentModelAxisConvention(); + Quaternion correctionQuaternion = adapter.CreateCanonicalRotationCorrection(_objectRotationCorrection); + + if (CanonicalPlanarPoseBuilder.TryCreateQuaternionFromForward( + canonicalForward, + HostCoordinateAdapter.CanonicalUpVector3, + convention, + correctionQuaternion, + out var quaternion)) + { + // 正常:路径对齐 + 角度修正 + rotation = adapter.FromCanonicalRotation(quaternion); + return true; + } + + // 纯垂直路径无水平方向:无法路径对齐,仅把角度修正叠加到当前姿态 + LogManager.Debug("[平面虚拟物体姿态] 路径方向无水平分量,仅应用角度修正到当前姿态"); + Quaternion currentHostQuaternion = Rotation3DToHostQuaternion(_trackedRotation); + Quaternion currentCanonicalQuaternion = AlignToGroundMinCrossSectionYawSearcher.HostQuaternionToCanonical(currentHostQuaternion, adapter); + Vector3 currentWorldForward = Vector3.Normalize(Vector3.Transform(convention.ForwardUnitVector, currentCanonicalQuaternion)); + Vector3 currentWorldUp = Vector3.Normalize(Vector3.Transform(convention.UpUnitVector, currentCanonicalQuaternion)); + LocalAxisPoseBuilder.ApplyLocalPreRotation( + convention, + correctionQuaternion, + out var correctedLocalForward, + out var correctedLocalUp); + Quaternion correctedQuaternion = LocalAxisPoseBuilder.CreateQuaternionFromLocalAxes( + correctedLocalForward, + correctedLocalUp, + currentWorldForward, + currentWorldUp); + rotation = adapter.FromCanonicalRotation(correctedQuaternion); + return true; + } + private bool TryCreatePlanarPathRotationFromHostForward(Vector3D hostForward, out Rotation3D rotation) { rotation = Rotation3D.Identity; @@ -5138,21 +5169,8 @@ namespace NavisworksTransport.Core.Animation out rotation); } - var convention = GetCurrentModelAxisConvention(); Vector3 canonicalForward = adapter.ToCanonicalVector3(new Vector3((float)hostForward.X, (float)hostForward.Y, (float)hostForward.Z)); - Quaternion correctionQuaternion = adapter.CreateCanonicalRotationCorrection(_objectRotationCorrection); - if (!CanonicalPlanarPoseBuilder.TryCreateQuaternionFromForward( - canonicalForward, - HostCoordinateAdapter.CanonicalUpVector3, - convention, - correctionQuaternion, - out var quaternion)) - { - return false; - } - - rotation = adapter.FromCanonicalRotation(quaternion); - return true; + return TryResolvePlanarVirtualObjectRotation(canonicalForward, out rotation); }