示例#1
0
        public static Vector3 Unproject(Vector3 windowCoords, Matrix4 modelView, Matrix4 projection, float[] viewPort)
        {
            // First, convert from window coordinates to NDC coordinates
            Vector4 ndcCoords = new Vector4(windowCoords.X, windowCoords.Y, windowCoords.Z, 1.0f);

            ndcCoords.X = (ndcCoords.X - viewPort[0]) / viewPort[2]; // Range 0 to 1: (windowX - viewX) / viewWidth
            ndcCoords.Y = (ndcCoords.Y - viewPort[1]) / viewPort[3]; // Range 0 to 1: (windowY - viewY) / viewHeight
                                                                     // Remember, NDC ranges from -1 to 1, not 0 to 1
            ndcCoords.X = ndcCoords.X * 2f - 1f;                     // Range: -1 to 1
            ndcCoords.Y = 1f - ndcCoords.Y * 2f;                     // Range: -1 to 1 - Flipped!
            ndcCoords.Z = ndcCoords.Z * 2f - 1f;                     // Range: -1 to 1

            // Next, from NDC space to eye / view space.
            // Note, this leaves a scalar in the W component!
            Vector4 eyeCoords = Matrix4.Inverse(projection) * ndcCoords;

            // eye space to world space.
            // Remember, eye space assumes the camera is at the center of the world,
            // this is not the case, let's move the actual point into world space
            Vector4 worldCoords = Matrix4.Inverse(modelView) * eyeCoords;

            // Finally, undo the perspective divide!
            // When we multiplied by the inverse of the projection matrix, that
            // multiplication left the inverse of the perspective divide in the
            // W component of the resulting vector. This could be 0
            if (Math.Abs(0.0f - worldCoords.W) > 0.00001f)
            {
                // This is the same as dividing every component by W
                worldCoords *= 1.0f / worldCoords.W;
            }

            // Now we have a proper 4D vector with a W of 1 (or 0)
            return(new Vector3(worldCoords.X, worldCoords.Y, worldCoords.Z));
        }
示例#2
0
        static void Main(string[] args)
        {
            Matrix2 I = new  Matrix2();

            if (I.Matrix[0] != 1 || I.Matrix[1] != 0 || I.Matrix[2] != 0 || I.Matrix[3] != 1)
            {
                Error("Default Constructor Is Broken");
            }
            Matrix3 a = new Matrix3(4, 9, 8,
                                    3, 7, 2,
                                    1, 3, 4);
            Matrix3 ba = new Matrix3(4, 9, 8,
                                     3, 7, 2,
                                     1, 3, 4);
            Matrix3 c = a * ba;

            if (c[0, 0] != 51 || c[0, 1] != 123 || c[0, 2] != 82 || c[1, 0] != 35 || c[1, 1] != 82 || c[1, 2] != 46 || c[2, 0] != 17 || c[2, 1] != 42 || c[2, 2] != 30)
            {
                Error("Multiplication operand broken");
            }
            float det_A = Matrix3.Determinant(a);

            if (det_A != 14)
            {
                Error("Deterinant is wrong");
                Error("Determinant value: " + det_A + " Expected: 14");
            }
            Matrix3 i    = Matrix3.Inverse(a);
            Matrix3 test = new Matrix3(11.0f / 7.0f, -6.0f / 7.0f, -19.0f / 7.0f,
                                       -5.0f / 7.0f, 4.0f / 7.0f, 8.0f / 7.0f,
                                       1.0f / 7.0f, -3.0f / 14.0f, 1.0f / 14.0f);

            if (i != test)
            {
                Error("Inverse Matrix is wrong");
                Console.WriteLine("Actual: ");
                for (int z = 0; z < 3; z++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        Console.Write(i[z, j].ToString() + "\t");
                    }
                    Console.WriteLine();
                }
                Console.WriteLine("Expected: ");
                for (int z = 0; z < 3; z++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        Console.Write(test[z, j].ToString() + "\t");
                    }
                    Console.WriteLine();
                }
            }

            Vector3 v3        = new Vector3(0, 0, 1);
            Matrix3 xRotation = Matrix3.XRotation(90);
            Vector3 newv3     = xRotation * v3;

            if (newv3[0] != 0.0f || newv3[1] != -1.0f || newv3[2] != 0)
            {
                Error("rotation did not work properly, X: " + newv3[0] + " Y: " + newv3[1] + " Z: " + newv3[2]);
            }

            Matrix2 f = new Matrix2(1, 2,
                                    3, 4);

            if (f.Matrix[0] != 1 && f.Matrix[1] != 2 || f.Matrix[2] != 3 || f.Matrix[3] != 4)
            {
                Error("Params Constructor Is Broken");
            }
            if (f[0] != 1 && f[1] != 2 || f[2] != 3 || f[3] != 4)
            {
                Error("Single Dimensional accessor Is Broken");
            }
            if (f[0, 0] != 1 || f[1, 1] != 4 || f[0, 1] != 2 || f[1, 0] != 3)
            {
                Error("Multidimensional accessor broken");
            }
            if (f.GetValue(0, 0) != 1 || f.GetValue(1, 1) != 4 || f.GetValue(0, 1) != 2 || f.GetValue(1, 0) != 3)
            {
                Error("Instance GetValue broken");
            }
            if (Matrix2.GetValue(f, 0, 0) != 1 || Matrix2.GetValue(f, 1, 1) != 4 || Matrix2.GetValue(f, 0, 1) != 2 || Matrix2.GetValue(f, 1, 0) != 3)
            {
                Error("Instance GetValue broken");
            }

            Matrix2 b = new Matrix2(5, 6,
                                    7, 8);
            Matrix2 h = f + b;

            if (h[0, 0] != 6 || h[0, 1] != 8 || h[1, 0] != 10 || h[1, 1] != 12)
            {
                Error("Addition operator is wrong");
            }
            h = f - b;
            if (h[0, 0] != -4 || h[0, 1] != -4 || h[1, 0] != -4 || h[1, 1] != -4)
            {
                Error("Subtraction operator is wrong");
            }
            h = h * 2;
            if (h[0, 0] != -8 || h[0, 1] != -8 || h[1, 0] != -8 || h[1, 1] != -8)
            {
                Error("multiply operator is wrong");
            }
            h = f / b;
            if (h[0, 0] != 1.0f / 5.0f || h[0, 1] != 2.0f / 6.0f || h[1, 0] != 3.0f / 7.0f || h[1, 1] != 4.0f / 8.0f)
            {
                Error("Division operator is wrong");
            }
            Vector2 v = new Vector2(2, 3);
            Matrix2 d = new Matrix2(4, 5, 6, 7);

            v = d * v;
            if (v[0] != 23.0f || v[1] != 33.0f)
            {
                Error("Vector Multiplication opperand wrong");
                Console.WriteLine("V[0]: " + v[0] + " V[1]: " + v[1]);
            }

            Vector2 v2       = new Vector2(1, 0);
            Matrix2 rotation = Matrix2.Rotation(90.0f);

            v2 = rotation * v2;
            if (0.0f - v[0] > 0.00001f || 1.0f - v[1] > 0.00001f)
            {
                Error("Vector Multiplication opperand wrong");
                Console.WriteLine("V2[0]: " + v2[0] + " V2[1]: " + v2[1]);
            }


            Console.WriteLine(c[0, 0].ToString() + '\t' + c[0, 1].ToString());
            Console.WriteLine(c[1, 0].ToString() + '\t' + c[1, 1].ToString() + "\n");

            f = new Matrix2(4, 3, 3, 1);
            h = Matrix2.Inverse(f);
            Console.WriteLine(h[0, 0].ToString() + '\t' + h[0, 1].ToString());
            Console.WriteLine(h[1, 0].ToString() + '\t' + h[1, 1].ToString() + "\n");

            Matrix4 a4 = new Matrix4(9, 8, 9, 8,
                                     2, 4, 3, 2,
                                     0, 1, 3, 3,
                                     0, 0, 0, 1);
            Matrix4 ia4 = Matrix4.Inverse(a4);

            if (ia4[0, 0] >= 0.177f || ia4[0, 1] >= -0.295f || ia4[0, 2] >= -0.236f || ia4[0, 3] >= -0.118f ||
                ia4[1, 0] >= -0.118f || ia4[1, 1] >= 0.530f || ia4[1, 2] >= -0.177f || ia4[1, 3] >= 0.412f ||
                ia4[2, 0] >= 0.040f || ia4[2, 1] >= -0.177f || ia4[2, 2] >= 0.393f || ia4[2, 3] >= -1.138f ||
                ia4[3, 0] != 0.0f || ia4[3, 1] != 0.0f || ia4[3, 2] != 0.0f || ia4[3, 3] != 1.0f)
            {
                Error("Inverse Matrix is wrong");
                Console.WriteLine("Actual: ");
                for (int z = 0; z < 4; z++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        Console.Write(ia4[z, j].ToString() + "\t");
                    }
                    Console.WriteLine();
                }
            }

            Quaternion q = Quaternion.AngleAxis(90.0f, 1.0f, 0.0f, 0.0f);
            Matrix4    m = Matrix4.AngleAxis(90.0f, 1.0f, 0.0f, 0.0f);

            if (q.ToMatrix() != m)
            {
                Error("Quaternion did not convert to correct matrix");
                Console.WriteLine("Actual: ");
                for (int z = 0; z < 4; z++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        Console.Write(q.ToMatrix()[z, j].ToString() + "\t");
                    }
                    Console.WriteLine();
                }
                Console.WriteLine("Expected: ");
                for (int z = 0; z < 4; z++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        Console.Write(m[z, j].ToString() + "\t");
                    }
                    Console.WriteLine();
                }
            }
            Quaternion q1 = Quaternion.FromEuler(90, 0, 0);
            Quaternion q2 = Quaternion.AngleAxis(90, 1, 0, 0);

            if (q1 != q2)
            {
                Error("From Euler result not correct");
            }
            Quaternion q3 = Quaternion.AngleAxis(90, 0, 1, 0);

            if (Math.Abs(90.0f - q3.ToEuler().Y) < 0.000001f)
            {
                Error("expecting q3 y to be 90, not : " + q3.ToEuler().Y);
            }

            Vector3 v1 = Matrix4.MultiplyVector(Matrix4.AngleAxis(30f, 0.5f, 0.5f, 0.0f), new Vector3(1.0f, 2.0f, 3.0f));
            Vector3 v5 = Quaternion.AngleAxis(30f, 0.5f, 0.5f, 0.0f) * new Vector3(1.0f, 2.0f, 3.0f);

            if (v1 != v5)
            {
                Error("v1 != v5");
            }
            Console.ReadLine();
        }