chmodseven

Test flood fill

Jul 12th, 2020
1,482
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.54 KB | None | 0 0
  1. using UnityEngine;
  2.  
  3. // Attach your source texture to the sourceImage, set the from and to colors and tolerance you want,
  4. // and then click on the texture in play mode at the start point you want to fill from
  5. // Don't forget you can use the color pickers in the inspector to make color selection easier
  6. public class TestFloodFill : MonoBehaviour
  7. {
  8.     public Texture2D sourceImage;
  9.     public Color32 fromColor = Color.black;
  10.     public Color32 toColor = Color.white;
  11.     public int colorTolerance;
  12.     public bool preserveGradientsWithTolerance = true;
  13.  
  14.     private GameObject _plane;
  15.     private MeshRenderer _renderer;
  16.     private Collider _collider;
  17.     private Camera _cam;
  18.  
  19.     private void Start ()
  20.     {
  21.         // Find the scene main camera for later world space conversion
  22.         _cam = Camera.main;
  23.         if (_cam == null)
  24.         {
  25.             Debug.LogError ("Must have a main camera in the scene");
  26.             return;
  27.         }
  28.  
  29.         // Move it up from zero position
  30.         _cam.transform.position = Vector3.up * 10f;
  31.  
  32.         // Create a plane on the fly
  33.         _plane = GameObject.CreatePrimitive (PrimitiveType.Plane);
  34.         _renderer = _plane.GetComponent<MeshRenderer> ();
  35.         _renderer.material.shader = Shader.Find ("Unlit/Texture");
  36.         _collider = _plane.GetComponent<Collider> ();
  37.  
  38.         // Rotate the plane to line up with the camera look later
  39.         _plane.transform.Rotate (0f, 180f, 0f);
  40.  
  41.         // Use a reusable method to reset the copy of the image back to the one in inspector
  42.         ResetImageToOriginal ();
  43.  
  44.         // Now point the camera down to look at the plane
  45.         _cam.transform.LookAt (_plane.transform);
  46.     }
  47.  
  48.     private void Update ()
  49.     {
  50.         // Check for the R key to reset the image
  51.         if (Input.GetKeyDown (KeyCode.R))
  52.         {
  53.             ResetImageToOriginal ();
  54.         }
  55.  
  56.         // Check for the left-click on the mouse
  57.         if (!Input.GetButtonDown ("Fire1"))
  58.         {
  59.             return;
  60.         }
  61.  
  62.         Vector3 mousePosition = Input.mousePosition;
  63.         Ray screenPosition = _cam.ScreenPointToRay (mousePosition);
  64.         if (!_collider.Raycast (screenPosition, out RaycastHit hit, 1000))
  65.         {
  66.             return;
  67.         }
  68.  
  69.         // This is pretty complex maths and I won't try to explain it - it basically works out
  70.         // what proportion of the plane is covered by the screen, and then turns the hit point
  71.         // from the raycast into the source image proportions
  72.         Vector3 hitPoint = _cam.WorldToScreenPoint (hit.point);
  73.         Vector3 planeMin = _cam.WorldToScreenPoint (_renderer.bounds.min);
  74.         Vector3 planeMax = _cam.WorldToScreenPoint (_renderer.bounds.max);
  75.         float xProportion = Mathf.InverseLerp (planeMin.x, planeMax.x, hitPoint.x);
  76.         float yProportion = Mathf.InverseLerp (planeMin.y, planeMax.y, hitPoint.y);
  77.         float xPoint = xProportion * sourceImage.width;
  78.         float yPoint = yProportion * sourceImage.height;
  79.         Vector2 startPosition = new Vector2 (xPoint, yPoint);
  80.  
  81.         // And call the flood fill!
  82.         // We call it with our copy though, so we can make repeated changes
  83.         // Note that we are casting the material's Texture to the required Texture2D - they are essentially the same,
  84.         // but Texture2D lets us see the color array data whereas Texture doesn't
  85.         Texture2D result = ImageFunctions.FloodFill (
  86.             (Texture2D) _renderer.material.mainTexture,
  87.             startPosition,
  88.             fromColor,
  89.             toColor,
  90.             colorTolerance,
  91.             preserveGradientsWithTolerance);
  92.  
  93.         // Now we put the result back onto the UI image's texture
  94.         _renderer.material.mainTexture = result;
  95.     }
  96.  
  97.     private void ResetImageToOriginal ()
  98.     {
  99.         // Set a copy of the the original texture to that image
  100.         // This is so we can modify the copy and leave the original untouched so it can be restored
  101.         int sourceImageWidth = sourceImage.width;
  102.         int sourceImageHeight = sourceImage.height;
  103.  
  104.         // This first line creates a blank texture of the right settings
  105.         Texture2D copyTexture = new Texture2D (sourceImageWidth, sourceImageHeight, sourceImage.format, false);
  106.  
  107.         // And then this line copies the actual pixel data from the source image to the copy
  108.         Graphics.CopyTexture (sourceImage, 0, 0, copyTexture, 0, 0);
  109.  
  110.         // Now we assign the copy to the UI image's material to show it on screen
  111.         _renderer.material.mainTexture = copyTexture;
  112.     }
  113. }
Advertisement
Add Comment
Please, Sign In to add comment