NavisworksTransport/UnitTests/CoordinateSystem/RealObjectReferencePoseResolverTests.cs

161 lines
6.7 KiB
C#

using Microsoft.VisualStudio.TestTools.UnitTesting;
using NavisworksTransport.Utils.CoordinateSystem;
using System.Collections.Generic;
using System.Numerics;
namespace NavisworksTransport.UnitTests.CoordinateSystem
{
[TestClass]
public class RealObjectReferencePoseResolverTests
{
[TestMethod]
public void YUp_HostWithFragmentDefaultZ_ShouldInterpretRepresentativeFrameToHostSemantics()
{
var fragmentMatrices = new List<double[]>
{
CreateMatrix(
axisX: new Vector3(1.0f, 0.0f, 0.0f),
axisY: new Vector3(0.0f, 1.0f, 0.0f),
axisZ: new Vector3(0.0f, 0.0f, 1.0f))
};
bool ok = RealObjectReferencePoseResolver.TryResolveFromFragmentMatrices(
fragmentMatrices,
fragmentDefaultUpAxis: "Z",
hostUpAxis: "Y",
out RealObjectReferencePose pose);
Assert.IsTrue(ok);
AssertVector(pose.RawAxisX, 1.0, 0.0, 0.0);
AssertVector(pose.RawAxisY, 0.0, 1.0, 0.0);
AssertVector(pose.RawAxisZ, 0.0, 0.0, 1.0);
AssertVector(pose.AxisX, 1.0, 0.0, 0.0);
AssertVector(pose.AxisY, 0.0, 0.0, 1.0);
AssertVector(pose.AxisZ, 0.0, -1.0, 0.0);
Assert.AreEqual(LocalAxisDirection.PositiveX, pose.HostWorldXAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.PositiveY, pose.HostWorldYAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.PositiveZ, pose.HostWorldZAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.PositiveX, pose.HostSemanticXAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.PositiveZ, pose.HostSemanticYAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.NegativeY, pose.HostSemanticZAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.PositiveZ, pose.HostUpLocalAxis);
}
[TestMethod]
public void YUp_WorldAxisMapping_ShouldFollowRawRepresentativeFrame()
{
var fragmentMatrices = new List<double[]>
{
CreateMatrix(
axisX: new Vector3(0.0f, 0.0f, 1.0f),
axisY: new Vector3(1.0f, 0.0f, 0.0f),
axisZ: new Vector3(0.0f, 1.0f, 0.0f))
};
bool ok = RealObjectReferencePoseResolver.TryResolveFromFragmentMatrices(
fragmentMatrices,
fragmentDefaultUpAxis: "Z",
hostUpAxis: "Y",
out RealObjectReferencePose pose);
Assert.IsTrue(ok);
Assert.AreEqual(LocalAxisDirection.PositiveY, pose.HostWorldXAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.PositiveZ, pose.HostWorldYAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.PositiveX, pose.HostWorldZAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.PositiveX, pose.HostSemanticXAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.PositiveZ, pose.HostSemanticYAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.NegativeY, pose.HostSemanticZAxisLocalAxis);
}
[TestMethod]
public void DetectDefaultUpAxis_ShouldReturnZ_WhenRepresentativeZMatchesHostUp()
{
var fragmentMatrices = new List<double[]>
{
CreateMatrix(
axisX: new Vector3(1.0f, 0.0f, 0.0f),
axisY: new Vector3(0.0f, 0.0f, -1.0f),
axisZ: new Vector3(0.0f, 1.0f, 0.0f))
};
bool ok = RealObjectReferencePoseResolver.TryDetectDefaultUpAxis(
fragmentMatrices,
"Y",
out string detectedAxis,
out float yAlignment,
out float zAlignment);
Assert.IsTrue(ok);
Assert.AreEqual("Z", detectedAxis);
Assert.AreEqual(0.0, yAlignment, 1e-6);
Assert.AreEqual(1.0, zAlignment, 1e-6);
}
[TestMethod]
public void YUp_WorldAxisMapping_ShouldAcceptSlightlyRotatedRawFragmentFrame()
{
var fragmentMatrices = new List<double[]>
{
CreateMatrix(
axisX: Vector3.Normalize(new Vector3(0.9980f, 0.0638f, 0.0f)),
axisY: new Vector3(0.0f, 0.0f, -1.0f),
axisZ: Vector3.Normalize(new Vector3(-0.0638f, 0.9980f, 0.0f)))
};
bool ok = RealObjectReferencePoseResolver.TryResolveFromFragmentMatrices(
fragmentMatrices,
fragmentDefaultUpAxis: "Y",
hostUpAxis: "Y",
out RealObjectReferencePose pose);
Assert.IsTrue(ok);
Assert.AreEqual(LocalAxisDirection.PositiveX, pose.HostWorldXAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.PositiveZ, pose.HostWorldYAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.NegativeY, pose.HostWorldZAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.PositiveX, pose.HostSemanticXAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.PositiveY, pose.HostSemanticYAxisLocalAxis);
Assert.AreEqual(LocalAxisDirection.PositiveZ, pose.HostSemanticZAxisLocalAxis);
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)
{
return new double[]
{
axisX.X, axisX.Y, axisX.Z, 0.0,
axisY.X, axisY.Y, axisY.Z, 0.0,
axisZ.X, axisZ.Y, axisZ.Z, 0.0,
0.0, 0.0, 0.0, 1.0
};
}
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);
}
}
}