summaryrefslogtreecommitdiffstats
path: root/modules/mono/glue/Managed/Files/Transform.cs
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/glue/Managed/Files/Transform.cs')
-rw-r--r--modules/mono/glue/Managed/Files/Transform.cs191
1 files changed, 191 insertions, 0 deletions
diff --git a/modules/mono/glue/Managed/Files/Transform.cs b/modules/mono/glue/Managed/Files/Transform.cs
new file mode 100644
index 0000000000..e432d5b52c
--- /dev/null
+++ b/modules/mono/glue/Managed/Files/Transform.cs
@@ -0,0 +1,191 @@
+using System;
+using System.Runtime.InteropServices;
+#if REAL_T_IS_DOUBLE
+using real_t = System.Double;
+#else
+using real_t = System.Single;
+#endif
+
+namespace Godot
+{
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Transform : IEquatable<Transform>
+ {
+ public Basis basis;
+ public Vector3 origin;
+
+ public Transform AffineInverse()
+ {
+ Basis basisInv = basis.Inverse();
+ return new Transform(basisInv, basisInv.Xform(-origin));
+ }
+
+ public Transform Inverse()
+ {
+ Basis basisTr = basis.Transposed();
+ return new Transform(basisTr, basisTr.Xform(-origin));
+ }
+
+ public Transform LookingAt(Vector3 target, Vector3 up)
+ {
+ var t = this;
+ t.SetLookAt(origin, target, up);
+ return t;
+ }
+
+ public Transform Orthonormalized()
+ {
+ return new Transform(basis.Orthonormalized(), origin);
+ }
+
+ public Transform Rotated(Vector3 axis, real_t phi)
+ {
+ return new Transform(new Basis(axis, phi), new Vector3()) * this;
+ }
+
+ public Transform Scaled(Vector3 scale)
+ {
+ return new Transform(basis.Scaled(scale), origin * scale);
+ }
+
+ public void SetLookAt(Vector3 eye, Vector3 target, Vector3 up)
+ {
+ // Make rotation matrix
+ // Z vector
+ Vector3 zAxis = eye - target;
+
+ zAxis.Normalize();
+
+ Vector3 yAxis = up;
+
+ Vector3 xAxis = yAxis.Cross(zAxis);
+
+ // Recompute Y = Z cross X
+ yAxis = zAxis.Cross(xAxis);
+
+ xAxis.Normalize();
+ yAxis.Normalize();
+
+ basis = Basis.CreateFromAxes(xAxis, yAxis, zAxis);
+
+ origin = eye;
+ }
+
+ public Transform Translated(Vector3 ofs)
+ {
+ return new Transform(basis, new Vector3
+ (
+ origin[0] += basis[0].Dot(ofs),
+ origin[1] += basis[1].Dot(ofs),
+ origin[2] += basis[2].Dot(ofs)
+ ));
+ }
+
+ public Vector3 Xform(Vector3 v)
+ {
+ return new Vector3
+ (
+ basis[0].Dot(v) + origin.x,
+ basis[1].Dot(v) + origin.y,
+ basis[2].Dot(v) + origin.z
+ );
+ }
+
+ public Vector3 XformInv(Vector3 v)
+ {
+ Vector3 vInv = v - origin;
+
+ return new Vector3
+ (
+ basis[0, 0] * vInv.x + basis[1, 0] * vInv.y + basis[2, 0] * vInv.z,
+ basis[0, 1] * vInv.x + basis[1, 1] * vInv.y + basis[2, 1] * vInv.z,
+ basis[0, 2] * vInv.x + basis[1, 2] * vInv.y + basis[2, 2] * vInv.z
+ );
+ }
+
+ // Constants
+ private static readonly Transform _identity = new Transform(Basis.Identity, Vector3.Zero);
+ private static readonly Transform _flipX = new Transform(new Basis(new Vector3(-1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1)), Vector3.Zero);
+ private static readonly Transform _flipY = new Transform(new Basis(new Vector3(1, 0, 0), new Vector3(0, -1, 0), new Vector3(0, 0, 1)), Vector3.Zero);
+ private static readonly Transform _flipZ = new Transform(new Basis(new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, -1)), Vector3.Zero);
+
+ public static Transform Identity { get { return _identity; } }
+ public static Transform FlipX { get { return _flipX; } }
+ public static Transform FlipY { get { return _flipY; } }
+ public static Transform FlipZ { get { return _flipZ; } }
+
+ // Constructors
+ public Transform(Vector3 xAxis, Vector3 yAxis, Vector3 zAxis, Vector3 origin)
+ {
+ basis = Basis.CreateFromAxes(xAxis, yAxis, zAxis);
+ this.origin = origin;
+ }
+
+ public Transform(Quat quat, Vector3 origin)
+ {
+ basis = new Basis(quat);
+ this.origin = origin;
+ }
+
+ public Transform(Basis basis, Vector3 origin)
+ {
+ this.basis = basis;
+ this.origin = origin;
+ }
+
+ public static Transform operator *(Transform left, Transform right)
+ {
+ left.origin = left.Xform(right.origin);
+ left.basis *= right.basis;
+ return left;
+ }
+
+ public static bool operator ==(Transform left, Transform right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(Transform left, Transform right)
+ {
+ return !left.Equals(right);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is Transform)
+ {
+ return Equals((Transform)obj);
+ }
+
+ return false;
+ }
+
+ public bool Equals(Transform other)
+ {
+ return basis.Equals(other.basis) && origin.Equals(other.origin);
+ }
+
+ public override int GetHashCode()
+ {
+ return basis.GetHashCode() ^ origin.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return String.Format("{0} - {1}", new object[]
+ {
+ basis.ToString(),
+ origin.ToString()
+ });
+ }
+
+ public string ToString(string format)
+ {
+ return String.Format("{0} - {1}", new object[]
+ {
+ basis.ToString(format),
+ origin.ToString(format)
+ });
+ }
+ }
+}