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); }
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; } } }
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); }