refactor: 清理 fragment/参考姿态残留命名(默认轴约定一致性)

RealObjectRailAxisConventionResolver:
- 头注释改为默认轴约定语义,参数 referenceAxisX/Y/Z → defaultAxisX/Y/Z

PathAnimationManager:
- 字段 _realObjectReference* → _realObjectDefault*(默认轴约定)
- 方法 RealObjectReferenceRotation → RealObjectDefaultConvention、
  ReferenceBasedRealObjectPlanarPose → DefaultConventionRealObjectPlanarPose
- ResolveCurrentRotationBaseline 参数 hasReferenceRotation/referenceRotation → hasDefaultRotation/defaultRotation

RealObjectPlanarPoseSolver:
- TryCreatePlanarPoseFromReferencePose → FromDefaultPose、
  参数 referenceRotation → defaultRotation、fixedReferenceAxis → fixedDefaultAxis
- 属性 SelectedReferenceAxis* → SelectedDefaultAxis*(含测试同步)

测试: 方法名/局部变量 referenceRotation → defaultRotation 同步
  (VirtualObjectReferencePose 虚拟物体资产参考姿态为有效概念,保留)

TestAutomationHttpService: 过时错误文案(fragment 姿态解析失败)→ 盒内/层级链描述

验证: 单元 185/185、集成 25/25
This commit is contained in:
tian 2026-08-06 00:16:00 +08:00
parent 29da68f6d3
commit 869bfd3787
8 changed files with 162 additions and 163 deletions

View File

@ -227,8 +227,8 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
isRealObjectMode: true, isRealObjectMode: true,
hasTrackedRotation: true, hasTrackedRotation: true,
trackedRotation: trackedRotation, trackedRotation: trackedRotation,
hasReferenceRotation: false, hasDefaultRotation: false,
referenceRotation: Rotation3D.Identity, defaultRotation: Rotation3D.Identity,
transformRotation: Rotation3D.Identity, transformRotation: Rotation3D.Identity,
hasActualGeometryRotation: true, hasActualGeometryRotation: true,
actualGeometryRotation: actualGeometryRotation); actualGeometryRotation: actualGeometryRotation);
@ -250,8 +250,8 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
isRealObjectMode: true, isRealObjectMode: true,
hasTrackedRotation: true, hasTrackedRotation: true,
trackedRotation: trackedRotation, trackedRotation: trackedRotation,
hasReferenceRotation: false, hasDefaultRotation: false,
referenceRotation: Rotation3D.Identity, defaultRotation: Rotation3D.Identity,
transformRotation: Rotation3D.Identity, transformRotation: Rotation3D.Identity,
hasActualGeometryRotation: true, hasActualGeometryRotation: true,
actualGeometryRotation: actualGeometryRotation); actualGeometryRotation: actualGeometryRotation);

View File

@ -9,36 +9,36 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
public class RealObjectPlanarPoseSolverTests public class RealObjectPlanarPoseSolverTests
{ {
[TestMethod] [TestMethod]
public void ShouldChooseClosestCandidateAxis_FromRotatedReferencePose() public void ShouldChooseClosestCandidateAxis_FromRotatedDefaultPose()
{ {
Quaternion referenceRotation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, (float)(Math.PI / 6.0)); Quaternion defaultRotation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, (float)(Math.PI / 6.0));
Vector3 desiredForward = new Vector3(1.0f, 0.2f, 0.1f); Vector3 desiredForward = new Vector3(1.0f, 0.2f, 0.1f);
Vector3 desiredUp = Vector3.UnitZ; Vector3 desiredUp = Vector3.UnitZ;
bool ok = RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromReferencePose( bool ok = RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromDefaultPose(
referenceRotation, defaultRotation,
desiredForward, desiredForward,
desiredUp, desiredUp,
out RealObjectPlanarPoseSolution solution); out RealObjectPlanarPoseSolution solution);
Assert.IsTrue(ok); Assert.IsTrue(ok);
AssertVector(solution.SelectedReferenceAxisLocal, 1.0, 0.0, 0.0); AssertVector(solution.SelectedDefaultAxisLocal, 1.0, 0.0, 0.0);
Vector3 transformedSelectedAxis = Vector3.Normalize(Vector3.Transform(solution.SelectedReferenceAxisLocal, solution.BaselineRotation)); Vector3 transformedSelectedAxis = Vector3.Normalize(Vector3.Transform(solution.SelectedDefaultAxisLocal, solution.BaselineRotation));
AssertVector(transformedSelectedAxis, desiredForward.X / desiredForward.Length(), desiredForward.Y / desiredForward.Length(), desiredForward.Z / desiredForward.Length(), 1e-4); AssertVector(transformedSelectedAxis, desiredForward.X / desiredForward.Length(), desiredForward.Y / desiredForward.Length(), desiredForward.Z / desiredForward.Length(), 1e-4);
} }
[TestMethod] [TestMethod]
public void ShouldPreferNegativeAxisWhenItMatchesForwardBest() public void ShouldPreferNegativeAxisWhenItMatchesForwardBest()
{ {
bool ok = RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromReferencePose( bool ok = RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromDefaultPose(
Quaternion.Identity, Quaternion.Identity,
new Vector3(-0.1f, -1.0f, 0.05f), new Vector3(-0.1f, -1.0f, 0.05f),
Vector3.UnitZ, Vector3.UnitZ,
out RealObjectPlanarPoseSolution solution); out RealObjectPlanarPoseSolution solution);
Assert.IsTrue(ok); Assert.IsTrue(ok);
AssertVector(solution.SelectedReferenceAxisLocal, 0.0, -1.0, 0.0); AssertVector(solution.SelectedDefaultAxisLocal, 0.0, -1.0, 0.0);
} }
[TestMethod] [TestMethod]
@ -46,21 +46,21 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
{ {
Vector3 desiredForward = Vector3.Normalize(new Vector3(1.0f, 1.0f, 1.0f)); Vector3 desiredForward = Vector3.Normalize(new Vector3(1.0f, 1.0f, 1.0f));
bool ok = RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromReferencePose( bool ok = RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromDefaultPose(
Quaternion.Identity, Quaternion.Identity,
desiredForward, desiredForward,
Vector3.UnitY, Vector3.UnitY,
out RealObjectPlanarPoseSolution solution); out RealObjectPlanarPoseSolution solution);
Assert.IsTrue(ok); Assert.IsTrue(ok);
Vector3 transformedSelectedAxis = Vector3.Normalize(Vector3.Transform(solution.SelectedReferenceAxisLocal, solution.BaselineRotation)); Vector3 transformedSelectedAxis = Vector3.Normalize(Vector3.Transform(solution.SelectedDefaultAxisLocal, solution.BaselineRotation));
AssertVector(transformedSelectedAxis, desiredForward.X, desiredForward.Y, desiredForward.Z, 1e-4); AssertVector(transformedSelectedAxis, desiredForward.X, desiredForward.Y, desiredForward.Z, 1e-4);
} }
[TestMethod] [TestMethod]
public void ShouldPreserveReferenceOrthogonalityByApplyingSingleRotationDelta() public void ShouldPreserveDefaultOrthogonalityByApplyingSingleRotationDelta()
{ {
Quaternion referenceRotation = Quaternion.Normalize( Quaternion defaultRotation = Quaternion.Normalize(
Quaternion.CreateFromYawPitchRoll( Quaternion.CreateFromYawPitchRoll(
(float)(Math.PI / 7.0), (float)(Math.PI / 7.0),
(float)(Math.PI / 9.0), (float)(Math.PI / 9.0),
@ -68,8 +68,8 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
Vector3 desiredForward = Vector3.Normalize(new Vector3(-0.3f, 0.8f, 0.52f)); Vector3 desiredForward = Vector3.Normalize(new Vector3(-0.3f, 0.8f, 0.52f));
bool ok = RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromReferencePose( bool ok = RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromDefaultPose(
referenceRotation, defaultRotation,
desiredForward, desiredForward,
Vector3.UnitZ, Vector3.UnitZ,
out RealObjectPlanarPoseSolution solution); out RealObjectPlanarPoseSolution solution);
@ -89,33 +89,33 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
} }
[TestMethod] [TestMethod]
public void FixedReferenceAxis_ShouldKeepAxisFamilyAcrossTurn() public void FixedDefaultAxis_ShouldKeepAxisFamilyAcrossTurn()
{ {
Quaternion referenceRotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, (float)Math.PI); Quaternion defaultRotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, (float)Math.PI);
Vector3 desiredForwardStart = Vector3.Normalize(new Vector3(-0.95f, 0.0f, 0.31f)); Vector3 desiredForwardStart = Vector3.Normalize(new Vector3(-0.95f, 0.0f, 0.31f));
Vector3 desiredForwardTurn = Vector3.Normalize(new Vector3(0.22f, 0.0f, 0.97f)); Vector3 desiredForwardTurn = Vector3.Normalize(new Vector3(0.22f, 0.0f, 0.97f));
Vector3 desiredUp = Vector3.UnitY; Vector3 desiredUp = Vector3.UnitY;
bool startOk = RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromReferencePose( bool startOk = RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromDefaultPose(
referenceRotation, defaultRotation,
desiredForwardStart, desiredForwardStart,
desiredUp, desiredUp,
out RealObjectPlanarPoseSolution startSolution); out RealObjectPlanarPoseSolution startSolution);
Assert.IsTrue(startOk); Assert.IsTrue(startOk);
bool turnOk = RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromReferencePose( bool turnOk = RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromDefaultPose(
referenceRotation, defaultRotation,
desiredForwardTurn, desiredForwardTurn,
desiredUp, desiredUp,
startSolution.SelectedReferenceAxisDirection, startSolution.SelectedDefaultAxisDirection,
out RealObjectPlanarPoseSolution turnSolution); out RealObjectPlanarPoseSolution turnSolution);
Assert.IsTrue(turnOk); Assert.IsTrue(turnOk);
Assert.AreEqual(startSolution.SelectedReferenceAxisDirection, turnSolution.SelectedReferenceAxisDirection); Assert.AreEqual(startSolution.SelectedDefaultAxisDirection, turnSolution.SelectedDefaultAxisDirection);
Vector3 transformedSelectedAxis = Vector3.Normalize( Vector3 transformedSelectedAxis = Vector3.Normalize(
Vector3.Transform(turnSolution.SelectedReferenceAxisLocal, turnSolution.BaselineRotation)); Vector3.Transform(turnSolution.SelectedDefaultAxisLocal, turnSolution.BaselineRotation));
AssertVector( AssertVector(
transformedSelectedAxis, transformedSelectedAxis,
desiredForwardTurn.X, desiredForwardTurn.X,
@ -127,23 +127,23 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
[TestMethod] [TestMethod]
public void FixedPositiveX_ShouldNotSwitchToZ_WhenPathLeansTowardZ() public void FixedPositiveX_ShouldNotSwitchToZ_WhenPathLeansTowardZ()
{ {
Quaternion referenceRotation = Quaternion.Identity; Quaternion defaultRotation = Quaternion.Identity;
Vector3 desiredForward = Vector3.Normalize(new Vector3(-0.690f, 0.0f, 0.724f)); Vector3 desiredForward = Vector3.Normalize(new Vector3(-0.690f, 0.0f, 0.724f));
Vector3 desiredUp = Vector3.UnitY; Vector3 desiredUp = Vector3.UnitY;
bool ok = RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromReferencePose( bool ok = RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromDefaultPose(
referenceRotation, defaultRotation,
desiredForward, desiredForward,
desiredUp, desiredUp,
LocalAxisDirection.PositiveX, LocalAxisDirection.PositiveX,
out RealObjectPlanarPoseSolution solution); out RealObjectPlanarPoseSolution solution);
Assert.IsTrue(ok); Assert.IsTrue(ok);
Assert.AreEqual(LocalAxisDirection.PositiveX, solution.SelectedReferenceAxisDirection); Assert.AreEqual(LocalAxisDirection.PositiveX, solution.SelectedDefaultAxisDirection);
AssertVector(solution.SelectedReferenceAxisLocal, 1.0, 0.0, 0.0); AssertVector(solution.SelectedDefaultAxisLocal, 1.0, 0.0, 0.0);
Vector3 transformedSelectedAxis = Vector3.Normalize( Vector3 transformedSelectedAxis = Vector3.Normalize(
Vector3.Transform(solution.SelectedReferenceAxisLocal, solution.BaselineRotation)); Vector3.Transform(solution.SelectedDefaultAxisLocal, solution.BaselineRotation));
AssertVector( AssertVector(
transformedSelectedAxis, transformedSelectedAxis,
desiredForward.X, desiredForward.X,

View File

@ -8,7 +8,7 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
public class RealObjectRailAxisConventionResolverTests public class RealObjectRailAxisConventionResolverTests
{ {
[TestMethod] [TestMethod]
public void YUp_InterpretedReferencePose_ShouldChoosePositiveXAndPositiveYForRail() public void YUp_DefaultAxis_ShouldChoosePositiveXAndPositiveYForRail()
{ {
Vector3 referenceAxisX = new Vector3(-1.0f, 0.0f, 0.0f); Vector3 referenceAxisX = new Vector3(-1.0f, 0.0f, 0.0f);
Vector3 referenceAxisY = new Vector3(0.0f, 1.0f, 0.0f); Vector3 referenceAxisY = new Vector3(0.0f, 1.0f, 0.0f);
@ -39,7 +39,7 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
} }
[TestMethod] [TestMethod]
public void ZUp_InterpretedReferencePose_ShouldChoosePositiveXAndPositiveZForRail() public void ZUp_DefaultAxis_ShouldChoosePositiveXAndPositiveZForRail()
{ {
Vector3 referenceAxisX = new Vector3(-1.0f, 0.0f, 0.0f); Vector3 referenceAxisX = new Vector3(-1.0f, 0.0f, 0.0f);
Vector3 referenceAxisY = new Vector3(0.0f, 1.0f, 0.0f); Vector3 referenceAxisY = new Vector3(0.0f, 1.0f, 0.0f);

View File

@ -112,15 +112,15 @@ namespace NavisworksTransport.Core.Animation
private double _realObjectLength = 0; // 真实物体长度(模型单位,固定物理尺寸) private double _realObjectLength = 0; // 真实物体长度(模型单位,固定物理尺寸)
private double _realObjectWidth = 0; // 真实物体宽度(模型单位,固定物理尺寸) private double _realObjectWidth = 0; // 真实物体宽度(模型单位,固定物理尺寸)
private double _realObjectHeight = 0; // 真实物体高度(模型单位,固定物理尺寸) private double _realObjectHeight = 0; // 真实物体高度(模型单位,固定物理尺寸)
private Quaternion _realObjectReferenceRotation = Quaternion.Identity; private Quaternion _realObjectDefaultRotation = Quaternion.Identity;
private Vector3 _realObjectReferenceAxisX = Vector3.UnitX; private Vector3 _realObjectDefaultAxisX = Vector3.UnitX;
private Vector3 _realObjectReferenceAxisY = Vector3.UnitY; private Vector3 _realObjectDefaultAxisY = Vector3.UnitY;
private Vector3 _realObjectReferenceAxisZ = Vector3.UnitZ; private Vector3 _realObjectDefaultAxisZ = Vector3.UnitZ;
private LocalAxisDirection _realObjectReferenceHostWorldXAxisLocalAxis = LocalAxisDirection.PositiveX; private LocalAxisDirection _realObjectDefaultHostWorldXAxisLocalAxis = LocalAxisDirection.PositiveX;
private LocalAxisDirection _realObjectReferenceHostWorldYAxisLocalAxis = LocalAxisDirection.PositiveY; private LocalAxisDirection _realObjectDefaultHostWorldYAxisLocalAxis = LocalAxisDirection.PositiveY;
private LocalAxisDirection _realObjectReferenceHostWorldZAxisLocalAxis = LocalAxisDirection.PositiveZ; private LocalAxisDirection _realObjectDefaultHostWorldZAxisLocalAxis = LocalAxisDirection.PositiveZ;
private LocalAxisDirection _realObjectReferenceHostUpLocalAxis = LocalAxisDirection.PositiveY; private LocalAxisDirection _realObjectDefaultHostUpLocalAxis = LocalAxisDirection.PositiveY;
private bool _hasRealObjectReferenceRotation = false; private bool _hasRealObjectDefaultConvention = false;
private LocalAxisDirection _realObjectPlanarSelectedForwardAxis = LocalAxisDirection.PositiveX; private LocalAxisDirection _realObjectPlanarSelectedForwardAxis = LocalAxisDirection.PositiveX;
private bool _hasRealObjectPlanarSelectedForwardAxis = false; private bool _hasRealObjectPlanarSelectedForwardAxis = false;
private List<Point3D> _pathPoints; private List<Point3D> _pathPoints;
@ -597,7 +597,7 @@ namespace NavisworksTransport.Core.Animation
_animatedObjectMode = animatedObject == null _animatedObjectMode = animatedObject == null
? AnimatedObjectMode.None ? AnimatedObjectMode.None
: AnimatedObjectMode.RealObject; : AnimatedObjectMode.RealObject;
ResetRealObjectReferenceRotation(); ResetRealObjectDefaultConvention();
if (animatedObject != null) if (animatedObject != null)
{ {
@ -619,7 +619,7 @@ namespace NavisworksTransport.Core.Animation
: (_animatedObject != null ? AnimatedObjectMode.RealObject : AnimatedObjectMode.None); : (_animatedObject != null ? AnimatedObjectMode.RealObject : AnimatedObjectMode.None);
if (isVirtualObject) if (isVirtualObject)
{ {
ResetRealObjectReferenceRotation(); ResetRealObjectDefaultConvention();
} }
_virtualObjectLength = length; // 模型单位 _virtualObjectLength = length; // 模型单位
_virtualObjectWidth = width; // 模型单位 _virtualObjectWidth = width; // 模型单位
@ -762,7 +762,7 @@ namespace NavisworksTransport.Core.Animation
_animatedObjectMode = isVirtualObject _animatedObjectMode = isVirtualObject
? AnimatedObjectMode.VirtualObject ? AnimatedObjectMode.VirtualObject
: AnimatedObjectMode.RealObject; : AnimatedObjectMode.RealObject;
ResetRealObjectReferenceRotation(); ResetRealObjectDefaultConvention();
_originalTransform = animatedObject.Transform; _originalTransform = animatedObject.Transform;
_originalCenter = animatedObject.BoundingBox().Center; _originalCenter = animatedObject.BoundingBox().Center;
_trackedPosition = ResolveInitialBusinessTrackedPosition(animatedObject); _trackedPosition = ResolveInitialBusinessTrackedPosition(animatedObject);
@ -1018,7 +1018,7 @@ namespace NavisworksTransport.Core.Animation
_animatedObjectMode = isVirtualObject _animatedObjectMode = isVirtualObject
? AnimatedObjectMode.VirtualObject ? AnimatedObjectMode.VirtualObject
: AnimatedObjectMode.RealObject; : AnimatedObjectMode.RealObject;
ResetRealObjectReferenceRotation(); ResetRealObjectDefaultConvention();
_originalTransform = animatedObject.Transform; _originalTransform = animatedObject.Transform;
_originalCenter = animatedObject.BoundingBox().Center; _originalCenter = animatedObject.BoundingBox().Center;
_trackedPosition = ResolveInitialBusinessTrackedPosition(animatedObject); _trackedPosition = ResolveInitialBusinessTrackedPosition(animatedObject);
@ -2898,11 +2898,11 @@ namespace NavisworksTransport.Core.Animation
{ {
currentRotation = _trackedRotation; currentRotation = _trackedRotation;
} }
else if (IsRealObjectMode && _hasRealObjectReferenceRotation) else if (IsRealObjectMode && _hasRealObjectDefaultConvention)
{ {
currentRotation = CoordinateSystemManager.Instance currentRotation = CoordinateSystemManager.Instance
.CreateHostAdapter() .CreateHostAdapter()
.FromHostQuaternionDirect(_realObjectReferenceRotation); .FromHostQuaternionDirect(_realObjectDefaultRotation);
} }
else else
{ {
@ -4061,7 +4061,7 @@ namespace NavisworksTransport.Core.Animation
return pathType != PathType.Hoisting && pathType != PathType.Ground; return pathType != PathType.Hoisting && pathType != PathType.Ground;
} }
internal static bool ShouldUseReferenceBasedRealObjectPlanarPose(PathType pathType) internal static bool ShouldUseDefaultConventionRealObjectPlanarPose(PathType pathType)
{ {
return pathType != PathType.Ground && pathType != PathType.Hoisting; return pathType != PathType.Ground && pathType != PathType.Hoisting;
} }
@ -4156,8 +4156,8 @@ namespace NavisworksTransport.Core.Animation
bool isRealObjectMode, bool isRealObjectMode,
bool hasTrackedRotation, bool hasTrackedRotation,
Rotation3D trackedRotation, Rotation3D trackedRotation,
bool hasReferenceRotation, bool hasDefaultRotation,
Rotation3D referenceRotation, Rotation3D defaultRotation,
Rotation3D transformRotation, Rotation3D transformRotation,
bool hasActualGeometryRotation, bool hasActualGeometryRotation,
Rotation3D actualGeometryRotation) Rotation3D actualGeometryRotation)
@ -4174,9 +4174,9 @@ namespace NavisworksTransport.Core.Animation
return trackedRotation; return trackedRotation;
} }
if (isRealObjectMode && hasReferenceRotation) if (isRealObjectMode && hasDefaultRotation)
{ {
return referenceRotation; return defaultRotation;
} }
return transformRotation; return transformRotation;
@ -4660,14 +4660,14 @@ namespace NavisworksTransport.Core.Animation
} }
var adapter = CoordinateSystemManager.Instance.CreateHostAdapter(); var adapter = CoordinateSystemManager.Instance.CreateHostAdapter();
if (IsRealObjectMode && _hasRealObjectReferenceRotation) if (IsRealObjectMode && _hasRealObjectDefaultConvention)
{ {
if (PathTargetFrameResolver.TryCreateRailHostFrame(_route, previousPoint, currentPoint, nextPoint, out var targetFrame) && if (PathTargetFrameResolver.TryCreateRailHostFrame(_route, previousPoint, currentPoint, nextPoint, out var targetFrame) &&
RealObjectRailAxisConventionResolver.TryResolve( RealObjectRailAxisConventionResolver.TryResolve(
_realObjectReferenceAxisX, _realObjectDefaultAxisX,
_realObjectReferenceAxisY, _realObjectDefaultAxisY,
_realObjectReferenceAxisZ, _realObjectDefaultAxisZ,
_realObjectReferenceHostUpLocalAxis, _realObjectDefaultHostUpLocalAxis,
targetFrame.Forward, targetFrame.Forward,
adapter.HostType, adapter.HostType,
out convention, out convention,
@ -4681,7 +4681,7 @@ namespace NavisworksTransport.Core.Animation
$"真实物体参考姿态生效, Forward={convention.ForwardAxis}, Up={convention.UpAxis}, " + $"真实物体参考姿态生效, Forward={convention.ForwardAxis}, Up={convention.UpAxis}, " +
$"选中Forward轴={selectedForwardAxis}, 选中Forward世界轴=({selectedForwardWorldAxis.X:F4},{selectedForwardWorldAxis.Y:F4},{selectedForwardWorldAxis.Z:F4}), " + $"选中Forward轴={selectedForwardAxis}, 选中Forward世界轴=({selectedForwardWorldAxis.X:F4},{selectedForwardWorldAxis.Y:F4},{selectedForwardWorldAxis.Z:F4}), " +
$"选中Up轴={selectedUpAxis}, 选中Up世界轴=({selectedUpWorldAxis.X:F4},{selectedUpWorldAxis.Y:F4},{selectedUpWorldAxis.Z:F4}), " + $"选中Up轴={selectedUpAxis}, 选中Up世界轴=({selectedUpWorldAxis.X:F4},{selectedUpWorldAxis.Y:F4},{selectedUpWorldAxis.Z:F4}), " +
$"宿主Up对应本地轴={_realObjectReferenceHostUpLocalAxis}, " + $"宿主Up对应本地轴={_realObjectDefaultHostUpLocalAxis}, " +
$"目标Forward=({targetFrame.Forward.X:F4},{targetFrame.Forward.Y:F4},{targetFrame.Forward.Z:F4}), " + $"目标Forward=({targetFrame.Forward.X:F4},{targetFrame.Forward.Y:F4},{targetFrame.Forward.Z:F4}), " +
$"目标Up=({targetFrame.Up.X:F4},{targetFrame.Up.Y:F4},{targetFrame.Up.Z:F4})"); $"目标Up=({targetFrame.Up.X:F4},{targetFrame.Up.Y:F4},{targetFrame.Up.Z:F4})");
return true; return true;
@ -4725,7 +4725,7 @@ namespace NavisworksTransport.Core.Animation
extents = (0.0, 0.0, 0.0); extents = (0.0, 0.0, 0.0);
if (!IsRealObjectMode || if (!IsRealObjectMode ||
!_hasRealObjectReferenceRotation || !_hasRealObjectDefaultConvention ||
_realObjectLength <= 0.0 || _realObjectLength <= 0.0 ||
_realObjectWidth <= 0.0 || _realObjectWidth <= 0.0 ||
_realObjectHeight <= 0.0) _realObjectHeight <= 0.0)
@ -4767,10 +4767,10 @@ namespace NavisworksTransport.Core.Animation
localCorrection); localCorrection);
return RealObjectRailExtentResolver.TryResolveProjectedSemanticExtents( return RealObjectRailExtentResolver.TryResolveProjectedSemanticExtents(
_realObjectReferenceAxisX, _realObjectDefaultAxisX,
_realObjectReferenceAxisY, _realObjectDefaultAxisY,
_realObjectReferenceAxisZ, _realObjectDefaultAxisZ,
_realObjectReferenceHostUpLocalAxis, _realObjectDefaultHostUpLocalAxis,
targetFrame.Forward, targetFrame.Forward,
adapter.HostType, adapter.HostType,
_realObjectLength, _realObjectLength,
@ -4792,9 +4792,9 @@ namespace NavisworksTransport.Core.Animation
convention = null; convention = null;
extents = (0.0, 0.0, 0.0); extents = (0.0, 0.0, 0.0);
bool requiresReferenceRotation = _route?.PathType != PathType.Hoisting; bool requiresDefaultConvention = _route?.PathType != PathType.Hoisting;
if (!IsRealObjectMode || if (!IsRealObjectMode ||
(requiresReferenceRotation && !_hasRealObjectReferenceRotation) || (requiresDefaultConvention && !_hasRealObjectDefaultConvention) ||
_realObjectLength <= 0.0 || _realObjectLength <= 0.0 ||
_realObjectWidth <= 0.0 || _realObjectWidth <= 0.0 ||
_realObjectHeight <= 0.0) _realObjectHeight <= 0.0)
@ -4822,9 +4822,9 @@ namespace NavisworksTransport.Core.Animation
convention = null; convention = null;
extents = (0.0, 0.0, 0.0); extents = (0.0, 0.0, 0.0);
bool requiresReferenceRotation = ShouldUseReferenceBasedRealObjectPlanarPose(_route?.PathType ?? PathType.Ground); bool requiresDefaultConvention = ShouldUseDefaultConventionRealObjectPlanarPose(_route?.PathType ?? PathType.Ground);
if (!IsRealObjectMode || if (!IsRealObjectMode ||
(requiresReferenceRotation && !_hasRealObjectReferenceRotation) || (requiresDefaultConvention && !_hasRealObjectDefaultConvention) ||
_realObjectLength <= 0.0 || _realObjectLength <= 0.0 ||
_realObjectWidth <= 0.0 || _realObjectWidth <= 0.0 ||
_realObjectHeight <= 0.0) _realObjectHeight <= 0.0)
@ -4865,7 +4865,7 @@ namespace NavisworksTransport.Core.Animation
adapter.HostType == CoordinateSystemType.YUp adapter.HostType == CoordinateSystemType.YUp
? LocalAxisDirection.PositiveY ? LocalAxisDirection.PositiveY
: LocalAxisDirection.PositiveZ; : LocalAxisDirection.PositiveZ;
convention = new ModelAxisConvention(solution.SelectedReferenceAxisDirection, semanticUpAxis); convention = new ModelAxisConvention(solution.SelectedDefaultAxisDirection, semanticUpAxis);
Quaternion finalHostQuaternion = adapter.ComposeHostQuaternion( Quaternion finalHostQuaternion = adapter.ComposeHostQuaternion(
solution.BaselineRotation, solution.BaselineRotation,
@ -5271,7 +5271,7 @@ namespace NavisworksTransport.Core.Animation
Matrix4x4 hostComposedLocalAxesLinear = Matrix4x4.CreateFromQuaternion(hostComposedQuaternion); Matrix4x4 hostComposedLocalAxesLinear = Matrix4x4.CreateFromQuaternion(hostComposedQuaternion);
LogManager.Debug( LogManager.Debug(
$"[真实物体起点姿态] 选中参考轴=({solution.SelectedReferenceAxisLocal.X:F3},{solution.SelectedReferenceAxisLocal.Y:F3},{solution.SelectedReferenceAxisLocal.Z:F3}), " + $"[真实物体起点姿态] 选中参考轴=({solution.SelectedDefaultAxisLocal.X:F3},{solution.SelectedDefaultAxisLocal.Y:F3},{solution.SelectedDefaultAxisLocal.Z:F3}), " +
$"投影前进=({solution.ProjectedForward.X:F3},{solution.ProjectedForward.Y:F3},{solution.ProjectedForward.Z:F3}), " + $"投影前进=({solution.ProjectedForward.X:F3},{solution.ProjectedForward.Y:F3},{solution.ProjectedForward.Z:F3}), " +
$"宿主修正={_objectRotationCorrection}, 本地修正={localCorrection}, " + $"宿主修正={_objectRotationCorrection}, 本地修正={localCorrection}, " +
$"hostBaselineLocalXAxis=({hostBaselineLocalAxesLinear.M11:F4},{hostBaselineLocalAxesLinear.M21:F4},{hostBaselineLocalAxesLinear.M31:F4}), " + $"hostBaselineLocalXAxis=({hostBaselineLocalAxesLinear.M11:F4},{hostBaselineLocalAxesLinear.M21:F4},{hostBaselineLocalAxesLinear.M31:F4}), " +
@ -5308,12 +5308,12 @@ namespace NavisworksTransport.Core.Animation
{ {
solution = null; solution = null;
if (!ShouldUseReferenceBasedRealObjectPlanarPose(_route?.PathType ?? PathType.Ground)) if (!ShouldUseDefaultConventionRealObjectPlanarPose(_route?.PathType ?? PathType.Ground))
{ {
return false; return false;
} }
if (!TryGetRealObjectReferenceRotation(out var referenceRotation)) if (!TryGetRealObjectDefaultConvention(out var defaultRotation))
{ {
return false; return false;
} }
@ -5326,8 +5326,8 @@ namespace NavisworksTransport.Core.Animation
fixedForwardAxis = LocalAxisDirection.PositiveX; fixedForwardAxis = LocalAxisDirection.PositiveX;
} }
if (!RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromReferencePose( if (!RealObjectPlanarPoseSolver.TryCreatePlanarPoseFromDefaultPose(
referenceRotation, defaultRotation,
targetForward, targetForward,
targetUp, targetUp,
fixedForwardAxis, fixedForwardAxis,
@ -5347,13 +5347,13 @@ namespace NavisworksTransport.Core.Animation
return true; return true;
} }
private bool TryGetRealObjectReferenceRotation(out Quaternion referenceRotation) private bool TryGetRealObjectDefaultConvention(out Quaternion defaultRotation)
{ {
referenceRotation = Quaternion.Identity; defaultRotation = Quaternion.Identity;
if (_hasRealObjectReferenceRotation) if (_hasRealObjectDefaultConvention)
{ {
referenceRotation = _realObjectReferenceRotation; defaultRotation = _realObjectDefaultRotation;
return true; return true;
} }
@ -5362,12 +5362,12 @@ namespace NavisworksTransport.Core.Animation
return false; return false;
} }
if (!ShouldUseReferenceBasedRealObjectPlanarPose(_route?.PathType ?? PathType.Ground)) if (!ShouldUseDefaultConventionRealObjectPlanarPose(_route?.PathType ?? PathType.Ground))
{ {
return false; return false;
} }
if (!TryCaptureRealObjectReferenceRotation(_animatedObject, out referenceRotation)) if (!TryCaptureRealObjectDefaultConvention(_animatedObject, out defaultRotation))
{ {
string objectName = _animatedObject?.DisplayName ?? "未知对象"; string objectName = _animatedObject?.DisplayName ?? "未知对象";
LogManager.Error($"[真实物体参考姿态] {objectName} 无法获取 fragment 参考姿态,已禁止回退默认姿态。"); LogManager.Error($"[真实物体参考姿态] {objectName} 无法获取 fragment 参考姿态,已禁止回退默认姿态。");
@ -5377,9 +5377,9 @@ namespace NavisworksTransport.Core.Animation
return true; return true;
} }
private bool TryCaptureRealObjectReferenceRotation(ModelItem sourceObject, out Quaternion referenceRotation) private bool TryCaptureRealObjectDefaultConvention(ModelItem sourceObject, out Quaternion defaultRotation)
{ {
referenceRotation = Quaternion.Identity; defaultRotation = Quaternion.Identity;
if (sourceObject == null) if (sourceObject == null)
{ {
@ -5394,21 +5394,21 @@ namespace NavisworksTransport.Core.Animation
// 用户通过“调整物体”窗口手工指定最终朝向(所见即所得),无需 fragment。 // 用户通过“调整物体”窗口手工指定最终朝向(所见即所得),无需 fragment。
var adapter = CoordinateSystemManager.Instance.CreateHostAdapter(); var adapter = CoordinateSystemManager.Instance.CreateHostAdapter();
referenceRotation = Quaternion.Identity; defaultRotation = Quaternion.Identity;
_realObjectReferenceRotation = Quaternion.Identity; _realObjectDefaultRotation = Quaternion.Identity;
_realObjectReferenceAxisX = Vector3.UnitX; _realObjectDefaultAxisX = Vector3.UnitX;
_realObjectReferenceAxisY = Vector3.UnitY; _realObjectDefaultAxisY = Vector3.UnitY;
_realObjectReferenceAxisZ = Vector3.UnitZ; _realObjectDefaultAxisZ = Vector3.UnitZ;
LocalAxisDirection hostUpLocal = adapter.HostType == CoordinateSystemType.YUp LocalAxisDirection hostUpLocal = adapter.HostType == CoordinateSystemType.YUp
? LocalAxisDirection.PositiveY ? LocalAxisDirection.PositiveY
: LocalAxisDirection.PositiveZ; : LocalAxisDirection.PositiveZ;
_realObjectReferenceHostUpLocalAxis = hostUpLocal; _realObjectDefaultHostUpLocalAxis = hostUpLocal;
_realObjectReferenceHostWorldXAxisLocalAxis = LocalAxisDirection.PositiveX; _realObjectDefaultHostWorldXAxisLocalAxis = LocalAxisDirection.PositiveX;
_realObjectReferenceHostWorldYAxisLocalAxis = LocalAxisDirection.PositiveY; _realObjectDefaultHostWorldYAxisLocalAxis = LocalAxisDirection.PositiveY;
_realObjectReferenceHostWorldZAxisLocalAxis = LocalAxisDirection.PositiveZ; _realObjectDefaultHostWorldZAxisLocalAxis = LocalAxisDirection.PositiveZ;
_hasRealObjectReferenceRotation = true; _hasRealObjectDefaultConvention = true;
LogManager.Info( LogManager.Info(
$"[真实物体参考姿态] {sourceObject.DisplayName} 使用默认轴约定(不再依赖 fragment: " + $"[真实物体参考姿态] {sourceObject.DisplayName} 使用默认轴约定(不再依赖 fragment: " +
@ -5448,7 +5448,7 @@ namespace NavisworksTransport.Core.Animation
} }
if (!isVirtualObject && if (!isVirtualObject &&
!ShouldUseReferenceBasedRealObjectPlanarPose(_route?.PathType ?? PathType.Ground) && !ShouldUseDefaultConventionRealObjectPlanarPose(_route?.PathType ?? PathType.Ground) &&
ModelItemTransformHelper.TryGetCurrentGeometryRotation(sourceObject, out var groundActualGeometryRotation)) ModelItemTransformHelper.TryGetCurrentGeometryRotation(sourceObject, out var groundActualGeometryRotation))
{ {
_trackedRotation = groundActualGeometryRotation; _trackedRotation = groundActualGeometryRotation;
@ -5464,16 +5464,16 @@ namespace NavisworksTransport.Core.Animation
return; return;
} }
if (!isVirtualObject && TryCaptureRealObjectReferenceRotation(sourceObject, out Quaternion referenceRotation)) if (!isVirtualObject && TryCaptureRealObjectDefaultConvention(sourceObject, out Quaternion defaultRotation))
{ {
var adapter = CoordinateSystemManager.Instance.CreateHostAdapter(); var adapter = CoordinateSystemManager.Instance.CreateHostAdapter();
_trackedRotation = adapter.FromHostQuaternionDirect(referenceRotation); _trackedRotation = adapter.FromHostQuaternionDirect(defaultRotation);
_hasTrackedRotation = true; _hasTrackedRotation = true;
_currentYaw = ModelItemTransformHelper.GetYawFromRotation(_trackedRotation); _currentYaw = ModelItemTransformHelper.GetYawFromRotation(_trackedRotation);
return; return;
} }
if (!ShouldUseReferenceBasedRealObjectPlanarPose(_route?.PathType ?? PathType.Ground)) if (!ShouldUseDefaultConventionRealObjectPlanarPose(_route?.PathType ?? PathType.Ground))
{ {
// Ground/Hoisting 路径:无需参考姿态,使用单位旋转 // Ground/Hoisting 路径:无需参考姿态,使用单位旋转
_trackedRotation = Rotation3D.Identity; _trackedRotation = Rotation3D.Identity;
@ -5498,17 +5498,17 @@ namespace NavisworksTransport.Core.Animation
return ModelAxisConvention.CreateVirtualObjectAssetConvention(); return ModelAxisConvention.CreateVirtualObjectAssetConvention();
} }
private void ResetRealObjectReferenceRotation() private void ResetRealObjectDefaultConvention()
{ {
_realObjectReferenceRotation = Quaternion.Identity; _realObjectDefaultRotation = Quaternion.Identity;
_realObjectReferenceAxisX = Vector3.UnitX; _realObjectDefaultAxisX = Vector3.UnitX;
_realObjectReferenceAxisY = Vector3.UnitY; _realObjectDefaultAxisY = Vector3.UnitY;
_realObjectReferenceAxisZ = Vector3.UnitZ; _realObjectDefaultAxisZ = Vector3.UnitZ;
_realObjectReferenceHostWorldXAxisLocalAxis = LocalAxisDirection.PositiveX; _realObjectDefaultHostWorldXAxisLocalAxis = LocalAxisDirection.PositiveX;
_realObjectReferenceHostWorldYAxisLocalAxis = LocalAxisDirection.PositiveY; _realObjectDefaultHostWorldYAxisLocalAxis = LocalAxisDirection.PositiveY;
_realObjectReferenceHostWorldZAxisLocalAxis = LocalAxisDirection.PositiveZ; _realObjectDefaultHostWorldZAxisLocalAxis = LocalAxisDirection.PositiveZ;
_realObjectReferenceHostUpLocalAxis = LocalAxisDirection.PositiveY; _realObjectDefaultHostUpLocalAxis = LocalAxisDirection.PositiveY;
_hasRealObjectReferenceRotation = false; _hasRealObjectDefaultConvention = false;
_realObjectPlanarSelectedForwardAxis = LocalAxisDirection.PositiveX; _realObjectPlanarSelectedForwardAxis = LocalAxisDirection.PositiveX;
_hasRealObjectPlanarSelectedForwardAxis = false; _hasRealObjectPlanarSelectedForwardAxis = false;
} }
@ -5524,9 +5524,9 @@ namespace NavisworksTransport.Core.Animation
{ {
return HostCoordinateAdapter.RemapHostSemanticCorrectionToLocalAxes( return HostCoordinateAdapter.RemapHostSemanticCorrectionToLocalAxes(
_objectRotationCorrection, _objectRotationCorrection,
_realObjectReferenceHostWorldXAxisLocalAxis, _realObjectDefaultHostWorldXAxisLocalAxis,
_realObjectReferenceHostWorldYAxisLocalAxis, _realObjectDefaultHostWorldYAxisLocalAxis,
_realObjectReferenceHostWorldZAxisLocalAxis); _realObjectDefaultHostWorldZAxisLocalAxis);
} }
/// <summary> /// <summary>

View File

@ -2824,7 +2824,7 @@ namespace NavisworksTransport.Core.Services
if (!IsSameModelItem(animationViewModel.SelectedAnimatedObject, realObject)) if (!IsSameModelItem(animationViewModel.SelectedAnimatedObject, realObject))
{ {
string detail = animationViewModel.SelectedAnimatedObject == null string detail = animationViewModel.SelectedAnimatedObject == null
? "选择真实物体失败:物体在当前文档不可用(fragment 姿态解析失败,常见于导出局部模型中的嵌套实例物体;请改用虚拟物体或单层结构物体" ? "选择真实物体失败:物体在当前文档不可用(导出局部模型中未解析到该物体,常见于物体不在路径剖面盒内或层级链不匹配;请改用虚拟物体或确认物体在盒内"
: "选择真实物体失败:动画视图模型未保留选中的对象"; : "选择真实物体失败:动画视图模型未保留选中的对象";
throw new InvalidOperationException(detail); throw new InvalidOperationException(detail);
} }

View File

@ -16,30 +16,30 @@ namespace NavisworksTransport.Utils.CoordinateSystem
{ {
private const float AxisEpsilon = 1e-6f; private const float AxisEpsilon = 1e-6f;
public static bool TryCreatePlanarPoseFromReferencePose( public static bool TryCreatePlanarPoseFromDefaultPose(
Quaternion referenceRotation, Quaternion defaultRotation,
Vector3 desiredForward, Vector3 desiredForward,
Vector3 desiredUp, Vector3 desiredUp,
out RealObjectPlanarPoseSolution solution) out RealObjectPlanarPoseSolution solution)
{ {
return TryCreatePlanarPoseFromReferencePose( return TryCreatePlanarPoseFromDefaultPose(
referenceRotation, defaultRotation,
desiredForward, desiredForward,
desiredUp, desiredUp,
null, null,
out solution); out solution);
} }
public static bool TryCreatePlanarPoseFromReferencePose( public static bool TryCreatePlanarPoseFromDefaultPose(
Quaternion referenceRotation, Quaternion defaultRotation,
Vector3 desiredForward, Vector3 desiredForward,
Vector3 desiredUp, Vector3 desiredUp,
LocalAxisDirection? fixedReferenceAxis, LocalAxisDirection? fixedDefaultAxis,
out RealObjectPlanarPoseSolution solution) out RealObjectPlanarPoseSolution solution)
{ {
solution = null; solution = null;
if (!TryNormalize(referenceRotation, out Quaternion normalizedReferenceRotation)) if (!TryNormalize(defaultRotation, out Quaternion normalizedReferenceRotation))
{ {
return false; return false;
} }
@ -54,8 +54,8 @@ namespace NavisworksTransport.Utils.CoordinateSystem
return false; return false;
} }
CandidateAxis bestCandidate = fixedReferenceAxis.HasValue CandidateAxis bestCandidate = fixedDefaultAxis.HasValue
? CreateCandidateAxisFromFixedDirection(fixedReferenceAxis.Value, normalizedReferenceRotation) ? CreateCandidateAxisFromFixedDirection(fixedDefaultAxis.Value, normalizedReferenceRotation)
: SelectBestCandidateAxis( : SelectBestCandidateAxis(
normalizedReferenceRotation, normalizedReferenceRotation,
normalizedForward); normalizedForward);
@ -83,12 +83,12 @@ namespace NavisworksTransport.Utils.CoordinateSystem
} }
private static CandidateAxis SelectBestCandidateAxis( private static CandidateAxis SelectBestCandidateAxis(
Quaternion referenceRotation, Quaternion defaultRotation,
Vector3 desiredForward) Vector3 desiredForward)
{ {
CandidateAxis bestCandidate = CandidateAxis.Invalid; CandidateAxis bestCandidate = CandidateAxis.Invalid;
foreach (var candidate in EnumerateCandidateAxes(referenceRotation)) foreach (var candidate in EnumerateCandidateAxes(defaultRotation))
{ {
float score = Vector3.Dot(candidate.WorldAxis, desiredForward); float score = Vector3.Dot(candidate.WorldAxis, desiredForward);
if (bestCandidate.IsInvalid || score > bestCandidate.Score) if (bestCandidate.IsInvalid || score > bestCandidate.Score)
@ -106,32 +106,32 @@ namespace NavisworksTransport.Utils.CoordinateSystem
private static CandidateAxis CreateCandidateAxisFromFixedDirection( private static CandidateAxis CreateCandidateAxisFromFixedDirection(
LocalAxisDirection direction, LocalAxisDirection direction,
Quaternion referenceRotation) Quaternion defaultRotation)
{ {
Vector3 localAxis = GetAxisVector(direction); Vector3 localAxis = GetAxisVector(direction);
Vector3 worldAxis = Vector3.Normalize(Vector3.Transform(localAxis, referenceRotation)); Vector3 worldAxis = Vector3.Normalize(Vector3.Transform(localAxis, defaultRotation));
return new CandidateAxis(direction, localAxis, worldAxis, 0f); return new CandidateAxis(direction, localAxis, worldAxis, 0f);
} }
private static CandidateAxis[] EnumerateCandidateAxes(Quaternion referenceRotation) private static CandidateAxis[] EnumerateCandidateAxes(Quaternion defaultRotation)
{ {
return new[] return new[]
{ {
CreateCandidateAxis(LocalAxisDirection.PositiveX, Vector3.UnitX, referenceRotation), CreateCandidateAxis(LocalAxisDirection.PositiveX, Vector3.UnitX, defaultRotation),
CreateCandidateAxis(LocalAxisDirection.NegativeX, -Vector3.UnitX, referenceRotation), CreateCandidateAxis(LocalAxisDirection.NegativeX, -Vector3.UnitX, defaultRotation),
CreateCandidateAxis(LocalAxisDirection.PositiveY, Vector3.UnitY, referenceRotation), CreateCandidateAxis(LocalAxisDirection.PositiveY, Vector3.UnitY, defaultRotation),
CreateCandidateAxis(LocalAxisDirection.NegativeY, -Vector3.UnitY, referenceRotation), CreateCandidateAxis(LocalAxisDirection.NegativeY, -Vector3.UnitY, defaultRotation),
CreateCandidateAxis(LocalAxisDirection.PositiveZ, Vector3.UnitZ, referenceRotation), CreateCandidateAxis(LocalAxisDirection.PositiveZ, Vector3.UnitZ, defaultRotation),
CreateCandidateAxis(LocalAxisDirection.NegativeZ, -Vector3.UnitZ, referenceRotation) CreateCandidateAxis(LocalAxisDirection.NegativeZ, -Vector3.UnitZ, defaultRotation)
}; };
} }
private static CandidateAxis CreateCandidateAxis( private static CandidateAxis CreateCandidateAxis(
LocalAxisDirection direction, LocalAxisDirection direction,
Vector3 localAxis, Vector3 localAxis,
Quaternion referenceRotation) Quaternion defaultRotation)
{ {
Vector3 worldAxis = Vector3.Normalize(Vector3.Transform(localAxis, referenceRotation)); Vector3 worldAxis = Vector3.Normalize(Vector3.Transform(localAxis, defaultRotation));
return new CandidateAxis(direction, localAxis, worldAxis, float.MinValue); return new CandidateAxis(direction, localAxis, worldAxis, float.MinValue);
} }
@ -263,26 +263,26 @@ namespace NavisworksTransport.Utils.CoordinateSystem
{ {
public Vector3 ProjectedForward { get; } public Vector3 ProjectedForward { get; }
public Vector3 DesiredUp { get; } public Vector3 DesiredUp { get; }
public LocalAxisDirection SelectedReferenceAxisDirection { get; } public LocalAxisDirection SelectedDefaultAxisDirection { get; }
public Vector3 SelectedReferenceAxisLocal { get; } public Vector3 SelectedDefaultAxisLocal { get; }
public Vector3 SelectedReferenceAxisWorld { get; } public Vector3 SelectedDefaultAxisWorld { get; }
public Quaternion RotationDelta { get; } public Quaternion RotationDelta { get; }
public Quaternion BaselineRotation { get; } public Quaternion BaselineRotation { get; }
public RealObjectPlanarPoseSolution( public RealObjectPlanarPoseSolution(
Vector3 projectedForward, Vector3 projectedForward,
Vector3 desiredUp, Vector3 desiredUp,
LocalAxisDirection selectedReferenceAxisDirection, LocalAxisDirection selectedDefaultAxisDirection,
Vector3 selectedReferenceAxisLocal, Vector3 selectedDefaultAxisLocal,
Vector3 selectedReferenceAxisWorld, Vector3 selectedDefaultAxisWorld,
Quaternion rotationDelta, Quaternion rotationDelta,
Quaternion baselineRotation) Quaternion baselineRotation)
{ {
ProjectedForward = projectedForward; ProjectedForward = projectedForward;
DesiredUp = desiredUp; DesiredUp = desiredUp;
SelectedReferenceAxisDirection = selectedReferenceAxisDirection; SelectedDefaultAxisDirection = selectedDefaultAxisDirection;
SelectedReferenceAxisLocal = selectedReferenceAxisLocal; SelectedDefaultAxisLocal = selectedDefaultAxisLocal;
SelectedReferenceAxisWorld = selectedReferenceAxisWorld; SelectedDefaultAxisWorld = selectedDefaultAxisWorld;
RotationDelta = rotationDelta; RotationDelta = rotationDelta;
BaselineRotation = baselineRotation; BaselineRotation = baselineRotation;
} }

View File

@ -4,24 +4,23 @@ using System.Numerics;
namespace NavisworksTransport.Utils.CoordinateSystem namespace NavisworksTransport.Utils.CoordinateSystem
{ {
/// <summary> /// <summary>
/// 根据“已解释为当前宿主语义”的真实物体参考姿态,解析 Rail 路径应使用的局部轴约定。 /// 在“默认局部轴约定”下解析 Rail 路径应使用的局部轴约定。
/// ///
/// 语义: /// 语义0.18.2 起,真实物体姿态链不依赖 fragment
/// - 真实物体没有资产坐标系,但 fragment 参考姿态经过 Fragment默认Up 解释后, /// - 真实物体没有资产坐标系姿态链使用默认局部轴forward=+Xup=宿主 up
/// 可以得到“当前宿主语义下”的真实参考三轴。 /// 作为基线,用户通过“调整物体”手工指定最终朝向。
/// - Rail 与 Ground/Hoisting 的统一点在于:都先解释对象姿态,再进入路径框架。 /// - 本解析器只负责回答:在这组默认局部轴中,哪个局部 forward 轴最接近当前路径 forward
/// - Rail 的特殊性只在路径框架forward 来自 rail 切向up 来自 rail 法向。
/// - 本解析器只负责回答:对这个真实物体来说,哪个局部 forward 轴最接近当前路径 forward
/// up 轴始终采用当前宿主语义对应的轴族YUp => +YZUp => +Z /// up 轴始终采用当前宿主语义对应的轴族YUp => +YZUp => +Z
/// - 这样轨道沿 Y 时自动用 +Y 作 forward避免 90° 基线偏差,减少用户调整量。
/// </summary> /// </summary>
public static class RealObjectRailAxisConventionResolver public static class RealObjectRailAxisConventionResolver
{ {
private const float AxisEpsilon = 1e-6f; private const float AxisEpsilon = 1e-6f;
public static bool TryResolve( public static bool TryResolve(
Vector3 referenceAxisX, Vector3 defaultAxisX,
Vector3 referenceAxisY, Vector3 defaultAxisY,
Vector3 referenceAxisZ, Vector3 defaultAxisZ,
LocalAxisDirection hostUpLocalAxis, LocalAxisDirection hostUpLocalAxis,
Vector3 desiredForward, Vector3 desiredForward,
CoordinateSystemType hostType, CoordinateSystemType hostType,
@ -44,9 +43,9 @@ namespace NavisworksTransport.Utils.CoordinateSystem
return false; return false;
} }
if (!TryNormalize(referenceAxisX, out Vector3 axisX) || if (!TryNormalize(defaultAxisX, out Vector3 axisX) ||
!TryNormalize(referenceAxisY, out Vector3 axisY) || !TryNormalize(defaultAxisY, out Vector3 axisY) ||
!TryNormalize(referenceAxisZ, out Vector3 axisZ)) !TryNormalize(defaultAxisZ, out Vector3 axisZ))
{ {
return false; return false;
} }

View File

@ -17,9 +17,9 @@ namespace NavisworksTransport.Utils.CoordinateSystem
public static class RealObjectRailExtentResolver public static class RealObjectRailExtentResolver
{ {
public static bool TryResolveProjectedSemanticExtents( public static bool TryResolveProjectedSemanticExtents(
Vector3 referenceAxisX, Vector3 defaultAxisX,
Vector3 referenceAxisY, Vector3 defaultAxisY,
Vector3 referenceAxisZ, Vector3 defaultAxisZ,
LocalAxisDirection hostUpLocalAxis, LocalAxisDirection hostUpLocalAxis,
Vector3 desiredForward, Vector3 desiredForward,
CoordinateSystemType hostType, CoordinateSystemType hostType,
@ -35,9 +35,9 @@ namespace NavisworksTransport.Utils.CoordinateSystem
extents = (0.0, 0.0, 0.0); extents = (0.0, 0.0, 0.0);
if (!RealObjectRailAxisConventionResolver.TryResolve( if (!RealObjectRailAxisConventionResolver.TryResolve(
referenceAxisX, defaultAxisX,
referenceAxisY, defaultAxisY,
referenceAxisZ, defaultAxisZ,
hostUpLocalAxis, hostUpLocalAxis,
desiredForward, desiredForward,
hostType, hostType,