using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Xna.Framework; namespace SharpGLTF.Runtime { static class SceneUtils { #region helpers public static Matrix CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance = float.PositiveInfinity) { CreatePerspectiveFieldOfView(fieldOfView, aspectRatio, nearPlaneDistance, farPlaneDistance, out Matrix m); return m; } // Microsoft recently updated this method in System.Numerics.Vectors to support farPlaneDistance infinity // https://github.com/dotnet/runtime/blob/e64bc548c609455652fcd4107f1f4a2ac3084ff3/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs#L860 public static void CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance, out Matrix result) { if (fieldOfView <= 0.0f || fieldOfView >= MathHelper.Pi) throw new ArgumentOutOfRangeException(nameof(fieldOfView)); if (nearPlaneDistance <= 0.0f) throw new ArgumentOutOfRangeException(nameof(nearPlaneDistance)); if (farPlaneDistance <= 0.0f) throw new ArgumentOutOfRangeException(nameof(farPlaneDistance)); if (nearPlaneDistance >= farPlaneDistance) throw new ArgumentOutOfRangeException(nameof(nearPlaneDistance)); float yScale = 1.0f / (float)Math.Tan(fieldOfView * 0.5f); float xScale = yScale / aspectRatio; result.M11 = xScale; result.M12 = result.M13 = result.M14 = 0.0f; result.M22 = yScale; result.M21 = result.M23 = result.M24 = 0.0f; result.M31 = result.M32 = 0.0f; float negFarRange = float.IsPositiveInfinity(farPlaneDistance) ? -1.0f : farPlaneDistance / (nearPlaneDistance - farPlaneDistance); result.M33 = negFarRange; result.M34 = -1.0f; result.M41 = result.M42 = result.M44 = 0.0f; result.M43 = nearPlaneDistance * negFarRange; } #endregion } }