Пример #1
0
 public Transform(float[,] mat)
 {
     this.m = new Matrix4x4(mat[0, 0], mat[0, 1], mat[0, 2], mat[0, 3],
                   mat[1, 0], mat[1, 1], mat[1, 2], mat[1, 3],
                   mat[2, 0], mat[2, 1], mat[2, 2], mat[2, 3],
                   mat[3, 0], mat[3, 1], mat[3, 2], mat[3, 3]);
     this.mInv = Inverse(this.m);
 }
Пример #2
0
 public static Matrix4x4 Mul(Matrix4x4 m1, Matrix4x4 m2)
 {
     Matrix4x4 r = new Matrix4x4();
     for (int i = 0; i < 4; ++i)
         for (int j = 0; j < 4; ++j)
             r.m[i, j] = m1.m[i, 0] * m2.m[0, j] +
                        m1.m[i, 1] * m2.m[1, j] +
                        m1.m[i, 2] * m2.m[2, j] +
                        m1.m[i, 3] * m2.m[3, j];
     return r;
 }
Пример #3
0
        public Transform ToTransform()
        {
            float xx = v.x * v.x, yy = v.y * v.y, zz = v.z * v.z;
            float xy = v.x * v.y, xz = v.x * v.z, yz = v.y * v.z;
            float wx = v.x * w, wy = v.y * w, wz = v.z * w;

            Matrix4x4 m = new Matrix4x4();
            m.m[0, 0] = 1.0f - 2.0f * (yy + zz);
            m.m[0, 1] = 2.0f * (xy + wz);
            m.m[0, 2] = 2.0f * (xz - wy);
            m.m[1, 0] = 2.0f * (xy - wz);
            m.m[1, 1] = 1.0f - 2.0f * (xx + zz);
            m.m[1, 2] = 2.0f * (yz + wx);
            m.m[2, 0] = 2.0f * (xz + wy);
            m.m[2, 1] = 2.0f * (yz - wx);
            m.m[2, 2] = 1.0f - 2.0f * (xx + yy);

            // Transpose since we are left-handed.  Ugh.
            return new Transform(Transform.Transpose(m), m);
        }
Пример #4
0
        public static Matrix4x4 Inverse(Matrix4x4 m)
        {
            int[] indxc = new int[4];
            int[] indxr = new int[4];
            int[] ipiv = { 0, 0, 0, 0 };
            float[,] minv = new float[4, 4];
            Array.Copy(m.m, minv, 4 * 4);

            for (int i = 0; i < 4; i++)
            {
                int irow = -1, icol = -1;
                float big = 0.0f;
                // Choose pivot
                for (int j = 0; j < 4; j++)
                {
                    if (ipiv[j] != 1)
                    {
                        for (int k = 0; k < 4; k++)
                        {
                            if (ipiv[k] == 0)
                            {
                                if (Math.Abs(minv[j, k]) >= big)
                                {
                                    big = (float)(Math.Abs(minv[j, k]));
                                    irow = j;
                                    icol = k;
                                }
                            }
                            else if (ipiv[k] > 1)
                                throw new Exception("Singular matrix in MatrixInvert");
                        }
                    }
                }
                ++ipiv[icol];
                // Swap rows _irow_ and _icol_ for pivot
                if (irow != icol)
                {
                    for (int k = 0; k < 4; ++k)
                        Utility.Swap<float>(ref minv[irow, k], ref  minv[icol, k]);
                }
                indxr[i] = irow;
                indxc[i] = icol;
                if (minv[icol, icol] == 0.0f)
                    throw new Exception("Singular matrix in MatrixInvert");

                // Set $m[icol][icol]$ to one by scaling row _icol_ appropriately
                float pivinv = 1.0f / minv[icol, icol];
                minv[icol, icol] = 1.0f;
                for (int j = 0; j < 4; j++)
                    minv[icol, j] *= pivinv;

                // Subtract this row from others to zero out their columns
                for (int j = 0; j < 4; j++)
                {
                    if (j != icol)
                    {
                        float save = minv[j, icol];
                        minv[j, icol] = 0;
                        for (int k = 0; k < 4; k++)
                            minv[j, k] -= minv[icol, k] * save;
                    }
                }
            }
            // Swap columns to reflect permutation
            for (int j = 3; j >= 0; j--)
            {
                if (indxr[j] != indxc[j])
                {
                    for (int k = 0; k < 4; k++)
                        Utility.Swap<float>(ref minv[k, indxr[j]], ref minv[k, indxc[j]]);
                }
            }
            return new Matrix4x4(minv);
        }
Пример #5
0
 public Transform(Matrix4x4 mat, Matrix4x4 minv)
 {
     this.m = mat;
     this.mInv = minv;
 }
Пример #6
0
 public Transform(Matrix4x4 mat)
 {
     this.m = mat;
     this.mInv = Inverse(mat);
 }
Пример #7
0
 public static Matrix4x4 Transpose(Matrix4x4 m)
 {
     return new Matrix4x4(m.m[0, 0], m.m[1, 0], m.m[2, 0], m.m[3, 0],
                      m.m[0, 1], m.m[1, 1], m.m[2, 1], m.m[3, 1],
                      m.m[0, 2], m.m[1, 2], m.m[2, 2], m.m[3, 2],
                      m.m[0, 3], m.m[1, 3], m.m[2, 3], m.m[3, 3]);
 }
Пример #8
0
 public static Transform Translate(Vector delta)
 {
     Matrix4x4 m = new Matrix4x4(1, 0, 0, delta.x,
                 0, 1, 0, delta.y,
                 0, 0, 1, delta.z,
                 0, 0, 0, 1);
     Matrix4x4 minv = new Matrix4x4(1, 0, 0, -delta.x,
                    0, 1, 0, -delta.y,
                    0, 0, 1, -delta.z,
                    0, 0, 0, 1);
     return new Transform(m, minv);
 }
Пример #9
0
 public static Transform Scale(float x, float y, float z)
 {
     Matrix4x4 m = new Matrix4x4(x, 0, 0, 0,
                 0, y, 0, 0,
                 0, 0, z, 0,
                 0, 0, 0, 1);
     Matrix4x4 minv = new Matrix4x4(1.0f / x, 0, 0, 0,
                    0, 1.0f / y, 0, 0,
                    0, 0, 1.0f / z, 0,
                    0, 0, 0, 1);
     return new Transform(m, minv);
 }
Пример #10
0
 public static Transform RotateZ(float angle)
 {
     float sin_t = (float)Math.Sin(Utility.Radians(angle));
     float cos_t = (float)Math.Cos(Utility.Radians(angle));
     Matrix4x4 m = new Matrix4x4(cos_t, -sin_t, 0, 0,
                 sin_t, cos_t, 0, 0,
                 0, 0, 1, 0,
                 0, 0, 0, 1);
     return new Transform(m, Transpose(m));
 }
Пример #11
0
        public static Transform Rotate(float angle, Vector axis)
        {
            Vector a = Geometry.Geometry.Normalize(axis);
            float s = (float)Math.Sin(Utility.Radians(angle));
            float c = (float)Math.Cos(Utility.Radians(angle));
            float[,] m = new float[4, 4];

            m[0, 0] = a.x * a.x + (1.0f - a.x * a.x) * c;
            m[0, 1] = a.x * a.y * (1.0f - c) - a.z * s;
            m[0, 2] = a.x * a.z * (1.0f - c) + a.y * s;
            m[0, 3] = 0;

            m[1, 0] = a.x * a.y * (1.0f - c) + a.z * s;
            m[1, 1] = a.y * a.y + (1.0f - a.y * a.y) * c;
            m[1, 2] = a.y * a.z * (1.0f - c) - a.x * s;
            m[1, 3] = 0;

            m[2, 0] = a.x * a.z * (1.0f - c) - a.y * s;
            m[2, 1] = a.y * a.z * (1.0f - c) + a.x * s;
            m[2, 2] = a.z * a.z + (1.0f - a.z * a.z) * c;
            m[2, 3] = 0;

            m[3, 0] = 0;
            m[3, 1] = 0;
            m[3, 2] = 0;
            m[3, 3] = 1;

            Matrix4x4 mat = new Matrix4x4(m);
            return new Transform(mat, Transpose(mat));
        }
Пример #12
0
        public static Transform LookAt(Point pos, Point look, Vector up)
        {
            float[,] m = new float[4, 4];
            // Initialize fourth column of viewing matrix
            m[0, 3] = pos.x;
            m[1, 3] = pos.y;
            m[2, 3] = pos.z;
            m[3, 3] = 1;

            // Initialize first three columns of viewing matrix
            Vector dir = Geometry.Geometry.Normalize(look - pos);
            Vector left = Geometry.Geometry.Normalize(Geometry.Geometry.Cross(Geometry.Geometry.Normalize(up), dir));
            Vector newUp = Geometry.Geometry.Cross(dir, left);
            m[0, 0] = left.x;
            m[1, 0] = left.y;
            m[2, 0] = left.z;
            m[3, 0] = 0.0f;
            m[0, 1] = newUp.x;
            m[1, 1] = newUp.y;
            m[2, 1] = newUp.z;
            m[3, 1] = 0.0f;
            m[0, 2] = dir.x;
            m[1, 2] = dir.y;
            m[2, 2] = dir.z;
            m[3, 2] = 0.0f;
            Matrix4x4 camToWorld = new Matrix4x4(m);
            return new Transform(Inverse(camToWorld), camToWorld);
        }