fix: 自由路径保持物体原始姿态,起点不做自动旋转调整

真实物体(YUp)的自由路径自动对齐路径方向的旋转在宿主/几何姿态
解析上容易出错(对齐了错误前向、侧滚90°)。按用户要求,自由路径
改为保持物体原始姿态:
- MoveObjectToPathStart:自由路径纯平移(ApplyTrackedTranslationOnly),
  不应用任何自动旋转
- ShouldPreservePathRotationForFrames:对 Free 始终返回 true,帧锁定
  起点姿态,物体沿路径平移而保持朝向
- 移除废弃的 TryCreateFreePathRotationForFrame/AtStart(平面自动旋转)
257 单测全过。
This commit is contained in:
tian 2026-07-31 17:01:03 +08:00
parent ead8a35372
commit d3535fc5a0

View File

@ -955,16 +955,13 @@ namespace NavisworksTransport.Core.Animation
_hasGroundRealObjectBasePose = false;
}
}
else if (_route.PathType == PathType.Free &&
TryCreateFreePathRotationAtStart(out var freeStartRotation))
{
ApplyFullPoseUpdate(startPosition, freeStartRotation);
LogManager.Debug("[移动到起点] 自由路径已应用完整三维姿态(切线前向 + 世界up正交化");
}
else if (_route.PathType == PathType.Free)
{
LogManager.Error("[移动到起点] 自由路径未能生成完整三维姿态,已禁止退回旧 yaw 链路");
return false;
// 自由路径:保持物体原始姿态,仅平移到起点(不做任何自动旋转调整)
ApplyTrackedTranslationOnly(startPosition);
SyncTrackedRotationToDisplayedPose(CurrentControlledObject ?? _animatedObject);
_hasGroundRealObjectBasePose = false;
LogManager.Debug("[移动到起点] 自由路径已保持原始姿态纯平移到起点");
}
else if (_route.PathType == PathType.Ground || _route.PathType == PathType.Hoisting)
{
@ -1508,12 +1505,6 @@ namespace NavisworksTransport.Core.Animation
frame.Rotation = railRotation;
frame.HasCustomRotation = true;
}
else if (_route.PathType == PathType.Free &&
TryCreateFreePathRotationForFrame(previousFramePoint, framePosition, nextFramePoint, out var freeRotation))
{
frame.Rotation = freeRotation;
frame.HasCustomRotation = true;
}
else if ((_route.PathType == PathType.Ground || _route.PathType == PathType.Hoisting) &&
!_route.IsTwoPointVertical &&
TryCreatePlanarPathRotationForFrame(previousFramePoint, framePosition, nextFramePoint, out var planarRotation))
@ -4030,7 +4021,18 @@ namespace NavisworksTransport.Core.Animation
ObjectStartPlacementMode placementMode,
bool hasPreservedRotation)
{
if (!hasPreservedRotation || placementMode != ObjectStartPlacementMode.PreserveInitialPose)
if (!hasPreservedRotation)
{
return false;
}
// 自由路径:保持物体原始姿态,不自动对齐路径方向(用户通过"调整物体"控制朝向)
if (pathType == PathType.Free)
{
return true;
}
if (placementMode != ObjectStartPlacementMode.PreserveInitialPose)
{
return false;
}
@ -4937,61 +4939,6 @@ namespace NavisworksTransport.Core.Animation
return true;
}
/// <summary>
/// 自由路径姿态(平面):像地面路径一样,物体转向前进方向的水平投影,
/// 但只绕垂直轴up 轴旋转yaw不绕前进轴滚动。
/// 复用 CanonicalPlanarPoseBuilderforward=路径水平投影up=世界up
/// </summary>
private bool TryCreateFreePathRotationForFrame(Point3D previousPoint, Point3D currentPoint, Point3D nextPoint, out Rotation3D rotation)
{
rotation = Rotation3D.Identity;
var adapter = CoordinateSystemManager.Instance.CreateHostAdapter();
var convention = GetCurrentModelAxisConvention();
Vector3 canonicalPrevious = ToNumerics(adapter.ToCanonicalPoint(previousPoint));
Vector3 canonicalCurrent = ToNumerics(adapter.ToCanonicalPoint(currentPoint));
Vector3 canonicalNext = ToNumerics(adapter.ToCanonicalPoint(nextPoint));
Vector3 canonicalForward = canonicalNext - canonicalPrevious;
if (canonicalForward.LengthSquared() < 1e-6f)
{
canonicalForward = canonicalNext - canonicalCurrent;
}
if (!CanonicalPlanarPoseBuilder.TryCreateQuaternionFromForward(
canonicalForward,
HostCoordinateAdapter.CanonicalUpVector3,
convention,
_objectRotationCorrection,
out var canonicalRotation))
{
return false;
}
rotation = adapter.FromCanonicalRotation(canonicalRotation);
return true;
}
/// <summary>
/// 自由路径起点姿态以首段方向水平投影为前向只绕垂直轴旋转yaw
/// </summary>
private bool TryCreateFreePathRotationAtStart(out Rotation3D rotation)
{
rotation = Rotation3D.Identity;
if (_pathPoints == null || _pathPoints.Count < 2)
{
return false;
}
return TryCreateFreePathRotationForFrame(
_pathPoints[0],
_pathPoints[0],
_pathPoints[1],
out rotation);
}
private bool TryCreateRailPathRotation(
Point3D previousPoint,
Point3D currentPoint,