SceneUtils.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Microsoft.Xna.Framework;
  7. namespace SharpGLTF.Runtime
  8. {
  9. static class SceneUtils
  10. {
  11. #region helpers
  12. public static Matrix CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance = float.PositiveInfinity)
  13. {
  14. CreatePerspectiveFieldOfView(fieldOfView, aspectRatio, nearPlaneDistance, farPlaneDistance, out Matrix m);
  15. return m;
  16. }
  17. // Microsoft recently updated this method in System.Numerics.Vectors to support farPlaneDistance infinity
  18. // https://github.com/dotnet/runtime/blob/e64bc548c609455652fcd4107f1f4a2ac3084ff3/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs#L860
  19. public static void CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance, out Matrix result)
  20. {
  21. if (fieldOfView <= 0.0f || fieldOfView >= MathHelper.Pi)
  22. throw new ArgumentOutOfRangeException(nameof(fieldOfView));
  23. if (nearPlaneDistance <= 0.0f)
  24. throw new ArgumentOutOfRangeException(nameof(nearPlaneDistance));
  25. if (farPlaneDistance <= 0.0f)
  26. throw new ArgumentOutOfRangeException(nameof(farPlaneDistance));
  27. if (nearPlaneDistance >= farPlaneDistance)
  28. throw new ArgumentOutOfRangeException(nameof(nearPlaneDistance));
  29. float yScale = 1.0f / (float)Math.Tan(fieldOfView * 0.5f);
  30. float xScale = yScale / aspectRatio;
  31. result.M11 = xScale;
  32. result.M12 = result.M13 = result.M14 = 0.0f;
  33. result.M22 = yScale;
  34. result.M21 = result.M23 = result.M24 = 0.0f;
  35. result.M31 = result.M32 = 0.0f;
  36. float negFarRange = float.IsPositiveInfinity(farPlaneDistance) ? -1.0f : farPlaneDistance / (nearPlaneDistance - farPlaneDistance);
  37. result.M33 = negFarRange;
  38. result.M34 = -1.0f;
  39. result.M41 = result.M42 = result.M44 = 0.0f;
  40. result.M43 = nearPlaneDistance * negFarRange;
  41. }
  42. #endregion
  43. }
  44. }