LoadSpecialModelsTest.cs 5.9 KB

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