public Vector3 GetColor(double searchSquareRarius, ref Vector3 inter, int knnSize, ref Vector3 normal)
        {
            Vector3 colorTemp = new Vector3();

            currentKNNSize = 1;
            knn            = new List <Photon>(knnSize + 1);
            for (int i = 0; i <= knnSize; i++)
            {
                knn[i] = null;
            }
            if (data.Count() == 0)
            {
                crateDataVector(photons.Count());
                createKdTree(photons, 1, 0, photons.Count(), 1);
            }
            double search = searchSquareRarius;

            findPhotons(ref inter, knnSize, ref search, 1, ref knn);
            if (knn[1] == null)
            {
                return(colorTemp);
            }
            double r = knn[1].distance;

            for (int i = 1; i < knn.Count(); i++)
            {
                Photon photon = knn[i];
                if (photon == null)
                {
                    continue;
                }
                double cosinus = normal.x * photon.direction[0] + normal.y * photon.direction[1] + normal.z * photon.direction[2];
                if (cosinus < 0)
                {
                    continue;
                }
                colorTemp.x += photon.energy[0];
                colorTemp.y += photon.energy[1];
                colorTemp.z += photon.energy[2];
            }
            colorTemp *= (1 / (Math.PI * r));
            return(colorTemp);
        }
        public void insertPhotonToKNN(ref Photon p, ref List <Photon> knnPhotons)
        {
            int    position       = currentKNNSize;
            int    parentPosition = currentKNNSize;
            Photon temp;

            if (knn[1] == null)
            {            //pusty kopiec
                knn[1]         = p;
                currentKNNSize = currentKNNSize + 1;
                return;
            }
            else
            {
                knn[position]  = p;
                currentKNNSize = currentKNNSize + 1;
                while (position > 1)
                {
                    parentPosition = parentPosition / 2;
                    if (knn[parentPosition] == null)
                    {
                        temp = knn[parentPosition];
                        knn[parentPosition] = knn[position];
                        knn[position]       = temp;
                        position            = parentPosition;
                    }
                    else if (knn[parentPosition].distance < knn[position].distance)
                    {
                        temp = knn[parentPosition];
                        knn[parentPosition] = knn[position];
                        knn[position]       = temp;
                        position            = parentPosition;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
        public int partition(ref List <Photon> photons, int dimension, int a, int b)
        {
            float e, tmp;

            e = photons[a].position[dimension];
            while (a < b)
            {
                while ((a < b) && (photons[b].position[dimension] >= e))
                {
                    b--;
                }
                while ((a < b) && (photons[a].position[dimension] < e))
                {
                    a++;
                }
                if (a < b)
                {
                    Photon temp = photons[a];
                    photons[a] = photons[b];
                    photons[b] = temp;
                }
            }
            return(a);
        }
Beispiel #4
0
        public void TracePhoton(ref Photon photon, PhotonMap photonMap, PhotonReflection type)
        {
            bool   wasReflection        = false;
            bool   wasCausticReflection = false;
            Random rnd = new Random();

            for (int i = 0; i < maxReflections; i++)
            {
                Ray ray = new Ray(new Vector3(photon.position[0], photon.position[1], photon.position[2]), new Vector3(photon.direction[0], photon.direction[1], photon.direction[2]));
                //cout << "pozycja " << ray.Origin() << endl;
                //cout << "kierunek " << ray.Direction() << endl;
                int    index    = -1;
                int    j        = -1;
                double distance = 1000;
                bool   wasHit   = false;
                foreach (Mesh mezh in meshes)
                {
                    j++;

                    if (mezh.Intersect(ref ray))
                    {
                        wasHit = true;
                    }
                }
                if (!wasHit)
                {
                    break;
                }
                Mesh    mesh   = meshes[index];
                Vector3 inter  = mesh.IntersectV(ref ray);
                Vector3 normal = mesh.getNormal(ray, distance, inter);
                Color   baze   = new Color();
                if (mesh.faces[0].GetTriangle().GetMaterial() != null)
                {
                    Float2 coords = mesh.getUVCoords(normal, inter);
                    baze = mesh.faces[0].GetTriangle().GetMaterial().diffuseColor;
                }
                else
                {
                    baze = mesh.faces[0].GetTriangle().GetMaterial().diffuseColor;
                }
                float avgColor = (float)((baze.Red() + baze.Green() + baze.Blue()) / 3.0);
                float newRed   = (float)(photon.energy[0] * baze.Red() / avgColor);
                float newBlue  = (float)(photon.energy[1] * baze.Blue() / avgColor);
                float newGreen = (float)(photon.energy[2] * baze.Green() / avgColor);
                if (mesh.faces[0].GetTriangle().GetMaterial() != null)
                {
                    if (!wasCausticReflection && type == PhotonReflection.caustic)
                    {
                        break;
                    }
                    photon.position[0] = inter.x;
                    photon.position[1] = inter.y;
                    photon.position[2] = inter.z;
                    int probability = rnd.Next() % 100;                    //prawdopodobienstwo odbicia
                    if (probability < 40)
                    {
                        photonMap.AddPhoton(ref photon);
                        break;
                    }
                    else
                    {
                        //	cout << "odbicie\n";
                        //wasReflection = true;
                        float[] tab = new float[3];
                        do
                        {
                            tab[0] = (float)((rnd.Next() % 10000 - 5000.0) / 5000.0);
                            tab[1] = (float)((rnd.Next() % 10000 - 5000.0) / 5000.0);
                            tab[2] = (float)((rnd.Next() % 10000 - 5000.0) / 5000.0);
                        } while (tab[0] * tab[0] + tab[1] * tab[1] + tab[2] * tab[2] > 1);
                        for (int m = 0; m < 3; m++)
                        {
                            photon.direction[m] = tab[m];
                        }
                        if (!wasCausticReflection && type == PhotonReflection.caustic)
                        {
                            photon.energy[0] = newRed;
                            photon.energy[1] = newGreen;
                            photon.energy[2] = newBlue;
                            continue;
                        }
                        else
                        {
                            photonMap.AddPhoton(ref photon);
                            photon.energy[0] = newRed;
                            photon.energy[1] = newGreen;
                            photon.energy[2] = newBlue;
                        }
                    }
                }
                else
                {
                    wasReflection        = true;
                    wasCausticReflection = true;
                    Ray topoint   = new Ray(new Vector3(photon.position[0], photon.position[1], photon.position[2]), inter);
                    Ray FromPoint = new Ray();
                    if (mesh.faces[0].GetTriangle().GetMaterial().mirror > 0)
                    {
                        FromPoint = mesh.faces[0].GetTriangle().GetMaterial().MirrorRay(ref topoint, ref normal, ref inter);
                    }
                    else if (mesh.faces[0].GetTriangle().GetMaterial().refractive > 0)
                    {
                        FromPoint = mesh.faces[0].GetTriangle().GetMaterial().RefractRay(ref topoint, ref normal, ref inter, false);
                    }
                    photon.position[0] = inter.x;
                    photon.position[1] = inter.y;
                    photon.position[2] = inter.z;
                    Vector3 dir = FromPoint.Direction;
                    dir.GetNormalized();
                    photon.direction[0] = dir.x;
                    photon.direction[1] = dir.y;
                    photon.direction[2] = dir.z;
                    photon.energy[0]    = newRed;
                    photon.energy[1]    = newGreen;
                    photon.energy[2]    = newBlue;
                    //	cout << "zmienil sie kierunek photonu na " << photon.direction << endl;
                }
            }
        }
Beispiel #5
0
        public void emitPhotons(ref PhotonMap photonMap, bool causticMap, PhotonReflection type)
        {
            Random rnd       = new Random();
            float  intensity = lights[0].intensity;
            float  red       = (float)(lights[0].color.Red() * intensity);
            float  green     = (float)(lights[0].color.Green() * intensity);
            float  blue      = (float)(lights[0].color.Blue() * intensity);

            while (photonMap.size() < photonMap.maxPhotons)
            {
                Photon  photon = new Photon();
                float[] tab    = new float[3];
                do
                {
                    tab[0] = (float)((rnd.Next() % 10000 - 5000.0) / 5000.0);
                    tab[1] = (float)((rnd.Next() % 10000 - 5000.0) / 5000.0);
                    tab[2] = (float)((rnd.Next() % 10000 - 5000.0) / 5000.0);
                } while (tab[0] * tab[0] + tab[1] * tab[1] + tab[2] * tab[2] > 1);

                photon.position[0]  = lights[0].position.x;
                photon.direction[0] = tab[0];
                photon.position[1]  = lights[0].position.y;
                photon.direction[1] = tab[1];
                photon.position[2]  = lights[0].position.z;
                photon.direction[2] = tab[2];

                photon.position[0] += (float)(((rnd.Next() % 50) / 10.0) - 5.0);
                photon.position[2] += (float)(((rnd.Next() % 50) / 10.0) - 5.0);
                if (causticMap)
                {
                    bool wasIntesect = false;
                    Ray  ray         = new Ray(new Vector3(photon.position[0], photon.position[1], photon.position[2]), new Vector3(tab[0], tab[1], tab[2]));
                    ray.Direction.GetNormalized();
                    int    index    = -1;
                    double distance = 1000;
                    foreach (var x in meshes)
                    {
                        index++;
                        double hitDistance = 1000;
                        if (x.Intersect(ref ray))
                        {
                            if (hitDistance < distance)
                            {
                                distance = hitDistance;


                                wasIntesect = true;
                            }
                        }
                    }
                    if (!wasIntesect)
                    {
                        photon = new Photon();
                        continue;
                    }
                }
                photon.energy[0] = red;
                photon.energy[1] = green;
                photon.energy[2] = blue;
                TracePhoton(ref photon, photonMap, type);

                photon = new Photon();
            }


            photonMap.ScaleEnergy();
        }
 public void AddPhoton(ref Photon p)
 {
     photons.Add(p);
 }