Unify planar collision pose replay
This commit is contained in:
parent
970d3465f4
commit
315fa46043
@ -132,6 +132,24 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
|
|||||||
Assert.IsFalse(PathAnimationManager.ShouldUsePlanarRealObjectPureIncrementFrames(PathType.Rail, true));
|
Assert.IsFalse(PathAnimationManager.ShouldUsePlanarRealObjectPureIncrementFrames(PathType.Rail, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ResolveAnimationFramePlaybackYawRadians_ShouldPreferPlanarHostYawWithHostCorrection()
|
||||||
|
{
|
||||||
|
var frame = new AnimationFrame
|
||||||
|
{
|
||||||
|
YawRadians = 0.25,
|
||||||
|
PlanarHostYawRadians = 0.75,
|
||||||
|
HasCustomRotation = true
|
||||||
|
};
|
||||||
|
|
||||||
|
double resolved = PathAnimationManager.ResolveAnimationFramePlaybackYawRadians(
|
||||||
|
frame,
|
||||||
|
new LocalEulerRotationCorrection(10.0, 20.0, 30.0),
|
||||||
|
CoordinateSystemType.YUp);
|
||||||
|
|
||||||
|
Assert.AreEqual(0.75 + 20.0 * System.Math.PI / 180.0, resolved, 1e-9);
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void ApplyRecordedPlanarRealObjectFramePose_ShouldPreserveFullRotation_ForGroundCollisionLogCase()
|
public void ApplyRecordedPlanarRealObjectFramePose_ShouldPreserveFullRotation_ForGroundCollisionLogCase()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -759,7 +759,7 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
$"Y=({railLinearTransform.Get(0, 1):F4},{railLinearTransform.Get(1, 1):F4},{railLinearTransform.Get(2, 1):F4}), " +
|
$"Y=({railLinearTransform.Get(0, 1):F4},{railLinearTransform.Get(1, 1):F4},{railLinearTransform.Get(2, 1):F4}), " +
|
||||||
$"Z=({railLinearTransform.Get(0, 2):F4},{railLinearTransform.Get(1, 2):F4},{railLinearTransform.Get(2, 2):F4})");
|
$"Z=({railLinearTransform.Get(0, 2):F4},{railLinearTransform.Get(1, 2):F4},{railLinearTransform.Get(2, 2):F4})");
|
||||||
|
|
||||||
UpdateObjectPosition(startPosition, railRotation);
|
ApplyFullPoseUpdate(startPosition, railRotation);
|
||||||
LogManager.Info("[移动到起点] Rail路径已应用完整三维旋转姿态");
|
LogManager.Info("[移动到起点] Rail路径已应用完整三维旋转姿态");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -821,7 +821,7 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
else if (_route.PathType != PathType.Rail &&
|
else if (_route.PathType != PathType.Rail &&
|
||||||
TryCreatePlanarPathRotationAtStart(out var planarRotation))
|
TryCreatePlanarPathRotationAtStart(out var planarRotation))
|
||||||
{
|
{
|
||||||
UpdateObjectPosition(startPosition, planarRotation);
|
ApplyFullPoseUpdate(startPosition, planarRotation);
|
||||||
LogManager.Info("[移动到起点] 地面/吊装路径已应用完整三维姿态");
|
LogManager.Info("[移动到起点] 地面/吊装路径已应用完整三维姿态");
|
||||||
|
|
||||||
var startAppliedPoint = GetLiveBoundingBoxCenter(CurrentControlledObject ?? _animatedObject);
|
var startAppliedPoint = GetLiveBoundingBoxCenter(CurrentControlledObject ?? _animatedObject);
|
||||||
@ -975,7 +975,7 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
startPosition = ApplyGroundPathObjectLiftOffset(startPosition);
|
startPosition = ApplyGroundPathObjectLiftOffset(startPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateObjectPosition(startPosition);
|
ApplyLegacyYawPoseUpdate(startPosition);
|
||||||
SyncTrackedRotationToDisplayedPose(CurrentControlledObject ?? _animatedObject);
|
SyncTrackedRotationToDisplayedPose(CurrentControlledObject ?? _animatedObject);
|
||||||
_hasGroundRealObjectBasePose = false;
|
_hasGroundRealObjectBasePose = false;
|
||||||
|
|
||||||
@ -1879,7 +1879,7 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
_pausedProgress = 0.0; // 重置暂停进度
|
_pausedProgress = 0.0; // 重置暂停进度
|
||||||
|
|
||||||
// 初始化动画状态时不再强行覆盖 _currentYaw 为第一帧的 yaw
|
// 初始化动画状态时不再强行覆盖 _currentYaw 为第一帧的 yaw
|
||||||
// 这样在 UpdateObjectPosition(firstFrame.Position, firstFrame.YawRadians) 时
|
// 这样在 ApplyLegacyYawPoseUpdate(firstFrame.Position, firstFrame.YawRadians) 时
|
||||||
// deltaYaw = firstFrame.YawRadians - 物体初始Yaw,从而产生旋转增量让物体转向
|
// deltaYaw = firstFrame.YawRadians - 物体初始Yaw,从而产生旋转增量让物体转向
|
||||||
|
|
||||||
if (_animationFrames != null && _animationFrames.Count > 0)
|
if (_animationFrames != null && _animationFrames.Count > 0)
|
||||||
@ -2685,7 +2685,7 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新对象位置和朝向(支持绕物体中心旋转)
|
/// 更新对象位置和朝向(支持绕物体中心旋转)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void UpdateObjectPosition(Point3D newPosition, double newYaw = double.NaN)
|
private void ApplyLegacyYawPoseUpdate(Point3D newPosition, double newYaw = double.NaN)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -2741,7 +2741,7 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
{
|
{
|
||||||
// 纯平移
|
// 纯平移
|
||||||
incrementalTransform = Transform3D.CreateTranslation(deltaPos);
|
incrementalTransform = Transform3D.CreateTranslation(deltaPos);
|
||||||
LogManager.Debug($"[UpdateObjectPosition] 纯平移: ({deltaPos.X:F2},{deltaPos.Y:F2},{deltaPos.Z:F2})");
|
LogManager.Debug($"[LegacyYawPose] 纯平移: ({deltaPos.X:F2},{deltaPos.Y:F2},{deltaPos.Z:F2})");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 应用增量变换(false = 增量模式)
|
// 应用增量变换(false = 增量模式)
|
||||||
@ -2760,7 +2760,7 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
/// 使用完整三维姿态更新对象位置。
|
/// 使用完整三维姿态更新对象位置。
|
||||||
/// 当前先用于 Rail 路径,避免影响现有地面/吊装路径的 yaw 流程。
|
/// 当前先用于 Rail 路径,避免影响现有地面/吊装路径的 yaw 流程。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void UpdateObjectPosition(Point3D newPosition, Rotation3D newRotation)
|
private void ApplyFullPoseUpdate(Point3D newPosition, Rotation3D newRotation)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -3054,19 +3054,13 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
$"Z=({linear.Get(0, 2):F4},{linear.Get(1, 2):F4},{linear.Get(2, 2):F4})");
|
$"Z=({linear.Get(0, 2):F4},{linear.Get(1, 2):F4},{linear.Get(2, 2):F4})");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_savedObjectHasCustomRotation)
|
ApplyResolvedObjectPose(
|
||||||
{
|
_savedObjectPosition,
|
||||||
UpdateObjectPosition(_savedObjectPosition, _savedObjectRotation);
|
_savedObjectYaw,
|
||||||
}
|
_savedObjectRotation,
|
||||||
else
|
_savedObjectHasCustomRotation,
|
||||||
{
|
frameIndex: -1,
|
||||||
UpdateObjectPosition(_savedObjectPosition, _savedObjectYaw);
|
planarHostYawRadians: _savedObjectYaw);
|
||||||
}
|
|
||||||
|
|
||||||
_trackedPosition = _savedObjectPosition;
|
|
||||||
_currentYaw = _savedObjectYaw;
|
|
||||||
_trackedRotation = _savedObjectRotation;
|
|
||||||
_hasTrackedRotation = _savedObjectHasCustomRotation;
|
|
||||||
|
|
||||||
LogHostActualPoseAxes(obj, "[PAM恢复后宿主姿态]", false);
|
LogHostActualPoseAxes(obj, "[PAM恢复后宿主姿态]", false);
|
||||||
|
|
||||||
@ -3132,14 +3126,13 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
|
|
||||||
LogHostActualPoseAxes(obj, "[动画姿态复用前宿主姿态]", false);
|
LogHostActualPoseAxes(obj, "[动画姿态复用前宿主姿态]", false);
|
||||||
|
|
||||||
if (hasCustomRotation)
|
ApplyResolvedObjectPose(
|
||||||
{
|
targetPosition,
|
||||||
UpdateObjectPosition(targetPosition, targetRotation);
|
targetYawRadians,
|
||||||
}
|
targetRotation,
|
||||||
else
|
hasCustomRotation,
|
||||||
{
|
frameIndex: -1,
|
||||||
UpdateObjectPosition(targetPosition, targetYawRadians);
|
planarHostYawRadians: targetYawRadians);
|
||||||
}
|
|
||||||
|
|
||||||
LogHostActualPoseAxes(obj, "[动画姿态复用后宿主姿态]", false);
|
LogHostActualPoseAxes(obj, "[动画姿态复用后宿主姿态]", false);
|
||||||
|
|
||||||
@ -3251,16 +3244,9 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
|
|
||||||
_currentFrameIndex = frameIndex;
|
_currentFrameIndex = frameIndex;
|
||||||
|
|
||||||
// 更新对象位置和朝向
|
// 更新对象位置和朝向,复用动画主播放与恢复使用的同一入口。
|
||||||
var frameData = _animationFrames[_currentFrameIndex];
|
var frameData = _animationFrames[_currentFrameIndex];
|
||||||
if (frameData.HasCustomRotation)
|
ApplyAnimationFramePose(frameData, _currentFrameIndex);
|
||||||
{
|
|
||||||
UpdateObjectPosition(frameData.Position, frameData.Rotation);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateObjectPosition(frameData.Position, ResolveAnimationFramePlaybackYawRadians(frameData));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新碰撞高亮
|
// 更新碰撞高亮
|
||||||
UpdateCollisionHighlightFromFrame();
|
UpdateCollisionHighlightFromFrame();
|
||||||
@ -5740,27 +5726,57 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ApplyResolvedObjectPose(
|
||||||
|
frameData.Position,
|
||||||
|
ResolveAnimationFramePlaybackYawRadians(frameData),
|
||||||
|
frameData.Rotation,
|
||||||
|
frameData.HasCustomRotation,
|
||||||
|
frameIndex,
|
||||||
|
frameData.PlanarHostYawRadians);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyResolvedObjectPose(
|
||||||
|
Point3D targetPosition,
|
||||||
|
double resolvedYawRadians,
|
||||||
|
Rotation3D targetRotation,
|
||||||
|
bool hasCustomRotation,
|
||||||
|
int frameIndex,
|
||||||
|
double? planarHostYawRadians = null)
|
||||||
|
{
|
||||||
if (ShouldUsePlanarRealObjectPureIncrementFrames(_route?.PathType ?? PathType.Ground, IsRealObjectMode) &&
|
if (ShouldUsePlanarRealObjectPureIncrementFrames(_route?.PathType ?? PathType.Ground, IsRealObjectMode) &&
|
||||||
frameData.PlanarHostYawRadians.HasValue)
|
planarHostYawRadians.HasValue)
|
||||||
{
|
{
|
||||||
ApplyPlanarAnimationFrame(frameData.Position, frameData.PlanarHostYawRadians.Value);
|
ApplyPlanarAnimationFrame(targetPosition, planarHostYawRadians.Value);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (frameData.HasCustomRotation)
|
|
||||||
|
if (hasCustomRotation)
|
||||||
{
|
{
|
||||||
UpdateObjectPosition(frameData.Position, frameData.Rotation);
|
ApplyFullPoseUpdate(targetPosition, targetRotation);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (_route?.PathType == PathType.Ground || _route?.PathType == PathType.Hoisting)
|
|
||||||
|
if (_route?.PathType == PathType.Ground || _route?.PathType == PathType.Hoisting)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new InvalidOperationException(
|
||||||
$"平面路径播放帧 {frameIndex} 缺少完整姿态,禁止退回旧 yaw 链路。");
|
$"平面路径播放帧 {frameIndex} 缺少完整姿态,禁止退回旧 yaw 链路。");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
ApplyLegacyYawPoseUpdate(targetPosition, resolvedYawRadians);
|
||||||
UpdateObjectPosition(frameData.Position, ResolveAnimationFramePlaybackYawRadians(frameData));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private double ResolveAnimationFramePlaybackYawRadians(AnimationFrame frameData)
|
private double ResolveAnimationFramePlaybackYawRadians(AnimationFrame frameData)
|
||||||
|
{
|
||||||
|
return ResolveAnimationFramePlaybackYawRadians(
|
||||||
|
frameData,
|
||||||
|
_objectRotationCorrection,
|
||||||
|
CoordinateSystemManager.Instance.ResolvedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static double ResolveAnimationFramePlaybackYawRadians(
|
||||||
|
AnimationFrame frameData,
|
||||||
|
LocalEulerRotationCorrection rotationCorrection,
|
||||||
|
CoordinateSystemType hostType)
|
||||||
{
|
{
|
||||||
if (frameData == null)
|
if (frameData == null)
|
||||||
{
|
{
|
||||||
@ -5772,14 +5788,14 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
return NormalizeRadians(
|
return NormalizeRadians(
|
||||||
frameData.PlanarHostYawRadians.Value +
|
frameData.PlanarHostYawRadians.Value +
|
||||||
ResolvePlanarHostUpCorrectionRadians(
|
ResolvePlanarHostUpCorrectionRadians(
|
||||||
_objectRotationCorrection,
|
rotationCorrection,
|
||||||
CoordinateSystemManager.Instance.ResolvedType));
|
hostType));
|
||||||
}
|
}
|
||||||
|
|
||||||
double resolvedYaw = frameData.YawRadians;
|
double resolvedYaw = frameData.YawRadians;
|
||||||
if (!frameData.HasCustomRotation && !_objectRotationCorrection.IsZero)
|
if (!frameData.HasCustomRotation && !rotationCorrection.IsZero)
|
||||||
{
|
{
|
||||||
resolvedYaw += _objectRotationCorrection.ZDegrees * Math.PI / 180.0;
|
resolvedYaw += rotationCorrection.ZDegrees * Math.PI / 180.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NormalizeRadians(resolvedYaw);
|
return NormalizeRadians(resolvedYaw);
|
||||||
|
|||||||
@ -804,7 +804,7 @@ namespace NavisworksTransport
|
|||||||
if (candidate.AnimatedObjectHasTrackedRotation && targetRotation != null)
|
if (candidate.AnimatedObjectHasTrackedRotation && targetRotation != null)
|
||||||
{
|
{
|
||||||
LogManager.Info(
|
LogManager.Info(
|
||||||
$"[ClashDetective验证] 三维候选恢复: " +
|
$"[ClashDetective验证] 已跟踪姿态候选恢复: " +
|
||||||
$"对象={testAnimatedObject.DisplayName}, " +
|
$"对象={testAnimatedObject.DisplayName}, " +
|
||||||
$"目标跟踪点=({targetPosition.X:F3},{targetPosition.Y:F3},{targetPosition.Z:F3})");
|
$"目标跟踪点=({targetPosition.X:F3},{targetPosition.Y:F3},{targetPosition.Z:F3})");
|
||||||
|
|
||||||
@ -821,7 +821,7 @@ namespace NavisworksTransport
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new InvalidOperationException(
|
||||||
$"ClashDetective三维候选恢复失败:对象 {testAnimatedObject.DisplayName} 不受当前动画管理器控制。");
|
$"ClashDetective已跟踪姿态候选恢复失败:对象 {testAnimatedObject.DisplayName} 不受当前动画管理器控制。");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user