protected override void DrawWindowPre(int id) { v = FlightGlobals.ActiveVessel; vlat = SCANUtil.fixLatShift(v.latitude); vlon = SCANUtil.fixLonShift(v.longitude); //Grab the active scanners on this vessel sensors = SCANcontroller.controller.activeSensorsOnVessel(v.id); //if (maptraq_frame >= Time.frameCount - 5) //Still not sure what this actually does if (true) { //Check if region below the vessel is scanned if (SCANUtil.isCovered(vlon, vlat, data, SCANtype.AltimetryLoRes)) { sensors |= SCANtype.Altimetry; } else if (SCANUtil.isCovered(vlon, vlat, data, SCANtype.AltimetryHiRes)) { sensors |= SCANtype.Altimetry; } if (SCANUtil.isCovered(vlon, vlat, data, SCANtype.Biome)) { sensors |= SCANtype.Biome; } } }
internal bool IsCovered(double lon, double lat, CelestialBody body, string scan_type) { bool iscovered = false; if (scansatinstalled) { iscovered = SCANUtil.isCovered(lon, lat, body, GetSCANtype(scan_type)); } return(iscovered); }
//Update the Kethane database - used after background scanning private void updateKethaneData(SCANdata.SCANtype type) { print("[SCAN Kethane] Updating Kethane Database"); for (int ilat = 0; ilat < 180; ilat++) { for (int ilon = 0; ilon < 360; ilon++) { if (SCANUtil.isCovered(ilon, ilat, body, (int)type)) { cell = getKethaneCell(ilon - 180, ilat - 90); if (!KethaneData.Current[resource.name][body].IsCellScanned(cell)) { KethaneData.Current[resource.name][body].ScanCell(cell); } } } } }
/* Calculates the terrain elevation based on scanning coverage; fetches data from elevation cache if possible */ private float terrainElevation(double Lon, double Lat, SCANdata Data, out int Scheme) { float elevation = 0f; Scheme = SCANcontroller.controller.colours; if (SCANUtil.isCovered(Lon, Lat, Data, SCANtype.AltimetryHiRes)) { if (cache) { double lon = fixUnscale(unScaleLongitude(Lon), mapwidth); double lat = fixUnscale(unScaleLatitude(Lat), mapheight); elevation = big_heightmap[Mathf.RoundToInt((float)lon), Mathf.RoundToInt((float)lat)]; if (elevation == 0f) { elevation = (float)SCANUtil.getElevation(body, Lon, Lat); } } else { elevation = (float)SCANUtil.getElevation(body, Lon, Lat); } } else { if (cache) { double lon = fixUnscale(unScaleLongitude(Lon), mapwidth); double lat = fixUnscale(unScaleLatitude(Lat), mapheight); elevation = big_heightmap[((int)(lon * 5)) / 5, ((int)(lat * 5)) / 5]; if (elevation == 0f) { elevation = (float)SCANUtil.getElevation(body, ((int)(Lon * 5)) / 5, ((int)(Lat * 5)) / 5); } } else { elevation = (float)SCANUtil.getElevation(body, ((int)(Lon * 5)) / 5, ((int)(Lat * 5)) / 5); } Scheme = 1; } return(elevation); }
//Reset the resource value array - quicker than rebuildKethaneData (), called on map resets private void rebuildResourceValue(SCANdata.SCANtype type) { if (!rebuildingValue) { print("[SCAN Kethane] Rebuilding Value Array"); rebuildingValue = true; } SCANdata data = SCANUtil.getData(body); for (int ilat = 4 * rebuildValueStep; ilat < 4 * (rebuildValueStep + 1); ilat++) { for (int ilon = 0; ilon < 360; ilon++) { if (SCANUtil.isCovered(ilon, ilat, body, (int)type)) { if (data.kethaneValueMap[ilon, ilat] == 0) //Only check unassigned values { cell = getKethaneCell(ilon - 180, ilat - 90); double?depositValue = KethaneData.Current[resource.name][body].Resources.GetQuantity(cell); if (depositValue != null) { updateResourceValue(ilon, ilat, depositValue, data); } else { updateResourceValue(ilon, ilat, -1d, data); //Give empty cells -1 resources, account for this later on } } } } } rebuildValueStep++; if (rebuildValueStep >= 45) { print("[SCAN Kethane] Value Array Rebuilt"); rebuildingValue = false; } }
/* MAP: build: map to Texture2D */ internal Texture2D getPartialMap() { SCANdata data = SCANUtil.getData(body); if (data == null) { return(new Texture2D(1, 1)); } Color[] pix; /* init cache if necessary */ if (cache) { if (body != big_heightmap_body) { for (int x = 0; x < mapwidth; x++) { for (int y = 0; y < mapwidth / 2; y++) { big_heightmap[x, y] = 0f; } } big_heightmap_body = body; } } if (map == null) { map = new Texture2D(mapwidth, mapheight, TextureFormat.ARGB32, false); pix = map.GetPixels(); for (int i = 0; i < pix.Length; ++i) { pix[i] = palette.clear; } map.SetPixels(pix); } else if (mapstep >= map.height) { return(map); } if (palette.redline == null || palette.redline.Length != map.width) { palette.redline = new Color[map.width]; for (int i = 0; i < palette.redline.Length; ++i) { palette.redline[i] = palette.red; } } if (mapstep < map.height - 1) { map.SetPixels(0, mapstep + 1, map.width, 1, palette.redline); } if (mapstep <= 0) { mapstep = 0; mapline = new double[map.width]; } pix = map.GetPixels(0, mapstep, map.width, 1); for (int i = 0; i < map.width; i++) { Color baseColor = palette.grey; pix[i] = baseColor; int scheme = SCANcontroller.controller.colours; float projVal = 0f; double lat = (mapstep * 1.0f / mapscale) - 90f + lat_offset; double lon = (i * 1.0f / mapscale) - 180f + lon_offset; double la = lat, lo = lon; lat = unprojectLatitude(lo, la); lon = unprojectLongitude(lo, la); /* Introduce altimetry check here; Use unprojected lat/long coordinates * All cached altimetry data stored in a single 2D array in rectangular format * Pull altimetry data from cache after unprojection */ if (body.pqsController != null && cache) { if (big_heightmap[i, mapstep] == 0f) { if (SCANUtil.isCovered(lo, la, data, SCANtype.Altimetry)) { terrainHeightToArray(lo, la, i, mapstep); } } } if (double.IsNaN(lat) || double.IsNaN(lon) || lat < -90 || lat > 90 || lon < -180 || lon > 180) { pix[i] = palette.clear; continue; } /* Altimetry Map */ if (mType == mapType.Altimetry) { if (body.pqsController == null) { baseColor = palette.lerp(palette.black, palette.white, UnityEngine.Random.value); } else if (SCANUtil.isCovered(lon, lat, data, SCANtype.Altimetry)) { projVal = terrainElevation(lon, lat, data, out scheme); baseColor = palette.heightToColor(projVal, scheme, data); } mapline[i] = projVal; if (SCANcontroller.controller.map_ResourceOverlay && SCANconfigLoader.GlobalResource && resource != null) { pix[i] = SCANuiUtil.resourceToColor(lon, lat, data, baseColor, resource); } else { pix[i] = baseColor; } /* draw height lines - works, but mostly useless... * int step = (int)(val / 1000); * int step_h = step, step_v = step; * if(i > 0) step_h = (int)(bigline[i - 1] / 1000); * if(bigstep > 0) step_v = (int)(bigline[i] / 1000); * if(step != step_h || step != step_v) { * pix[i] = palette.white; * } */ //mapline [i] = val; } /* Slope Map */ else if (mType == mapType.Slope) { if (body.pqsController == null) { baseColor = palette.lerp(palette.black, palette.white, UnityEngine.Random.value); } else if (SCANUtil.isCovered(lon, lat, data, SCANtype.Altimetry)) { projVal = terrainElevation(lon, lat, data, out scheme); if (mapstep == 0) { baseColor = palette.grey; } else { // This doesn't actually calculate the slope per se, but it's faster // than asking for yet more elevation data. Please don't use this // code to operate nuclear power plants or rockets. double v1 = mapline[i]; if (i > 0) { v1 = Math.Max(v1, mapline[i - 1]); } if (i < mapline.Length - 1) { v1 = Math.Max(v1, mapline[i + 1]); } float v = Mathf.Clamp((float)Math.Abs(projVal - v1) / 1000f, 0, 2f); if (SCANcontroller.controller.colours == 1) { baseColor = palette.lerp(palette.black, palette.white, v / 2f); } else { if (v < 1) { baseColor = palette.lerp(SCANcontroller.controller.lowSlopeColorOne, SCANcontroller.controller.highSlopeColorOne, v); } else { baseColor = palette.lerp(SCANcontroller.controller.lowSlopeColorTwo, SCANcontroller.controller.highSlopeColorTwo, v - 1); } } } mapline[i] = projVal; } if (SCANcontroller.controller.map_ResourceOverlay && SCANconfigLoader.GlobalResource && resource != null) { pix[i] = SCANuiUtil.resourceToColor(lon, lat, data, baseColor, resource); } else { pix[i] = baseColor; } } /* Biome Map */ else if (mType == mapType.Biome) { if (body.BiomeMap == null) { baseColor = palette.lerp(palette.black, palette.white, UnityEngine.Random.value); } /* // this just basically stretches the actual biome map to fit... it looks horrible * float u = ((lon + 360 + 180 + 90)) % 360; * float v = ((lat + 180 + 90)) % 180; * if(u < 0 || v < 0 || u >= 360 || v >= 180) continue; * u /= 360f; v /= 180f; * pix[i] = body.BiomeMap.Map.GetPixelBilinear(u, v); */ else if (SCANUtil.isCovered(lon, lat, data, SCANtype.Biome)) { double bio = SCANUtil.getBiomeIndexFraction(body, lon, lat); Color biome = palette.grey; if (SCANcontroller.controller.colours == 1) { if ((i > 0 && mapline[i - 1] != bio) || (mapstep > 0 && mapline[i] != bio)) { biome = palette.white; } else { biome = palette.lerp(palette.black, palette.white, (float)bio); } } else { Color elevation = palette.grey; if (SCANcontroller.controller.biomeTransparency > 0) { if (body.pqsController == null) { elevation = palette.grey; } else if (SCANUtil.isCovered(lon, lat, data, SCANtype.Altimetry)) { projVal = terrainElevation(lon, lat, data, out scheme); elevation = palette.lerp(palette.black, palette.white, Mathf.Clamp(projVal + 1500f, 0, 9000) / 9000f); } } if ((i > 0 && mapline[i - 1] != bio) || (mapstep > 0 && mapline[i] != bio)) { biome = palette.white; } else if (SCANcontroller.controller.useStockBiomes) { Color c = SCANUtil.getBiome(body, lon, lat).mapColor; biome = palette.lerp(c, elevation, SCANcontroller.controller.biomeTransparency / 100f); } else { biome = palette.lerp(palette.lerp(SCANcontroller.controller.lowBiomeColor, SCANcontroller.controller.highBiomeColor, (float)bio), elevation, SCANcontroller.controller.biomeTransparency / 100f); } } baseColor = biome; mapline[i] = bio; } if (SCANcontroller.controller.map_ResourceOverlay && SCANconfigLoader.GlobalResource && resource != null) { pix[i] = SCANuiUtil.resourceToColor(lon, lat, data, baseColor, resource); } else { pix[i] = baseColor; } } } map.SetPixels(0, mapstep, map.width, 1, pix); mapstep++; if (mapstep % 10 == 0 || mapstep >= map.height) { map.Apply(); } return(map); }
//Draws the actual map texture internal void drawHeightScanline(SCANtype type) { Color[] cols_height_map_small = map_small.GetPixels(0, scanline, 360, 1); for (int ilon = 0; ilon < 360; ilon += 1) { int scheme = SCANcontroller.controller.colours; float val = heightmap[ilon, scanline]; if (val == 0) { //Some preparation for bigger changes in map caching, automatically calculate elevation for every point on the small map, only display scanned areas if (body.pqsController == null) { heightmap[ilon, scanline] = 0; cols_height_map_small[ilon] = palette.lerp(palette.black, palette.white, UnityEngine.Random.value); continue; } else { // convert to radial vector val = (float)SCANUtil.getElevation(body, ilon - 180, scanline - 90); if (val == 0) { val = -0.001f; // this is terrible } heightmap[ilon, scanline] = val; } } Color c = palette.black; if (SCANUtil.isCovered(ilon, scanline, this, SCANtype.Altimetry)) { //We check for coverage down here now, after elevation data is collected if (SCANUtil.isCovered(ilon, scanline, this, SCANtype.AltimetryHiRes)) { c = palette.heightToColor(val, scheme, this); } else { c = palette.heightToColor(val, 1, this); } } else { c = palette.grey; if (scanline % 30 == 0 && ilon % 3 == 0) { c = palette.white; } else if (ilon % 30 == 0 && scanline % 3 == 0) { c = palette.white; } } if (type != SCANtype.Nothing) { if (!SCANUtil.isCoveredByAll(ilon, scanline, this, type)) { c = palette.lerp(c, palette.black, 0.5f); } } cols_height_map_small[ilon] = c; } map_small.SetPixels(0, scanline, 360, 1, cols_height_map_small); scanline = scanline + 1; if (scanline >= 180) { scanstep += 1; scanline = 0; } }