Example #1
0
        public Color ColorCastAtPrimitive(ref Ray ray, int depth)
        {
            HitInfo   hi         = new HitInfo();
            Primitive nearestHit = null;

            nearestHit = CastAtPrimitive(ref ray, ref hi);

            if (nearestHit != null)
            {
                MultiColor baze = new MultiColor();
                baze.diffuse  = new Color(1, 1, 1);
                baze.specular = new Color(1, 1, 1);

                Triangle triHit = null;
                Sphere   sphHit = null;
                //if (nearestHit is Triangle)
                //    triHit=(Triangle)nearestHit;
                //if (nearestHit is Sphere)

                //    sphHit = (Sphere)nearestHit;
                // Sphere sphHit =null;

                if (nearestHit.GetMaterial().texture != null)
                {
                    if (nearestHit is Triangle)
                    {
                        triHit = nearestHit as Triangle;
                        Vector3 texUV =
                            triHit.UVx * hi.uvw.x +
                            triHit.UVy * hi.uvw.y +
                            triHit.UVz * hi.uvw.z;

                        int texX = (int)((triHit.GetMaterial().texture.Width - 1) * texUV.x);
                        int texY = (int)((triHit.GetMaterial().texture.Height - 1) * texUV.y);

                        System.Drawing.Color tem = triHit.GetMaterial().texture.GetPixel(texX, texY);


                        baze.diffuse.Set(tem.R, tem.G, tem.B);
                    }
                    else if (nearestHit is Sphere)
                    {
                        sphHit = nearestHit as Sphere;
                        Console.WriteLine("xD1");
                        Console.ReadLine();
                        Vector3 hit = (hi.point - sphHit.Center) / sphHit.Radius;
                        double  theta, phi;
                        Vector3 texUV = new Vector3();

                        theta = Math.Acos(hit.y);
                        phi   = Math.Atan2(hit.x, hit.z);

                        if (phi < 0.0)
                        {
                            phi += 6.28318;
                        }
                        if (phi > 6.28318)
                        {
                            phi -= 6.28318;
                        }
                        if (theta < 0.0)
                        {
                            theta += 3.14159;
                        }
                        if (theta > 3.14159)
                        {
                            theta -= 3.14159;
                        }

                        texUV.y = (float)(phi * 0.159154);         // u
                        texUV.x = (float)(1.0 - theta * 0.318309); // v

                        /*texUV = texUV*4;
                         * texUV.x = fmod(texUV.x, 1);
                         * texUV.y = fmod(texUV.y, 1);
                         * texUV.z = fmod(texUV.z, 1);*/

                        int texY = (int)((sphHit.GetMaterial().texture.Width - 1) * (1 - texUV.x));
                        int texX = (int)((sphHit.GetMaterial().texture.Height - 1) * texUV.y);
                        System.Drawing.Color tem = sphHit.GetMaterial().texture.GetPixel(texX, texY);
                        //Console.WriteLine((tem.R / 255.0) + "," + (tem.G / 255.0) + "," + (tem.B / 255.0));
                        baze.diffuse.Set(tem.R, tem.G, tem.B);
                        //  baze.diffuse.Set(sphHit.GetMaterial().diffuseColor.Red(), sphHit.GetMaterial().diffuseColor.Green(), sphHit.GetMaterial().diffuseColor.Blue());
                    }
                }

                Color      basicColor = new Color();
                MultiColor result     = new MultiColor();
                //if (!baze.specular.isZero() && !baze.specular.isOne())
                //    baze.specular.Show();
                foreach (Light l in scene.lights)
                {
                    MultiColor tmpColor = new MultiColor();
                    tmpColor.diffuse  = baze.diffuse;
                    tmpColor.specular = baze.specular;

                    l.TestColor(ref ray, ref hi, ref nearestHit, ref scene.primitives, ref tmpColor);

                    result.diffuse  = result.diffuse + tmpColor.diffuse;
                    result.specular = result.specular + tmpColor.specular;
                }


                basicColor = result.diffuse + result.specular + scene.ambientColor * nearestHit.GetMaterial().diffuseColor;

                double mirror     = nearestHit.GetMaterial().mirror;
                double refractive = nearestHit.GetMaterial().refractive;

                if (depth > 0)
                {
                    Color mirrorColor = new Color();

                    Color refractColor = new Color();
                    bool  combine      = false;
                    if (mirror > 0)
                    {
                        Vector3 nextRayDirection = ray.Direction.Reflect(hi.normal);
                        Ray     nextRay          = new Ray(hi.point + nextRayDirection * 0.01, nextRayDirection);
                        mirrorColor = ColorCastAtPrimitive(ref nextRay, depth - 1);

                        combine = true;
                    }
                    if (refractive > 0)
                    {
                        Vector3 refractiveDir = (ray.Direction - hi.normal * (nearestHit.GetMaterial().refractiveIndex - 1)).GetNormalized();
                        Ray     insideRay     = new Ray(hi.point - refractiveDir, refractiveDir);
                        HitInfo outHit        = new HitInfo();
                        int     secondResult  = nearestHit.Intersect(ref insideRay, ref outHit);
                        if (secondResult == -1)
                        {
                            Vector3 refractiveDir2 = (insideRay.Direction + outHit.normal * (1 - nearestHit.GetMaterial().refractiveIndex)).GetNormalized();
                            Ray     movedRay       = new Ray(outHit.point + refractiveDir2 * 0.01, refractiveDir2);
                            refractColor = ColorCastAtPrimitive(ref movedRay, depth - 1);
                        }

                        Ray temp = new Ray(hi.point + refractiveDir * 0.01, refractiveDir);
                        refractColor = ColorCastAtPrimitive(ref temp, depth - 1);

                        combine = true;
                    }

                    if (combine)
                    {
                        Color c = basicColor * (1.0 - mirror - refractive) + mirrorColor * mirror + refractColor * refractive;



                        return(c);
                    }

                    else
                    {
                        return(basicColor);
                    }
                }
                else
                {
                    return(basicColor);
                }
            }
            else
            {
                return(new Color(0, 0, 0));
            }
        }