using UnityEngine;
using System.Collections;
[RequireComponent(typeof(UIWidget))]
public class UIHitAlphaTest : MonoBehaviour {
[Range(0.01f,1f)]
public float threshold = 0.5f;
void Start () {
GetComponent<UIWidget>().hitCheck = HitCheck;
}
bool HitCheck(Vector3 worldPos) {
UIWidget w = GetComponent<UIWidget>();
Vector3 localPos = w.cachedTransform.InverseTransformPoint(worldPos);
Texture2D tex = w.mainTexture as Texture2D;
for( int i = 0; i < w.geometry.verts.size; i+=4 ) {
if( CheckTriangle( localPos,
w.geometry.verts.buffer[i], w.geometry.verts.buffer[i+2], w.geometry.verts.buffer[i+1],
w.geometry.uvs.buffer[i], w.geometry.uvs.buffer[i+2], w.geometry.uvs.buffer[i+1], tex ) ||
CheckTriangle( localPos,
w.geometry.verts.buffer[i], w.geometry.verts.buffer[i+3], w.geometry.verts.buffer[i+2],
w.geometry.uvs.buffer[i], w.geometry.uvs.buffer[i+3], w.geometry.uvs.buffer[i+2], tex ) )
return true;
}
return false;
}
bool CheckTriangle(Vector3 pos, Vector3 v1, Vector3 v2, Vector3 v3, Vector2 uv1, Vector2 uv2, Vector2 uv3, Texture2D tex) {
Vector3 normal = Vector3.Cross( v3-v1, v2-v1 );
if( normal.sqrMagnitude < 0.01f )
return false;
pos = pos - Vector3.Dot( pos-v1, normal ) * normal; //Project point onto plane
float area = normal.magnitude; //Technically area*2
float a1 = Vector3.Cross( v2-pos, v3-pos ).magnitude / area;
if( a1 < 0 || a1 > 1 )
return false;
float a2 = Vector3.Cross( v3-pos, v1-pos ).magnitude / area;
if( a2 < 0 || a2 > 1 )
return false;
float a3 = 1f-a1-a2; //Vector3.Cross( v1-pos, v2-pos ).magnitude / (2*area);
if( a3 < 0 || a3 > 1 )
return false;
Vector2 finalUV = uv1 * a1 + uv2 * a2 + uv3 * a3;
Color pixel = tex.GetPixel( (int)(finalUV.x * tex.width), (int)(finalUV.y * tex.height) );
return pixel.a >= threshold;
}
}