UP-Viagg-io/Viagg-io/Assets/EzySlice/Framework/TextureRegion.cs

115 lines
4.3 KiB
C#

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);
}
}
}