using Microsoft.VisualStudio.TestTools.UnitTesting; using NavisworksTransport.Core; namespace NavisworksTransport.UnitTests.CoordinateSystem { [TestClass] public class VirtualObjectModelTransformTests { [TestMethod] public void BuildModelTransformPreservingScale_ShouldKeepExistingScaleAndReplaceRotationTranslation() { const double scaleX = 4.9213; const double scaleY = 3.2808; const double scaleZ = 6.5617; var targetRotation = new QuaternionData(0.0, 0.7071068, 0.0, 0.7071068); VirtualObjectManager.ModelTransformComponents result = VirtualObjectManager.CreateModelTransformPreservingScale( scaleX, scaleY, scaleZ, -177.129, 18.114, -2.793, targetRotation.ToRotation3D()); Assert.AreEqual(scaleX, result.ScaleX, 1e-4); Assert.AreEqual(scaleY, result.ScaleY, 1e-4); Assert.AreEqual(scaleZ, result.ScaleZ, 1e-4); AssertRotationEquivalent(targetRotation, result.Rotation); Assert.AreEqual(-177.129, result.TranslationX, 1e-6); Assert.AreEqual(18.114, result.TranslationY, 1e-6); Assert.AreEqual(-2.793, result.TranslationZ, 1e-6); } [TestMethod] public void BuildModelTransformPreservingScale_ResetPose_ShouldOnlyClearRotationAndTranslation() { VirtualObjectManager.ModelTransformComponents result = VirtualObjectManager.CreateModelTransformPreservingScale( 12.0, 5.0, 7.0, 0.0, 0.0, 0.0, QuaternionData.Identity.ToRotation3D()); Assert.AreEqual(12.0, result.ScaleX, 1e-6); Assert.AreEqual(5.0, result.ScaleY, 1e-6); Assert.AreEqual(7.0, result.ScaleZ, 1e-6); AssertRotationEquivalent(QuaternionData.Identity, result.Rotation); Assert.AreEqual(0.0, result.TranslationX, 1e-6); Assert.AreEqual(0.0, result.TranslationY, 1e-6); Assert.AreEqual(0.0, result.TranslationZ, 1e-6); } private static void AssertRotationEquivalent(QuaternionData expected, Autodesk.Navisworks.Api.Rotation3D actual) { bool same = NearlyEqual(expected.X, actual.A) && NearlyEqual(expected.Y, actual.B) && NearlyEqual(expected.Z, actual.C) && NearlyEqual(expected.W, actual.D); bool negatedSame = NearlyEqual(expected.X, -actual.A) && NearlyEqual(expected.Y, -actual.B) && NearlyEqual(expected.Z, -actual.C) && NearlyEqual(expected.W, -actual.D); Assert.IsTrue(same || negatedSame, "Rotation3D quaternion should match target rotation up to sign."); } private static bool NearlyEqual(double left, double right) { return System.Math.Abs(left - right) < 1e-6; } private struct QuaternionData { public QuaternionData(double x, double y, double z, double w) { X = x; Y = y; Z = z; W = w; } public double X { get; } public double Y { get; } public double Z { get; } public double W { get; } public Autodesk.Navisworks.Api.Rotation3D ToRotation3D() { return new Autodesk.Navisworks.Api.Rotation3D(X, Y, Z, W); } public static QuaternionData Identity => new QuaternionData(0, 0, 0, 1); } } }