private void terrainHeightToArray(double lon, double lat, int ilon, int ilat) { float alt = 0f; alt = (float)SCANUtil.getElevation(body, lon, lat); if (alt == 0f) { alt = -0.001f; } big_heightmap[ilon, ilat] = alt; }
/* 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); }
//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; } }
//Display the current vessel altitude private void altInfo(int id) { if ((sensors & SCANtype.Altimetry) != SCANtype.Nothing) { double h = v.altitude; double pqs = 0; if (v.mainBody.pqsController != null) { pqs = v.PQSAltitude(); if (pqs > 0 || !v.mainBody.ocean) { h -= pqs; } } if (h < 0) { h = v.altitude; } if (v.situation == Vessel.Situations.LANDED || v.situation == Vessel.Situations.SPLASHED || v.situation == Vessel.Situations.PRELAUNCH) { GUILayout.Label(string.Format("Terrain: {0:N1}m", pqs), SCANskins.SCAN_insColorLabel); } else { GUILayout.Label(string.Format("Altitude: {0}", SCANuiUtil.distanceString(h, 100000)), SCANskins.SCAN_insColorLabel); } fillS(-10); //Calculate slope less frequently; the rapidly changing value makes it difficult to read otherwise if (v.mainBody.pqsController != null) { float deltaTime = 1f; if (Time.deltaTime != 0) { deltaTime = TimeWarp.deltaTime / Time.deltaTime; } if (deltaTime > 5) { deltaTime = 5; } if (((Time.time * deltaTime) - lastUpdate) > updateInterval) { lastUpdate = Time.time; /* Slope is calculated using a nine point grid centered 5m around the vessel location * The rise between the vessel location's elevation and each point on the grid is calculated, converted to slope in degrees, and averaged; * Note: Averageing is not the most accurate method */ double latOffset = degreeOffset * Math.Cos(Mathf.Deg2Rad * vlat); double[] e = new double[9]; double[] s = new double[8]; e[0] = pqs; e[1] = SCANUtil.getElevation(v.mainBody, vlon + latOffset, vlat); e[2] = SCANUtil.getElevation(v.mainBody, vlon - latOffset, vlat); e[3] = SCANUtil.getElevation(v.mainBody, vlon, vlat + degreeOffset); e[4] = SCANUtil.getElevation(v.mainBody, vlon, vlat - degreeOffset); e[5] = SCANUtil.getElevation(v.mainBody, vlon + latOffset, vlat + degreeOffset); e[6] = SCANUtil.getElevation(v.mainBody, vlon + latOffset, vlat - degreeOffset); e[7] = SCANUtil.getElevation(v.mainBody, vlon - latOffset, vlat + degreeOffset); e[8] = SCANUtil.getElevation(v.mainBody, vlon - latOffset, vlat - degreeOffset); /* Calculate rise for each point on the grid * The distance is 5m for adjacent points and 7.071m for the points on the corners * Rise is converted to slope; i.e. a 5m elevation change over a 5m distance is a rise of 1 * Converted to slope using the inverse tangent this gives a slope of 45° * */ for (int i = 1; i <= 4; i++) { s[i - 1] = Math.Atan((Math.Abs(e[i] - e[0])) / 5) * Mathf.Rad2Deg; } for (int i = 5; i <= 8; i++) { s[i - 1] = Math.Atan((Math.Abs(e[i] - e[0])) / 7.071) * Mathf.Rad2Deg; } slopeAVG = s.Sum() / 8; } GUILayout.Label(string.Format("Slope: {0:F2}°", slopeAVG), SCANskins.SCAN_insColorLabel); fillS(-10); } } }