示例#1
0
 /// <summary>
 /// Create and assign matrix values with rows.
 /// </summary>
 public Tensor4(Euler4 x, Euler4 y, Euler4 z, Euler4 t, Euler4 u, Euler4 v)
 {
     ex = x;
     ey = y;
     ez = z;
     et = t;
     eu = u;
     ev = v;
 }
示例#2
0
 /// <summary>
 /// Create a diagonal tensor matrix.
 /// </summary>
 public Tensor4(Euler4 scale)
 {
     ex = new Euler4(scale.x, 0, 0, 0, 0, 0);
     ey = new Euler4(0, scale.y, 0, 0, 0, 0);
     ez = new Euler4(0, 0, scale.z, 0, 0, 0);
     et = new Euler4(0, 0, 0, scale.t, 0, 0);
     eu = new Euler4(0, 0, 0, 0, scale.u, 0);
     ev = new Euler4(0, 0, 0, 0, 0, scale.v);
 }
示例#3
0
 /// <summary>
 /// Create a diagonally uniform tensor matrix.
 /// </summary>
 public Tensor4(float scale)
 {
     ex = new Euler4(scale, 0, 0, 0, 0, 0);
     ey = new Euler4(0, scale, 0, 0, 0, 0);
     ez = new Euler4(0, 0, scale, 0, 0, 0);
     et = new Euler4(0, 0, 0, scale, 0, 0);
     eu = new Euler4(0, 0, 0, 0, scale, 0);
     ev = new Euler4(0, 0, 0, 0, 0, scale);
 }
示例#4
0
 /// <summary>
 /// Create inertia from rotation matrix.
 /// </summary>
 public static Tensor4 Cross(Matrix4 t)
 {
     return(new Tensor4(
                Euler4.Cross(t.ey, t.ez),
                Euler4.Cross(t.ez, t.ex),
                Euler4.Cross(t.ex, t.ey),
                Euler4.Cross(t.ex, t.ew),
                Euler4.Cross(t.ey, t.ew),
                Euler4.Cross(t.ez, t.ew)
                ));
 }
示例#5
0
 /// <summary>
 /// Transform euler rotation by the tensor.
 /// </summary>
 static public Euler4 operator *(Tensor4 lhs, Euler4 rhs)
 {
     return(new Euler4()
     {
         x = Euler4.Dot(lhs.ex, rhs),
         y = Euler4.Dot(lhs.ey, rhs),
         z = Euler4.Dot(lhs.ez, rhs),
         t = Euler4.Dot(lhs.et, rhs),
         u = Euler4.Dot(lhs.eu, rhs),
         v = Euler4.Dot(lhs.ev, rhs),
     });
 }
示例#6
0
        /// <summary>
        /// Get Nth-row of the matrix
        /// </summary>
        public        Euler4 this[int index]
        {
            get
            {
                switch (index)
                {
                case 0: return(ex);

                case 1: return(ey);

                case 2: return(ez);

                case 3: return(et);

                case 4: return(eu);

                case 5: return(ev);

                default: throw new IndexOutOfRangeException();
                }
            }
            set
            {
                switch (index)
                {
                case 0: ex = value; break;

                case 1: ey = value; break;

                case 2: ez = value; break;

                case 3: et = value; break;

                case 4: eu = value; break;

                case 5: ev = value; break;

                default: throw new IndexOutOfRangeException();
                }
            }
        }
示例#7
0
        /// <summary>
        /// Convert matrix into euler degree rotation
        /// </summary>
        /// <remarks>
        /// The method is not valid in 90 deg singularity (WIP).
        /// The method won't check for orthogonality.
        /// </remarks>
        public Euler4 ToEuler()
        {
            // Singularity check.
            //var d = Diagonal; var t = d.x * d.y * d.z * d.w; var t2 = Vector4.Dot(d, Vector4.one); t2 = t2 * t2;
            //if (t > 0.99F) return ToEulerInSingularity(); // Because Utility.Atan2AvoidPi doesn't care about 180 deg singularities...
            // if (t2 - 1 < 0.001F) return ToEulerInHalfSingularity(); // 90 deg is bad. Some cos() parameters got zero, and could results in chaos because of losing sign information

            // Back to main topic..
            // Based on Euler() sequence, the raw formula is...
            // matrix{{ach, dh, -bch, -j}, {k(bg-adf)-acjl, cfk-djl, k(bdf+ag)+bcjl, -hl}, {-ln(bg-adf)+m(adg+bf)-acjkn, -cgm-cfln-djkn, -ln(bdf+ag)+m(af-bdg)+bcjkn, -hkn}, {lm(bg-adf)+n(adg+bf)+acjkm, cflm+djkm-cgn, lm(bdf+ag)+n(af-bdg)-bcjkm, hkm}}

            // matrix{{ach, -dh, bch, -j}, {k(adf+bg)-acjl, cfk+djl, k(bdf-ag)-bcjl, -hl},
            // { -ln(adf+bg)+m(adg-bf)-acjkn, cgm+djkn-cfln, -ln(bdf-ag)+m(bdg+af)-bcjkn, -hkn},
            // { lm(adf+bg)+n(adg-bf)+acjkm, cflm-djkm+cgn, lm(bdf-ag)+n(bdg+af)+bcjkm, hkm}}

            Euler4 result = new Euler4();

            result.y = AngleTidy(Math.Atan2(this[0, 2], this[0, 0]));  // ach, bch
            result.v = AngleTidy(Math.Atan2(-this[2, 3], this[3, 3])); // hkm, -hkn

            // (So lucky) We got the first and last matrix sequence.  Now make the matrix simpler
            // Simplify into : matrix{{ch, dh, 0, -j}, {-cjl-dfk, cfk-djl, gk, -hl}, {dg, -cg, f, 0}, {cjk-dfl, cfl+djk, gl, hk}}
            // matrix{{ch, -dh, 0, -j}, {dfk-cjl, cfk+djl, -gk, -hl}, {dg, cg, f, 0}, {cjk+dfl, cfl-djk, -gl, hk}}

            var m2 = Euler(5, -result.v) * this * Euler(1, -result.y);

            result.z = AngleTidy(Math.Atan2(-m2[0, 1], m2[0, 0])); // ch, -dh
            result.u = AngleTidy(Math.Atan2(-m2[1, 3], m2[3, 3])); // hk, -hl

            // Idk if it's safe to get x and t from that matrix, but working > efficient
            // Simplify into : matrix{{h, 0, 0, -j}, {0, f, g, 0}, {0, -g, f, 0}, {j, 0, 0, h}}

            var m3 = Euler(4, -result.u) * m2 * Euler(2, -result.z);

            result.x = AngleTidy(Math.Atan2(m3[2, 1], m3[1, 1]));  // f, g
            result.t = AngleTidy(Math.Atan2(-m3[0, 3], m3[0, 0])); // h, -j

            return(result);
        }
示例#8
0
 /// <summary>
 /// Rotate this transform (in euler) in given space orientation.
 /// </summary>
 public void Rotate(Euler4 value, Space4 space)
 {
     Rotate(Matrix4.Euler(value), space);
 }
示例#9
0
 /// <summary>
 /// Convert degree euler to orthogonal matrix rotation.
 /// </summary>
 public static Matrix4 Euler(Euler4 rot)
 {
     return(Euler(rot.x, rot.y, rot.z, rot.t, rot.u, rot.v));
 }