Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Text;
namespace SharpGLTF.Transforms
{
/// <summary>
/// Utility class to calculate camera matrices
/// </summary>
/// <see href="https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#projection-matrices"/>
public static class Projection
{
/// <summary>
/// Calculates an orthographic projection matrix.
/// </summary>
/// <param name="xmag">Magnification in the X axis.</param>
/// <param name="ymag">Magnification in the Y axis.</param>
/// <param name="znear">Distance to the near pane in the Z axis.</param>
/// <param name="zfar">Distance to the far plane in the Z axis.</param>
/// <returns>A projection matrix</returns>
public static Matrix4x4 CreateOrthographicMatrix(float xmag, float ymag, float znear, float zfar)
{
Guard.MustBeGreaterThanOrEqualTo(znear, 0, nameof(znear));
Guard.MustBeGreaterThanOrEqualTo(zfar, 0, nameof(zfar));
Guard.MustBeGreaterThan(zfar, znear, nameof(zfar));
Guard.MustBeLessThan(zfar, float.PositiveInfinity, nameof(zfar));
var d = znear - zfar;
var x = 1 / xmag;
var y = 1 / ymag;
var z = 2 / d;
var w = (zfar + znear) / d;
return new Matrix4x4
(
x, 0, 0, 0,
0, y, 0, 0,
0, 0, z, w,
0, 0, 0, 1
);
}
/// <summary>
/// Calculates a perspective projection matrix.
/// </summary>
/// <param name="aspectRatio">The aspect ratio between horizontal and vertical. (optional)</param>
/// <param name="yfov">The vertical field of view, in radians.</param>
/// <param name="znear">Distance to the near pane in the Z axis.</param>
/// <param name="zfar">Distance to the far plane in the Z axis. Optionally, this value can be positive infinity</param>
/// <returns>A projection matrix</returns>
public static Matrix4x4 CreatePerspectiveMatrix(float aspectRatio, float yfov, float znear, float zfar = float.PositiveInfinity)
{
Guard.MustBeGreaterThan(aspectRatio, 0, nameof(aspectRatio));
Guard.MustBeGreaterThan(yfov, 0, nameof(yfov));
Guard.MustBeLessThan(yfov, (float)Math.PI, nameof(yfov));
Guard.MustBeGreaterThanOrEqualTo(znear, 0, nameof(znear));
Guard.MustBeGreaterThanOrEqualTo(zfar, 0, nameof(zfar));
Guard.MustBeGreaterThan(zfar, znear, nameof(zfar));
var v = (float)Math.Tan(0.5 * yfov);
var h = aspectRatio * v;
var x = 1 / h;
var y = 1 / v;
var z = -1f;
var w = -2 * znear;
if (!float.IsPositiveInfinity(zfar))
{
var d = znear - zfar;
z = (zfar + znear) / d;
w = (2f * zfar * znear) / d;
}
return new Matrix4x4
(
x, 0, 0, 0,
0, y, 0, 0,
0, 0, z, w,
0, 0, -1, 0
);
}
}
}
d49ffeb42This file is pinned to the selected release. Download the original to open it in your design tool.