using System; using System.Runtime.CompilerServices; using Unity.IL2CPP.CompilerServices; using static Unity.Mathematics.math; namespace Unity.Mathematics { /// /// An affine transformation type. /// [Il2CppEagerStaticClassConstruction] [Serializable] public struct AffineTransform : IEquatable, IFormattable { /// /// The rotation and scale part of the affine transformation. /// public float3x3 rs; /// /// The translation part of the affine transformation. /// public float3 t; /// An AffineTransform representing the identity transform. public static readonly AffineTransform identity = new AffineTransform(float3.zero, float3x3.identity); /// /// An AffineTransform zero value. /// public static readonly AffineTransform zero; /// Constructs an AffineTransform from a translation represented by a float3 vector and rotation represented by a unit quaternion. /// The translation vector. /// The rotation quaternion. [MethodImpl(MethodImplOptions.AggressiveInlining)] public AffineTransform(float3 translation, quaternion rotation) { rs = float3x3(rotation); t = translation; } /// Constructs an AffineTransform from a translation represented by a float3 vector, rotation represented by a unit quaternion and scale represented by a float3 vector. /// The translation vector. /// The rotation quaternion. /// The scale vector. [MethodImpl(MethodImplOptions.AggressiveInlining)] public AffineTransform(float3 translation, quaternion rotation, float3 scale) { rs = mulScale(math.float3x3(rotation), scale); t = translation; } /// Constructs an AffineTransform from a translation represented by float3 vector and a float3x3 matrix representing both rotation and scale. /// The translation vector. /// The rotation and scale matrix. [MethodImpl(MethodImplOptions.AggressiveInlining)] public AffineTransform(float3 translation, float3x3 rotationScale) { rs = rotationScale; t = translation; } /// Constructs an AffineTransform from float3x3 matrix representating both rotation and scale. /// The rotation and scale matrix. [MethodImpl(MethodImplOptions.AggressiveInlining)] public AffineTransform(float3x3 rotationScale) { rs = rotationScale; t = float3.zero; } /// Constructs an AffineTransform from a RigidTransform. /// The RigidTransform. [MethodImpl(MethodImplOptions.AggressiveInlining)] public AffineTransform(RigidTransform rigid) { rs = math.float3x3(rigid.rot); t = rigid.pos; } /// Constructs an AffineTransform from a float3x4 matrix. /// The float3x4 matrix. [MethodImpl(MethodImplOptions.AggressiveInlining)] public AffineTransform(float3x4 m) { rs = math.float3x3(m.c0, m.c1, m.c2); t = m.c3; } /// Constructs an AffineTransform from a float4x4 matrix. /// The float4x4 matrix. [MethodImpl(MethodImplOptions.AggressiveInlining)] public AffineTransform(float4x4 m) { rs = math.float3x3(m.c0.xyz, m.c1.xyz, m.c2.xyz); t = m.c3.xyz; } /// Implicit float3x4 cast operator. /// The AffineTransform. /// The converted AffineTransform. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator float3x4(AffineTransform m) { return float3x4(m.rs.c0, m.rs.c1, m.rs.c2, m.t); } /// Implicit float4x4 cast operator. /// The AffineTransform. /// The converted AffineTransform. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator float4x4(AffineTransform m) { return float4x4(float4(m.rs.c0, 0f), float4(m.rs.c1, 0f), float4(m.rs.c2, 0f), float4(m.t, 1f)); } /// Returns true if the AffineTransform is equal to a given AffineTransform, false otherwise. /// Right hand side argument to compare equality with. /// The result of the equality comparison. [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(AffineTransform rhs) { return rs.Equals(rhs.rs) && t.Equals(rhs.t); } /// Returns true if the AffineTransform is equal to a given AffineTransform, false otherwise. /// Right hand side argument to compare equality with. /// The result of the equality comparison. public override bool Equals(object o) { return o is AffineTransform converted && Equals(converted); } /// Returns a hash code for the AffineTransform. /// The computed hash code. [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { return (int)hash(this); } /// Returns a string representation of the AffineTransform. /// String representation of the value. [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { return string.Format("AffineTransform(({0}f, {1}f, {2}f, {3}f, {4}f, {5}f, {6}f, {7}f, {8}f), ({9}f, {10}f, {11}f))", rs.c0.x, rs.c1.x, rs.c2.x, rs.c0.y, rs.c1.y, rs.c2.y, rs.c0.z, rs.c1.z, rs.c2.z, t.x, t.y, t.z ); } /// Returns a string representation of the AffineTransform using a specified format and culture-specific format information. /// Format string to use during string formatting. /// Format provider to use during string formatting. /// String representation of the value. [MethodImpl(MethodImplOptions.AggressiveInlining)] public string ToString(string format, IFormatProvider formatProvider) { return string.Format("AffineTransform(({0}f, {1}f, {2}f, {3}f, {4}f, {5}f, {6}f, {7}f, {8}f), ({9}f, {10}f, {11}f))", rs.c0.x.ToString(format, formatProvider), rs.c1.x.ToString(format, formatProvider), rs.c2.x.ToString(format, formatProvider), rs.c0.y.ToString(format, formatProvider), rs.c1.y.ToString(format, formatProvider), rs.c2.y.ToString(format, formatProvider), rs.c0.z.ToString(format, formatProvider), rs.c1.z.ToString(format, formatProvider), rs.c2.z.ToString(format, formatProvider), t.x.ToString(format, formatProvider), t.y.ToString(format, formatProvider), t.z.ToString(format, formatProvider) ); } } public static partial class math { /// Returns an AffineTransform constructed from a translation represented by a float3 vector and rotation represented by a unit quaternion. /// The AffineTransform translation. /// The AffineTransform rotation. /// The AffineTransform given the translation vector and rotation quaternion. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AffineTransform AffineTransform(float3 translation, quaternion rotation) { return new AffineTransform(translation, rotation); } /// Returns an AffineTransform constructed from a translation represented by a float3 vector, rotation represented by a unit quaternion and scale represented by a float3 vector. /// The translation vector. /// The rotation quaternion. /// The scale vector. /// The AffineTransform given the translation vector, rotation quaternion and scale vector. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AffineTransform AffineTransform(float3 translation, quaternion rotation, float3 scale) { return new AffineTransform(translation, rotation, scale); } /// Returns an AffineTransform constructed from a translation represented by float3 vector and a float3x3 matrix representing both rotation and scale. /// The translation vector. /// The rotation and scale matrix. /// The AffineTransform given the translation vector and float3x3 matrix. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AffineTransform AffineTransform(float3 translation, float3x3 rotationScale) { return new AffineTransform(translation, rotationScale); } /// Returns an AffineTransform constructed from a float3x3 matrix representing both rotation and scale. /// The rotation and scale matrix. /// The AffineTransform given a float3x3 matrix. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AffineTransform AffineTransform(float3x3 rotationScale) { return new AffineTransform(rotationScale); } /// Returns an AffineTransform constructed from a float4x4 matrix. /// The float4x4 matrix. /// The AffineTransform given a float4x4 matrix. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AffineTransform AffineTransform(float4x4 m) { return new AffineTransform(m); } /// Returns an AffineTransform constructed from a float3x4 matrix. /// The float3x4 matrix. /// The AffineTransform given a float3x4 matrix. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AffineTransform AffineTransform(float3x4 m) { return new AffineTransform(m); } /// Returns an AffineTransform constructed from a RigidTransform. /// The RigidTransform. /// The AffineTransform given a RigidTransform. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AffineTransform AffineTransform(RigidTransform rigid) { return new AffineTransform (rigid); } /// Returns a float4x4 matrix constructed from an AffineTransform. /// The AffineTransform. /// The float4x4 matrix given an AffineTransform. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float4x4 float4x4(AffineTransform transform) { return float4x4(float4(transform.rs.c0, 0f), float4(transform.rs.c1, 0f), float4(transform.rs.c2, 0f), float4(transform.t, 1f)); } /// Returns a float3x4 matrix constructed from an AffineTransform. /// The AffineTransform. /// The float3x4 matrix given an AffineTransform. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float3x4 float3x4(AffineTransform transform) { return float3x4(transform.rs.c0, transform.rs.c1, transform.rs.c2, transform.t); } /// Returns the result of transforming the AffineTransform b by the AffineTransform a. /// The AffineTransform on the left. /// The AffineTransform on the right. /// The AffineTransform of a transforming b. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AffineTransform mul(AffineTransform a, AffineTransform b) { return new AffineTransform(transform(a, b.t), mul(a.rs, b.rs)); } /// Returns the result of transforming the AffineTransform b by a float3x3 matrix a. /// The float3x3 matrix on the left. /// The AffineTransform on the right. /// The AffineTransform of a transforming b. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AffineTransform mul(float3x3 a, AffineTransform b) { return new AffineTransform(mul(a, b.t), mul(a, b.rs)); } /// Returns the result of transforming the float3x3 b by an AffineTransform a. /// The AffineTransform on the left. /// The float3x3 matrix on the right. /// The AffineTransform of a transforming b. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AffineTransform mul(AffineTransform a, float3x3 b) { return new AffineTransform(a.t, mul(b, a.rs)); } /// Returns the result of transforming a float4 homogeneous coordinate by an AffineTransform. /// The AffineTransform. /// The position to be transformed. /// The transformed position. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float4 mul(AffineTransform a, float4 pos) { return float4(mul(a.rs, pos.xyz) + a.t * pos.w, pos.w); } /// Returns the result of rotating a float3 vector by an AffineTransform. /// The AffineTransform. /// The direction vector to rotate. /// The rotated direction vector. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float3 rotate(AffineTransform a, float3 dir) { return mul(a.rs, dir); } /// Returns the result of transforming a float3 point by an AffineTransform. /// The AffineTransform. /// The position to transform. /// The transformed position. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float3 transform(AffineTransform a, float3 pos) { return a.t + mul(a.rs, pos); } /// Returns the inverse of an AffineTransform. /// The AffineTransform to invert. /// The inverse AffineTransform. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AffineTransform inverse(AffineTransform a) { AffineTransform inv; inv.rs = pseudoinverse(a.rs); inv.t = mul(inv.rs, -a.t); return inv; } /// Decomposes the AffineTransform in translation, rotation and scale. /// The AffineTransform /// The decomposed translation vector of the AffineTransform. /// The decomposed rotation quaternion of the AffineTransform. /// The decomposed scale of the AffineTransform. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void decompose(AffineTransform a, out float3 translation, out quaternion rotation, out float3 scale) { translation = a.t; rotation = math.rotation(a.rs); var sm = mul(float3x3(conjugate(rotation)), a.rs); scale = float3(sm.c0.x, sm.c1.y, sm.c2.z); } /// Returns a uint hash code of an AffineTransform. /// The AffineTransform to hash. /// The hash code of the input AffineTransform. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint hash(AffineTransform a) { return hash(a.rs) + 0xC5C5394Bu * hash(a.t); } /// /// Returns a uint4 vector hash code of an AffineTransform. /// When multiple elements are to be hashes together, it can more efficient to calculate and combine wide hash /// that are only reduced to a narrow uint hash at the very end instead of at every step. /// /// The AffineTransform to hash. /// The uint4 wide hash code. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint4 hashwide(AffineTransform a) { return hashwide(a.rs).xyzz + 0xC5C5394Bu * hashwide(a.t).xyzz; } } }