Remove legacy yaw recovery fallbacks
This commit is contained in:
parent
315fa46043
commit
61e6b79299
@ -975,7 +975,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
startPosition = ApplyGroundPathObjectLiftOffset(startPosition);
|
||||
}
|
||||
|
||||
ApplyLegacyYawPoseUpdate(startPosition);
|
||||
ApplyTrackedTranslationOnly(startPosition);
|
||||
SyncTrackedRotationToDisplayedPose(CurrentControlledObject ?? _animatedObject);
|
||||
_hasGroundRealObjectBasePose = false;
|
||||
|
||||
@ -1878,9 +1878,8 @@ namespace NavisworksTransport.Core.Animation
|
||||
_currentFrameIndex = 0; // 重置当前帧索引,确保从第一帧开始
|
||||
_pausedProgress = 0.0; // 重置暂停进度
|
||||
|
||||
// 初始化动画状态时不再强行覆盖 _currentYaw 为第一帧的 yaw
|
||||
// 这样在 ApplyLegacyYawPoseUpdate(firstFrame.Position, firstFrame.YawRadians) 时
|
||||
// deltaYaw = firstFrame.YawRadians - 物体初始Yaw,从而产生旋转增量让物体转向
|
||||
// 初始化动画状态时不再强行覆盖 _currentYaw 为第一帧的 yaw,
|
||||
// 由记录姿态应用链自行解释第一帧姿态。
|
||||
|
||||
if (_animationFrames != null && _animationFrames.Count > 0)
|
||||
{
|
||||
@ -2119,7 +2118,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
if (_currentFrameIndex != lastFrameIndex)
|
||||
{
|
||||
_currentFrameIndex = lastFrameIndex;
|
||||
ApplyAnimationFramePose(_animationFrames[_currentFrameIndex], _currentFrameIndex);
|
||||
ApplyRecordedPose(_animationFrames[_currentFrameIndex], _currentFrameIndex);
|
||||
LogManager.Info("[动画结束] 当前尚未到最后一帧,已补落最终姿态");
|
||||
}
|
||||
else
|
||||
@ -2683,9 +2682,10 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新对象位置和朝向(支持绕物体中心旋转)
|
||||
/// 仅按业务跟踪点执行平移,不改变当前姿态语义。
|
||||
/// PreserveInitialPose 起点搬运等链路应显式使用此入口,而不是借用旧 yaw 链。
|
||||
/// </summary>
|
||||
private void ApplyLegacyYawPoseUpdate(Point3D newPosition, double newYaw = double.NaN)
|
||||
private void ApplyTrackedTranslationOnly(Point3D newPosition)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -2699,50 +2699,8 @@ namespace NavisworksTransport.Core.Animation
|
||||
newPosition.Z - _trackedPosition.Z
|
||||
);
|
||||
|
||||
Transform3D incrementalTransform;
|
||||
|
||||
if (!double.IsNaN(newYaw))
|
||||
{
|
||||
// 有旋转:需要实现"绕物体当前位置自转"
|
||||
// 由于Transform3DComponents.Rotation总是绕世界原点旋转
|
||||
// 我们需要手动计算旋转导致的位置偏移,并补偿
|
||||
|
||||
double deltaYaw = newYaw - _currentYaw;
|
||||
//LogManager.Debug($"[UpdateObjectPosition] 当前yaw={_currentYaw * 180 / Math.PI:F2}度, 目标yaw={newYaw * 180 / Math.PI:F2}度, 旋转增量deltaYaw={deltaYaw * 180 / Math.PI:F2}度");
|
||||
|
||||
// 计算绕当前位置旋转的等效变换:
|
||||
// 1. 如果绕原点旋转deltaYaw,当前位置_trackedPosition会移动到哪里?
|
||||
double cos = Math.Cos(deltaYaw);
|
||||
double sin = Math.Sin(deltaYaw);
|
||||
double rotatedX = _trackedPosition.X * cos - _trackedPosition.Y * sin;
|
||||
double rotatedY = _trackedPosition.X * sin + _trackedPosition.Y * cos;
|
||||
|
||||
// 2. 但我们希望物体绕自己旋转,位置移动到newPosition
|
||||
// 所以需要的平移 = newPosition - (旋转后的位置)
|
||||
var compensatedTranslation = new Vector3D(
|
||||
newPosition.X - rotatedX,
|
||||
newPosition.Y - rotatedY,
|
||||
newPosition.Z - _trackedPosition.Z // Z保持deltaPos
|
||||
);
|
||||
|
||||
// 3. 组合:先旋转(绕原点),再平移(补偿+目标位置)
|
||||
var identity = Transform3D.CreateTranslation(new Vector3D(0, 0, 0));
|
||||
var components = identity.Factor();
|
||||
components.Rotation = new Rotation3D(new UnitVector3D(0, 0, 1), deltaYaw);
|
||||
components.Translation = compensatedTranslation;
|
||||
|
||||
incrementalTransform = components.Combine();
|
||||
|
||||
_currentYaw = newYaw;
|
||||
_trackedRotation = Rotation3D.Identity;
|
||||
_hasTrackedRotation = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 纯平移
|
||||
incrementalTransform = Transform3D.CreateTranslation(deltaPos);
|
||||
LogManager.Debug($"[LegacyYawPose] 纯平移: ({deltaPos.X:F2},{deltaPos.Y:F2},{deltaPos.Z:F2})");
|
||||
}
|
||||
Transform3D incrementalTransform = Transform3D.CreateTranslation(deltaPos);
|
||||
LogManager.Debug($"[TrackedTranslation] 纯平移: ({deltaPos.X:F2},{deltaPos.Y:F2},{deltaPos.Z:F2})");
|
||||
|
||||
// 应用增量变换(false = 增量模式)
|
||||
doc.Models.OverridePermanentTransform(modelItems, incrementalTransform, false);
|
||||
@ -3056,10 +3014,9 @@ namespace NavisworksTransport.Core.Animation
|
||||
|
||||
ApplyResolvedObjectPose(
|
||||
_savedObjectPosition,
|
||||
_savedObjectYaw,
|
||||
_savedObjectRotation,
|
||||
_savedObjectHasCustomRotation,
|
||||
frameIndex: -1,
|
||||
-1,
|
||||
planarHostYawRadians: _savedObjectYaw);
|
||||
|
||||
LogHostActualPoseAxes(obj, "[PAM恢复后宿主姿态]", false);
|
||||
@ -3128,10 +3085,9 @@ namespace NavisworksTransport.Core.Animation
|
||||
|
||||
ApplyResolvedObjectPose(
|
||||
targetPosition,
|
||||
targetYawRadians,
|
||||
targetRotation,
|
||||
hasCustomRotation,
|
||||
frameIndex: -1,
|
||||
-1,
|
||||
planarHostYawRadians: targetYawRadians);
|
||||
|
||||
LogHostActualPoseAxes(obj, "[动画姿态复用后宿主姿态]", false);
|
||||
@ -3246,7 +3202,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
|
||||
// 更新对象位置和朝向,复用动画主播放与恢复使用的同一入口。
|
||||
var frameData = _animationFrames[_currentFrameIndex];
|
||||
ApplyAnimationFramePose(frameData, _currentFrameIndex);
|
||||
ApplyRecordedPose(frameData, _currentFrameIndex);
|
||||
|
||||
// 更新碰撞高亮
|
||||
UpdateCollisionHighlightFromFrame();
|
||||
@ -5488,11 +5444,11 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保留给旧单轴调用方:按当前宿主 up 轴映射成三轴角度修正。
|
||||
/// 单轴兼容入口:按当前宿主 up 轴映射成三轴角度修正。
|
||||
/// </summary>
|
||||
public void SetObjectRotationCorrection(double rotationCorrection)
|
||||
{
|
||||
SetObjectRotationCorrection(CreateLegacyUpAxisCorrection(rotationCorrection));
|
||||
SetObjectRotationCorrection(CreateSingleAxisUpCorrection(rotationCorrection));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -5529,14 +5485,14 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保留给旧单轴调用方:按当前宿主 up 轴映射成三轴角度修正。
|
||||
/// 单轴兼容入口:按当前宿主 up 轴映射成三轴角度修正。
|
||||
/// </summary>
|
||||
public void SetObjectRotationCorrectionDirect(double rotationCorrection)
|
||||
{
|
||||
SetObjectRotationCorrectionDirect(CreateLegacyUpAxisCorrection(rotationCorrection));
|
||||
SetObjectRotationCorrectionDirect(CreateSingleAxisUpCorrection(rotationCorrection));
|
||||
}
|
||||
|
||||
private LocalEulerRotationCorrection CreateLegacyUpAxisCorrection(double rotationCorrection)
|
||||
private LocalEulerRotationCorrection CreateSingleAxisUpCorrection(double rotationCorrection)
|
||||
{
|
||||
var adapter = CoordinateSystemManager.Instance.CreateHostAdapter();
|
||||
return adapter.HostType == CoordinateSystemType.YUp
|
||||
@ -5692,7 +5648,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
if (_currentFrameIndex < _animationFrames.Count)
|
||||
{
|
||||
var frameData = _animationFrames[_currentFrameIndex];
|
||||
ApplyAnimationFramePose(frameData, _currentFrameIndex);
|
||||
ApplyRecordedPose(frameData, _currentFrameIndex);
|
||||
|
||||
// 更新碰撞高亮(基于预计算结果)
|
||||
UpdateCollisionHighlightFromFrame();
|
||||
@ -5719,7 +5675,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
UpdateFPSCounterAndCheckSwitch();
|
||||
}
|
||||
|
||||
private void ApplyAnimationFramePose(AnimationFrame frameData, int frameIndex)
|
||||
private void ApplyRecordedPose(AnimationFrame frameData, int frameIndex)
|
||||
{
|
||||
if (frameData == null)
|
||||
{
|
||||
@ -5728,16 +5684,16 @@ namespace NavisworksTransport.Core.Animation
|
||||
|
||||
ApplyResolvedObjectPose(
|
||||
frameData.Position,
|
||||
ResolveAnimationFramePlaybackYawRadians(frameData),
|
||||
frameData.Rotation,
|
||||
frameData.HasCustomRotation,
|
||||
frameIndex,
|
||||
frameData.PlanarHostYawRadians);
|
||||
frameData.PlanarHostYawRadians.HasValue
|
||||
? (double?)ResolveAnimationFramePlaybackYawRadians(frameData)
|
||||
: null);
|
||||
}
|
||||
|
||||
private void ApplyResolvedObjectPose(
|
||||
Point3D targetPosition,
|
||||
double resolvedYawRadians,
|
||||
Rotation3D targetRotation,
|
||||
bool hasCustomRotation,
|
||||
int frameIndex,
|
||||
@ -5746,7 +5702,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
if (ShouldUsePlanarRealObjectPureIncrementFrames(_route?.PathType ?? PathType.Ground, IsRealObjectMode) &&
|
||||
planarHostYawRadians.HasValue)
|
||||
{
|
||||
ApplyPlanarAnimationFrame(targetPosition, planarHostYawRadians.Value);
|
||||
ApplyPlanarTrackedPose(targetPosition, planarHostYawRadians.Value);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5756,13 +5712,9 @@ namespace NavisworksTransport.Core.Animation
|
||||
return;
|
||||
}
|
||||
|
||||
if (_route?.PathType == PathType.Ground || _route?.PathType == PathType.Hoisting)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"平面路径播放帧 {frameIndex} 缺少完整姿态,禁止退回旧 yaw 链路。");
|
||||
}
|
||||
|
||||
ApplyLegacyYawPoseUpdate(targetPosition, resolvedYawRadians);
|
||||
string pathTypeName = (_route?.PathType ?? PathType.Ground).GetDisplayName();
|
||||
throw new InvalidOperationException(
|
||||
$"{pathTypeName}记录姿态 {frameIndex} 缺少完整姿态,禁止退回旧 yaw 链路。");
|
||||
}
|
||||
|
||||
private double ResolveAnimationFramePlaybackYawRadians(AnimationFrame frameData)
|
||||
@ -5802,9 +5754,9 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 专门用于Ground路径动画帧播放。使用业务跟踪点 _trackedPosition 作为当前位置,不读取实时包围盒中心回写主链。
|
||||
/// 应用平面路径的已记录姿态。使用业务跟踪点 _trackedPosition 作为当前位置,不读取实时包围盒中心回写主链。
|
||||
/// </summary>
|
||||
private void ApplyPlanarAnimationFrame(Point3D targetPosition, double targetYawRadians)
|
||||
private void ApplyPlanarTrackedPose(Point3D targetPosition, double targetYawRadians)
|
||||
{
|
||||
var controlledObject = CurrentControlledObject;
|
||||
if (controlledObject == null) return;
|
||||
|
||||
@ -826,50 +826,10 @@ namespace NavisworksTransport
|
||||
}
|
||||
else
|
||||
{
|
||||
// 旧二维候选验证仍沿用“回到 CAD 原始位置再应用增量”的成熟语义。
|
||||
doc.Models.ResetPermanentTransform(modelItems);
|
||||
|
||||
var originalBounds = testAnimatedObject.BoundingBox();
|
||||
var originalPos = new Point3D(
|
||||
(originalBounds.Min.X + originalBounds.Max.X) / 2,
|
||||
(originalBounds.Min.Y + originalBounds.Max.Y) / 2,
|
||||
(originalBounds.Min.Z + originalBounds.Max.Z) / 2
|
||||
);
|
||||
var originalYaw = ModelItemTransformHelper.GetYawFromTransform(testAnimatedObject.Transform);
|
||||
|
||||
var deltaPos = new Vector3D(
|
||||
targetPosition.X - originalPos.X,
|
||||
targetPosition.Y - originalPos.Y,
|
||||
targetPosition.Z - originalPos.Z
|
||||
);
|
||||
double deltaYaw = targetYaw - originalYaw;
|
||||
|
||||
Transform3D transform;
|
||||
if (Math.Abs(deltaYaw) > 0.001)
|
||||
{
|
||||
double cos = Math.Cos(deltaYaw);
|
||||
double sin = Math.Sin(deltaYaw);
|
||||
double rotatedX = originalPos.X * cos - originalPos.Y * sin;
|
||||
double rotatedY = originalPos.X * sin + originalPos.Y * cos;
|
||||
|
||||
var compensatedTranslation = new Vector3D(
|
||||
targetPosition.X - rotatedX,
|
||||
targetPosition.Y - rotatedY,
|
||||
deltaPos.Z
|
||||
);
|
||||
|
||||
var identity = Transform3D.CreateTranslation(new Vector3D(0, 0, 0));
|
||||
var components = identity.Factor();
|
||||
components.Rotation = new Rotation3D(new UnitVector3D(0, 0, 1), deltaYaw);
|
||||
components.Translation = compensatedTranslation;
|
||||
transform = components.Combine();
|
||||
}
|
||||
else
|
||||
{
|
||||
transform = Transform3D.CreateTranslation(deltaPos);
|
||||
}
|
||||
|
||||
doc.Models.OverridePermanentTransform(modelItems, transform, false);
|
||||
throw new InvalidOperationException(
|
||||
$"ClashDetective候选恢复缺少完整姿态:对象 {testAnimatedObject.DisplayName}," +
|
||||
$"目标跟踪点=({targetPosition.X:F3},{targetPosition.Y:F3},{targetPosition.Z:F3})," +
|
||||
$"TrackedYaw={targetYaw:F6}rad。");
|
||||
}
|
||||
|
||||
var tempTestName = $"临时验证_{confirmedCount + 1}_{i}_{DateTime.Now:HHmmss_fff}";
|
||||
|
||||
@ -98,49 +98,47 @@ namespace NavisworksTransport.Utils
|
||||
{
|
||||
if (animatedObject == null) return null;
|
||||
|
||||
try
|
||||
var pam = PathAnimationManager.GetInstance();
|
||||
if (pam == null || !pam.ControlsAnimatedObject(animatedObject))
|
||||
{
|
||||
// 从PathAnimationManager获取当前实际朝向
|
||||
var pam = PathAnimationManager.GetInstance();
|
||||
var currentYaw = pam.CurrentYaw;
|
||||
var currentRotation = pam.TrackedRotation;
|
||||
var hasCustomRotation = pam.HasTrackedRotation;
|
||||
var currentState = pam.GetObjectCurrentPosition(animatedObject);
|
||||
pam.SaveObjectState(animatedObject);
|
||||
throw new InvalidOperationException(
|
||||
$"保存碰撞场景前的动画物体状态必须复用 PathAnimationManager:对象 {animatedObject.DisplayName} 不受当前动画管理器控制。");
|
||||
}
|
||||
|
||||
var state = ModelItemTransformHelper.SaveObjectState(
|
||||
animatedObject,
|
||||
currentYaw,
|
||||
currentState.Position,
|
||||
currentRotation,
|
||||
hasCustomRotation);
|
||||
|
||||
LogManager.Info(string.Format("已保存动画物体状态: {0}, 位置=({1:F2},{2:F2},{3:F2}), 朝向={4:F2}°, customRotation={5}",
|
||||
animatedObject.DisplayName, state.Position.X, state.Position.Y, state.Position.Z,
|
||||
currentYaw * 180 / Math.PI, state.HasCustomRotation));
|
||||
if (state.HasCustomRotation && state.Rotation != null)
|
||||
{
|
||||
var linear = new Transform3D(state.Rotation).Linear;
|
||||
LogManager.Info(string.Format(
|
||||
"[报告姿态保存] {0} 保存姿态: " +
|
||||
"位置=({1:F3},{2:F3},{3:F3}), " +
|
||||
"X=({4:F4},{5:F4},{6:F4}), " +
|
||||
"Y=({7:F4},{8:F4},{9:F4}), " +
|
||||
"Z=({10:F4},{11:F4},{12:F4})",
|
||||
animatedObject.DisplayName,
|
||||
state.Position.X, state.Position.Y, state.Position.Z,
|
||||
linear.Get(0, 0), linear.Get(1, 0), linear.Get(2, 0),
|
||||
linear.Get(0, 1), linear.Get(1, 1), linear.Get(2, 1),
|
||||
linear.Get(0, 2), linear.Get(1, 2), linear.Get(2, 2)));
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
catch (Exception ex)
|
||||
// 从 PathAnimationManager 获取当前实际姿态,不再退回工具层旧 yaw 快照语义。
|
||||
var currentYaw = pam.CurrentYaw;
|
||||
var currentRotation = pam.TrackedRotation;
|
||||
var hasCustomRotation = pam.HasTrackedRotation;
|
||||
var currentState = pam.GetObjectCurrentPosition(animatedObject);
|
||||
pam.SaveObjectState(animatedObject);
|
||||
|
||||
var state = new ModelItemTransformHelper.ObjectStateSnapshot
|
||||
{
|
||||
LogManager.Error(string.Format("保存动画物体状态失败: {0}", ex.Message), ex);
|
||||
return null;
|
||||
Position = currentState.Position,
|
||||
Rotation = currentRotation,
|
||||
HasCustomRotation = hasCustomRotation
|
||||
};
|
||||
|
||||
LogManager.Info(string.Format("已保存动画物体状态: {0}, 位置=({1:F2},{2:F2},{3:F2}), 朝向={4:F2}°, customRotation={5}",
|
||||
animatedObject.DisplayName, state.Position.X, state.Position.Y, state.Position.Z,
|
||||
currentYaw * 180 / Math.PI, state.HasCustomRotation));
|
||||
if (state.HasCustomRotation && state.Rotation != null)
|
||||
{
|
||||
var linear = new Transform3D(state.Rotation).Linear;
|
||||
LogManager.Info(string.Format(
|
||||
"[报告姿态保存] {0} 保存姿态: " +
|
||||
"位置=({1:F3},{2:F3},{3:F3}), " +
|
||||
"X=({4:F4},{5:F4},{6:F4}), " +
|
||||
"Y=({7:F4},{8:F4},{9:F4}), " +
|
||||
"Z=({10:F4},{11:F4},{12:F4})",
|
||||
animatedObject.DisplayName,
|
||||
state.Position.X, state.Position.Y, state.Position.Z,
|
||||
linear.Get(0, 0), linear.Get(1, 0), linear.Get(2, 0),
|
||||
linear.Get(0, 1), linear.Get(1, 1), linear.Get(2, 1),
|
||||
linear.Get(0, 2), linear.Get(1, 2), linear.Get(2, 2)));
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -152,76 +150,34 @@ namespace NavisworksTransport.Utils
|
||||
{
|
||||
if (animatedObject == null || state == null) return;
|
||||
|
||||
try
|
||||
if (state.HasCustomRotation && state.Rotation != null)
|
||||
{
|
||||
if (state.HasCustomRotation && state.Rotation != null)
|
||||
{
|
||||
var linear = new Transform3D(state.Rotation).Linear;
|
||||
LogManager.Info(string.Format(
|
||||
"[报告姿态恢复] {0} 恢复目标姿态: " +
|
||||
"位置=({1:F3},{2:F3},{3:F3}), " +
|
||||
"X=({4:F4},{5:F4},{6:F4}), " +
|
||||
"Y=({7:F4},{8:F4},{9:F4}), " +
|
||||
"Z=({10:F4},{11:F4},{12:F4})",
|
||||
animatedObject.DisplayName,
|
||||
state.Position.X, state.Position.Y, state.Position.Z,
|
||||
linear.Get(0, 0), linear.Get(1, 0), linear.Get(2, 0),
|
||||
linear.Get(0, 1), linear.Get(1, 1), linear.Get(2, 1),
|
||||
linear.Get(0, 2), linear.Get(1, 2), linear.Get(2, 2)));
|
||||
}
|
||||
|
||||
var pam = PathAnimationManager.GetInstance();
|
||||
if (pam != null && pam.ControlsAnimatedObject(animatedObject))
|
||||
{
|
||||
pam.RestoreAnimatedObjectState(animatedObject);
|
||||
LogManager.Info(string.Format(
|
||||
"动画物体已通过PathAnimationManager恢复状态: {0}, customRotation={1}",
|
||||
animatedObject.DisplayName,
|
||||
state.HasCustomRotation));
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.HasCustomRotation)
|
||||
{
|
||||
bool isVirtualWithCustomRotation = VirtualObjectManager.Instance.IsVirtualObjectActive &&
|
||||
VirtualObjectManager.Instance.CurrentVirtualObject == animatedObject;
|
||||
if (isVirtualWithCustomRotation)
|
||||
{
|
||||
ModelItemTransformHelper.RestoreObjectStateWithScale(animatedObject, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModelItemTransformHelper.RestoreObjectState(animatedObject, state);
|
||||
}
|
||||
|
||||
LogManager.Info(string.Format("动画物体已通过状态快照恢复三维姿态: {0}", animatedObject.DisplayName));
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否是虚拟物体
|
||||
bool isVirtual = VirtualObjectManager.Instance.IsVirtualObjectActive &&
|
||||
VirtualObjectManager.Instance.CurrentVirtualObject == animatedObject;
|
||||
|
||||
if (isVirtual)
|
||||
{
|
||||
// 虚拟物体:使用带当前缩放的移动方法
|
||||
ModelItemTransformHelper.MoveItemToPositionAndYawWithCurrentScale(
|
||||
animatedObject, state.Position, state.YawRadians);
|
||||
LogManager.Info(string.Format("虚拟物体已恢复到原始状态: {0}, 位置=({1:F2},{2:F2},{3:F2}), 朝向={4:F2}°",
|
||||
animatedObject.DisplayName, state.Position.X, state.Position.Y, state.Position.Z,
|
||||
state.YawRadians * 180 / Math.PI));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 普通物体:使用标准恢复
|
||||
ModelItemTransformHelper.RestoreObjectState(animatedObject, state);
|
||||
LogManager.Info(string.Format("动画物体已恢复到原始状态: {0}", animatedObject.DisplayName));
|
||||
}
|
||||
var linear = new Transform3D(state.Rotation).Linear;
|
||||
LogManager.Info(string.Format(
|
||||
"[报告姿态恢复] {0} 恢复目标姿态: " +
|
||||
"位置=({1:F3},{2:F3},{3:F3}), " +
|
||||
"X=({4:F4},{5:F4},{6:F4}), " +
|
||||
"Y=({7:F4},{8:F4},{9:F4}), " +
|
||||
"Z=({10:F4},{11:F4},{12:F4})",
|
||||
animatedObject.DisplayName,
|
||||
state.Position.X, state.Position.Y, state.Position.Z,
|
||||
linear.Get(0, 0), linear.Get(1, 0), linear.Get(2, 0),
|
||||
linear.Get(0, 1), linear.Get(1, 1), linear.Get(2, 1),
|
||||
linear.Get(0, 2), linear.Get(1, 2), linear.Get(2, 2)));
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
var pam = PathAnimationManager.GetInstance();
|
||||
if (pam == null || !pam.ControlsAnimatedObject(animatedObject))
|
||||
{
|
||||
LogManager.Error(string.Format("恢复动画物体状态失败: {0}", ex.Message), ex);
|
||||
throw new InvalidOperationException(
|
||||
$"恢复碰撞场景前的动画物体状态必须复用 PathAnimationManager:对象 {animatedObject.DisplayName} 不受当前动画管理器控制。");
|
||||
}
|
||||
|
||||
pam.RestoreAnimatedObjectState(animatedObject);
|
||||
LogManager.Info(string.Format(
|
||||
"动画物体已通过PathAnimationManager恢复状态: {0}, customRotation={1}",
|
||||
animatedObject.DisplayName,
|
||||
state.HasCustomRotation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1237,197 +1237,8 @@ namespace NavisworksTransport.Utils
|
||||
public class ObjectStateSnapshot
|
||||
{
|
||||
public Point3D Position { get; set; }
|
||||
public double YawRadians { get; set; }
|
||||
public Rotation3D Rotation { get; set; }
|
||||
public bool HasCustomRotation { get; set; }
|
||||
public Transform3D Transform { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存物体当前状态
|
||||
/// 注意:YawRadians 通过当前位置计算,因为 Transform 返回的是CAD原始值
|
||||
/// </summary>
|
||||
public static ObjectStateSnapshot SaveObjectState(
|
||||
ModelItem item,
|
||||
double? currentYaw = null,
|
||||
Point3D currentPosition = null,
|
||||
Rotation3D currentRotation = null,
|
||||
bool hasCustomRotation = false)
|
||||
{
|
||||
if (item == null) return null;
|
||||
|
||||
var bounds = item.BoundingBox();
|
||||
|
||||
// 🔥 关键:如果提供了当前朝向(如 PathAnimationManager._currentYaw),使用它
|
||||
// 否则从 Transform 获取(但这可能不是实际朝向)
|
||||
double yaw;
|
||||
if (currentYaw.HasValue)
|
||||
{
|
||||
yaw = currentYaw.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 尝试通过包围盒方向计算(如果物体有几何特征)
|
||||
yaw = GetYawFromTransform(item.Transform);
|
||||
LogManager.Debug($"[SaveObjectState] 未提供当前朝向,使用Transform: {yaw * 180 / Math.PI:F2}°");
|
||||
}
|
||||
|
||||
return new ObjectStateSnapshot
|
||||
{
|
||||
Position = currentPosition ?? new Point3D(bounds.Center.X, bounds.Center.Y, bounds.Min.Z),
|
||||
YawRadians = yaw,
|
||||
Rotation = currentRotation ?? Rotation3D.Identity,
|
||||
HasCustomRotation = hasCustomRotation,
|
||||
Transform = item.Transform
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从状态快照恢复物体位置和朝向(标准版本,会重置缩放)
|
||||
/// </summary>
|
||||
public static void RestoreObjectState(ModelItem item, ObjectStateSnapshot state)
|
||||
{
|
||||
RestoreObjectStateInternal(item, state, preserveScale: false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从状态快照恢复物体位置和朝向(保留缩放版本,用于虚拟物体)
|
||||
/// </summary>
|
||||
public static void RestoreObjectStateWithScale(ModelItem item, ObjectStateSnapshot state)
|
||||
{
|
||||
RestoreObjectStateInternal(item, state, preserveScale: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从状态快照恢复物体位置的内部实现
|
||||
/// </summary>
|
||||
private static void RestoreObjectStateInternal(ModelItem item, ObjectStateSnapshot state, bool preserveScale)
|
||||
{
|
||||
if (item == null || state == null) return;
|
||||
|
||||
if (state.HasCustomRotation)
|
||||
{
|
||||
if (preserveScale)
|
||||
{
|
||||
MoveItemToPositionAndRotationWithCurrentScale(item, state.Position, state.Rotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
MoveItemToPositionAndRotation(item, state.Position, state.Rotation);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var doc = Application.ActiveDocument;
|
||||
var modelItems = new ModelItemCollection { item };
|
||||
|
||||
// 1. 先回到CAD原始位置
|
||||
doc.Models.ResetPermanentTransform(modelItems);
|
||||
|
||||
// 2. 从CAD原始位置移动到保存的位置
|
||||
// 获取CAD原始状态
|
||||
var originalBounds = item.BoundingBox();
|
||||
var originalCenterPos = originalBounds.Center;
|
||||
var originalYaw = GetYawFromTransform(item.Transform);
|
||||
|
||||
// 计算到保存位置的增量
|
||||
var deltaPos = new Vector3D(
|
||||
state.Position.X - originalCenterPos.X,
|
||||
state.Position.Y - originalCenterPos.Y,
|
||||
state.Position.Z - originalCenterPos.Z
|
||||
);
|
||||
double deltaYaw = state.YawRadians - originalYaw;
|
||||
|
||||
// 应用增量变换
|
||||
Transform3D transform;
|
||||
if (Math.Abs(deltaYaw) > 0.001)
|
||||
{
|
||||
double cos = Math.Cos(deltaYaw);
|
||||
double sin = Math.Sin(deltaYaw);
|
||||
double rotatedX = originalCenterPos.X * cos - originalCenterPos.Y * sin;
|
||||
double rotatedY = originalCenterPos.X * sin + originalCenterPos.Y * cos;
|
||||
|
||||
var compensatedTranslation = new Vector3D(
|
||||
state.Position.X - rotatedX,
|
||||
state.Position.Y - rotatedY,
|
||||
state.Position.Z - originalCenterPos.Z
|
||||
);
|
||||
|
||||
var identity = Transform3D.CreateTranslation(new Vector3D(0, 0, 0));
|
||||
var components = identity.Factor();
|
||||
components.Rotation = new Rotation3D(new UnitVector3D(0, 0, 1), deltaYaw);
|
||||
components.Translation = compensatedTranslation;
|
||||
transform = components.Combine();
|
||||
}
|
||||
else
|
||||
{
|
||||
transform = Transform3D.CreateTranslation(deltaPos);
|
||||
}
|
||||
|
||||
doc.Models.OverridePermanentTransform(modelItems, transform, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将物体移动到指定位置和朝向,同时保持当前缩放(专为虚拟物体设计)
|
||||
/// </summary>
|
||||
public static void MoveItemToPositionAndYawWithCurrentScale(ModelItem item, Point3D targetPosition, double targetYaw)
|
||||
{
|
||||
var doc = Application.ActiveDocument;
|
||||
var modelItems = new ModelItemCollection { item };
|
||||
|
||||
// 获取当前变换中的缩放
|
||||
var currentTransform = item.Transform;
|
||||
var currentComponents = currentTransform.Factor();
|
||||
var currentScale = currentComponents.Scale;
|
||||
|
||||
// 重置到CAD原始状态
|
||||
doc.Models.ResetPermanentTransform(modelItems);
|
||||
|
||||
// 获取CAD原始状态
|
||||
var originalBounds = item.BoundingBox();
|
||||
var originalCenterPos = originalBounds.Center;
|
||||
var originalYaw = GetYawFromTransform(item.Transform);
|
||||
|
||||
// 计算从CAD原始位置到目标位置的增量
|
||||
var deltaPos = new Vector3D(
|
||||
targetPosition.X - originalCenterPos.X,
|
||||
targetPosition.Y - originalCenterPos.Y,
|
||||
targetPosition.Z - originalCenterPos.Z
|
||||
);
|
||||
double deltaYaw = targetYaw - originalYaw;
|
||||
|
||||
// 构建变换组件,保留原有缩放
|
||||
var identity = Transform3D.CreateTranslation(new Vector3D(0, 0, 0));
|
||||
var components = identity.Factor();
|
||||
components.Scale = currentScale; // 保留当前缩放
|
||||
|
||||
if (Math.Abs(deltaYaw) > 0.001)
|
||||
{
|
||||
components.Rotation = new Rotation3D(new UnitVector3D(0, 0, 1), deltaYaw);
|
||||
}
|
||||
|
||||
// 计算平移(考虑旋转带来的位置偏移)
|
||||
if (Math.Abs(deltaYaw) > 0.001)
|
||||
{
|
||||
double cos = Math.Cos(deltaYaw);
|
||||
double sin = Math.Sin(deltaYaw);
|
||||
double rotatedX = originalCenterPos.X * cos - originalCenterPos.Y * sin;
|
||||
double rotatedY = originalCenterPos.X * sin + originalCenterPos.Y * cos;
|
||||
|
||||
components.Translation = new Vector3D(
|
||||
targetPosition.X - rotatedX,
|
||||
targetPosition.Y - rotatedY,
|
||||
targetPosition.Z - originalCenterPos.Z
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
components.Translation = deltaPos;
|
||||
}
|
||||
|
||||
// 应用组合变换
|
||||
Transform3D transform = components.Combine();
|
||||
doc.Models.OverridePermanentTransform(modelItems, transform, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user