context: /*
  Copyright (c) 2010, Raphael Lopes Baldi & Aquiris Game Experience LTDA.
  
  See the document "TERMS OF USE" included in the project folder for licencing details.
  */
  
  using UnityEngine;
  using System.Collections.Generic;
  
  public class Decal : MonoBehaviour 
  {
  	static public int dCount;
  	
  	//The gameObjects that will be affected by the decal.
  	[HideInInspector]
  	public GameObject[] affectedObjects;
  	
  	public float maxAngle = 90.0f;
  	
  	private float angleCosine;
  	
  	//Decal bounds. We'll never show it on inspector as user should
  	//not modify this value.
  	[HideInInspector]
  	public Bounds bounds;
  	
  	#region STATE PROPERTIES
  	[HideInInspector]
  	public float previousUVAngle;
  	
  	[HideInInspector]
  	public Vector3 previousPosition;
  	
  	[HideInInspector]
  	public Quaternion previousRotation;
  	
  	[HideInInspector]
  	public Vector3 previousScale;
  	
  	[HideInInspector]
  	public float previousMaxAngle;
  	
  	[HideInInspector]
  	public float previousPushDistance = 0.009f;
  	
  	[HideInInspector]
  	public Vector2 previousTiling;
  	
  	[HideInInspector]
  	public Vector2 previousOffset;
  	
  	[HideInInspector]
  	public bool useMeshCollider;
  	#endregion
  	
  	#region UV PROPERTIES
  	//[HideInInspector]
  	public Vector2 tiling = Vector2.one;
  	
  	//[HideInInspector]
  	public Vector2 offset = Vector2.zero;
  	
  	[HideInInspector]
  	public float uvAngle = 0.0f;
  	private float uCos;
  	private float vSin;
  	#endregion
  	
  	public Material decalMaterial;
  	
  	[HideInInspector]
  	public DecalMode decalMode;
  	
  	#region DECAL CREATION PROPERTIES
  	private List<DecalPolygon> startPolygons;
  	private List<DecalPolygon> clippedPolygons;
  	
  	[HideInInspector]
  	public Vector4 bottomPlane;
  	
  	[HideInInspector]
  	public Vector4 topPlane;
  	
  	[HideInInspector]
  	public Vector4 leftPlane;
  	
  	[HideInInspector]
  	public Vector4 rightPlane;
  	
  	[HideInInspector]
  	public Vector4 frontPlane;
  	
  	[HideInInspector]
  	public Vector4 backPlane;
  
  	[HideInInspector]
  	public Vector3 decalNormal;// = transf.MultiplyVector(-transform.forward);
  	
  	[HideInInspector]
  	public Vector3 decalCenter;// = transf.MultiplyPoint(transform.position);
  	
  	[HideInInspector]
  	public Vector3 decalTangent;// = transf.MultiplyVector(transform.right);
  	
  	[HideInInspector]
  	public Vector3 decalBinormal;// = transf.MultiplyVector(transform.up);
  	
  	[HideInInspector]
  	public Vector3 decalSize;// = transf.MultiplyPoint(transform.lossyScale);
  	#endregion
  	
  	public float pushDistance = 0.009f;
  	
  	private List<MeshCombineUtility.MeshInstance> instancesList;
  	
  	//Should the system stop checking for objects that will be affected?
  	public bool checkAutomatically;
  	public LayerMask affectedLayers;
  	public bool affectOtherDecals;
  	public bool affectInactiveRenderers;
  	
  	#region INSPECTOR PROPERTIES
  	[HideInInspector]
  	public bool showAffectedObjectsOptions;
  	
  	[HideInInspector]
  	public bool showObjects;
  	#endregion
  	
  //	private void OnDrawGizmosSelected()
  //	{
  //		Gizmos.DrawIcon(transform.position, "decal_icon");
  //	}
  	
  	private void OnDrawGizmosSelected()
  	{
  		//Calculate current decal bounds.
  		CalculateBounds();
  		
  		//Gizmos.DrawRay(decalCenter, decalNormal);
  		
  		//Draw the helper gizmos with the correct object matrix.
  		Gizmos.matrix = transform.localToWorldMatrix;
  		Gizmos.DrawWireCube(Vector3.zero, Vector3.one);
  	}
  	
  	//Method responsible for calculating decal's bounds, used to detect the 
  	//affected objects.
   	public void CalculateBounds()
  	{
  		//Extend decal's bounds a little in order to make sure that everything will
  		//still working when the projector is rotated.
  		bounds = new Bounds(transform.position, transform.lossyScale * 1.414214f);
  	}
  	
  	//Method responsible for constructing the Decal Mesh, based on the affected objects.
  	public void CalculateDecal()
  	{
  		ClearDecals();
  		
  		maxAngle = Mathf.Clamp(maxAngle, 0.0f, 180.0f);
  		angleCosine = Mathf.Cos(maxAngle * Mathf.Deg2Rad);
  		
  		uvAngle = Mathf.Clamp(uvAngle, 0.0f, 360.0f);
  		uCos = Mathf.Cos(uvAngle * Mathf.Deg2Rad);
  		vSin = Mathf.Sin(uvAngle * Mathf.Deg2Rad);
  		
  		if(affectedObjects == null)
  		{
  			//Debug.LogWarning("No object will be affected. Decal will not be calculated.");
  			return;
  		}
  		else if(affectedObjects.Length <= 0)
  		{
  			//Debug.LogWarning("No object will be affected. Decal will not be calculated.");
  			return;
  		}
  		
  		//Current transform matrix
  		Matrix4x4 myTransform = transform.worldToLocalMatrix;
  		
  		instancesList = new List<MeshCombineUtility.MeshInstance>();
  		
  		for(int i = 0; i < affectedObjects.Length; i++)
  		{
  			if(affectedObjects[i] == null) continue;
  			
  			CalculateObjectDecal(affectedObjects[i], myTransform);
  		}
  		
  		if(instancesList.Count > 0)
  		{
  			MeshCombineUtility.MeshInstance[] instances = new MeshCombineUtility.MeshInstance[instancesList.Count];
  			for(int i = 0; i < instances.Length; i++)
  			{
  				instances[i] = instancesList[i];
  			}
  			
  			MeshRenderer r = gameObject.GetComponent<MeshRenderer>();
  			if(r == null)
  			{
  				r = gameObject.AddComponent<MeshRenderer>();
  			}
  			
  			r.material = decalMaterial;
  			
  			MeshFilter fi = gameObject.GetComponent<MeshFilter>();
  			
  			if(fi == null)
  			{
  				fi = gameObject.AddComponent<MeshFilter>();
  			}
  			else
  			{
  				DestroyImmediate(fi.sharedMesh);
  			}
  			
  			Mesh finalMesh = MeshCombineUtility.Combine(instances, true);
  			
  			if(pushDistance > 0.0f)
  			{
  				List<List<int>> relations = new List<List<int>>();
  				Vector3[] vert = finalMesh.vertices;
  				Vector3[] normals = finalMesh.normals;
  				
  				bool[] usedIndex = new bool[vert.Length];
  				for(int i = 0; i < usedIndex.Length; i++)
  				{
  					usedIndex[i] = false;
  				}
  				
  				for(int i = 0; i < vert.Length; i++)
  				{
  					if(usedIndex[i]) continue;
  					
  					List<int> c = new List<int>();
  					c.Add(i);
  					
  					usedIndex[i] = true;
  					
  
gt: 					for(int j = i + 1; j < vert.Length; j++)