1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093 |
- using System.Runtime.CompilerServices;
- using static Unity.Mathematics.math;
-
- namespace Unity.Mathematics
- {
- public partial struct float2x2
- {
- /// <summary>
- /// Computes a float2x2 matrix representing a counter-clockwise rotation by an angle in radians.
- /// </summary>
- /// <remarks>
- /// A positive rotation angle will produce a counter-clockwise rotation and a negative rotation angle will
- /// produce a clockwise rotation.
- /// </remarks>
- /// <param name="angle">Rotation angle in radians.</param>
- /// <returns>Returns the 2x2 rotation matrix.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float2x2 Rotate(float angle)
- {
- float s, c;
- sincos(angle, out s, out c);
- return float2x2(c, -s,
- s, c);
- }
-
- /// <summary>Returns a float2x2 matrix representing a uniform scaling of both axes by s.</summary>
- /// <param name="s">The scaling factor.</param>
- /// <returns>The float2x2 matrix representing uniform scale by s.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float2x2 Scale(float s)
- {
- return float2x2(s, 0.0f,
- 0.0f, s);
- }
-
- /// <summary>Returns a float2x2 matrix representing a non-uniform axis scaling by x and y.</summary>
- /// <param name="x">The x-axis scaling factor.</param>
- /// <param name="y">The y-axis scaling factor.</param>
- /// <returns>The float2x2 matrix representing a non-uniform scale.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float2x2 Scale(float x, float y)
- {
- return float2x2(x, 0.0f,
- 0.0f, y);
- }
-
- /// <summary>Returns a float2x2 matrix representing a non-uniform axis scaling by the components of the float2 vector v.</summary>
- /// <param name="v">The float2 containing the x and y axis scaling factors.</param>
- /// <returns>The float2x2 matrix representing a non-uniform scale.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float2x2 Scale(float2 v)
- {
- return Scale(v.x, v.y);
- }
- }
-
- public partial struct float3x3
- {
- /// <summary>
- /// Constructs a float3x3 from the upper left 3x3 of a float4x4.
- /// </summary>
- /// <param name="f4x4"><see cref="float4x4"/> to extract a float3x3 from.</param>
- public float3x3(float4x4 f4x4)
- {
- c0 = f4x4.c0.xyz;
- c1 = f4x4.c1.xyz;
- c2 = f4x4.c2.xyz;
- }
-
- /// <summary>Constructs a float3x3 matrix from a unit quaternion.</summary>
- /// <param name="q">The quaternion rotation.</param>
- public float3x3(quaternion q)
- {
- float4 v = q.value;
- float4 v2 = v + v;
-
- uint3 npn = uint3(0x80000000, 0x00000000, 0x80000000);
- uint3 nnp = uint3(0x80000000, 0x80000000, 0x00000000);
- uint3 pnn = uint3(0x00000000, 0x80000000, 0x80000000);
- c0 = v2.y * asfloat(asuint(v.yxw) ^ npn) - v2.z * asfloat(asuint(v.zwx) ^ pnn) + float3(1, 0, 0);
- c1 = v2.z * asfloat(asuint(v.wzy) ^ nnp) - v2.x * asfloat(asuint(v.yxw) ^ npn) + float3(0, 1, 0);
- c2 = v2.x * asfloat(asuint(v.zwx) ^ pnn) - v2.y * asfloat(asuint(v.wzy) ^ nnp) + float3(0, 0, 1);
- }
-
- /// <summary>
- /// Returns a float3x3 matrix representing a rotation around a unit axis by an angle in radians.
- /// The rotation direction is clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="axis">The rotation axis.</param>
- /// <param name="angle">The angle of rotation in radians.</param>
- /// <returns>The float3x3 matrix representing the rotation around an axis.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 AxisAngle(float3 axis, float angle)
- {
- float sina, cosa;
- math.sincos(angle, out sina, out cosa);
-
- float3 u = axis;
- float3 u_yzx = u.yzx;
- float3 u_zxy = u.zxy;
- float3 u_inv_cosa = u - u * cosa; // u * (1.0f - cosa);
- float4 t = float4(u * sina, cosa);
-
- uint3 ppn = uint3(0x00000000, 0x00000000, 0x80000000);
- uint3 npp = uint3(0x80000000, 0x00000000, 0x00000000);
- uint3 pnp = uint3(0x00000000, 0x80000000, 0x00000000);
-
- return float3x3(
- u.x * u_inv_cosa + asfloat(asuint(t.wzy) ^ ppn),
- u.y * u_inv_cosa + asfloat(asuint(t.zwx) ^ npp),
- u.z * u_inv_cosa + asfloat(asuint(t.yxw) ^ pnp)
- );
- /*
- return float3x3(
- cosa + u.x * u.x * (1.0f - cosa), u.y * u.x * (1.0f - cosa) - u.z * sina, u.z * u.x * (1.0f - cosa) + u.y * sina,
- u.x * u.y * (1.0f - cosa) + u.z * sina, cosa + u.y * u.y * (1.0f - cosa), u.y * u.z * (1.0f - cosa) - u.x * sina,
- u.x * u.z * (1.0f - cosa) - u.y * sina, u.y * u.z * (1.0f - cosa) + u.x * sina, cosa + u.z * u.z * (1.0f - cosa)
- );
- */
- }
-
- /// <summary>
- /// Returns a float3x3 rotation matrix constructed by first performing a rotation around the x-axis, then the y-axis and finally the z-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="xyz">A float3 vector containing the rotation angles around the x-, y- and z-axis measures in radians.</param>
- /// <returns>The float3x3 rotation matrix representing the rotation by Euler angles in x-y-z order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 EulerXYZ(float3 xyz)
- {
- // return mul(rotateZ(xyz.z), mul(rotateY(xyz.y), rotateX(xyz.x)));
- float3 s, c;
- sincos(xyz, out s, out c);
- return float3x3(
- c.y * c.z, c.z * s.x * s.y - c.x * s.z, c.x * c.z * s.y + s.x * s.z,
- c.y * s.z, c.x * c.z + s.x * s.y * s.z, c.x * s.y * s.z - c.z * s.x,
- -s.y, c.y * s.x, c.x * c.y
- );
- }
-
- /// <summary>
- /// Returns a float3x3 rotation matrix constructed by first performing a rotation around the x-axis, then the z-axis and finally the y-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="xyz">A float3 vector containing the rotation angles around the x-, y- and z-axis measures in radians.</param>
- /// <returns>The float3x3 rotation matrix representing the rotation by Euler angles in x-z-y order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 EulerXZY(float3 xyz)
- {
- // return mul(rotateY(xyz.y), mul(rotateZ(xyz.z), rotateX(xyz.x))); }
- float3 s, c;
- sincos(xyz, out s, out c);
- return float3x3(
- c.y * c.z, s.x * s.y - c.x * c.y * s.z, c.x * s.y + c.y * s.x * s.z,
- s.z, c.x * c.z, -c.z * s.x,
- -c.z * s.y, c.y * s.x + c.x * s.y * s.z, c.x * c.y - s.x * s.y * s.z
- );
- }
-
- /// <summary>
- /// Returns a float3x3 rotation matrix constructed by first performing a rotation around the y-axis, then the x-axis and finally the z-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="xyz">A float3 vector containing the rotation angles around the x-, y- and z-axis measures in radians.</param>
- /// <returns>The float3x3 rotation matrix representing the rotation by Euler angles in y-x-z order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 EulerYXZ(float3 xyz)
- {
- // return mul(rotateZ(xyz.z), mul(rotateX(xyz.x), rotateY(xyz.y)));
- float3 s, c;
- sincos(xyz, out s, out c);
- return float3x3(
- c.y * c.z - s.x * s.y * s.z, -c.x * s.z, c.z * s.y + c.y * s.x * s.z,
- c.z * s.x * s.y + c.y * s.z, c.x * c.z, s.y * s.z - c.y * c.z * s.x,
- -c.x * s.y, s.x, c.x * c.y
- );
- }
-
- /// <summary>
- /// Returns a float3x3 rotation matrix constructed by first performing a rotation around the y-axis, then the z-axis and finally the x-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="xyz">A float3 vector containing the rotation angles around the x-, y- and z-axis measures in radians.</param>
- /// <returns>The float3x3 rotation matrix representing the rotation by Euler angles in y-z-x order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 EulerYZX(float3 xyz)
- {
- // return mul(rotateX(xyz.x), mul(rotateZ(xyz.z), rotateY(xyz.y)));
- float3 s, c;
- sincos(xyz, out s, out c);
- return float3x3(
- c.y * c.z, -s.z, c.z * s.y,
- s.x * s.y + c.x * c.y * s.z, c.x * c.z, c.x * s.y * s.z - c.y * s.x,
- c.y * s.x * s.z - c.x * s.y, c.z * s.x, c.x * c.y + s.x * s.y * s.z
- );
- }
-
- /// <summary>
- /// Returns a float3x3 rotation matrix constructed by first performing a rotation around the z-axis, then the x-axis and finally the y-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// This is the default order rotation order in Unity.
- /// </summary>
- /// <param name="xyz">A float3 vector containing the rotation angles around the x-, y- and z-axis measures in radians.</param>
- /// <returns>The float3x3 rotation matrix representing the rotation by Euler angles in z-x-y order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 EulerZXY(float3 xyz)
- {
- // return mul(rotateY(xyz.y), mul(rotateX(xyz.x), rotateZ(xyz.z)));
- float3 s, c;
- sincos(xyz, out s, out c);
- return float3x3(
- c.y * c.z + s.x * s.y * s.z, c.z * s.x * s.y - c.y * s.z, c.x * s.y,
- c.x * s.z, c.x * c.z, -s.x,
- c.y * s.x * s.z - c.z * s.y, c.y * c.z * s.x + s.y * s.z, c.x * c.y
- );
- }
-
- /// <summary>
- /// Returns a float3x3 rotation matrix constructed by first performing a rotation around the z-axis, then the y-axis and finally the x-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="xyz">A float3 vector containing the rotation angles around the x-, y- and z-axis measures in radians.</param>
- /// <returns>The float3x3 rotation matrix representing the rotation by Euler angles in z-y-x order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 EulerZYX(float3 xyz)
- {
- // return mul(rotateX(xyz.x), mul(rotateY(xyz.y), rotateZ(xyz.z)));
- float3 s, c;
- sincos(xyz, out s, out c);
- return float3x3(
- c.y * c.z, -c.y * s.z, s.y,
- c.z * s.x * s.y + c.x * s.z, c.x * c.z - s.x * s.y * s.z, -c.y * s.x,
- s.x * s.z - c.x * c.z * s.y, c.z * s.x + c.x * s.y * s.z, c.x * c.y
- );
- }
-
- /// <summary>
- /// Returns a float3x3 rotation matrix constructed by first performing a rotation around the x-axis, then the y-axis and finally the z-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="x">The rotation angle around the x-axis in radians.</param>
- /// <param name="y">The rotation angle around the y-axis in radians.</param>
- /// <param name="z">The rotation angle around the z-axis in radians.</param>
- /// <returns>The float3x3 rotation matrix representing the rotation by Euler angles in x-y-z order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 EulerXYZ(float x, float y, float z) { return EulerXYZ(float3(x, y, z)); }
-
- /// <summary>
- /// Returns a float3x3 rotation matrix constructed by first performing a rotation around the x-axis, then the z-axis and finally the y-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="x">The rotation angle around the x-axis in radians.</param>
- /// <param name="y">The rotation angle around the y-axis in radians.</param>
- /// <param name="z">The rotation angle around the z-axis in radians.</param>
- /// <returns>The float3x3 rotation matrix representing the rotation by Euler angles in x-z-y order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 EulerXZY(float x, float y, float z) { return EulerXZY(float3(x, y, z)); }
-
- /// <summary>
- /// Returns a float3x3 rotation matrix constructed by first performing a rotation around the y-axis, then the x-axis and finally the z-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="x">The rotation angle around the x-axis in radians.</param>
- /// <param name="y">The rotation angle around the y-axis in radians.</param>
- /// <param name="z">The rotation angle around the z-axis in radians.</param>
- /// <returns>The float3x3 rotation matrix representing the rotation by Euler angles in y-x-z order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 EulerYXZ(float x, float y, float z) { return EulerYXZ(float3(x, y, z)); }
-
- /// <summary>
- /// Returns a float3x3 rotation matrix constructed by first performing a rotation around the y-axis, then the z-axis and finally the x-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="x">The rotation angle around the x-axis in radians.</param>
- /// <param name="y">The rotation angle around the y-axis in radians.</param>
- /// <param name="z">The rotation angle around the z-axis in radians.</param>
- /// <returns>The float3x3 rotation matrix representing the rotation by Euler angles in y-z-x order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 EulerYZX(float x, float y, float z) { return EulerYZX(float3(x, y, z)); }
-
- /// <summary>
- /// Returns a float3x3 rotation matrix constructed by first performing a rotation around the z-axis, then the x-axis and finally the y-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// This is the default order rotation order in Unity.
- /// </summary>
- /// <param name="x">The rotation angle around the x-axis in radians.</param>
- /// <param name="y">The rotation angle around the y-axis in radians.</param>
- /// <param name="z">The rotation angle around the z-axis in radians.</param>
- /// <returns>The float3x3 rotation matrix representing the rotation by Euler angles in z-x-y order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 EulerZXY(float x, float y, float z) { return EulerZXY(float3(x, y, z)); }
-
- /// <summary>
- /// Returns a float3x3 rotation matrix constructed by first performing a rotation around the z-axis, then the y-axis and finally the x-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="x">The rotation angle around the x-axis in radians.</param>
- /// <param name="y">The rotation angle around the y-axis in radians.</param>
- /// <param name="z">The rotation angle around the z-axis in radians.</param>
- /// <returns>The float3x3 rotation matrix representing the rotation by Euler angles in z-y-x order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 EulerZYX(float x, float y, float z) { return EulerZYX(float3(x, y, z)); }
-
- /// <summary>
- /// Returns a float3x3 rotation matrix constructed by first performing 3 rotations around the principal axes in a given order.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// When the rotation order is known at compile time, it is recommended for performance reasons to use specific
- /// Euler rotation constructors such as EulerZXY(...).
- /// </summary>
- /// <param name="xyz">A float3 vector containing the rotation angles around the x-, y- and z-axis measures in radians.</param>
- /// <param name="order">The order in which the rotations are applied.</param>
- /// <returns>The float3x3 rotation matrix representing the rotation by Euler angles in the given order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 Euler(float3 xyz, RotationOrder order = RotationOrder.Default)
- {
- switch (order)
- {
- case RotationOrder.XYZ:
- return EulerXYZ(xyz);
- case RotationOrder.XZY:
- return EulerXZY(xyz);
- case RotationOrder.YXZ:
- return EulerYXZ(xyz);
- case RotationOrder.YZX:
- return EulerYZX(xyz);
- case RotationOrder.ZXY:
- return EulerZXY(xyz);
- case RotationOrder.ZYX:
- return EulerZYX(xyz);
- default:
- return float3x3.identity;
- }
- }
-
- /// <summary>
- /// Returns a float3x3 rotation matrix constructed by first performing 3 rotations around the principal axes in a given order.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// When the rotation order is known at compile time, it is recommended for performance reasons to use specific
- /// Euler rotation constructors such as EulerZXY(...).
- /// </summary>
- /// <param name="x">The rotation angle around the x-axis in radians.</param>
- /// <param name="y">The rotation angle around the y-axis in radians.</param>
- /// <param name="z">The rotation angle around the z-axis in radians.</param>
- /// <param name="order">The order in which the rotations are applied.</param>
- /// <returns>The float3x3 rotation matrix representing the rotation by Euler angles in the given order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 Euler(float x, float y, float z, RotationOrder order = RotationOrder.Default)
- {
- return Euler(float3(x, y, z), order);
- }
-
- /// <summary>Returns a float3x3 matrix that rotates around the x-axis by a given number of radians.</summary>
- /// <param name="angle">The clockwise rotation angle when looking along the x-axis towards the origin in radians.</param>
- /// <returns>The float3x3 rotation matrix representing a rotation around the x-axis.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 RotateX(float angle)
- {
- // {{1, 0, 0}, {0, c_0, -s_0}, {0, s_0, c_0}}
- float s, c;
- sincos(angle, out s, out c);
- return float3x3(1.0f, 0.0f, 0.0f,
- 0.0f, c, -s,
- 0.0f, s, c);
- }
-
- /// <summary>Returns a float3x3 matrix that rotates around the y-axis by a given number of radians.</summary>
- /// <param name="angle">The clockwise rotation angle when looking along the y-axis towards the origin in radians.</param>
- /// <returns>The float3x3 rotation matrix representing a rotation around the y-axis.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 RotateY(float angle)
- {
- // {{c_1, 0, s_1}, {0, 1, 0}, {-s_1, 0, c_1}}
- float s, c;
- sincos(angle, out s, out c);
- return float3x3(c, 0.0f, s,
- 0.0f, 1.0f, 0.0f,
- -s, 0.0f, c);
- }
-
- /// <summary>Returns a float3x3 matrix that rotates around the z-axis by a given number of radians.</summary>
- /// <param name="angle">The clockwise rotation angle when looking along the z-axis towards the origin in radians.</param>
- /// <returns>The float3x3 rotation matrix representing a rotation around the z-axis.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 RotateZ(float angle)
- {
- // {{c_2, -s_2, 0}, {s_2, c_2, 0}, {0, 0, 1}}
- float s, c;
- sincos(angle, out s, out c);
- return float3x3(c, -s, 0.0f,
- s, c, 0.0f,
- 0.0f, 0.0f, 1.0f);
- }
-
- /// <summary>Returns a float3x3 matrix representing a uniform scaling of all axes by s.</summary>
- /// <param name="s">The uniform scaling factor.</param>
- /// <returns>The float3x3 matrix representing a uniform scale.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 Scale(float s)
- {
- return float3x3(s, 0.0f, 0.0f,
- 0.0f, s, 0.0f,
- 0.0f, 0.0f, s);
- }
-
- /// <summary>Returns a float3x3 matrix representing a non-uniform axis scaling by x, y and z.</summary>
- /// <param name="x">The x-axis scaling factor.</param>
- /// <param name="y">The y-axis scaling factor.</param>
- /// <param name="z">The z-axis scaling factor.</param>
- /// <returns>The float3x3 rotation matrix representing a non-uniform scale.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 Scale(float x, float y, float z)
- {
- return float3x3(x, 0.0f, 0.0f,
- 0.0f, y, 0.0f,
- 0.0f, 0.0f, z);
- }
-
- /// <summary>Returns a float3x3 matrix representing a non-uniform axis scaling by the components of the float3 vector v.</summary>
- /// <param name="v">The vector containing non-uniform scaling factors.</param>
- /// <returns>The float3x3 rotation matrix representing a non-uniform scale.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 Scale(float3 v)
- {
- return Scale(v.x, v.y, v.z);
- }
-
- /// <summary>
- /// Returns a float3x3 view rotation matrix given a unit length forward vector and a unit length up vector.
- /// The two input vectors are assumed to be unit length and not collinear.
- /// If these assumptions are not met use float3x3.LookRotationSafe instead.
- /// </summary>
- /// <param name="forward">The forward vector to align the center of view with.</param>
- /// <param name="up">The up vector to point top of view toward.</param>
- /// <returns>The float3x3 view rotation matrix.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 LookRotation(float3 forward, float3 up)
- {
- float3 t = normalize(cross(up, forward));
- return float3x3(t, cross(forward, t), forward);
- }
-
- /// <summary>
- /// Returns a float3x3 view rotation matrix given a forward vector and an up vector.
- /// The two input vectors are not assumed to be unit length.
- /// If the magnitude of either of the vectors is so extreme that the calculation cannot be carried out reliably or the vectors are collinear,
- /// the identity will be returned instead.
- /// </summary>
- /// <param name="forward">The forward vector to align the center of view with.</param>
- /// <param name="up">The up vector to point top of view toward.</param>
- /// <returns>The float3x3 view rotation matrix or the identity matrix.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 LookRotationSafe(float3 forward, float3 up)
- {
- float forwardLengthSq = dot(forward, forward);
- float upLengthSq = dot(up, up);
-
- forward *= rsqrt(forwardLengthSq);
- up *= rsqrt(upLengthSq);
-
- float3 t = cross(up, forward);
- float tLengthSq = dot(t, t);
- t *= rsqrt(tLengthSq);
-
- float mn = min(min(forwardLengthSq, upLengthSq), tLengthSq);
- float mx = max(max(forwardLengthSq, upLengthSq), tLengthSq);
-
- bool accept = mn > 1e-35f && mx < 1e35f && isfinite(forwardLengthSq) && isfinite(upLengthSq) && isfinite(tLengthSq);
- return float3x3(
- select(float3(1,0,0), t, accept),
- select(float3(0,1,0), cross(forward, t), accept),
- select(float3(0,0,1), forward, accept));
- }
-
- /// <summary>
- /// Converts a float4x4 to a float3x3.
- /// </summary>
- /// <param name="f4x4">The float4x4 to convert to a float3x3.</param>
- /// <returns>The float3x3 constructed from the upper left 3x3 of the input float4x4 matrix.</returns>
- public static explicit operator float3x3(float4x4 f4x4) => new float3x3(f4x4);
- }
-
- public partial struct float4x4
- {
- /// <summary>Constructs a float4x4 from a float3x3 rotation matrix and a float3 translation vector.</summary>
- /// <param name="rotation">The float3x3 rotation matrix.</param>
- /// <param name="translation">The translation vector.</param>
- public float4x4(float3x3 rotation, float3 translation)
- {
- c0 = float4(rotation.c0, 0.0f);
- c1 = float4(rotation.c1, 0.0f);
- c2 = float4(rotation.c2, 0.0f);
- c3 = float4(translation, 1.0f);
- }
-
- /// <summary>Constructs a float4x4 from a quaternion and a float3 translation vector.</summary>
- /// <param name="rotation">The quaternion rotation.</param>
- /// <param name="translation">The translation vector.</param>
- public float4x4(quaternion rotation, float3 translation)
- {
- float3x3 rot = float3x3(rotation);
- c0 = float4(rot.c0, 0.0f);
- c1 = float4(rot.c1, 0.0f);
- c2 = float4(rot.c2, 0.0f);
- c3 = float4(translation, 1.0f);
- }
-
- /// <summary>Constructs a float4x4 from a RigidTransform.</summary>
- /// <param name="transform">The RigidTransform.</param>
- public float4x4(RigidTransform transform)
- {
- float3x3 rot = float3x3(transform.rot);
- c0 = float4(rot.c0, 0.0f);
- c1 = float4(rot.c1, 0.0f);
- c2 = float4(rot.c2, 0.0f);
- c3 = float4(transform.pos, 1.0f);
- }
-
- /// <summary>
- /// Returns a float4x4 matrix representing a rotation around a unit axis by an angle in radians.
- /// The rotation direction is clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="axis">The axis of rotation.</param>
- /// <param name="angle">The angle of rotation in radians.</param>
- /// <returns>The float4x4 matrix representing the rotation about an axis.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 AxisAngle(float3 axis, float angle)
- {
- float sina, cosa;
- math.sincos(angle, out sina, out cosa);
-
- float4 u = float4(axis, 0.0f);
- float4 u_yzx = u.yzxx;
- float4 u_zxy = u.zxyx;
- float4 u_inv_cosa = u - u * cosa; // u * (1.0f - cosa);
- float4 t = float4(u.xyz * sina, cosa);
-
- uint4 ppnp = uint4(0x00000000, 0x00000000, 0x80000000, 0x00000000);
- uint4 nppp = uint4(0x80000000, 0x00000000, 0x00000000, 0x00000000);
- uint4 pnpp = uint4(0x00000000, 0x80000000, 0x00000000, 0x00000000);
- uint4 mask = uint4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000);
-
- return float4x4(
- u.x * u_inv_cosa + asfloat((asuint(t.wzyx) ^ ppnp) & mask),
- u.y * u_inv_cosa + asfloat((asuint(t.zwxx) ^ nppp) & mask),
- u.z * u_inv_cosa + asfloat((asuint(t.yxwx) ^ pnpp) & mask),
- float4(0.0f, 0.0f, 0.0f, 1.0f)
- );
-
- }
-
- /// <summary>
- /// Returns a float4x4 rotation matrix constructed by first performing a rotation around the x-axis, then the y-axis and finally the z-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="xyz">A float3 vector containing the rotation angles around the x-, y- and z-axis measures in radians.</param>
- /// <returns>The float4x4 rotation matrix of the Euler angle rotation in x-y-z order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 EulerXYZ(float3 xyz)
- {
- // return mul(rotateZ(xyz.z), mul(rotateY(xyz.y), rotateX(xyz.x)));
- float3 s, c;
- sincos(xyz, out s, out c);
- return float4x4(
- c.y * c.z, c.z * s.x * s.y - c.x * s.z, c.x * c.z * s.y + s.x * s.z, 0.0f,
- c.y * s.z, c.x * c.z + s.x * s.y * s.z, c.x * s.y * s.z - c.z * s.x, 0.0f,
- -s.y, c.y * s.x, c.x * c.y, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f
- );
- }
-
- /// <summary>
- /// Returns a float4x4 rotation matrix constructed by first performing a rotation around the x-axis, then the z-axis and finally the y-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="xyz">A float3 vector containing the rotation angles around the x-, y- and z-axis measures in radians.</param>
- /// <returns>The float4x4 rotation matrix of the Euler angle rotation in x-z-y order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 EulerXZY(float3 xyz)
- {
- // return mul(rotateY(xyz.y), mul(rotateZ(xyz.z), rotateX(xyz.x))); }
- float3 s, c;
- sincos(xyz, out s, out c);
- return float4x4(
- c.y * c.z, s.x * s.y - c.x * c.y * s.z, c.x * s.y + c.y * s.x * s.z, 0.0f,
- s.z, c.x * c.z, -c.z * s.x, 0.0f,
- -c.z * s.y, c.y * s.x + c.x * s.y * s.z, c.x * c.y - s.x * s.y * s.z, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f
- );
- }
-
- /// <summary>
- /// Returns a float4x4 rotation matrix constructed by first performing a rotation around the y-axis, then the x-axis and finally the z-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="xyz">A float3 vector containing the rotation angles around the x-, y- and z-axis measures in radians.</param>
- /// <returns>The float4x4 rotation matrix of the Euler angle rotation in y-x-z order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 EulerYXZ(float3 xyz)
- {
- // return mul(rotateZ(xyz.z), mul(rotateX(xyz.x), rotateY(xyz.y)));
- float3 s, c;
- sincos(xyz, out s, out c);
- return float4x4(
- c.y * c.z - s.x * s.y * s.z, -c.x * s.z, c.z * s.y + c.y * s.x * s.z, 0.0f,
- c.z * s.x * s.y + c.y * s.z, c.x * c.z, s.y * s.z - c.y * c.z * s.x, 0.0f,
- -c.x * s.y, s.x, c.x * c.y, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f
- );
- }
-
- /// <summary>
- /// Returns a float4x4 rotation matrix constructed by first performing a rotation around the y-axis, then the z-axis and finally the x-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="xyz">A float3 vector containing the rotation angles around the x-, y- and z-axis measures in radians.</param>
- /// <returns>The float4x4 rotation matrix of the Euler angle rotation in y-z-x order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 EulerYZX(float3 xyz)
- {
- // return mul(rotateX(xyz.x), mul(rotateZ(xyz.z), rotateY(xyz.y)));
- float3 s, c;
- sincos(xyz, out s, out c);
- return float4x4(
- c.y * c.z, -s.z, c.z * s.y, 0.0f,
- s.x * s.y + c.x * c.y * s.z, c.x * c.z, c.x * s.y * s.z - c.y * s.x, 0.0f,
- c.y * s.x * s.z - c.x * s.y, c.z * s.x, c.x * c.y + s.x * s.y * s.z, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f
- );
- }
-
- /// <summary>
- /// Returns a float4x4 rotation matrix constructed by first performing a rotation around the z-axis, then the x-axis and finally the y-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// This is the default order rotation order in Unity.
- /// </summary>
- /// <param name="xyz">A float3 vector containing the rotation angles around the x-, y- and z-axis measures in radians.</param>
- /// <returns>The float4x4 rotation matrix of the Euler angle rotation in z-x-y order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 EulerZXY(float3 xyz)
- {
- // return mul(rotateY(xyz.y), mul(rotateX(xyz.x), rotateZ(xyz.z)));
- float3 s, c;
- sincos(xyz, out s, out c);
- return float4x4(
- c.y * c.z + s.x * s.y * s.z, c.z * s.x * s.y - c.y * s.z, c.x * s.y, 0.0f,
- c.x * s.z, c.x * c.z, -s.x, 0.0f,
- c.y * s.x * s.z - c.z * s.y, c.y * c.z * s.x + s.y * s.z, c.x * c.y, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f
- );
- }
-
- /// <summary>
- /// Returns a float4x4 rotation matrix constructed by first performing a rotation around the z-axis, then the y-axis and finally the x-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="xyz">A float3 vector containing the rotation angles around the x-, y- and z-axis measures in radians.</param>
- /// <returns>The float4x4 rotation matrix of the Euler angle rotation in z-y-x order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 EulerZYX(float3 xyz)
- {
- // return mul(rotateX(xyz.x), mul(rotateY(xyz.y), rotateZ(xyz.z)));
- float3 s, c;
- sincos(xyz, out s, out c);
- return float4x4(
- c.y * c.z, -c.y * s.z, s.y, 0.0f,
- c.z * s.x * s.y + c.x * s.z, c.x * c.z - s.x * s.y * s.z, -c.y * s.x, 0.0f,
- s.x * s.z - c.x * c.z * s.y, c.z * s.x + c.x * s.y * s.z, c.x * c.y, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f
- );
- }
-
- /// <summary>
- /// Returns a float4x4 rotation matrix constructed by first performing a rotation around the x-axis, then the y-axis and finally the z-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="x">The rotation angle around the x-axis in radians.</param>
- /// <param name="y">The rotation angle around the y-axis in radians.</param>
- /// <param name="z">The rotation angle around the z-axis in radians.</param>
- /// <returns>The float4x4 rotation matrix of the Euler angle rotation in x-y-z order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 EulerXYZ(float x, float y, float z) { return EulerXYZ(float3(x, y, z)); }
-
- /// <summary>
- /// Returns a float4x4 rotation matrix constructed by first performing a rotation around the x-axis, then the z-axis and finally the y-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="x">The rotation angle around the x-axis in radians.</param>
- /// <param name="y">The rotation angle around the y-axis in radians.</param>
- /// <param name="z">The rotation angle around the z-axis in radians.</param>
- /// <returns>The float4x4 rotation matrix of the Euler angle rotation in x-z-y order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 EulerXZY(float x, float y, float z) { return EulerXZY(float3(x, y, z)); }
-
- /// <summary>
- /// Returns a float4x4 rotation matrix constructed by first performing a rotation around the y-axis, then the x-axis and finally the z-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="x">The rotation angle around the x-axis in radians.</param>
- /// <param name="y">The rotation angle around the y-axis in radians.</param>
- /// <param name="z">The rotation angle around the z-axis in radians.</param>
- /// <returns>The float4x4 rotation matrix of the Euler angle rotation in y-x-z order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 EulerYXZ(float x, float y, float z) { return EulerYXZ(float3(x, y, z)); }
-
- /// <summary>
- /// Returns a float4x4 rotation matrix constructed by first performing a rotation around the y-axis, then the z-axis and finally the x-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="x">The rotation angle around the x-axis in radians.</param>
- /// <param name="y">The rotation angle around the y-axis in radians.</param>
- /// <param name="z">The rotation angle around the z-axis in radians.</param>
- /// <returns>The float4x4 rotation matrix of the Euler angle rotation in y-z-x order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 EulerYZX(float x, float y, float z) { return EulerYZX(float3(x, y, z)); }
-
- /// <summary>
- /// Returns a float4x4 rotation matrix constructed by first performing a rotation around the z-axis, then the x-axis and finally the y-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// This is the default order rotation order in Unity.
- /// </summary>
- /// <param name="x">The rotation angle around the x-axis in radians.</param>
- /// <param name="y">The rotation angle around the y-axis in radians.</param>
- /// <param name="z">The rotation angle around the z-axis in radians.</param>
- /// <returns>The float4x4 rotation matrix of the Euler angle rotation in z-x-y order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 EulerZXY(float x, float y, float z) { return EulerZXY(float3(x, y, z)); }
-
- /// <summary>
- /// Returns a float4x4 rotation matrix constructed by first performing a rotation around the z-axis, then the y-axis and finally the x-axis.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// </summary>
- /// <param name="x">The rotation angle around the x-axis in radians.</param>
- /// <param name="y">The rotation angle around the y-axis in radians.</param>
- /// <param name="z">The rotation angle around the z-axis in radians.</param>
- /// <returns>The float4x4 rotation matrix of the Euler angle rotation in z-y-x order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 EulerZYX(float x, float y, float z) { return EulerZYX(float3(x, y, z)); }
-
- /// <summary>
- /// Returns a float4x4 constructed by first performing 3 rotations around the principal axes in a given order.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// When the rotation order is known at compile time, it is recommended for performance reasons to use specific
- /// Euler rotation constructors such as EulerZXY(...).
- /// </summary>
- /// <param name="xyz">A float3 vector containing the rotation angles around the x-, y- and z-axis measures in radians.</param>
- /// <param name="order">The order in which the rotations are applied.</param>
- /// <returns>The float4x4 rotation matrix of the Euler angle rotation in given order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 Euler(float3 xyz, RotationOrder order = RotationOrder.Default)
- {
- switch (order)
- {
- case RotationOrder.XYZ:
- return EulerXYZ(xyz);
- case RotationOrder.XZY:
- return EulerXZY(xyz);
- case RotationOrder.YXZ:
- return EulerYXZ(xyz);
- case RotationOrder.YZX:
- return EulerYZX(xyz);
- case RotationOrder.ZXY:
- return EulerZXY(xyz);
- case RotationOrder.ZYX:
- return EulerZYX(xyz);
- default:
- return float4x4.identity;
- }
- }
-
- /// <summary>
- /// Returns a float4x4 rotation matrix constructed by first performing 3 rotations around the principal axes in a given order.
- /// All rotation angles are in radians and clockwise when looking along the rotation axis towards the origin.
- /// When the rotation order is known at compile time, it is recommended for performance reasons to use specific
- /// Euler rotation constructors such as EulerZXY(...).
- /// </summary>
- /// <param name="x">The rotation angle around the x-axis in radians.</param>
- /// <param name="y">The rotation angle around the y-axis in radians.</param>
- /// <param name="z">The rotation angle around the z-axis in radians.</param>
- /// <param name="order">The order in which the rotations are applied.</param>
- /// <returns>The float4x4 rotation matrix of the Euler angle rotation in given order.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 Euler(float x, float y, float z, RotationOrder order = RotationOrder.Default)
- {
- return Euler(float3(x, y, z), order);
- }
-
- /// <summary>Returns a float4x4 matrix that rotates around the x-axis by a given number of radians.</summary>
- /// <param name="angle">The clockwise rotation angle when looking along the x-axis towards the origin in radians.</param>
- /// <returns>The float4x4 rotation matrix that rotates around the x-axis.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 RotateX(float angle)
- {
- // {{1, 0, 0}, {0, c_0, -s_0}, {0, s_0, c_0}}
- float s, c;
- sincos(angle, out s, out c);
- return float4x4(1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, c, -s, 0.0f,
- 0.0f, s, c, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
-
- }
-
- /// <summary>Returns a float4x4 matrix that rotates around the y-axis by a given number of radians.</summary>
- /// <param name="angle">The clockwise rotation angle when looking along the y-axis towards the origin in radians.</param>
- /// <returns>The float4x4 rotation matrix that rotates around the y-axis.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 RotateY(float angle)
- {
- // {{c_1, 0, s_1}, {0, 1, 0}, {-s_1, 0, c_1}}
- float s, c;
- sincos(angle, out s, out c);
- return float4x4(c, 0.0f, s, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- -s, 0.0f, c, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
-
- }
-
- /// <summary>Returns a float4x4 matrix that rotates around the z-axis by a given number of radians.</summary>
- /// <param name="angle">The clockwise rotation angle when looking along the z-axis towards the origin in radians.</param>
- /// <returns>The float4x4 rotation matrix that rotates around the z-axis.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 RotateZ(float angle)
- {
- // {{c_2, -s_2, 0}, {s_2, c_2, 0}, {0, 0, 1}}
- float s, c;
- sincos(angle, out s, out c);
- return float4x4(c, -s, 0.0f, 0.0f,
- s, c, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
-
- }
-
- /// <summary>Returns a float4x4 scale matrix given 3 axis scales.</summary>
- /// <param name="s">The uniform scaling factor.</param>
- /// <returns>The float4x4 matrix that represents a uniform scale.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 Scale(float s)
- {
- return float4x4(s, 0.0f, 0.0f, 0.0f,
- 0.0f, s, 0.0f, 0.0f,
- 0.0f, 0.0f, s, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
- }
-
- /// <summary>Returns a float4x4 scale matrix given a float3 vector containing the 3 axis scales.</summary>
- /// <param name="x">The x-axis scaling factor.</param>
- /// <param name="y">The y-axis scaling factor.</param>
- /// <param name="z">The z-axis scaling factor.</param>
- /// <returns>The float4x4 matrix that represents a non-uniform scale.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 Scale(float x, float y, float z)
- {
- return float4x4(x, 0.0f, 0.0f, 0.0f,
- 0.0f, y, 0.0f, 0.0f,
- 0.0f, 0.0f, z, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
- }
-
- /// <summary>Returns a float4x4 scale matrix given a float3 vector containing the 3 axis scales.</summary>
- /// <param name="scales">The vector containing scale factors for each axis.</param>
- /// <returns>The float4x4 matrix that represents a non-uniform scale.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 Scale(float3 scales)
- {
- return Scale(scales.x, scales.y, scales.z);
- }
-
- /// <summary>Returns a float4x4 translation matrix given a float3 translation vector.</summary>
- /// <param name="vector">The translation vector.</param>
- /// <returns>The float4x4 translation matrix.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 Translate(float3 vector)
- {
- return float4x4(float4(1.0f, 0.0f, 0.0f, 0.0f),
- float4(0.0f, 1.0f, 0.0f, 0.0f),
- float4(0.0f, 0.0f, 1.0f, 0.0f),
- float4(vector.x, vector.y, vector.z, 1.0f));
- }
-
- /// <summary>
- /// Returns a float4x4 view matrix given an eye position, a target point and a unit length up vector.
- /// The up vector is assumed to be unit length, the eye and target points are assumed to be distinct and
- /// the vector between them is assumes to be collinear with the up vector.
- /// If these assumptions are not met use float4x4.LookRotationSafe instead.
- /// </summary>
- /// <param name="eye">The eye position.</param>
- /// <param name="target">The view target position.</param>
- /// <param name="up">The eye up direction.</param>
- /// <returns>The float4x4 view matrix.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 LookAt(float3 eye, float3 target, float3 up)
- {
- float3x3 rot = float3x3.LookRotation(normalize(target - eye), up);
-
- float4x4 matrix;
- matrix.c0 = float4(rot.c0, 0.0F);
- matrix.c1 = float4(rot.c1, 0.0F);
- matrix.c2 = float4(rot.c2, 0.0F);
- matrix.c3 = float4(eye, 1.0F);
- return matrix;
- }
-
- /// <summary>
- /// Returns a float4x4 centered orthographic projection matrix.
- /// </summary>
- /// <param name="width">The width of the view volume.</param>
- /// <param name="height">The height of the view volume.</param>
- /// <param name="near">The distance to the near plane.</param>
- /// <param name="far">The distance to the far plane.</param>
- /// <returns>The float4x4 centered orthographic projection matrix.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 Ortho(float width, float height, float near, float far)
- {
- float rcpdx = 1.0f / width;
- float rcpdy = 1.0f / height;
- float rcpdz = 1.0f / (far - near);
-
- return float4x4(
- 2.0f * rcpdx, 0.0f, 0.0f, 0.0f,
- 0.0f, 2.0f * rcpdy, 0.0f, 0.0f,
- 0.0f, 0.0f, -2.0f * rcpdz, -(far + near) * rcpdz,
- 0.0f, 0.0f, 0.0f, 1.0f
- );
- }
-
- /// <summary>
- /// Returns a float4x4 off-center orthographic projection matrix.
- /// </summary>
- /// <param name="left">The minimum x-coordinate of the view volume.</param>
- /// <param name="right">The maximum x-coordinate of the view volume.</param>
- /// <param name="bottom">The minimum y-coordinate of the view volume.</param>
- /// <param name="top">The minimum y-coordinate of the view volume.</param>
- /// <param name="near">The distance to the near plane.</param>
- /// <param name="far">The distance to the far plane.</param>
- /// <returns>The float4x4 off-center orthographic projection matrix.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 OrthoOffCenter(float left, float right, float bottom, float top, float near, float far)
- {
- float rcpdx = 1.0f / (right - left);
- float rcpdy = 1.0f / (top - bottom);
- float rcpdz = 1.0f / (far - near);
-
- return float4x4(
- 2.0f * rcpdx, 0.0f, 0.0f, -(right + left) * rcpdx,
- 0.0f, 2.0f * rcpdy, 0.0f, -(top + bottom) * rcpdy,
- 0.0f, 0.0f, -2.0f * rcpdz, -(far + near) * rcpdz,
- 0.0f, 0.0f, 0.0f, 1.0f
- );
- }
-
- /// <summary>
- /// Returns a float4x4 perspective projection matrix based on field of view.
- /// </summary>
- /// <param name="verticalFov">Vertical Field of view in radians.</param>
- /// <param name="aspect">X:Y aspect ratio.</param>
- /// <param name="near">Distance to near plane. Must be greater than zero.</param>
- /// <param name="far">Distance to far plane. Must be greater than zero.</param>
- /// <returns>The float4x4 perspective projection matrix.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 PerspectiveFov(float verticalFov, float aspect, float near, float far)
- {
- float cotangent = 1.0f / tan(verticalFov * 0.5f);
- float rcpdz = 1.0f / (near - far);
-
- return float4x4(
- cotangent / aspect, 0.0f, 0.0f, 0.0f,
- 0.0f, cotangent, 0.0f, 0.0f,
- 0.0f, 0.0f, (far + near) * rcpdz, 2.0f * near * far * rcpdz,
- 0.0f, 0.0f, -1.0f, 0.0f
- );
- }
-
- /// <summary>
- /// Returns a float4x4 off-center perspective projection matrix.
- /// </summary>
- /// <param name="left">The x-coordinate of the left side of the clipping frustum at the near plane.</param>
- /// <param name="right">The x-coordinate of the right side of the clipping frustum at the near plane.</param>
- /// <param name="bottom">The y-coordinate of the bottom side of the clipping frustum at the near plane.</param>
- /// <param name="top">The y-coordinate of the top side of the clipping frustum at the near plane.</param>
- /// <param name="near">Distance to the near plane. Must be greater than zero.</param>
- /// <param name="far">Distance to the far plane. Must be greater than zero.</param>
- /// <returns>The float4x4 off-center perspective projection matrix.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 PerspectiveOffCenter(float left, float right, float bottom, float top, float near, float far)
- {
- float rcpdz = 1.0f / (near - far);
- float rcpWidth = 1.0f / (right - left);
- float rcpHeight = 1.0f / (top - bottom);
-
- return float4x4(
- 2.0f * near * rcpWidth, 0.0f, (left + right) * rcpWidth, 0.0f,
- 0.0f, 2.0f * near * rcpHeight, (bottom + top) * rcpHeight, 0.0f,
- 0.0f, 0.0f, (far + near) * rcpdz, 2.0f * near * far * rcpdz,
- 0.0f, 0.0f, -1.0f, 0.0f
- );
- }
-
- /// <summary>
- /// Returns a float4x4 matrix representing a combined scale-, rotation- and translation transform.
- /// Equivalent to mul(translationTransform, mul(rotationTransform, scaleTransform)).
- /// </summary>
- /// <param name="translation">The translation vector.</param>
- /// <param name="rotation">The quaternion rotation.</param>
- /// <param name="scale">The scaling factors of each axis.</param>
- /// <returns>The float4x4 matrix representing the translation, rotation, and scale by the inputs.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 TRS(float3 translation, quaternion rotation, float3 scale)
- {
- float3x3 r = float3x3(rotation);
- return float4x4( float4(r.c0 * scale.x, 0.0f),
- float4(r.c1 * scale.y, 0.0f),
- float4(r.c2 * scale.z, 0.0f),
- float4(translation, 1.0f));
- }
- }
-
- partial class math
- {
- /// <summary>
- /// Extracts a float3x3 from the upper left 3x3 of a float4x4.
- /// </summary>
- /// <param name="f4x4"><see cref="float4x4"/> to extract a float3x3 from.</param>
- /// <returns>Upper left 3x3 matrix as float3x3.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 float3x3(float4x4 f4x4)
- {
- return new float3x3(f4x4);
- }
-
- /// <summary>Returns a float3x3 matrix constructed from a quaternion.</summary>
- /// <param name="rotation">The quaternion representing a rotation.</param>
- /// <returns>The float3x3 constructed from a quaternion.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 float3x3(quaternion rotation)
- {
- return new float3x3(rotation);
- }
-
- /// <summary>Returns a float4x4 constructed from a float3x3 rotation matrix and a float3 translation vector.</summary>
- /// <param name="rotation">The float3x3 rotation matrix.</param>
- /// <param name="translation">The translation vector.</param>
- /// <returns>The float4x4 constructed from a rotation and translation.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 float4x4(float3x3 rotation, float3 translation)
- {
- return new float4x4(rotation, translation);
- }
-
- /// <summary>Returns a float4x4 constructed from a quaternion and a float3 translation vector.</summary>
- /// <param name="rotation">The quaternion rotation.</param>
- /// <param name="translation">The translation vector.</param>
- /// <returns>The float4x4 constructed from a rotation and translation.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 float4x4(quaternion rotation, float3 translation)
- {
- return new float4x4(rotation, translation);
- }
-
- /// <summary>Returns a float4x4 constructed from a RigidTransform.</summary>
- /// <param name="transform">The rigid transformation.</param>
- /// <returns>The float4x4 constructed from a RigidTransform.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float4x4 float4x4(RigidTransform transform)
- {
- return new float4x4(transform);
- }
-
- /// <summary>Returns an orthonormalized version of a float3x3 matrix.</summary>
- /// <param name="i">The float3x3 to be orthonormalized.</param>
- /// <returns>The orthonormalized float3x3 matrix.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float3x3 orthonormalize(float3x3 i)
- {
- float3x3 o;
-
- float3 u = i.c0;
- float3 v = i.c1 - i.c0 * math.dot(i.c1, i.c0);
-
- float lenU = math.length(u);
- float lenV = math.length(v);
-
- bool c = lenU > 1e-30f && lenV > 1e-30f;
-
- o.c0 = math.select(float3(1, 0, 0), u / lenU, c);
- o.c1 = math.select(float3(0, 1, 0), v / lenV, c);
- o.c2 = math.cross(o.c0, o.c1);
-
- return o;
- }
- }
- }
|