public static int MINIMUM_THRESHOLD = -333; //!< Minimum threshold. /// Minimum alpha a point must have to be rendered at all. /// //Inputs: speedAndPos | the dictionary that stores all the points and their different color values // cam | the main camera // plane | the heatplane that the texture is going to be put on //Outputs: Texture2D | the texture that the heatmap is put on //Functionality: creates a texture for the heatmap to be stored on using all the points and their color values public static Texture2D CreateHeatmap(Dictionary <Vector2, float> speedAndPos, Camera cam, GameObject plane) { //find camera if (cam == null) { if (Camera.main == null) { Debug.LogWarning("No camera found. Returning an empty texture."); return(new Texture2D(0, 0)); } else { cam = Camera.main; } } // Create new texture Texture2D map = new Texture2D((int)(plane.transform.localScale.x * 30 * 10), (int)(plane.transform.localScale.z * 30 * 10), TextureFormat.ARGB32, false); // Set texture to alpha-fied state map.SetPixels(Heatmap.ColorArray(new Color(1f, 1f, 1f, 0f), map.width * map.height), 0); //Going through each point, set the alpha value to the color value in speedAndPos foreach (KeyValuePair <Vector2, float> keyval in speedAndPos) { //this checks if the color value is 0, in which case the color should be different. This represents the starting position of the agent //this is currently turned off in Tracker if (keyval.Value == 0) { map.SetPixel((int)keyval.Key.x, (int)keyval.Key.y, Color.cyan); } else { map.SetPixel((int)keyval.Key.x, (int)keyval.Key.y, new Color(1f, 1f, 1f, keyval.Value)); } } //finish the map by applying all changes and setting the rest of the pixels map.Apply(); map.SetPixels(Colorize(map.GetPixels(0)), 0); map.Apply(); return(map); }
public static int MINIMUM_THRESHOLD = 100; //!< Minimum threshold. /// Minimum alpha a point must have to be rendered at all. /*! <summary> * Creates a Heatmap image given a set of world points. * </summary> * <remarks> * This method accepts a series of world points, and returns a transparent overlay of the heatmap. Usually you will want to pair this call with CreateRenderPlane() to actually view the heatmap. * </remarks> * <param name="worldPoints">An array of Vector3 points to be translated into heatmap points.</param> * <param name="cam">The camera to render from. If passed a null value, CreateHeatmap() attempts to use Camera.main.</param> * <param name="radius">Raidus in pixels that each point should create. Larger radii produce denser heatmaps, and vice-versa.</param> * <returns>Returns a new Texture2D containing a transparent overlay of the heatmap.</returns> */ public static Texture2D CreateHeatmap(Vector3[] worldPoints, Camera cam, int radius) { if (cam == null) { if (Camera.main == null) { Debug.LogWarning("No camera found. Returning an empty texture."); return(new Texture2D(0, 0)); } else { cam = Camera.main; } } // Create new texture // Texture2D map = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false); Texture2D map = new Texture2D((int)cam.pixelWidth, (int)cam.pixelHeight, TextureFormat.ARGB32, false); // Set texture to alpha-fied state map.SetPixels(Heatmap.ColorArray(new Color(1f, 1f, 1f, 0f), map.width * map.height), 0); // Convert world to screen points Vector2[] points = new Vector2[worldPoints.Length]; for (int i = 0; i < worldPoints.Length; i++) { points[i] = cam.WorldToScreenPoint(worldPoints[i]); } /*** Generate Grayscale Values ***/ { int x2; // the offset x val in img coordinates int y2; // the offset y val in img coordinates (0,0) - (maxX, maxY) float pointAlpha = .9f; // The alpha that the darkest pixel will be in a poitn. Color color = new Color(1f, 1f, 1f, pointAlpha); int lineWidth = 1; //(int)(radius * .05f); Dictionary <Vector2, Color> pixelAlpha = new Dictionary <Vector2, Color>(); for (int i = 0; i < points.Length; i++) // generate alpha add for each point and a specified circumference { pixelAlpha.Clear(); for (int r = 0; r < radius; r += lineWidth) // draw and fill them circles { for (int angle = 0; angle < 360; angle++) { x2 = (int)(r * Mathf.Cos(angle)) + (int)points[i].x; y2 = (int)(r * Mathf.Sin(angle)) + (int)points[i].y; // This could be sped up for (int y = y2; y > y2 - lineWidth; y--) { for (int x = x2; x < x2 + lineWidth; x++) { Vector2 coord = new Vector2(x, y); if (pixelAlpha.ContainsKey(coord)) { pixelAlpha[coord] = color; } else { pixelAlpha.Add(new Vector2(x, y), color); } } } } color = new Color(color.r, color.g, color.b, color.a - (pointAlpha / ((float)radius / lineWidth))); } // Since the radial fill code overwrites it's own pixels, make sure to only add finalized alpha to // old values. foreach (KeyValuePair <Vector2, Color> keyval in pixelAlpha) { Vector2 coord = keyval.Key; Color previousColor = map.GetPixel((int)coord.x, (int)coord.y); Color newColor = keyval.Value; map.SetPixel((int)coord.x, (int)coord.y, new Color(newColor.r, newColor.b, newColor.g, newColor.a + previousColor.a)); } // Reset color for next point color = new Color(color.r, color.g, color.b, pointAlpha); } } map.Apply(); map.SetPixels(Colorize(map.GetPixels(0)), 0); map.Apply(); return(map); }