public static async Task Doit(Config config, TraceListener log, Action <Stream, FeatureInfo[][]> drawToScreen) { DateTime start = DateTime.Now; BlobHelper.SetConnectionString(ConfigurationManager.AppSettings["ConnectionString"]); int subpixel = 3; var compositeBmp = new DirectBitmap(subpixel * config.Width, subpixel * config.Height); Device.RenderState renderState = new Device.RenderState(compositeBmp) { Camera = new Camera() { MaxAngleRad = config.MaxAngleDec * Math.PI / 180, MinAngleRad = config.MinAngleDec * Math.PI / 180, HeightOffset = config.HeightOffset, }, }; var chunks = View.GetRelevantChunkKeys(config, log); StandardChunkMetadata mainChunk = StandardChunkMetadata.GetRangeFromKey(chunks.Last()); var mainMesh = await Meshes.Current.GetData(mainChunk, log); var norm = mainMesh.GetCenterAndScale( config.Lat.DecimalDegree, config.Lon.DecimalDegree, mainChunk.ZoomLevel, mainChunk.LatDelta.DecimalDegree, 10, log); int counter = 0; foreach (var chunkKey in chunks) { StandardChunkMetadata chunk = StandardChunkMetadata.GetRangeFromKey(chunkKey); if (chunk == null) { continue; } var mesh = await Meshes.Current.GetData(chunk, log); if (mesh == null) { continue; } mesh.Match(norm); try { mesh.ImageData = await JpegImages.Current.GetData(chunk, log); } catch { } if (mesh.ImageData == null) { DirectBitmap tmp = new DirectBitmap(10, 10); tmp.SetAllPixels(new MyColor(0, 0, 0, 255)); using (var mss = new MemoryStream()) { tmp.WriteFile(OutputType.PNG, mss); mss.Position = 0; mesh.ImageData = new byte[mss.Length]; mss.Read(mesh.ImageData, 0, mesh.ImageData.Length); } } using (var renderMesh = SoftEngine.Mesh.GetMesh(mesh)) { Device.RenderInto(renderState, renderMesh); renderState.UpdateLatLons(chunk.LatLo, chunk.LatDelta, chunk.LonLo, chunk.LonDelta); } counter++; log?.WriteLine(counter); } FeatureInfo[][] features = renderState.GetLatLons().Select(q => q.Select(p => !p.HasValue ? null : UsgsRawFeatures.GetData(p.Value)).ToArray()).ToArray(); string fileNameRoot = DateTime.Now.ToString("HHmmss"); //config.LocalTime = new DateTimeOffset(2019, 3, 5, 0, 0, 0, TimeSpan.FromHours(-8)); //while (config.LocalTime < new DateTimeOffset(2019, 3, 6, 0, 0, 0, TimeSpan.FromHours(-8))) { var skyColor = new Nishita(config.SunPos); using (DirectBitmap lighted = renderState.RenderLight(config.Light, config.DirectLight, config.AmbientLight, skyColor)) { drawToScreen?.Invoke(lighted.GetStream(OutputType.PNG), features); using (var fs = File.OpenWrite("final_" + config.LocalTime.ToString("HHmmss") + "_" + fileNameRoot + ".jpg")) { lighted.WriteFile(OutputType.JPEG, fs); } } //config.LocalTime = config.LocalTime.AddHours(1); } DateTime end = DateTime.Now; log?.WriteLine(start); log?.WriteLine(end); log?.WriteLine(end - start); }
public DirectBitmap RenderLight(Vector3f light, float directLight, float ambientLight, Nishita skyColor) { var ret = new DirectBitmap(Width, Height); MyColor color = new MyColor(); var maxDistSq = DistSq.Select(p => p ?? -1).Max(); double fovRad = Camera.MaxAngleRad - Camera.MinAngleRad; NishitaInterp sc = skyColor == null ? null : new NishitaInterp(skyColor, Camera.HeightOffset, directLight, ambientLight, Math.Sqrt(maxDistSq), GetLatRadFromXIndex(0), GetLatRadFromXIndex(Width - 1), 10, GetLonRadFromYIndex(0), GetLonRadFromYIndex(Height - 1), 10); for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { var skyPt = new GeoPolar2d( Angle.FromRadians(GetLatRadFromXIndex(x)), Angle.FromRadians(GetLonRadFromYIndex(y))); var index = (Width - 1 - x) + y * Width; var distSq = DistSq[index]; if (!distSq.HasValue) { color = sc?.SkyColorAtPoint(skyPt) ?? View.skyColor; } else { Bmp.GetPixel(Width - 1 - x, y, ref color); ns[index].Normalize(); var dot = Math.Max(0, Vector3f.Dot(ref ns[index], ref light)); if (sc != null) { color = sc.SkyColorAtPointDist(skyPt, Math.Sqrt(distSq.Value), color, dot); } else { var l = dot * directLight + ambientLight; var ndotl = l > 1.0f ? 1.0f : l < 0.0f ? 0.0f : l; color.ScaleSelf(ndotl); } } ret.SetPixel(Width - 1 - x, Height - 1 - y, color); } } return(ret); }