Use actual hoisting pose baseline for real objects
This commit is contained in:
parent
766b5af887
commit
9093374399
@ -65,6 +65,7 @@
|
|||||||
<Compile Include="UnitTests\CoordinateSystem\CanonicalTrackedPositionResolverTests.cs" />
|
<Compile Include="UnitTests\CoordinateSystem\CanonicalTrackedPositionResolverTests.cs" />
|
||||||
<Compile Include="UnitTests\CoordinateSystem\FragmentRepresentativePoseHelperTests.cs" />
|
<Compile Include="UnitTests\CoordinateSystem\FragmentRepresentativePoseHelperTests.cs" />
|
||||||
<Compile Include="UnitTests\CoordinateSystem\HoistingCoordinateHelperTests.cs" />
|
<Compile Include="UnitTests\CoordinateSystem\HoistingCoordinateHelperTests.cs" />
|
||||||
|
<Compile Include="UnitTests\CoordinateSystem\HoistingRealObjectPoseHelperTests.cs" />
|
||||||
<Compile Include="UnitTests\CoordinateSystem\ModelAxisConventionTests.cs" />
|
<Compile Include="UnitTests\CoordinateSystem\ModelAxisConventionTests.cs" />
|
||||||
<Compile Include="UnitTests\CoordinateSystem\ProjectReferenceFrameTests.cs" />
|
<Compile Include="UnitTests\CoordinateSystem\ProjectReferenceFrameTests.cs" />
|
||||||
<Compile Include="UnitTests\CoordinateSystem\RealObjectPlanarPoseSolverTests.cs" />
|
<Compile Include="UnitTests\CoordinateSystem\RealObjectPlanarPoseSolverTests.cs" />
|
||||||
|
|||||||
@ -345,6 +345,7 @@
|
|||||||
<Compile Include="src\Utils\CoordinateSystem\FragmentRepresentativePoseHelper.cs" />
|
<Compile Include="src\Utils\CoordinateSystem\FragmentRepresentativePoseHelper.cs" />
|
||||||
<Compile Include="src\Utils\CoordinateSystem\RealObjectReferencePose.cs" />
|
<Compile Include="src\Utils\CoordinateSystem\RealObjectReferencePose.cs" />
|
||||||
<Compile Include="src\Utils\CoordinateSystem\RealObjectReferencePoseResolver.cs" />
|
<Compile Include="src\Utils\CoordinateSystem\RealObjectReferencePoseResolver.cs" />
|
||||||
|
<Compile Include="src\Utils\CoordinateSystem\HoistingRealObjectPoseHelper.cs" />
|
||||||
<Compile Include="src\Utils\CoordinateSystem\PathTargetFrame.cs" />
|
<Compile Include="src\Utils\CoordinateSystem\PathTargetFrame.cs" />
|
||||||
<Compile Include="src\Utils\CoordinateSystem\PathTargetFrameResolver.cs" />
|
<Compile Include="src\Utils\CoordinateSystem\PathTargetFrameResolver.cs" />
|
||||||
<Compile Include="src\Utils\CoordinateSystem\RealObjectPlanarPoseSolver.cs" />
|
<Compile Include="src\Utils\CoordinateSystem\RealObjectPlanarPoseSolver.cs" />
|
||||||
|
|||||||
@ -0,0 +1,73 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using NavisworksTransport.Utils.CoordinateSystem;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
namespace NavisworksTransport.UnitTests.CoordinateSystem
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class HoistingRealObjectPoseHelperTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void ShouldKeepActualUpAxis_WhenAligningHoistingForward()
|
||||||
|
{
|
||||||
|
Quaternion actualRotation = Quaternion.Normalize(new Quaternion(0.70710677f, 0.0f, 0.0f, 0.70710677f));
|
||||||
|
Vector3 hostUp = Vector3.UnitY;
|
||||||
|
Vector3 targetForward = -Vector3.UnitX;
|
||||||
|
|
||||||
|
bool ok = HoistingRealObjectPoseHelper.TryCreateRotationFromActualPose(
|
||||||
|
actualRotation,
|
||||||
|
targetForward,
|
||||||
|
hostUp,
|
||||||
|
out Quaternion resultRotation,
|
||||||
|
out LocalAxisDirection selectedDirection,
|
||||||
|
out Vector3 selectedAxisLocal,
|
||||||
|
out Vector3 projectedForward);
|
||||||
|
|
||||||
|
Assert.IsTrue(ok);
|
||||||
|
Assert.AreEqual(LocalAxisDirection.PositiveX, selectedDirection);
|
||||||
|
AssertVector(selectedAxisLocal, 1.0, 0.0, 0.0);
|
||||||
|
AssertVector(projectedForward, 1.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
Vector3 transformedUp = Vector3.Normalize(Vector3.Transform(-Vector3.UnitZ, resultRotation));
|
||||||
|
AssertVector(transformedUp, 0.0, 1.0, 0.0, 1e-4);
|
||||||
|
|
||||||
|
Vector3 transformedForward = Vector3.Normalize(Vector3.Transform(Vector3.UnitX, resultRotation));
|
||||||
|
AssertVector(transformedForward, 1.0, 0.0, 0.0, 1e-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ShouldChooseHorizontalAxisFromActualPose_ForHoisting()
|
||||||
|
{
|
||||||
|
Quaternion actualRotation = Quaternion.Normalize(new Quaternion(0.70710677f, 0.0f, 0.0f, 0.70710677f));
|
||||||
|
Vector3 hostUp = Vector3.UnitY;
|
||||||
|
Vector3 targetForward = Vector3.UnitX;
|
||||||
|
|
||||||
|
bool ok = HoistingRealObjectPoseHelper.TryCreateRotationFromActualPose(
|
||||||
|
actualRotation,
|
||||||
|
targetForward,
|
||||||
|
hostUp,
|
||||||
|
out Quaternion resultRotation,
|
||||||
|
out LocalAxisDirection selectedDirection,
|
||||||
|
out Vector3 selectedAxisLocal,
|
||||||
|
out Vector3 projectedForward);
|
||||||
|
|
||||||
|
Assert.IsTrue(ok);
|
||||||
|
Assert.AreEqual(LocalAxisDirection.PositiveX, selectedDirection);
|
||||||
|
AssertVector(selectedAxisLocal, 1.0, 0.0, 0.0);
|
||||||
|
AssertVector(projectedForward, 1.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
Vector3 transformedUp = Vector3.Normalize(Vector3.Transform(-Vector3.UnitZ, resultRotation));
|
||||||
|
AssertVector(transformedUp, 0.0, 1.0, 0.0, 1e-4);
|
||||||
|
|
||||||
|
Vector3 transformedForward = Vector3.Normalize(Vector3.Transform(Vector3.UnitX, resultRotation));
|
||||||
|
AssertVector(transformedForward, 1.0, 0.0, 0.0, 1e-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AssertVector(Vector3 actual, double x, double y, double z, double tolerance = 1e-6)
|
||||||
|
{
|
||||||
|
Assert.AreEqual(x, actual.X, tolerance);
|
||||||
|
Assert.AreEqual(y, actual.Y, tolerance);
|
||||||
|
Assert.AreEqual(z, actual.Z, tolerance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -118,6 +118,27 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
|
|||||||
Assert.AreEqual(LocalAxisDirection.PositiveY, pose.HostUpLocalAxis);
|
Assert.AreEqual(LocalAxisDirection.PositiveY, pose.HostUpLocalAxis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void YUp_WorldAxisMapping_ShouldRejectAmbiguousRawFragmentFrame()
|
||||||
|
{
|
||||||
|
var fragmentMatrices = new List<double[]>
|
||||||
|
{
|
||||||
|
CreateMatrix(
|
||||||
|
axisX: Vector3.Normalize(new Vector3(0.80f, 0.60f, 0.0f)),
|
||||||
|
axisY: new Vector3(0.0f, 0.0f, -1.0f),
|
||||||
|
axisZ: Vector3.Normalize(new Vector3(-0.60f, 0.80f, 0.0f)))
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ok = RealObjectReferencePoseResolver.TryResolveFromFragmentMatrices(
|
||||||
|
fragmentMatrices,
|
||||||
|
fragmentDefaultUpAxis: "Y",
|
||||||
|
hostUpAxis: "Y",
|
||||||
|
out RealObjectReferencePose pose);
|
||||||
|
|
||||||
|
Assert.IsFalse(ok);
|
||||||
|
Assert.IsNull(pose);
|
||||||
|
}
|
||||||
|
|
||||||
private static double[] CreateMatrix(Vector3 axisX, Vector3 axisY, Vector3 axisZ)
|
private static double[] CreateMatrix(Vector3 axisX, Vector3 axisY, Vector3 axisZ)
|
||||||
{
|
{
|
||||||
return new double[]
|
return new double[]
|
||||||
|
|||||||
@ -4609,6 +4609,12 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
{
|
{
|
||||||
rotation = Rotation3D.Identity;
|
rotation = Rotation3D.Identity;
|
||||||
|
|
||||||
|
if (_route?.PathType == PathType.Hoisting &&
|
||||||
|
TryCreateHoistingRealObjectRotationFromActualPose(hostForward, out rotation))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!PathTargetFrameResolver.TryCreatePlanarHostFrame(
|
if (!PathTargetFrameResolver.TryCreatePlanarHostFrame(
|
||||||
hostForward,
|
hostForward,
|
||||||
CoordinateSystemManager.Instance.CreateHostAdapter().HostType,
|
CoordinateSystemManager.Instance.CreateHostAdapter().HostType,
|
||||||
@ -4646,6 +4652,64 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool TryCreateHoistingRealObjectRotationFromActualPose(Vector3 hostForward, out Rotation3D rotation)
|
||||||
|
{
|
||||||
|
rotation = Rotation3D.Identity;
|
||||||
|
|
||||||
|
if (_animatedObject == null ||
|
||||||
|
!ModelItemTransformHelper.TryGetCurrentGeometryRotation(_animatedObject, out var actualRotation3D))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var actualRotation = new Quaternion(
|
||||||
|
(float)actualRotation3D.A,
|
||||||
|
(float)actualRotation3D.B,
|
||||||
|
(float)actualRotation3D.C,
|
||||||
|
(float)actualRotation3D.D);
|
||||||
|
|
||||||
|
var adapter = CoordinateSystemManager.Instance.CreateHostAdapter();
|
||||||
|
Vector3 hostUp = adapter.HostType == CoordinateSystemType.YUp ? Vector3.UnitY : Vector3.UnitZ;
|
||||||
|
if (!HoistingRealObjectPoseHelper.TryCreateRotationFromActualPose(
|
||||||
|
actualRotation,
|
||||||
|
hostForward,
|
||||||
|
hostUp,
|
||||||
|
out var baselineQuaternion,
|
||||||
|
out var selectedAxisDirection,
|
||||||
|
out var selectedAxisLocal,
|
||||||
|
out var projectedForward))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotation = adapter.FromHostQuaternionDirect(
|
||||||
|
adapter.ComposeHostQuaternion(baselineQuaternion, _objectRotationCorrection));
|
||||||
|
|
||||||
|
Matrix4x4 baselineLinear = Matrix4x4.CreateFromQuaternion(baselineQuaternion);
|
||||||
|
Matrix4x4 hostComposedLinear = Matrix4x4.CreateFromQuaternion(new Quaternion(
|
||||||
|
(float)rotation.A,
|
||||||
|
(float)rotation.B,
|
||||||
|
(float)rotation.C,
|
||||||
|
(float)rotation.D));
|
||||||
|
|
||||||
|
_realObjectPlanarSelectedForwardAxis = selectedAxisDirection;
|
||||||
|
_hasRealObjectPlanarSelectedForwardAxis = true;
|
||||||
|
|
||||||
|
LogManager.Info(
|
||||||
|
$"[真实物体平面前进轴] Hoisting 已改用实际几何姿态基线,选中对象轴={selectedAxisDirection}。");
|
||||||
|
LogManager.Info(
|
||||||
|
$"[真实物体起点姿态] 选中参考轴=({selectedAxisLocal.X:F3},{selectedAxisLocal.Y:F3},{selectedAxisLocal.Z:F3}), " +
|
||||||
|
$"投影前进=({projectedForward.X:F3},{projectedForward.Y:F3},{projectedForward.Z:F3}), " +
|
||||||
|
$"宿主修正={_objectRotationCorrection}, 本地修正=X=0.0°,Y=0.0°,Z=0.0°, " +
|
||||||
|
$"BaselineX=({baselineLinear.M11:F4},{baselineLinear.M21:F4},{baselineLinear.M31:F4}), " +
|
||||||
|
$"BaselineY=({baselineLinear.M12:F4},{baselineLinear.M22:F4},{baselineLinear.M32:F4}), " +
|
||||||
|
$"BaselineZ=({baselineLinear.M13:F4},{baselineLinear.M23:F4},{baselineLinear.M33:F4}), " +
|
||||||
|
$"HostComposeX=({hostComposedLinear.M11:F4},{hostComposedLinear.M21:F4},{hostComposedLinear.M31:F4}), " +
|
||||||
|
$"HostComposeY=({hostComposedLinear.M12:F4},{hostComposedLinear.M22:F4},{hostComposedLinear.M32:F4}), " +
|
||||||
|
$"HostComposeZ=({hostComposedLinear.M13:F4},{hostComposedLinear.M23:F4},{hostComposedLinear.M33:F4})");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private bool TryCreateRealObjectPlanarPoseSolution(
|
private bool TryCreateRealObjectPlanarPoseSolution(
|
||||||
Vector3 targetForward,
|
Vector3 targetForward,
|
||||||
Vector3 targetUp,
|
Vector3 targetUp,
|
||||||
|
|||||||
135
src/Utils/CoordinateSystem/HoistingRealObjectPoseHelper.cs
Normal file
135
src/Utils/CoordinateSystem/HoistingRealObjectPoseHelper.cs
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
namespace NavisworksTransport.Utils.CoordinateSystem
|
||||||
|
{
|
||||||
|
public static class HoistingRealObjectPoseHelper
|
||||||
|
{
|
||||||
|
public static bool TryCreateRotationFromActualPose(
|
||||||
|
Quaternion actualRotation,
|
||||||
|
Vector3 targetForward,
|
||||||
|
Vector3 hostUp,
|
||||||
|
out Quaternion resultRotation,
|
||||||
|
out LocalAxisDirection selectedForwardAxisDirection,
|
||||||
|
out Vector3 selectedForwardAxisLocal,
|
||||||
|
out Vector3 projectedForward)
|
||||||
|
{
|
||||||
|
resultRotation = Quaternion.Identity;
|
||||||
|
selectedForwardAxisDirection = LocalAxisDirection.PositiveX;
|
||||||
|
selectedForwardAxisLocal = Vector3.UnitX;
|
||||||
|
projectedForward = Vector3.Zero;
|
||||||
|
|
||||||
|
if (actualRotation.LengthSquared() < 1e-6f)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 normalizedHostUp = NormalizeSafe(hostUp);
|
||||||
|
if (normalizedHostUp.LengthSquared() < 1e-6f)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 normalizedTargetForward = NormalizeOnPlane(targetForward, normalizedHostUp);
|
||||||
|
if (normalizedTargetForward.LengthSquared() < 1e-6f)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion normalizedActualRotation = Quaternion.Normalize(actualRotation);
|
||||||
|
Vector3[] localAxes =
|
||||||
|
{
|
||||||
|
Vector3.UnitX,
|
||||||
|
Vector3.UnitY,
|
||||||
|
Vector3.UnitZ
|
||||||
|
};
|
||||||
|
LocalAxisDirection[] directions =
|
||||||
|
{
|
||||||
|
LocalAxisDirection.PositiveX,
|
||||||
|
LocalAxisDirection.PositiveY,
|
||||||
|
LocalAxisDirection.PositiveZ
|
||||||
|
};
|
||||||
|
|
||||||
|
float bestScore = float.NegativeInfinity;
|
||||||
|
Vector3 bestProjectedAxis = Vector3.Zero;
|
||||||
|
|
||||||
|
for (int i = 0; i < localAxes.Length; i++)
|
||||||
|
{
|
||||||
|
Vector3 worldAxis = Vector3.Transform(localAxes[i], normalizedActualRotation);
|
||||||
|
float upAlignment = Math.Abs(Vector3.Dot(Vector3.Normalize(worldAxis), normalizedHostUp));
|
||||||
|
if (upAlignment > 0.9f)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 projectedAxis = NormalizeOnPlane(worldAxis, normalizedHostUp);
|
||||||
|
if (projectedAxis.LengthSquared() < 1e-6f)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float score = Math.Abs(Vector3.Dot(projectedAxis, normalizedTargetForward));
|
||||||
|
if (score > bestScore)
|
||||||
|
{
|
||||||
|
bestScore = score;
|
||||||
|
bestProjectedAxis = projectedAxis;
|
||||||
|
selectedForwardAxisDirection = directions[i];
|
||||||
|
selectedForwardAxisLocal = localAxes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestScore == float.NegativeInfinity)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 resolvedForward = Vector3.Dot(bestProjectedAxis, normalizedTargetForward) >= 0.0f
|
||||||
|
? normalizedTargetForward
|
||||||
|
: -normalizedTargetForward;
|
||||||
|
|
||||||
|
projectedForward = resolvedForward;
|
||||||
|
float signedAngle = SignedAngleAroundAxis(bestProjectedAxis, resolvedForward, normalizedHostUp);
|
||||||
|
Quaternion deltaRotation = Quaternion.CreateFromAxisAngle(normalizedHostUp, signedAngle);
|
||||||
|
resultRotation = Quaternion.Normalize(deltaRotation * normalizedActualRotation);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vector3 NormalizeOnPlane(Vector3 vector, Vector3 planeNormal)
|
||||||
|
{
|
||||||
|
Vector3 planar = vector - Vector3.Dot(vector, planeNormal) * planeNormal;
|
||||||
|
return NormalizeSafe(planar);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vector3 NormalizeSafe(Vector3 vector)
|
||||||
|
{
|
||||||
|
if (vector.LengthSquared() < 1e-6f)
|
||||||
|
{
|
||||||
|
return Vector3.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Vector3.Normalize(vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float SignedAngleAroundAxis(Vector3 from, Vector3 to, Vector3 axis)
|
||||||
|
{
|
||||||
|
float dot = Vector3.Dot(from, to);
|
||||||
|
if (dot > 1.0f)
|
||||||
|
{
|
||||||
|
dot = 1.0f;
|
||||||
|
}
|
||||||
|
else if (dot < -1.0f)
|
||||||
|
{
|
||||||
|
dot = -1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float angle = (float)Math.Acos(dot);
|
||||||
|
float sign = Math.Sign(Vector3.Dot(axis, Vector3.Cross(from, to)));
|
||||||
|
if (Math.Abs(sign) < 1e-6f)
|
||||||
|
{
|
||||||
|
sign = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return angle * sign;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -17,6 +17,10 @@ namespace NavisworksTransport.Utils.CoordinateSystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class RealObjectReferencePoseResolver
|
public static class RealObjectReferencePoseResolver
|
||||||
{
|
{
|
||||||
|
private const float WorldAxisMinimumAlignment = 0.98f;
|
||||||
|
private const float SemanticAxisMinimumAlignment = 0.985f;
|
||||||
|
private const float MinimumBestToSecondGap = 0.02f;
|
||||||
|
|
||||||
public static bool TryResolveFromModelItem(
|
public static bool TryResolveFromModelItem(
|
||||||
ModelItem sourceObject,
|
ModelItem sourceObject,
|
||||||
Document doc,
|
Document doc,
|
||||||
@ -174,7 +178,7 @@ namespace NavisworksTransport.Utils.CoordinateSystem
|
|||||||
rawFrame.AxisX,
|
rawFrame.AxisX,
|
||||||
rawFrame.AxisY,
|
rawFrame.AxisY,
|
||||||
rawFrame.AxisZ,
|
rawFrame.AxisZ,
|
||||||
0.5f,
|
WorldAxisMinimumAlignment,
|
||||||
out hostWorldXAxisLocalAxis))
|
out hostWorldXAxisLocalAxis))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -185,7 +189,7 @@ namespace NavisworksTransport.Utils.CoordinateSystem
|
|||||||
rawFrame.AxisX,
|
rawFrame.AxisX,
|
||||||
rawFrame.AxisY,
|
rawFrame.AxisY,
|
||||||
rawFrame.AxisZ,
|
rawFrame.AxisZ,
|
||||||
0.5f,
|
WorldAxisMinimumAlignment,
|
||||||
out hostWorldYAxisLocalAxis))
|
out hostWorldYAxisLocalAxis))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -196,7 +200,7 @@ namespace NavisworksTransport.Utils.CoordinateSystem
|
|||||||
rawFrame.AxisX,
|
rawFrame.AxisX,
|
||||||
rawFrame.AxisY,
|
rawFrame.AxisY,
|
||||||
rawFrame.AxisZ,
|
rawFrame.AxisZ,
|
||||||
0.5f,
|
WorldAxisMinimumAlignment,
|
||||||
out hostWorldZAxisLocalAxis))
|
out hostWorldZAxisLocalAxis))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -221,7 +225,7 @@ namespace NavisworksTransport.Utils.CoordinateSystem
|
|||||||
rawFrame.AxisX,
|
rawFrame.AxisX,
|
||||||
rawFrame.AxisY,
|
rawFrame.AxisY,
|
||||||
rawFrame.AxisZ,
|
rawFrame.AxisZ,
|
||||||
0.95f,
|
SemanticAxisMinimumAlignment,
|
||||||
out hostSemanticXAxisLocalAxis))
|
out hostSemanticXAxisLocalAxis))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -232,7 +236,7 @@ namespace NavisworksTransport.Utils.CoordinateSystem
|
|||||||
rawFrame.AxisX,
|
rawFrame.AxisX,
|
||||||
rawFrame.AxisY,
|
rawFrame.AxisY,
|
||||||
rawFrame.AxisZ,
|
rawFrame.AxisZ,
|
||||||
0.95f,
|
SemanticAxisMinimumAlignment,
|
||||||
out hostSemanticYAxisLocalAxis))
|
out hostSemanticYAxisLocalAxis))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -243,7 +247,7 @@ namespace NavisworksTransport.Utils.CoordinateSystem
|
|||||||
rawFrame.AxisX,
|
rawFrame.AxisX,
|
||||||
rawFrame.AxisY,
|
rawFrame.AxisY,
|
||||||
rawFrame.AxisZ,
|
rawFrame.AxisZ,
|
||||||
0.95f,
|
SemanticAxisMinimumAlignment,
|
||||||
out hostSemanticZAxisLocalAxis))
|
out hostSemanticZAxisLocalAxis))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -262,15 +266,17 @@ namespace NavisworksTransport.Utils.CoordinateSystem
|
|||||||
{
|
{
|
||||||
axisDirection = LocalAxisDirection.PositiveX;
|
axisDirection = LocalAxisDirection.PositiveX;
|
||||||
float bestAlignment = float.NegativeInfinity;
|
float bestAlignment = float.NegativeInfinity;
|
||||||
|
float secondBestAlignment = float.NegativeInfinity;
|
||||||
|
|
||||||
TryUpdateBestMatch(targetAxis, rawAxisX, LocalAxisDirection.PositiveX, ref bestAlignment, ref axisDirection);
|
TryUpdateBestMatch(targetAxis, rawAxisX, LocalAxisDirection.PositiveX, ref bestAlignment, ref secondBestAlignment, ref axisDirection);
|
||||||
TryUpdateBestMatch(targetAxis, -rawAxisX, LocalAxisDirection.NegativeX, ref bestAlignment, ref axisDirection);
|
TryUpdateBestMatch(targetAxis, -rawAxisX, LocalAxisDirection.NegativeX, ref bestAlignment, ref secondBestAlignment, ref axisDirection);
|
||||||
TryUpdateBestMatch(targetAxis, rawAxisY, LocalAxisDirection.PositiveY, ref bestAlignment, ref axisDirection);
|
TryUpdateBestMatch(targetAxis, rawAxisY, LocalAxisDirection.PositiveY, ref bestAlignment, ref secondBestAlignment, ref axisDirection);
|
||||||
TryUpdateBestMatch(targetAxis, -rawAxisY, LocalAxisDirection.NegativeY, ref bestAlignment, ref axisDirection);
|
TryUpdateBestMatch(targetAxis, -rawAxisY, LocalAxisDirection.NegativeY, ref bestAlignment, ref secondBestAlignment, ref axisDirection);
|
||||||
TryUpdateBestMatch(targetAxis, rawAxisZ, LocalAxisDirection.PositiveZ, ref bestAlignment, ref axisDirection);
|
TryUpdateBestMatch(targetAxis, rawAxisZ, LocalAxisDirection.PositiveZ, ref bestAlignment, ref secondBestAlignment, ref axisDirection);
|
||||||
TryUpdateBestMatch(targetAxis, -rawAxisZ, LocalAxisDirection.NegativeZ, ref bestAlignment, ref axisDirection);
|
TryUpdateBestMatch(targetAxis, -rawAxisZ, LocalAxisDirection.NegativeZ, ref bestAlignment, ref secondBestAlignment, ref axisDirection);
|
||||||
|
|
||||||
return bestAlignment >= minimumAlignment;
|
return bestAlignment >= minimumAlignment
|
||||||
|
&& bestAlignment - secondBestAlignment >= MinimumBestToSecondGap;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void TryUpdateBestMatch(
|
private static void TryUpdateBestMatch(
|
||||||
@ -278,14 +284,20 @@ namespace NavisworksTransport.Utils.CoordinateSystem
|
|||||||
Vector3 candidateAxis,
|
Vector3 candidateAxis,
|
||||||
LocalAxisDirection candidateDirection,
|
LocalAxisDirection candidateDirection,
|
||||||
ref float bestAlignment,
|
ref float bestAlignment,
|
||||||
|
ref float secondBestAlignment,
|
||||||
ref LocalAxisDirection bestDirection)
|
ref LocalAxisDirection bestDirection)
|
||||||
{
|
{
|
||||||
float alignment = Vector3.Dot(Vector3.Normalize(targetAxis), Vector3.Normalize(candidateAxis));
|
float alignment = Vector3.Dot(Vector3.Normalize(targetAxis), Vector3.Normalize(candidateAxis));
|
||||||
if (alignment > bestAlignment)
|
if (alignment > bestAlignment)
|
||||||
{
|
{
|
||||||
|
secondBestAlignment = bestAlignment;
|
||||||
bestAlignment = alignment;
|
bestAlignment = alignment;
|
||||||
bestDirection = candidateDirection;
|
bestDirection = candidateDirection;
|
||||||
}
|
}
|
||||||
|
else if (alignment > secondBestAlignment)
|
||||||
|
{
|
||||||
|
secondBestAlignment = alignment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool TryDetectDefaultUpAxis(
|
public static bool TryDetectDefaultUpAxis(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user