private void build(List<Photon> points, int depth) { if (points.Count == 1) { p = points[0]; left = null; right = null; } else { points.OrderBy(x => KDTree.getComponentFromDepth(x.position, depth)); int medianIndex = points.Count / 2; p = points[medianIndex]; List<Photon> leftList = points.GetRange(0, medianIndex); List<Photon> rightList = points.GetRange(medianIndex + 1, points.Count - medianIndex - 1); left = new KDTree(leftList, depth + 1); //This should never be null as the case with 1 point is // taken care of above right = rightList.Count > 0 ? new KDTree(rightList, depth + 1) : null; //This will be null if only 2 points } }
void oneConstructor() { KDTree test = new KDTree(createList(1)); }
void twoConstructor() { KDTree test = new KDTree(createList(2)); }
void zeroConstructor() { KDTree test = new KDTree(new List<Photon>()); }
void longListConstructor() { KDTree test = new KDTree(createList(30000)); }
void oddLengthConstructor() { KDTree test = new KDTree(createList(55)); }
void evenLengthConstructor() { KDTree test = new KDTree(createList(40)); }
// Runs the light map process public static List<LightMap> runLightmaps(List<ModelInstance> models, List<Light> lights) { //Reset abort abort = false; //-- Get the geometry we need for lightmapping --// //The list of triangles which will be casting shadows, we don't care which models they come from List<Triangle> castingTriangles = new List<Triangle>(); //The list of models that need lightmaps, not all models receive lightmaps List<ModelInstance> receivingModels = new List<ModelInstance>(); //Find all the lightmapped models and casting triangles foreach (ModelInstance m in models) { if (m.baseModel.isLightmapped) receivingModels.Add(m); if (m.baseModel.castsShadows) castingTriangles.AddRange(m.tris); } Stopwatch watch; //-- Do the lightmapping --// //Make the lightmaps Settings.stream.WriteText("Creating maps . . . "); watch = Stopwatch.StartNew(); List<LightMap> maps = makeLightmaps(receivingModels); watch.Stop(); Settings.stream.WriteLine("Done ({0}ms)", watch.ElapsedMilliseconds); //Make the triangle partitioner Settings.stream.WriteText("Partitioning level . . . "); watch = Stopwatch.StartNew(); TrianglePartitioner partition = new Octree(castingTriangles); watch.Stop(); Settings.stream.WriteLine("Done ({0}ms)", watch.ElapsedMilliseconds); //Shoot the photons Settings.stream.WriteText("Firing photons with {0} threads, {1} photons per light . . . ", Settings.maxThreads, Settings.numPhotonsPerLight); watch = Stopwatch.StartNew(); List<Photon> photons = firePhotons(lights, partition); watch.Stop(); Settings.stream.WriteLine("Done ({0}ms)", watch.ElapsedMilliseconds); if (photons.Count > 0) { //Make the photon map Settings.stream.WriteText("Making photon map with {0} photons . . . ", photons.Count); watch = Stopwatch.StartNew(); PhotonPartitioner photonMap = new KDTree(photons); watch.Stop(); Settings.stream.WriteLine("Done ({0}ms)", watch.ElapsedMilliseconds); //Gather the photons for each patch in each map Settings.stream.WriteText("Gathering photons for lightmaps . . . "); watch = Stopwatch.StartNew(); gatherPhotons(maps, photonMap, partition, lights); watch.Stop(); Settings.stream.WriteLine("Done ({0}ms)", watch.ElapsedMilliseconds); } else { Settings.stream.WriteText("No lights affect the lightmaps, skipping to ambient occlusion."); } //Do Ambient Occlusion Settings.stream.WriteText("Calculating ambient occlusion . . . "); //calculateAmbientOcclusion(maps,partition); Settings.stream.WriteLine("Done"); return maps; }