LoadSpecialModelsTest.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Numerics;
  5. using System.Text;
  6. using NUnit.Framework;
  7. namespace SharpGLTF.Schema2.LoadAndSave
  8. {
  9. /// <summary>
  10. /// Test cases for models found in <see href="https://github.com/KhronosGroup/glTF-Blender-Exporter"/>
  11. /// </summary>
  12. [TestFixture]
  13. [Category("Model Load and Save")]
  14. public class LoadSpecialModelsTest
  15. {
  16. #region setup
  17. [OneTimeSetUp]
  18. public void Setup()
  19. {
  20. // TestFiles.DownloadReferenceModels();
  21. }
  22. #endregion
  23. [Test]
  24. public void LoadEscapedUriModel()
  25. {
  26. TestContext.CurrentContext.AttachShowDirLink();
  27. var path = System.IO.Path.Combine(TestContext.CurrentContext.TestDirectory, "Assets\\white space.gltf");
  28. var model = ModelRoot.Load(path);
  29. Assert.NotNull(model);
  30. model.AttachToCurrentTest("white space.glb");
  31. }
  32. public void LoadWithCustomImageLoader()
  33. {
  34. TestContext.CurrentContext.AttachShowDirLink();
  35. // load Polly model
  36. var model = ModelRoot.Load(TestFiles.GetPollyFileModelPath());
  37. }
  38. [Test(Description = "Example of traversing the visual tree all the way to individual vertices and indices")]
  39. public void LoadPollyModel()
  40. {
  41. TestContext.CurrentContext.AttachShowDirLink();
  42. // load Polly model
  43. var model = ModelRoot.Load(TestFiles.GetPollyFileModelPath(), Validation.ValidationMode.TryFix);
  44. Assert.NotNull(model);
  45. var triangles = model.DefaultScene
  46. .EvaluateTriangles<Geometry.VertexTypes.VertexPosition, Geometry.VertexTypes.VertexTexture1>(model.LogicalAnimations[0], 0.5f)
  47. .ToList();
  48. // Save as GLB, and also evaluate all triangles and save as Wavefront OBJ
  49. model.AttachToCurrentTest("polly_out.glb");
  50. model.AttachToCurrentTest("polly_out.obj");
  51. // hierarchically browse some elements of the model:
  52. var scene = model.DefaultScene;
  53. var pollyNode = scene.FindNode(n => n.Name == "Polly_Display");
  54. var pollyPrimitive = pollyNode.Mesh.Primitives[0];
  55. var pollyIndices = pollyPrimitive.GetIndices();
  56. var pollyPositions = pollyPrimitive.GetVertices("POSITION").AsVector3Array();
  57. var pollyNormals = pollyPrimitive.GetVertices("NORMAL").AsVector3Array();
  58. for (int i = 0; i < pollyIndices.Count; i += 3)
  59. {
  60. var a = (int)pollyIndices[i + 0];
  61. var b = (int)pollyIndices[i + 1];
  62. var c = (int)pollyIndices[i + 2];
  63. var ap = pollyPositions[a];
  64. var bp = pollyPositions[b];
  65. var cp = pollyPositions[c];
  66. var an = pollyNormals[a];
  67. var bn = pollyNormals[b];
  68. var cn = pollyNormals[c];
  69. TestContext.WriteLine($"Triangle {ap} {an} {bp} {bn} {cp} {cn}");
  70. }
  71. // create a clone and apply a global axis transform.
  72. var clonedModel = model.DeepClone();
  73. var basisTransform
  74. = Matrix4x4.CreateScale(1, 2, 1)
  75. * Matrix4x4.CreateFromYawPitchRoll(1, 2, 3)
  76. * Matrix4x4.CreateTranslation(10,5,2);
  77. clonedModel.ApplyBasisTransform(basisTransform);
  78. clonedModel.AttachToCurrentTest("polly_out_transformed.glb");
  79. }
  80. [Test]
  81. public void LoadUniVRM()
  82. {
  83. TestContext.CurrentContext.AttachShowDirLink();
  84. var path = TestFiles.GetUniVRMModelPath();
  85. var model = ModelRoot.Load(path);
  86. Assert.NotNull(model);
  87. var flattenExtensions = model.GatherUsedExtensions().ToArray();
  88. model.AttachToCurrentTest("AliceModel.glb");
  89. }
  90. // [Test]
  91. public void LoadShrekshaoModel()
  92. {
  93. TestContext.CurrentContext.AttachShowDirLink();
  94. var path = "Assets\\SpecialCases\\shrekshao.glb";
  95. var model = ModelRoot.Load(path);
  96. Assert.NotNull(model);
  97. }
  98. [Test]
  99. public void LoadMouseModel()
  100. {
  101. // this model has several nodes with curve animations containing a single animation key,
  102. // which is causing some problems to the interpolator.
  103. TestContext.CurrentContext.AttachShowDirLink();
  104. var path = System.IO.Path.Combine(TestContext.CurrentContext.TestDirectory, "Assets\\SpecialCases\\mouse.glb");
  105. var model = ModelRoot.Load(path);
  106. var boundingSphere = Runtime.MeshDecoder.EvaluateBoundingSphere(model.DefaultScene);
  107. var sampler = model
  108. .LogicalNodes[5]
  109. .GetCurveSamplers(model.LogicalAnimations[1])
  110. .Rotation
  111. .CreateCurveSampler(true);
  112. var node5_R_00 = sampler.GetPoint(0);
  113. var node5_R_01 = sampler.GetPoint(1);
  114. Assert.AreEqual(node5_R_00, node5_R_01);
  115. model.AttachToCurrentTest("mouse_00.obj", model.LogicalAnimations[1], 0f);
  116. model.AttachToCurrentTest("mouse_01.obj", model.LogicalAnimations[1], 1f);
  117. }
  118. [TestCase("SketchfabExport-WhatIsPBR.glb")] // model has exported tangents in the form <0,0,0,1>
  119. public void LoadSketchfabModels(string path)
  120. {
  121. // this model has several nodes with curve animations containing a single animation key,
  122. // which is causing some problems to the interpolator.
  123. TestContext.CurrentContext.AttachShowDirLink();
  124. path = System.IO.Path.Combine(TestContext.CurrentContext.TestDirectory, $"Assets\\SpecialCases\\{path}");
  125. var model = ModelRoot.Load(path, Validation.ValidationMode.TryFix);
  126. model.AttachToCurrentTest("output.glb");
  127. }
  128. // these models show normal mapping but lack tangents, which are expected to be
  129. // generated at runtime; These tests generate the tangents and check them against the baseline.
  130. [TestCase("NormalTangentTest.glb")]
  131. [TestCase("NormalTangentMirrorTest.glb")]
  132. public void LoadGeneratedTangetsTest(string fileName)
  133. {
  134. TestContext.CurrentContext.AttachShowDirLink();
  135. var path = TestFiles.GetSampleModelsPaths().FirstOrDefault(item => item.EndsWith(fileName));
  136. var model = ModelRoot.Load(path);
  137. var mesh = model.DefaultScene
  138. .EvaluateTriangles<Geometry.VertexTypes.VertexPositionNormalTangent, Geometry.VertexTypes.VertexTexture1>()
  139. .ToMeshBuilder( m => m.ToMaterialBuilder() );
  140. var editableScene = new Scenes.SceneBuilder();
  141. editableScene.AddRigidMesh(mesh, Matrix4x4.Identity);
  142. model.AttachToCurrentTest("original.glb");
  143. editableScene.ToGltf2().AttachToCurrentTest("WithTangents.glb");
  144. }
  145. }
  146. }