private Ray CastRefractionRay(Ray ray, HitRecord record, float refractive)
        {
            Vector rayDirection = ray.Direction;
            Vector surfaceNormal = record.SurfaceNormal;
            Vector refractedColor = new Vector();

            float newRefractive = record.Material.RefractionIndex.x;
            if (newRefractive == refractive)
            {
                newRefractive = 1.0f;
            }
            //rayDirection = -surfaceNormal;
            float dDotn = Vector.Dot3(ray.Direction, surfaceNormal);
            float sqrtArgs = 1.0f - (refractive * refractive * (1 - dDotn * dDotn)) / (newRefractive * newRefractive);
            Vector refractiveDir = new Vector();
            Ray refractionRay;

            if (sqrtArgs > 0.0f)
            {
                Vector nSqrt = surfaceNormal * (float)Math.Sqrt(sqrtArgs);
                refractiveDir = (refractive * (rayDirection - surfaceNormal * dDotn)) / newRefractive - nSqrt;
                refractiveDir.Normalize3();
                //refractiveDir = rayDirection;

                refractionRay = new Ray(record.HitPoint + refractiveDir * 0.1f, refractiveDir);
                refractionRay.Time = ray.Time;
                if (RenderingParameters.showMouse)
                {
                    //Console.WriteLine("Refracting");
                //    Console.WriteLine("Ray direction: ");
                //    Console.WriteLine(rayDirection);
                //    Console.WriteLine("Refraction direction: ");
                //    Console.WriteLine(refractiveDir);
                //    Console.WriteLine();
                }

                return refractionRay;
            }
            else
                return ray;
        }
        private Vector CalculateColor(Ray ray, float minDistance, float maxDistance, int reflections, int refractions, float refractive)
        {
            HitRecord record = new HitRecord();
            Vector finalColor = new Vector();
            Vector lightDirection = new Vector();
            bool hitSomething = false;
            Vector surfaceNormal = new Vector();
            Vector rayDirection = ray.Direction;

            foreach (SceneObject sceneObject in scene.Objects)
            {
                //First check intersection
                bool intersects = sceneObject.IsHit(ray, record, minDistance, maxDistance);
                //If it intersects, diffuse color is set, so set shading color

                if (intersects)
                {
                    hitSomething = true;
                    surfaceNormal = record.SurfaceNormal;

                    if (record.Material.RefractionIndex.x > 0.0f && record.Material.Refractiveness.x == 1.0f)
                    {
                        continue;
                    }
                    record.ShadedColors.Clear();
                    foreach (SceneLight light in scene.Lights)
                    {
                        Vector currentLightColor = new Vector();
                        lightDirection = light.Position - record.HitPoint;
                        lightDirection.Normalize3();

                        //Get cosine of angle between vectors
                        float similarity = Vector.Dot3(surfaceNormal, lightDirection);

                        Vector lambertColor = new Vector();
                        if (record.Material.TextureImage != null)
                        {
                            lambertColor = Vector.ColorMultiplication(light.Color, record.TextureColor) * Math.Max(0, similarity);
                        }
                        else
                        {
                            lambertColor = Vector.ColorMultiplication(light.Color, record.Material.Diffuse) * Math.Max(0, similarity);
                        }

                        //Get half vector between camera direction and light direction
                        Vector halfVector = -1 * rayDirection + lightDirection;
                        halfVector.Normalize3();

                        //Phong shading calculations
                        float normalHalfSimilarity = Vector.Dot3(surfaceNormal, halfVector);
                        Vector phongLightCoefficient = Vector.ColorMultiplication(light.Color, record.Material.Specular);
                        float shininessComponent = (float)Math.Pow(Math.Max(0, normalHalfSimilarity), record.Material.Shininess);
                        Vector phongColor = phongLightCoefficient * shininessComponent;

                        //Add colors and ambient light
                        //Assume no transparency

                        currentLightColor = Vector.LightAdd(lambertColor, phongColor);
                        record.ShadedColors.Add(currentLightColor);
                    }
                }
            }

            if (hitSomething)
            {
                if (RenderingParameters.showMouse)
                {
                    Console.WriteLine("Hit material " + record.Material.Name);
                }
                finalColor = new Vector();
                //////////////////////////////////////////////////////////////
                ///////////////////////SHADOWS///////////////////////////////
                /////////////////////////////////////////////////////////////

                    if (RenderingParameters.showMouse)
                    {
                        Console.WriteLine("Checking for shadows!");
                    }
                    for (int i = 0; i < scene.Lights.Count; i++) //For each light
                    {
                        if (renderingParameters.EnableShadows)
                        {
                            if (record.Material.RefractionIndex.x == 0.0f) //Not refractive surface
                            {
                                Vector direction = scene.Lights[i].Position - record.HitPoint;
                                direction.Normalize3();
                                Vector shadowStart = record.HitPoint + direction * 0.1f;
                                Ray shadowRay = new Ray(shadowStart, direction);
                                bool makesShadow = MakesShadow(shadowRay, scene.Lights[i], reflections, refractions, refractive, ray.Time);
                                if (makesShadow)
                                {
                                    record.ShadedColors[i] = new Vector();
                                }
                            }
                        }
                        if (record.Material.Refractiveness.x != 1.0f)
                        {
                            finalColor = Vector.LightAdd(finalColor, record.ShadedColors[i]);
                            finalColor.w = 1.0f;
                        }
                    }

                ///////////////////////////////////////////////////////////////
                //////////////////////REFRACTIONS/////////////////////////////
                //////////////////////////////////////////////////////////////
                if (renderingParameters.EnableRefractions && refractions < 10 && !record.Material.RefractionIndex.IsBlack())
                {
                    if (record.Material.Refractiveness.x < 1.0f)
                    {
                        int a = 1;
                    }
                    Ray refractedRay = CastRefractionRay(ray, record, refractive);
                    Vector refractiveNess = record.Material.Refractiveness;
                    if (RenderingParameters.showMouse)
                        Console.WriteLine("REFRACTING");

                    finalColor = Vector.ColorMultiplication(refractiveNess, CalculateColor(refractedRay, float.MinValue, float.MaxValue, reflections, refractions + 1, record.Material.RefractionIndex.x))
                        + Vector.ColorMultiplication(new Vector(1.0f, 1.0f, 1.0f) - refractiveNess, finalColor);
                }

                ///////////////////////////////////////////////////////////////
                //////////////////////REFLECTIONS/////////////////////////////
                //////////////////////////////////////////////////////////////
                if (renderingParameters.EnableReflections && reflections < 20 && !record.Material.Reflective.IsBlack() )
                {
                    Vector d = rayDirection;
                    //Check for reflections
                    Vector reflection = d -2* Vector.Dot3(d, surfaceNormal) * surfaceNormal;
                    reflection.Normalize3();
                    HitRecord reflectionRecord = new HitRecord();

                    Ray reflectionRay = new Ray(record.HitPoint + reflection * 0.01f, reflection);
                    reflectionRay.Time = ray.Time;
                    //if (showMouse)
                    //{
                    //    Console.WriteLine("Reflection direction: ");
                    //    Console.WriteLine(reflection);
                    //    Console.WriteLine();
                    //}
                    Vector reflectiveColor = record.Material.Reflective;
                    if (RenderingParameters.showMouse)
                    {
                        Console.WriteLine("REFLECTING - NORMAL: " + surfaceNormal + "\tReflection: " + reflection);
                    }
                    Vector reflectedObjectColor = CalculateColor(reflectionRay, float.MinValue, float.MaxValue, reflections + 1, refractions, refractive);
                    finalColor = Vector.LightAdd(finalColor, Vector.ColorMultiplication(reflectiveColor, reflectedObjectColor));
                    finalColor = Vector.LightAdd(finalColor, scene.Background.AmbientLight);
                }

            }

            if (reflections == 0 && refractions == 0)
            {
                //finalColor = Vector.LightAdd(finalColor, scene.Background.AmbientLight);
                if (RenderingParameters.showMouse)
                {
                    RenderingParameters.showMouse = false;
                    Console.WriteLine("-------------------------------------------------------");
                    Console.WriteLine("-------------------------------------------------------");
                }
            }

            finalColor.w = 1.0f;
            return finalColor;
        }