using System.Collections; using System.Collections.Generic; using UnityEngine; namespace EzySlice { /** * TextureRegion defines a region of a specific texture which can be used * for custom UV Mapping Routines. * * TextureRegions are always stored in normalized UV Coordinate space between * 0.0f and 1.0f */ public struct TextureRegion { private readonly float pos_start_x; private readonly float pos_start_y; private readonly float pos_end_x; private readonly float pos_end_y; public TextureRegion(float startX, float startY, float endX, float endY) { this.pos_start_x = startX; this.pos_start_y = startY; this.pos_end_x = endX; this.pos_end_y = endY; } public float startX { get { return this.pos_start_x; } } public float startY { get { return this.pos_start_y; } } public float endX { get { return this.pos_end_x; } } public float endY { get { return this.pos_end_y; } } public Vector2 start { get { return new Vector2(startX, startY); } } public Vector2 end { get { return new Vector2(endX, endY); } } /** * Perform a mapping of a UV coordinate (computed in 0,1 space) * into the new coordinates defined by the provided TextureRegion */ public Vector2 Map(Vector2 uv) { return Map(uv.x, uv.y); } /** * Perform a mapping of a UV coordinate (computed in 0,1 space) * into the new coordinates defined by the provided TextureRegion */ public Vector2 Map(float x, float y) { float mappedX = MAP(x, 0.0f, 1.0f, pos_start_x, pos_end_x); float mappedY = MAP(y, 0.0f, 1.0f, pos_start_y, pos_end_y); return new Vector2(mappedX, mappedY); } /** * Our mapping function to map arbitrary values into our required texture region */ private static float MAP(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } } /** * Define our TextureRegion extension to easily calculate * from a Texture2D Object. */ public static class TextureRegionExtension { /** * Helper function to quickly calculate the Texture Region from a material. * This extension function will use the mainTexture component to perform the * calculation. * * Will throw a null exception if the texture does not exist. See * Texture.getTextureRegion() for function details. */ public static TextureRegion GetTextureRegion(this Material mat, int pixX, int pixY, int pixWidth, int pixHeight) { return mat.mainTexture.GetTextureRegion(pixX, pixY, pixWidth, pixHeight); } /** * Using a Texture2D, calculate and return a specific TextureRegion * Coordinates are provided in pixel coordinates where 0,0 is the * bottom left corner of the texture. * * The texture region will automatically be calculated to ensure that it * will fit inside the provided texture. */ public static TextureRegion GetTextureRegion(this Texture tex, int pixX, int pixY, int pixWidth, int pixHeight) { int textureWidth = tex.width; int textureHeight = tex.height; // ensure we are not referencing out of bounds coordinates // relative to our texture int calcWidth = Mathf.Min(textureWidth, pixWidth); int calcHeight = Mathf.Min(textureHeight, pixHeight); int calcX = Mathf.Min(Mathf.Abs(pixX), textureWidth); int calcY = Mathf.Min(Mathf.Abs(pixY), textureHeight); float startX = calcX / (float) textureWidth; float startY = calcY / (float) textureHeight; float endX = (calcX + calcWidth) / (float) textureWidth; float endY = (calcY + calcHeight) / (float) textureHeight; // texture region is a struct which is allocated on the stack return new TextureRegion(startX, startY, endX, endY); } } }