private FragmentInData InterpolateWithReflection(Vector3 baryCoords, Triangle <FragmentInData> triangle)
        {
            PropertyInfo[] pi = typeof(FragmentInData).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);

            FragmentInData interpolatedData = new FragmentInData();

            foreach (var p in pi)
            {
                var value0 = p.GetValue(triangle.VertexData[0], null);
                var value1 = p.GetValue(triangle.VertexData[1], null);
                var value2 = p.GetValue(triangle.VertexData[2], null);


                if (value0 is float)
                {
                    float correctVal = (float)value0 * baryCoords.X + (float)value1 * baryCoords.Y + (float)value2 * baryCoords.Z;
                    p.SetValue(interpolatedData, correctVal);
                }
                else if (value0 is double)
                {
                    double correctVal = (double)value0 * baryCoords.X + (double)value1 * baryCoords.Y + (double)value2 * baryCoords.Z;
                    p.SetValue(interpolatedData, correctVal);
                }
                else if (value0 is int)
                {
                    int correctVal = (int)((int)value0 * baryCoords.X + (int)value1 * baryCoords.Y + (int)value2 * baryCoords.Z);
                    p.SetValue(interpolatedData, correctVal);
                }
                else if (value0 is uint)
                {
                    uint correctVal = (uint)((uint)value0 * baryCoords.X + (uint)value1 * baryCoords.Y + (uint)value2 * baryCoords.Z);
                    p.SetValue(interpolatedData, correctVal);
                }
                else if (value0 is Vector2)
                {
                    Vector2 correctVal = (Vector2)value0 * baryCoords.X + (Vector2)value1 * baryCoords.Y + (Vector2)value2 * baryCoords.Z;
                    p.SetValue(interpolatedData, correctVal);
                }
                else if (value0 is Vector3)
                {
                    Vector3 correctVal = (Vector3)value0 * baryCoords.X + (Vector3)value1 * baryCoords.Y + (Vector3)value2 * baryCoords.Z;
                    p.SetValue(interpolatedData, correctVal, null);
                }
                else if (value0 is Vector4)
                {
                    Vector4 correctVal = (Vector4)value0 * baryCoords.X + (Vector4)value1 * baryCoords.Y + (Vector4)value2 * baryCoords.Z;
                    p.SetValue(interpolatedData, correctVal);
                }
            }

            return(interpolatedData);
        }
        private FragmentInData InterpolateWithoutReflection(Vector3 baryCoords, Triangle <FragmentInData> triangle)
        {
            FragmentInData interpolatedData = new FragmentInData();

            interpolatedData.Position = baryCoords.X * triangle.VertexData[0].Position +
                                        baryCoords.Y * triangle.VertexData[1].Position +
                                        baryCoords.Z * triangle.VertexData[2].Position;

            interpolatedData.FloatVal = baryCoords.X * triangle.VertexData[0].FloatVal +
                                        baryCoords.Y * triangle.VertexData[1].FloatVal +
                                        baryCoords.Z * triangle.VertexData[2].FloatVal;


            interpolatedData.DoubleVal = baryCoords.X * triangle.VertexData[0].DoubleVal +
                                         baryCoords.Y * triangle.VertexData[1].DoubleVal +
                                         baryCoords.Z * triangle.VertexData[2].DoubleVal;


            interpolatedData.IntVal = (int)(baryCoords.X * triangle.VertexData[0].IntVal +
                                            baryCoords.Y * triangle.VertexData[1].IntVal +
                                            baryCoords.Z * triangle.VertexData[2].IntVal);


            interpolatedData.UintVal = (uint)(baryCoords.X * triangle.VertexData[0].UintVal +
                                              baryCoords.Y * triangle.VertexData[1].UintVal +
                                              baryCoords.Z * triangle.VertexData[2].UintVal);


            interpolatedData.Vector2Val = baryCoords.X * triangle.VertexData[0].Vector2Val +
                                          baryCoords.Y * triangle.VertexData[1].Vector2Val +
                                          baryCoords.Z * triangle.VertexData[2].Vector2Val;


            interpolatedData.Vector4Val = baryCoords.X * triangle.VertexData[0].Vector4Val +
                                          baryCoords.Y * triangle.VertexData[1].Vector4Val +
                                          baryCoords.Z * triangle.VertexData[2].Vector4Val;

            return(interpolatedData);
        }
        public void Interpolation()
        {
            List <FragmentInData> verticies = new List <FragmentInData>();

            verticies.Add(new FragmentInData(new Vector3(-1, -1, 0), 0, 0, 0, 0, new Vector2(0, 0), new Vector4(0)));
            verticies.Add(new FragmentInData(new Vector3(1, -1, 0), 1, 1, 1, 1, new Vector2(1, 1), new Vector4(1)));
            verticies.Add(new FragmentInData(new Vector3(0, 1, 0), 2, 2, 2, 2, new Vector2(2, 2), new Vector4(2)));
            Triangle <FragmentInData> triangle = new Triangle <FragmentInData>(verticies);

            BarycentricTests barycentricTests = new BarycentricTests();

            Vector3 baryCoords = barycentricTests.Barycentric(0, 0, triangle);

            FragmentInData correctData = new FragmentInData();

            correctData.Position = baryCoords.X * triangle.VertexData[0].Position +
                                   baryCoords.Y * triangle.VertexData[1].Position +
                                   baryCoords.Z * triangle.VertexData[2].Position;


            correctData.FloatVal = baryCoords.X * triangle.VertexData[0].FloatVal +
                                   baryCoords.Y * triangle.VertexData[1].FloatVal +
                                   baryCoords.Z * triangle.VertexData[2].FloatVal;


            correctData.DoubleVal = baryCoords.X * triangle.VertexData[0].DoubleVal +
                                    baryCoords.Y * triangle.VertexData[1].DoubleVal +
                                    baryCoords.Z * triangle.VertexData[2].DoubleVal;


            correctData.IntVal = (int)(baryCoords.X * triangle.VertexData[0].IntVal +
                                       baryCoords.Y * triangle.VertexData[1].IntVal +
                                       baryCoords.Z * triangle.VertexData[2].IntVal);


            correctData.UintVal = (uint)(baryCoords.X * triangle.VertexData[0].UintVal +
                                         baryCoords.Y * triangle.VertexData[1].UintVal +
                                         baryCoords.Z * triangle.VertexData[2].UintVal);


            correctData.Vector2Val = baryCoords.X * triangle.VertexData[0].Vector2Val +
                                     baryCoords.Y * triangle.VertexData[1].Vector2Val +
                                     baryCoords.Z * triangle.VertexData[2].Vector2Val;


            correctData.Vector4Val = baryCoords.X * triangle.VertexData[0].Vector4Val +
                                     baryCoords.Y * triangle.VertexData[1].Vector4Val +
                                     baryCoords.Z * triangle.VertexData[2].Vector4Val;


            FragmentInData temp0 = InterpolateWithReflection(baryCoords, triangle);
            FragmentInData temp1 = InterpolateWithoutReflection(baryCoords, triangle);


            int       sampleSize   = 10000;
            Stopwatch reflectionSw = new Stopwatch();

            reflectionSw.Start();

            for (int i = 0; i < sampleSize; i++)
            {
                FragmentInData interpolatedData = InterpolateWithReflection(baryCoords, triangle);
            }

            reflectionSw.Stop();


            Stopwatch compileRuntimeSw = new Stopwatch();
            {
                compileRuntimeSw.Start();

                FragmentInData interpolatedData = new FragmentInData();

                for (int i = 0; i < sampleSize; i++)
                {
                    interpolatedData.Interpolate(baryCoords, triangle);
                }

                compileRuntimeSw.Stop();
            }


            Stopwatch withoutReflectionSw = new Stopwatch();

            withoutReflectionSw.Start();

            for (int i = 0; i < sampleSize; i++)
            {
                FragmentInData interpolatedData = InterpolateWithoutReflection(baryCoords, triangle);
            }

            withoutReflectionSw.Stop();


            Console.WriteLine("Reflection: Ticks = " + reflectionSw.Elapsed.Ticks + " ; Ms = " + reflectionSw.Elapsed.Milliseconds);
            Console.WriteLine("CompMethod: Ticks = " + compileRuntimeSw.Elapsed.Ticks + " ; Ms = " + compileRuntimeSw.Elapsed.Milliseconds);
            Console.WriteLine("WoReflecti: Ticks = " + withoutReflectionSw.Elapsed.Ticks + " ; Ms = " + withoutReflectionSw.Elapsed.Milliseconds);



            Assert.AreEqual(temp0.Position.X, correctData.Position.X);
            Assert.AreEqual(temp0.Position.Y, correctData.Position.Y);
            Assert.AreEqual(temp0.Position.Z, correctData.Position.Z);

            Assert.AreEqual(temp0.FloatVal, correctData.FloatVal);
            Assert.AreEqual(temp0.DoubleVal, correctData.DoubleVal);
            Assert.AreEqual(temp0.IntVal, correctData.IntVal);
            Assert.AreEqual(temp0.UintVal, correctData.UintVal);

            Assert.AreEqual(temp0.Vector2Val.X, correctData.Vector2Val.X);
            Assert.AreEqual(temp0.Vector2Val.Y, correctData.Vector2Val.Y);

            Assert.AreEqual(temp0.Vector4Val.X, correctData.Vector4Val.X);
            Assert.AreEqual(temp0.Vector4Val.Y, correctData.Vector4Val.Y);
            Assert.AreEqual(temp0.Vector4Val.Z, correctData.Vector4Val.Z);
            Assert.AreEqual(temp0.Vector4Val.W, correctData.Vector4Val.W);
        }
        public void TestReflectionToCreateInterpolateMethod()
        {
            List <FragmentInData> verticies = new List <FragmentInData>();

            verticies.Add(new FragmentInData(new Vector3(-1, -1, 0), 0, 0, 0, 0, new Vector2(0, 0), new Vector4(0)));
            verticies.Add(new FragmentInData(new Vector3(1, -1, 0), 1, 1, 1, 1, new Vector2(1, 1), new Vector4(1)));
            verticies.Add(new FragmentInData(new Vector3(0, 1, 0), 2, 2, 2, 2, new Vector2(2, 2), new Vector4(2)));
            Triangle <FragmentInData> triangle = new Triangle <FragmentInData>(verticies);


            List <SimpleFragmentInData> simpleVerticies = new List <SimpleFragmentInData>();

            simpleVerticies.Add(new SimpleFragmentInData(new Vector3(-1, -1, 0)));
            simpleVerticies.Add(new SimpleFragmentInData(new Vector3(1, -1, 0)));
            simpleVerticies.Add(new SimpleFragmentInData(new Vector3(0, 1, 0)));
            Triangle <SimpleFragmentInData> simpleTriangle = new Triangle <SimpleFragmentInData>(simpleVerticies);

            BarycentricTests barycentricTests = new BarycentricTests();

            Vector3 baryCoords = barycentricTests.Barycentric(0, 0, triangle);

            FragmentInData       data       = new FragmentInData();
            SimpleFragmentInData simpleData = new SimpleFragmentInData();

            data.Interpolate(baryCoords, triangle);
            simpleData.Interpolate(baryCoords, simpleTriangle);

            for (int i = 0; i < 1; i++)
            {
                simpleData.Interpolate(baryCoords, simpleTriangle);
            }

            Console.WriteLine("Simple");
            Console.WriteLine(simpleData.Position);

            Console.WriteLine("Normal");
            Console.WriteLine(data.Position);
            Console.WriteLine(data.FloatVal);
            Console.WriteLine(data.DoubleVal);
            Console.WriteLine(data.IntVal);
            Console.WriteLine(data.UintVal);
            Console.WriteLine(data.Vector2Val);
            Console.WriteLine(data.Vector4Val);



            verticies = new List <FragmentInData>();
            verticies.Add(new FragmentInData(new Vector3(-1, -1, 0), 0, 0, 0, 0, new Vector2(0, 0), new Vector4(0)));
            verticies.Add(new FragmentInData(new Vector3(1, -1, 0), 1, 1, 1, 1, new Vector2(1, 1), new Vector4(1)));
            verticies.Add(new FragmentInData(new Vector3(0, 1, 0), 2, 2, 2, 2, new Vector2(2, 2), new Vector4(2)));
            triangle = new Triangle <FragmentInData>(verticies);


            FragmentInData correctData = new FragmentInData();

            correctData.Position = baryCoords.X * triangle.VertexData[0].Position +
                                   baryCoords.Y * triangle.VertexData[1].Position +
                                   baryCoords.Z * triangle.VertexData[2].Position;


            correctData.FloatVal = baryCoords.X * triangle.VertexData[0].FloatVal +
                                   baryCoords.Y * triangle.VertexData[1].FloatVal +
                                   baryCoords.Z * triangle.VertexData[2].FloatVal;


            correctData.DoubleVal = baryCoords.X * triangle.VertexData[0].DoubleVal +
                                    baryCoords.Y * triangle.VertexData[1].DoubleVal +
                                    baryCoords.Z * triangle.VertexData[2].DoubleVal;


            correctData.IntVal = (int)(baryCoords.X * triangle.VertexData[0].IntVal +
                                       baryCoords.Y * triangle.VertexData[1].IntVal +
                                       baryCoords.Z * triangle.VertexData[2].IntVal);


            correctData.UintVal = (uint)(baryCoords.X * triangle.VertexData[0].UintVal +
                                         baryCoords.Y * triangle.VertexData[1].UintVal +
                                         baryCoords.Z * triangle.VertexData[2].UintVal);


            correctData.Vector2Val = baryCoords.X * triangle.VertexData[0].Vector2Val +
                                     baryCoords.Y * triangle.VertexData[1].Vector2Val +
                                     baryCoords.Z * triangle.VertexData[2].Vector2Val;


            correctData.Vector4Val = baryCoords.X * triangle.VertexData[0].Vector4Val +
                                     baryCoords.Y * triangle.VertexData[1].Vector4Val +
                                     baryCoords.Z * triangle.VertexData[2].Vector4Val;


            Console.WriteLine("Correct");
            Console.WriteLine(correctData.Position);
            Console.WriteLine(correctData.FloatVal);
            Console.WriteLine(correctData.DoubleVal);
            Console.WriteLine(correctData.IntVal);
            Console.WriteLine(correctData.UintVal);
            Console.WriteLine(correctData.Vector2Val);
            Console.WriteLine(correctData.Vector4Val);
        }