//This asset was uploaded by https://unityassetcollection.com
/// ProFlares - v1.08 - Copyright 2014-2015 All rights reserved - ProFlares.com
/// 
/// ProFlareBatch.cs
/// Processes all the ProFlares in a scene, converts them into geometry that can be rendered.
/// 
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
public class FlareData {
	public ProFlare flare;
	public FlareOcclusion occlusion;
}
[System.Serializable]
public class FlarePixelOcclusion {
	public RenderTexture renderTexture;
	//public Texture2D texture2D = new Texture2D(1, 1, TextureFormat.RGBAHalf, false);
	public Texture2D texture2D;
	public Rect rect = new Rect(0, 0, 1, 1);
	public Color pixelColor = new Color();
	public Camera pixelCamera = new Camera ();
	public Transform pixelCameraTransform;
	public bool pixelOcclusionPingPong;
}
[System.Serializable]
public class FlareOcclusion {
	public bool occluded = false;
	public float occlusionScale = 1;
	public float occlusionBrigtness = 1;
	public float occlusionTarget = 1;
	public CullingState _CullingState;
	public float CullTimer = 0;
	public float cullFader = 1;
	public enum CullingState{
		Visible,
		CullCountDown,
		CanCull,
		Culled,
		NeverCull
	}
	public FlarePixelOcclusion flarePixelOcclusion;
}
[ExecuteInEditMode]
[RequireComponent (typeof (MeshRenderer))]
[RequireComponent (typeof (MeshFilter))]
public class ProFlareBatch : MonoBehaviour {
	
	public enum Mode{
		Standard = 0,
		SingleCamera = 1
		//VR = 2
	}
	
	public bool debugMessages = true;
	
	public Mode mode = Mode.Standard;
	
	public ProFlareAtlas _atlas;
	
	//List of flares
	//public List Flares = new List();
	
	public List FlaresList = new List();
	
	//List of FlareElements
	
	public List FlareElements = new List();
	public ProFlareElement[] FlareElementsArray;
	
	public Camera GameCamera;
	public Transform GameCameraTrans;
	
	//Camera that the flare geometry will be rendered from.
	public Camera FlareCamera;
	public Transform FlareCameraTrans;
	//Cached Components
	public MeshFilter meshFilter;
	public Transform thisTransform;
	
	public MeshRenderer meshRender;
	
	public float zPos = 10;
	
	//Multiple meshes used for double buffering technique
	private Mesh bufferMesh;
	private Mesh meshA;
	private Mesh meshB;
	
	//Ping pong value for double Buffering
	bool PingPong;
	
	//Material used for the Flares, this is automatically created.
	public Material mat;
	
	//Geometry Arrays
	Vector3[] vertices;
	Vector2[] uv;
	Color32[] colors;
	
	int[] triangles;
	
	//public FlareOcclusion[] FlareOcclusionData;
	
	//Debug Propertys
	public bool useBrightnessThreshold = true;
	public int BrightnessThreshold = 1;
	public bool overdrawDebug;
	
	//When set to true the Flarebatches' geomerty will be rebuilt.
	public bool dirty = false;
	
	public bool useCulling = true;
	public int cullFlaresAfterTime = 5;
	public int cullFlaresAfterCount = 5;
	
	public bool culledFlaresNowVisiable = false;
	private float reshowCulledFlaresTimer = 0;
	public float reshowCulledFlaresAfter = 0.3f;
	
	//HelperTransform used for FlarePositions calculations.
	public Transform helperTransform;
	
	public bool showAllConnectedFlares;
		
	public bool VR_Mode = false;
	public float VR_Depth = 0.2f;
	public bool SingleCamera_Mode = false;
	public bool linearColorSpace = false;
	void Reset(){
		if(helperTransform == null)
			CreateHelperTransform();
		if (linearColorSpace){
			mat = new Material(Shader.Find("ProFlares/Textured Flare Shader Linear"));
		}else{
			mat = new Material(Shader.Find("ProFlares/Textured Flare Shader Gamma"));
		}
		if(meshFilter == null)
			meshFilter = GetComponent();
		
        if(meshFilter == null)
            meshFilter = gameObject.AddComponent();
		
		meshRender = gameObject.GetComponent();
		
		if(meshRender == null)
            meshRender = gameObject.AddComponent();
		
		
		if(FlareCamera == null){
			FlareCamera = transform.root.GetComponentInChildren();
		}
        
		meshRender.material = mat;
		SetupMeshes();
		
		dirty = true;
	}
	
	void Awake(){
		PI_Div180 = Mathf.PI / 180;
		Div180_PI = 180 / Mathf.PI;
		
		ProFlare[] flares = GameObject.FindObjectsOfType(typeof(ProFlare)) as ProFlare[];
		
		for(int i = 0; i < flares.Length; i++){
			if(flares[i]._Atlas == _atlas)
				this.AddFlare(flares[i]);
		}
		for (int F = 0; F < FlaresList.Count; F++) {
			if (FlaresList [F].flare == null)
				continue;
		
			ProFlare flare_ = FlaresList [F].flare;
			if (Application.isPlaying) {
				FlareOcclusion data = FlaresList[F].occlusion;
				if(flare_.pixelBasedOcclusion)
					setupPixelBasedOcclusion (data, flare_);
			}else{
				//if(flare_.sunMode)
				//	setupSunMode(flare_);
			}
		}
		
	}
	
	void Start () {
		//Turn off overdraw debug mode.
		if(Application.isPlaying){
			overdrawDebug = false;
			//dirty = true;
		}
		
		if(GameCamera == null){
			GameObject GameCameraGo = GameObject.FindWithTag("MainCamera");
		
			if(GameCameraGo)
				if(GameCameraGo.GetComponent())
					GameCamera = GameCameraGo.GetComponent();
//#			if(GameCameraGo)
//				if(GameCameraGo.camera)
//ss					GameCamera = GameCameraGo.camera;
		}
        
		if(GameCamera)
			GameCameraTrans = GameCamera.transform;
	
		//Make sure we have the transform cached
		thisTransform = transform;
		SetupMeshes();
	}
	void CreateMat(){
//		Debug.LogError("CreateMat");
		if (linearColorSpace){
			mat = new Material(Shader.Find("ProFlares/Textured Flare Shader Linear"));
		}else{
			mat = new Material(Shader.Find("ProFlares/Textured Flare Shader Gamma"));
		}
		meshRender.material = mat;
		if(_atlas)
			if(_atlas.texture)
				mat.mainTexture = _atlas.texture;
	}
	
	
	
	//Call when you switch your main render.
	public void SwitchCamera(Camera newCamera){
		GameCamera = newCamera;
		GameCameraTrans = newCamera.transform; 
		
		//Update Occlusion data on changing camera new in v1.03
		//FixedUpdate ();
		for (int F = 0; F < FlaresList.Count; F++) {
			if (FlaresList [F].occlusion != null) {
			 
				FlareOcclusion data = FlaresList [F].occlusion;
				if (data.occluded)
					FlaresList [F].occlusion.occlusionTarget = 0;
					
				
				if (FlaresList[F].flare.pixelBasedOcclusion) {
					data.flarePixelOcclusion.pixelCamera.transform.parent = newCamera.transform;
					data.flarePixelOcclusion.pixelCamera.transform.position = Vector3.zero;
				}
			}
				
		}
	}
	
	void OnDestroy(){
		//Remove the helper transform.
		if(Application.isPlaying){
			Destroy(helperTransform.gameObject);
			Destroy(mat);
		}
		else{
			DestroyImmediate(helperTransform.gameObject);
			DestroyImmediate(mat);
		}
	}
	
	public void RemoveFlare(ProFlare _flare){
		bool found = false;
		FlareData targetFlare = null;
		for(int i = 0; i < FlaresList.Count; i++){
			if(_flare == FlaresList[i].flare){
				targetFlare = FlaresList[i];
				found = true;
				break;
			}
		}
		
		if(found)
			FlaresList.Remove(targetFlare);
	}
	
	//Called from ProFlare.cs
	//First checks if the flare is already in the list, if not adds it and rebuils the Flarebatch Geometry
	public void AddFlare(ProFlare _flare){
		bool found = false;
        
		if (_flare.thisGameObject.scene != gameObject.scene){
			return;
		}
		for(int i = 0; i < FlaresList.Count; i++){
			if(_flare == FlaresList[i].flare){
				found = true;
				break;
			}
		}
		
		if(!found){
			
			FlareData FlareData_ = new FlareData();
			FlareData_.flare = _flare;
			
			FlareOcclusion data = new FlareOcclusion();
			
			if(_flare.neverCull)
				data._CullingState = FlareOcclusion.CullingState.NeverCull;
			FlareData_.occlusion = data;
			FlaresList.Add(FlareData_);
			if(_flare.pixelBasedOcclusion){
				/*
				data.flarePixelOcclusion = new FlarePixelOcclusion();
				GameObject cameraGO = new GameObject("ProFlarePixelCamera");
				cameraGO.layer = 8;
				Camera camera = cameraGO.AddComponent();
				
				cameraGO.transform.parent = GameCameraTrans;
				camera.fieldOfView = 1;
				cameraGO.transform.localPosition = Vector3.zero;
				data.flarePixelOcclusion.pixelCamera = camera;
				data.flarePixelOcclusion.pixelCameraTransform = cameraGO.transform;
				data.flarePixelOcclusion.pixelCamera.clearFlags = CameraClearFlags.SolidColor;
				data.flarePixelOcclusion.pixelCamera.backgroundColor = new Color(0,0,0,0);
				data.flarePixelOcclusion.renderTexture = new RenderTexture(2,2,0,RenderTextureFormat.ARGBHalf);
				data.flarePixelOcclusion.rect = new Rect(0, 0, 1, 1);
				data.flarePixelOcclusion.texture2D = new Texture2D(2, 2, TextureFormat.RGBAHalf, false);
				camera.targetTexture = data.flarePixelOcclusion.renderTexture;
				*/
				setupPixelBasedOcclusion(data,_flare);
			}
			dirty = true;
		}
	}
	void setupPixelBasedOcclusion(FlareOcclusion data,ProFlare flare){
		Debug.Log("setupPixelBasedOcclusion");
		data.flarePixelOcclusion = new FlarePixelOcclusion();
		
		GameObject cameraGO = new GameObject("ProFlarePixelCamera");
		cameraGO.layer = 8;
		Camera camera = cameraGO.AddComponent();
		
		cameraGO.transform.parent = GameCameraTrans;
		camera.fieldOfView = 1;
		cameraGO.transform.localPosition = Vector3.zero;
		
		data.flarePixelOcclusion.pixelCamera = camera;
		data.flarePixelOcclusion.pixelCameraTransform = cameraGO.transform;
		
		data.flarePixelOcclusion.pixelCamera.clearFlags = CameraClearFlags.SolidColor;
		data.flarePixelOcclusion.pixelCamera.backgroundColor = new Color(0,0,0,0);
		
		data.flarePixelOcclusion.renderTexture = new RenderTexture(1,1,0,RenderTextureFormat.ARGB32);
		
		data.flarePixelOcclusion.rect = new Rect(0, 0, 1, 1);
		data.flarePixelOcclusion.texture2D = new Texture2D(1, 1, TextureFormat.ARGB32, false);
		camera.cullingMask = flare.pixelLayerMask;
		camera.enabled = false;
		camera.targetTexture = data.flarePixelOcclusion.renderTexture;
	}
	
	void CreateHelperTransform(){
		
		GameObject HelpTransformGo =  new GameObject("_HelperTransform");
		
		helperTransform = HelpTransformGo.transform;
		helperTransform.parent =  transform;
		helperTransform.localScale = Vector3.one;
		helperTransform.localPosition = Vector3.zero;
	}
	
	void Update(){
		Update2 ();
		if(thisTransform)
				thisTransform.localPosition = Vector3.forward*zPos;
		
		//Checks if you have deleted the helper transform. If its missing recreate it.....
		if(helperTransform == null)
			CreateHelperTransform();
		
        if(meshRender){
			if(meshRender.sharedMaterial == null)
				CreateMat();
		}else
			meshRender = gameObject.GetComponent();
		
		bool meshMissing = false;
		//if(meshA == null){
		//	meshMissing = true;
		//	meshA = SetupSingleMesh();
		//	meshA.name = "MeshA";
		//	meshA.MarkDynamic();
		//}
		
		//if(meshB == null){
		//	meshMissing = true;
			
		//	meshB = SetupSingleMesh();
		//	meshB.name = "MeshB";
		//	meshB.MarkDynamic();
		//}
		
		if(meshMissing)
			if(_atlas != null)
				SetupMeshes(); 
		
		if(dirty)
			ReBuildGeometry();
	}
	
	//Late update
	void LateUpdate () {
 		
		if(_atlas == null)
			return;
		
		UpdateFlares();
	
	}
	
	public void UpdateFlares(){
		
		bufferMesh = PingPong ? meshA : meshB;
		
		PingPong = !PingPong;
		
		UpdateGeometry();
		
		//Profiler.BeginSample("Set Arrays");
		if(bufferMesh != null){
			bufferMesh.vertices = vertices;
			
			bufferMesh.colors32 = colors;
		  	meshFilter.sharedMesh = bufferMesh;
		}
		//Profiler.EndSample();
	}
	
	public void ForceRefresh(){
		
		FlaresList.Clear();
		
		ProFlare[] flares = GameObject.FindObjectsOfType(typeof(ProFlare)) as ProFlare[];
		
		for(int i = 0; i < flares.Length; i++){
			if(flares[i]._Atlas == _atlas)
				this.AddFlare(flares[i]);
		}
		
		dirty = true;
	}
	
	
	void ReBuildGeometry(){
#if UNITY_EDITOR
		//See when the geometry is built, try and avoid triggering this in the middle of your game.
		//This can be triggered by the new culling system, if your only using a few flares you may want to turn it off as the speed increase from culling will be more limited.
		if(debugMessages)
			Debug.Log("ProFlares - Rebuilding Geometry : "+ gameObject.name,gameObject);
#endif
		
		FlareElements.Clear();
		
		int flareElementsCount = 0;
		bool missingFlare = false;
		for(int i = 0; i < FlaresList.Count; i++){
			
			if(FlaresList[i].flare == null){
				missingFlare = true;
				break;
			}
			
			for(int i2 = 0; i2 < FlaresList[i].flare.Elements.Count; i2++){
		//		FlareElements.Add(Flares[i].Elements[i2]);
				
				if(FlaresList[i].occlusion._CullingState ==  FlareOcclusion.CullingState.CanCull){
					FlaresList[i].occlusion._CullingState = FlareOcclusion.CullingState.Culled;
					FlaresList[i].occlusion.cullFader = 0;
				}
				
				
				if(FlaresList[i].occlusion._CullingState != FlareOcclusion.CullingState.Culled){
					flareElementsCount++;
				}
				
			}
		}
		
		FlareElementsArray = new ProFlareElement[flareElementsCount];
		
		flareElementsCount = 0;
		if(!missingFlare)
		for(int i = 0; i < FlaresList.Count; i++){
			
			for(int i2 = 0; i2 < FlaresList[i].flare.Elements.Count; i2++){
				if(FlaresList[i].occlusion._CullingState != FlareOcclusion.CullingState.Culled){
					FlareElementsArray[flareElementsCount] = (FlaresList[i].flare.Elements[i2]);
					flareElementsCount++;
				}
			}
		}
		
		if(missingFlare){
			ForceRefresh();
			ReBuildGeometry();
			missingFlare = false;
			
		}
		meshA = null;
		meshB = null;
		bufferMesh = null;
		
		SetupMeshes();
		dirty = false;
	}
	
	void SetupMeshes()
    {
		
		if(_atlas == null)
			return;
		if(FlareElementsArray == null)
			return;
        
		meshA = new Mesh();
		meshB = new Mesh();
		
		int vertSize = 0;
		int uvSize = 0;
		int colSize = 0;
		int triCount = 0;
		
		//Calculate how big each array needs to be based on the Flares
	 	for(int i = 0; i < FlareElementsArray.Length; i++){
			switch(FlareElementsArray[i].type){
				case(ProFlareElement.Type.Single):
				{
					vertSize = vertSize+4;
					uvSize = uvSize+4;
					colSize = colSize+4;
					triCount = triCount+6;
				}
                    break;
				case(ProFlareElement.Type.Multi):
				{
					int subCount = FlareElementsArray[i].subElements.Count;
					vertSize = vertSize+(4*subCount);
					uvSize = uvSize+(4*subCount);
					colSize = colSize+(4*subCount);
					triCount = triCount+(6*subCount);
				}
                    break;
			}
		}
		
		
		//Create Built in arrays
		vertices = new Vector3[vertSize];
    	uv = new Vector2[uvSize];
		colors = new Color32[colSize];
		triangles = new int[triCount];
        
		
		//Set Inital valuse for each vertex
		for(int i = 0; i < vertices.Length/4; i++){
			int extra = i * 4;
			vertices[0+extra] = new Vector3(1,1,0); //((Vector3.right)+(Vector3.up));
			vertices[1+extra] = new Vector3(1,-1,0);//((Vector3.right)+(Vector3.down));
			vertices[2+extra] = new Vector3(-1,1,0);//((Vector3.left)+(Vector3.up));
			vertices[3+extra] = new Vector3(-1,-1,0);//((Vector3.left)+(Vector3.down));
		}
		
		//Set UV coordinates for each vertex, this only needs to be done in the mesh rebuild.
		int count = 0;
		for(int i = 0; i < FlareElementsArray.Length; i++){
			switch(FlareElementsArray[i].type){
				case(ProFlareElement.Type.Single):
				{
					int extra = (count) * 4;
					Rect final = _atlas.elementsList[FlareElementsArray[i].elementTextureID].UV;
					uv[0+extra] = new Vector2(final.xMax,final.yMax);
					uv[1+extra] = new Vector2(final.xMax,final.yMin);
					uv[2+extra] = new Vector2(final.xMin,final.yMax);
					uv[3+extra] = new Vector2(final.xMin,final.yMin);
					count++;
				}break;
				case(ProFlareElement.Type.Multi):
				{
					for(int i2 = 0; i2 < FlareElementsArray[i].subElements.Count; i2++){
						
						int extra2 = (count+i2) * 4;
						
						Rect final = _atlas.elementsList[FlareElementsArray[i].elementTextureID].UV;
						
						uv[0+extra2] = new Vector2(final.xMax,final.yMax);
						uv[1+extra2] = new Vector2(final.xMax,final.yMin);
						uv[2+extra2] = new Vector2(final.xMin,final.yMax);
						uv[3+extra2] = new Vector2(final.xMin,final.yMin);
                        
					}
					count = count+FlareElementsArray[i].subElements.Count;
				}break;
			}
		}
		Color32 newColor = new Color32(255,255,255,255);
		//Set inital vertex colors.
		for(int i = 0; i < colors.Length/4; i++){
			int extra = i * 4;
			colors[0+extra] = newColor;
			colors[1+extra] = newColor;
			colors[2+extra] = newColor;
			colors[3+extra] = newColor;
		}
		
        
		
		//Set triangle array, this is only done in the mesh rebuild.
		for(int i = 0; i < triangles.Length/6; i++){
			int extra = i * 4;
			int extra2 = i * 6;
			triangles[0+extra2] = 0+extra;
			triangles[1+extra2] = 1+extra;
			triangles[2+extra2] = 2+extra;
			triangles[3+extra2] = 2+extra;
			triangles[4+extra2] = 1+extra;
			triangles[5+extra2] = 3+extra;
		}
		
        meshA.vertices = vertices;
        meshA.uv = uv;
        meshA.triangles = triangles;
  		meshA.colors32 = colors;
		
		meshA.bounds = new Bounds(Vector3.zero,Vector3.one*1000);
		
        meshB.vertices = vertices;
        meshB.uv = uv;
        meshB.triangles = triangles;
  		meshB.colors32 = colors;
		meshB.bounds = new Bounds(Vector3.zero,Vector3.one*1000);
	 	
    }
	
	Vector3[] verts;
	Vector2 _scale;
	Color32 _color;
    
	float PI_Div180;
	float Div180_PI;
	
	int visibleFlares = 0;
	
	/*
	public Vector3 RotatePoint(Vector3 p, float d,float ct,float st) {
		//float r = d * (Mathf.PI / 180);
		//float ct = Mathf.Cos(r);
		//float st = Mathf.Sin(r);
		float x = (ct * p.x - st * p.y);
		float y = (st * p.x + ct * p.y);
		return new Vector3(x,y,0);
	}*/
	
	void Update2(){
		
	
		if (!dirty) {
			for (int F = 0; F < FlaresList.Count; F++) {
			
				if (FlaresList [F].flare == null)
					continue;
				ProFlare flare_ = FlaresList [F].flare;
				FlareOcclusion data = FlaresList [F].occlusion;
			
				float distanceRay = -1;
				if (flare_.isVisible) {
					if(flare_.DisabledPlayMode)
						continue;
					if (flare_.RaycastPhysics) {
						data.occluded = true;
						RaycastHit hit;
				
						Vector3 direction = GameCameraTrans.position - flare_.thisTransform.position;
				
						if (flare_.sunMode) {
							direction = GameCameraTrans.position - flare_.sunModeTransformB.position;
						}
						distanceRay = Vector3.Distance (GameCameraTrans.position, flare_.thisTransform.position);
						Ray ray = new Ray (flare_.thisTransform.position, direction);
					
						if (Physics.Raycast (ray, out hit, distanceRay, flare_.mask)) {
						
							data.occluded = true;
							data.occlusionTarget = 0;
							#if UNITY_EDITOR					
							Debug.DrawRay (flare_.thisTransform.position, direction, Color.red);
							flare_.OccludingObject = hit.collider.gameObject;
							#endif
						} else {
							data.occluded = false;
							data.occlusionTarget = 1;
							#if UNITY_EDITOR
							flare_.OccludingObject = null;
							Debug.DrawRay (flare_.thisTransform.position, direction);
							#endif
						}
					}
					if (flare_.pixelBasedOcclusion && Application.isPlaying) {
						FlarePixelOcclusion flarePixelOcclusion = data.flarePixelOcclusion;
						if(!flarePixelOcclusion.pixelOcclusionPingPong){
							if (distanceRay < 0) {
								distanceRay = Vector3.Distance (GameCameraTrans.position, flare_.thisTransform.position);
							}
					
							if (flare_.sunMode) {
								flarePixelOcclusion.pixelCameraTransform.LookAt (flare_.sunModeTransformB);
								distanceRay = GameCamera.farClipPlane;
							} 
							else {
									if(flarePixelOcclusion.pixelCameraTransform != null)
										flarePixelOcclusion.pixelCameraTransform.LookAt (flare_.thisTransform);
							}
				
							flarePixelOcclusion.pixelCamera.farClipPlane = distanceRay;
							RenderTexture.active = flarePixelOcclusion.renderTexture;
					
							flarePixelOcclusion.pixelCamera.Render ();
									
							flarePixelOcclusion.texture2D.ReadPixels (flarePixelOcclusion.rect, 0, 0);
							flarePixelOcclusion.texture2D.Apply ();
							
								flarePixelOcclusion.pixelOcclusionPingPong = true;
						}else{
							Color pix = Color.white;
							
							pix = flarePixelOcclusion.texture2D.GetPixel(0, 0);
							float pixA = pix.a;
							data.occlusionTarget = Mathf.Abs(1 - Mathf.Clamp01(pixA));
							if (data.occlusionTarget < 0.01){
								data.occluded = false;
							}else if (pix.a < 1.0){
								data.occluded = false;
							}else{
								data.occluded = true;
							}
						
							if (data.occlusionTarget > 1)
								data.occlusionTarget = 1;
							if (data.occlusionTarget < 0)
								data.occlusionTarget = 0;
								flarePixelOcclusion.pixelOcclusionPingPong = false;
						}
  						//Debug.Log (pix);
					}
				}
			}
		}
	}
    
	
 	
	void UpdateGeometry(){
		
		if(GameCamera == null){
			meshRender.enabled = false;
			return;
		}
		
		meshRender.enabled = true;
		//Profiler.BeginSample("Update Pos");
		visibleFlares = 0;
		int canCullFlares = 0;
		for(int F = 0; F < FlaresList.Count; F++){
			//Profiler.BeginSample("Lens Pos");
			
			ProFlare flare_ = FlaresList[F].flare;
			FlareOcclusion data = FlaresList[F].occlusion;
			
			if(flare_ == null)
				continue;
			if ((flare_.sunMode)&&(flare_.sunModeTransformA!=null)&&(flare_.sunModeTransformB!=null)){
					flare_.sunModeTransformA.position = GameCameraTrans.position;
					flare_.LensPosition = GameCamera.WorldToViewportPoint(flare_.sunModeTransformB.position);
			
					flare_.sunModeTransformA.rotation = flare_.thisTransform.rotation;
			}else
				flare_.LensPosition = GameCamera.WorldToViewportPoint(flare_.thisTransform.position);
			Vector3 LensPosition = flare_.LensPosition;
			bool isVisible = (LensPosition.z > 0f && LensPosition.x+flare_.OffScreenFadeDist > 0f && LensPosition.x-flare_.OffScreenFadeDist < 1f && LensPosition.y+flare_.OffScreenFadeDist > 0f && LensPosition.y-flare_.OffScreenFadeDist < 1f);
			flare_.isVisible = isVisible;
			//Profiler.EndSample();
			//Profiler.BeginSample("offScreen Fading");
			//Off Screen fading
			float offScreenFade = 1;
			if(!(LensPosition.x > 0f && LensPosition.x < 1f && LensPosition.y > 0f && LensPosition.y < 1f)){
				float offScreenNorm = 1f/flare_.OffScreenFadeDist;
				float xPos = 0;
				float yPos = 0;
				
				if(!(LensPosition.x > 0f && LensPosition.x < 1f))
					xPos = LensPosition.x > 0.5f ? LensPosition.x-1f : Mathf.Abs(LensPosition.x);
				
				if(!(LensPosition.y > 0f && LensPosition.y < 1f))
					yPos = LensPosition.y > 0.5f ? LensPosition.y-1f : Mathf.Abs(LensPosition.y);
				
				offScreenFade = Mathf.Clamp01( offScreenFade - (Mathf.Max(xPos,yPos))*offScreenNorm);
			}
	        
			
			//Profiler.EndSample();
			//Profiler.BeginSample("Dynamic Triggering");
			
			//Dynamic Triggering Center
			float centerBoost = 0;
			if(LensPosition.x > 0.5f-flare_.DynamicCenterRange && LensPosition.x < 0.5f+flare_.DynamicCenterRange && LensPosition.y > 0.5f-flare_.DynamicCenterRange && LensPosition.y < 0.5f+flare_.DynamicCenterRange){
				if(flare_.DynamicCenterRange > 0){
					float centerBoostNorm = 1/(flare_.DynamicCenterRange);
					centerBoost = 1-Mathf.Max(Mathf.Abs(LensPosition.x-0.5f),Mathf.Abs(LensPosition.y-0.5f))*centerBoostNorm;
				}
			}
		
			//Dynamic Triggering Edge
			float DynamicEdgeAmount = 0;
			
			bool isInEdgeZone1 = (
	                              LensPosition.x > 0f+flare_.DynamicEdgeBias+(flare_.DynamicEdgeRange) &&
	                              LensPosition.x < 1f-flare_.DynamicEdgeBias-(flare_.DynamicEdgeRange) &&
	                              LensPosition.y > 0f+flare_.DynamicEdgeBias+(flare_.DynamicEdgeRange) &&
	                              LensPosition.y < 1f-flare_.DynamicEdgeBias-(flare_.DynamicEdgeRange)
	                              );
			
			bool isInEdgeZone2 = (
	                              LensPosition.x+(flare_.DynamicEdgeRange) > 0f+flare_.DynamicEdgeBias &&
	                              LensPosition.x-(flare_.DynamicEdgeRange) < 1f-flare_.DynamicEdgeBias &&
	                              LensPosition.y+(flare_.DynamicEdgeRange) > 0f+flare_.DynamicEdgeBias &&
	                              LensPosition.y-(flare_.DynamicEdgeRange) < 1f-flare_.DynamicEdgeBias
	                              );
			
			if(!isInEdgeZone1&&isInEdgeZone2){
				
				float DynamicEdgeNormalizeValue = 1/(flare_.DynamicEdgeRange);
				float DynamicEdgeX = 0;
				float DynamicEdgeY = 0;
				
				bool isInEdgeZoneX1 = (LensPosition.x > 0f+flare_.DynamicEdgeBias+(flare_.DynamicEdgeRange) && LensPosition.x < 1f-flare_.DynamicEdgeBias-(flare_.DynamicEdgeRange));
				bool isInEdgeZoneX2 = (LensPosition.x+(flare_.DynamicEdgeRange) > 0f+flare_.DynamicEdgeBias && LensPosition.x-(flare_.DynamicEdgeRange) < 1f-flare_.DynamicEdgeBias);
				bool isInEdgeZoneY1 = (LensPosition.y > 0f+flare_.DynamicEdgeBias+(flare_.DynamicEdgeRange) && LensPosition.y < 1f-flare_.DynamicEdgeBias-(flare_.DynamicEdgeRange));
				bool isInEdgeZoneY2 = (LensPosition.y+(flare_.DynamicEdgeRange) > 0f+flare_.DynamicEdgeBias && LensPosition.y-(flare_.DynamicEdgeRange) < 1f-flare_.DynamicEdgeBias);
				
				if(!isInEdgeZoneX1&&isInEdgeZoneX2){
					DynamicEdgeX = LensPosition.x > 0.5f ? (LensPosition.x - 1 +flare_.DynamicEdgeBias) + (flare_.DynamicEdgeRange) : Mathf.Abs(LensPosition.x -flare_.DynamicEdgeBias - (flare_.DynamicEdgeRange));
	                
					DynamicEdgeX = (DynamicEdgeX*DynamicEdgeNormalizeValue)*0.5f;
				}
				
				if(!isInEdgeZoneY1&&isInEdgeZoneY2){
					DynamicEdgeY = LensPosition.y > 0.5f ? (LensPosition.y - 1 + flare_.DynamicEdgeBias) + (flare_.DynamicEdgeRange) : Mathf.Abs(LensPosition.y-flare_.DynamicEdgeBias - (flare_.DynamicEdgeRange));
					
					DynamicEdgeY = (DynamicEdgeY*DynamicEdgeNormalizeValue)*0.5f;
				}
				
				DynamicEdgeAmount = Mathf.Max(DynamicEdgeX,DynamicEdgeY);
			}
			
						
			DynamicEdgeAmount = flare_.DynamicEdgeCurve.Evaluate(DynamicEdgeAmount);
			
			//Profiler.EndSample();
			//Profiler.BeginSample("Angle Fall Off");
			
			
			/*
			float AngleFallOff = 1;
 
			 
			if(flare_.UseAngleLimit){
				Vector3 playerAngle = flare_.thisTransform.forward;
				
 
				Vector3 cameraAngle = GameCameraTrans.forward;
				
				float horizDiffAngle = Vector3.Angle(cameraAngle, playerAngle);
				
 
				horizDiffAngle = Mathf.Abs( Mathf.Clamp(180-horizDiffAngle,-flare_.maxAngle,flare_.maxAngle));
				
				AngleFallOff = 1f-(horizDiffAngle*(1f/(flare_.maxAngle*0.5f)));
				
				if(flare_.UseAngleCurve)
					AngleFallOff = flare_.AngleCurve.Evaluate(AngleFallOff);
			}*/
			
			float AngleFallOff = 1;
			
			if(flare_.UseAngleLimit){
				Vector3 playerAngle = flare_.thisTransform.forward;          
				//Vector3 cameraAngle = GameCameraTrans.forward;
				
				//the direct vector from flare point to camera point
				Vector3 camToPoint = GameCameraTrans.position - flare_.thisTransform.position;
				float horizDiffAngle = Vector3.Angle(playerAngle, camToPoint);
				
				horizDiffAngle = Mathf.Abs( Mathf.Clamp(horizDiffAngle,-flare_.maxAngle,flare_.maxAngle));
				
				if (horizDiffAngle > flare_.maxAngle)
					AngleFallOff = 0;
				else
				{
					AngleFallOff = 1f - (horizDiffAngle * (1f / (flare_.maxAngle * 0.5f)));
					if (flare_.UseAngleCurve)
						AngleFallOff = flare_.AngleCurve.Evaluate(AngleFallOff);
				}          
			}
			
			
			//Profiler.EndSample();
			//Profiler.BeginSample("Distance Check");
			
			float distanceFalloff = 1f;
			
			if(flare_.useMaxDistance){
				
				Vector3 heading  = flare_.thisTransform.position - GameCameraTrans.position;
				
				float distance = Vector3.Dot(heading, GameCameraTrans.forward);
				
				float distanceNormalised = 1f-(distance/flare_.GlobalMaxDistance);
				
				distanceFalloff =  1f*distanceNormalised;
				if(distanceFalloff < 0.001f)
					flare_.isVisible = false;
				
			}
			//Profiler.EndSample();
			//Profiler.BeginSample("Check Occlusion Data");
			if(!dirty)
				if(data != null){
					data.occlusionScale = Mathf.Lerp(data.occlusionScale,data.occlusionTarget,Time.deltaTime*flare_.occlusionScaleSpeed);
					data.occlusionBrigtness = Mathf.Lerp(data.occlusionBrigtness,data.occlusionTarget,Time.deltaTime*flare_.occlusionBrightnessSpeed);
				}
					//if(data.occluded){
					//data.occlusionScale = Mathf.Lerp(data.occlusionScale,data.occlusionTarget,Time.deltaTime*16);
					//}else{
					//data.occlusionScale = Mathf.Lerp(data.occlusionScale,data.occlusionTarget,Time.deltaTime*16);
					//}
			
			//Profiler.EndSample();
			//Profiler.BeginSample("Final Lens Pos Set");
			
//			Debug.Log("Visible = "+Flares[F].isVisible+" | offScreenFade "+offScreenFade);
//			Debug.Log("distanceFalloff "+distanceFalloff);
			
			if(!flare_.isVisible)
				offScreenFade = 0;
				
			float tempScale = 1;
			
		 	if(FlareCamera)
		 		helperTransform.position = FlareCamera.ViewportToWorldPoint(LensPosition);
			
		  	LensPosition = helperTransform.localPosition;
			
			//Profiler.EndSample();
			
			if((!VR_Mode) && (!SingleCamera_Mode))
			  	LensPosition.z = 0f;
	        
			float finalAlpha;
			
			//Profiler.BeginSample("Elements Loo[");
			for(int i = 0; i < flare_.Elements.Count; i++){
				ProFlareElement _element = flare_.Elements[i];
				Color GlobalColor = flare_.GlobalTintColor;
				if(isVisible)
					switch(_element.type){
						case(ProFlareElement.Type.Single):
							//Do the color stuff.
					
							_element.ElementFinalColor.r = (_element.ElementTint.r * GlobalColor.r);
						 	_element.ElementFinalColor.g = (_element.ElementTint.g * GlobalColor.g);
						 	_element.ElementFinalColor.b = (_element.ElementTint.b * GlobalColor.b);
	                        
							finalAlpha = _element.ElementTint.a * GlobalColor.a;
							
							if(flare_.useDynamicEdgeBoost){
								if(_element.OverrideDynamicEdgeBrightness)
									finalAlpha = finalAlpha + (_element.DynamicEdgeBrightnessOverride*DynamicEdgeAmount);
								else
									finalAlpha = finalAlpha + (flare_.DynamicEdgeBrightness*DynamicEdgeAmount);
							}
							
							if(flare_.useDynamicCenterBoost){
								if(_element.OverrideDynamicCenterBrightness)
	                                finalAlpha += (_element.DynamicCenterBrightnessOverride*centerBoost);
								else
	                                finalAlpha += (flare_.DynamicCenterBrightness*centerBoost);
	                        }
							
							if(flare_.UseAngleBrightness)
								finalAlpha *= AngleFallOff;
	                        
							if(flare_.useDistanceFade)
								finalAlpha *= distanceFalloff;
	                        
 							finalAlpha *= data.occlusionBrigtness;
							
							finalAlpha *= data.cullFader;
					
							finalAlpha *= offScreenFade;
												
							_element.ElementFinalColor.a = finalAlpha;
	                        
	                        break;
	                        
						case(ProFlareElement.Type.Multi):
					//Profiler.BeginSample("Color Mutli Loop");
							for(int i2 = 0; i2 < _element.subElements.Count; i2++){
	                            //Do the color stuff.
 								SubElement _subElement = _element.subElements[i2];
	                            _subElement.colorFinal.r = (_subElement.color.r * GlobalColor.r);
	                           	_subElement.colorFinal.g = (_subElement.color.g * GlobalColor.g);
	                            _subElement.colorFinal.b = (_subElement.color.b * GlobalColor.b);
	                            
	                            finalAlpha = _subElement.color.a * GlobalColor.a;
	                            
	                            if(flare_.useDynamicEdgeBoost){
	                                if(_element.OverrideDynamicEdgeBrightness)
	                                    finalAlpha = finalAlpha + (_element.DynamicEdgeBrightnessOverride*DynamicEdgeAmount);
	                                else
	                                    finalAlpha = finalAlpha + (flare_.DynamicEdgeBrightness*DynamicEdgeAmount);
	                            }
	                            
	                            if(flare_.useDynamicCenterBoost){
	                                if(_element.OverrideDynamicCenterBrightness)
	                                    finalAlpha += (_element.DynamicCenterBrightnessOverride*centerBoost);
	                                else
	                                    finalAlpha += (flare_.DynamicCenterBrightness*centerBoost);
	                            } 
	                            
	                            if(flare_.UseAngleBrightness)
	                                finalAlpha *= AngleFallOff;
	                            
	                            if(flare_.useDistanceFade)
	                                finalAlpha *= distanceFalloff;
	                            
								finalAlpha *= data.occlusionBrigtness;
						
								finalAlpha *= data.cullFader;
						
	                            finalAlpha *= offScreenFade;
	                            
 	                            _subElement.colorFinal.a = finalAlpha;
	                            
							}
					//Profiler.EndSample();
	                        break;
					}
				else{
					switch(_element.type){
						case(ProFlareElement.Type.Single):
						//	_element.ElementFinalColor = Color.black;
							tempScale = 0;
						break;
						case(ProFlareElement.Type.Multi):
						//	for(int i2 = 0; i2 < _element.subElements.Count; i2++){
						//		_element.subElements[i2].colorFinal = Color.black;
						//	}
							tempScale = 0;
						break;
					}
				}
	            
				//Element Scale
				float finalScale = tempScale;
				
				if(flare_.useDynamicEdgeBoost){
					if(_element.OverrideDynamicEdgeBoost)
						finalScale = finalScale+((DynamicEdgeAmount)*_element.DynamicEdgeBoostOverride);
					else
						finalScale = finalScale+((DynamicEdgeAmount)*flare_.DynamicEdgeBoost);
				}
				
				if(flare_.useDynamicCenterBoost){
					if(_element.OverrideDynamicCenterBoost)
						finalScale = finalScale+(_element.DynamicCenterBoostOverride*centerBoost);
					else
						finalScale = finalScale+(flare_.DynamicCenterBoost*centerBoost);
				}
				
				if(finalScale < 0) finalScale = 0;
				
				if(flare_.UseAngleScale)
					finalScale *= AngleFallOff;
				
				if(flare_.useDistanceScale)
					finalScale *= distanceFalloff;
				
				finalScale *= data.occlusionScale;
				
				if(!_element.Visible)
					finalScale = 0;
				
				if(!isVisible)
					finalScale = 0;
				
				_element.ScaleFinal = finalScale;
	            
				float angles = 0;
				//Apply final screen position.
				if(isVisible)
				switch(_element.type){
					case(ProFlareElement.Type.Single):{
						Vector3 pos = LensPosition*-_element.position;
						//Debug.Log(pos.magnitude);
						float zpos = LensPosition.z;
						
						if(VR_Mode){
							float flarePos = (_element.position*-1)-1; 
							zpos = LensPosition.z *((flarePos*VR_Depth)+1);
						} 
					
						Vector3 newVect = new Vector3(
	                                                  Mathf.Lerp(pos.x,LensPosition.x,_element.Anamorphic.x),
	                                                  Mathf.Lerp(pos.y,LensPosition.y,_element.Anamorphic.y),
													  zpos
	                                                  );
						
						newVect = newVect + _element.OffsetPostion;
						_element.OffsetPosition = newVect;
						 
						if(_element.rotateToFlare){
							angles =  (Div180_PI)*(Mathf.Atan2(LensPosition.y - _element.OffsetPosition.y,LensPosition.x - _element.OffsetPosition.x));
						}
					}break;
					case(ProFlareElement.Type.Multi):{
					//Profiler.BeginSample("Scale Mutli Loop");
						for(int i2 = 0; i2 < _element.subElements.Count; i2++){
							SubElement _subElement = _element.subElements[i2];
	                        if(_element.useRangeOffset){
								
	                            Vector3 posM = LensPosition*-_subElement.position;
								//Vector3 posM = new Vector3(
								//	LensPosition.x*-_subElement.position+(_subElement.offset.x*_subElement.random*0.5f),
								//	LensPosition.y*-_subElement.position+(_subElement.offset.y*_subElement.random*0.5f),
								//	LensPosition.z*-_subElement.position
								//	);
								
								float zpos = LensPosition.z;
								
								if(VR_Mode){
									float  flarePos = (_subElement.position*-1)-1;	 
									zpos = LensPosition.z *((flarePos*VR_Depth)+1);
								}
							
	                            Vector3 newVectM = new Vector3(
	                                                           Mathf.Lerp(posM.x,LensPosition.x,_element.Anamorphic.x),
															   Mathf.Lerp(posM.y,LensPosition.y,_element.Anamorphic.y),
															   zpos
	                                                           );
	                            
	                            newVectM = newVectM + _element.OffsetPostion;
	                            
								_subElement.offset = newVectM;
								
								if(_element.rotateToFlare)
									_subElement.angle = (Div180_PI)*(Mathf.Atan2(LensPosition.y - _subElement.offset.y,LensPosition.x - _subElement.offset.x));
 								
	                        }
	                        else
	                            _subElement.offset = LensPosition*-_element.position;
						}
						//Profiler.EndSample();
						}break;
				}
				
				//Apply final element angle.
				//float angles = 0;
				//if(_element.rotateToFlare){
				//	angles =  (Div180_PI)*(Mathf.Atan2(LensPosition.y - 0,LensPosition.x - 0));
				//}
				angles = angles + (LensPosition.x*_element.rotationSpeed);
				
				angles = angles + (LensPosition.y*_element.rotationSpeed);
				
				angles = angles + (Time.time*_element.rotationOverTime);
				
				_element.FinalAngle = (_element.angle)+angles;
				
				
			}
			//Profiler.EndSample();
			
			
			
			if((!flare_.neverCull)&&useCulling){
				FlareOcclusion.CullingState _CullingState = data._CullingState;
				 
				if(flare_.isVisible){
					visibleFlares++;
					
					
					if(data.occluded){
						if(_CullingState == FlareOcclusion.CullingState.Visible){
							//Debug.Log("Culled via Occlusion");
							data.CullTimer = cullFlaresAfterTime;
							_CullingState = FlareOcclusion.CullingState.CullCountDown;
						}
					}else{
 						if(_CullingState == FlareOcclusion.CullingState.Culled){
							//Debug.Log("Re show not occluded");
							culledFlaresNowVisiable = true;
							
						}
						_CullingState = FlareOcclusion.CullingState.Visible;
					}
					
						
				}else{
					if(_CullingState == FlareOcclusion.CullingState.Visible){
						//Debug.Log("Culled via Not Vis");
						data.CullTimer = cullFlaresAfterTime;
						_CullingState = FlareOcclusion.CullingState.CullCountDown;
					}
				}
				
				switch(_CullingState){
					case(FlareOcclusion.CullingState.Visible):{
					
						
					}break;
					case(FlareOcclusion.CullingState.CullCountDown):{
						
						data.CullTimer = data.CullTimer-Time.deltaTime;
						
						if(data.CullTimer < 0)
							_CullingState = FlareOcclusion.CullingState.CanCull;
						
					}break;
				}
				
				if(_CullingState != FlareOcclusion.CullingState.Culled)
					data.cullFader = Mathf.Clamp01(data.cullFader+(Time.deltaTime));
	
				
				if(_CullingState == FlareOcclusion.CullingState.CanCull)
					canCullFlares++;
				
				data._CullingState = _CullingState;
				
			}
		 
			reshowCulledFlaresTimer += Time.deltaTime;
			
			if(reshowCulledFlaresTimer > reshowCulledFlaresAfter){
				reshowCulledFlaresTimer = 0;
				
				if(culledFlaresNowVisiable){
					//Debug.Log("A culled flare has now become visiable");
					dirty = true;
					culledFlaresNowVisiable = false;
					
				}
			}
			
			if(!dirty)
				if(canCullFlares >= cullFlaresAfterCount){
					
					Debug.Log("Culling Flares");dirty = true;	
				}
		}
		
		//Profiler.BeginSample("Rendering Bit");
		//Rendering Bit
		int count = 0;
		if(FlareElementsArray != null)
		for(int i = 0; i < FlareElementsArray.Length; i++){
			
			
			float scaleMulti = 1;
			ProFlare flare = FlareElementsArray[i].flare;
			if(flare.MultiplyScaleByTransformScale)
				scaleMulti = flare.thisTransform.localScale.x;
			
			
			switch(FlareElementsArray[i].type){
				case(ProFlareElement.Type.Single):
				{
					int extra = (count) * 4;
					
					//Check for DisabledPlayMode, then scale to zero. then skip over the rest of the calculations
					if(FlareElementsArray[i].flare.DisabledPlayMode){
					
						vertices[0+extra] = Vector3.zero;
						vertices[1+extra] = Vector3.zero;
						vertices[2+extra] = Vector3.zero;
						vertices[3+extra] = Vector3.zero;
						
					}
					
					_scale = (((FlareElementsArray[i].size*FlareElementsArray[i].Scale*0.01f)*flare.GlobalScale)*FlareElementsArray[i].ScaleFinal)*scaleMulti;
					
					//Avoid Negative scaling
					if((_scale.x < 0)||(_scale.y < 0))
                        _scale = Vector3.zero;
					
					Vector3 offset = FlareElementsArray[i].OffsetPosition;
					
					float angle = FlareElementsArray[i].FinalAngle;
					
					_color = FlareElementsArray[i].ElementFinalColor;
					
					if(useBrightnessThreshold){
                        
						if(_color.a < BrightnessThreshold){
							_scale = Vector2.zero;
						}else if(_color.r+_color.g+_color.b < BrightnessThreshold){
							_scale = Vector2.zero;
						}
					}
					
					if(overdrawDebug)
						_color = new Color32(20,20,20,100);
					
					if(!FlareElementsArray[i].flare.DisabledPlayMode){
						//Precalculate some of the RotatePoint function to avoid repeat math.
						float r = angle * (PI_Div180);
						float ct = Mathf.Cos(r);
						float st = Mathf.Sin(r);
                      
						vertices[0+extra] = new Vector3((ct * (1*_scale.x) - st * (1*_scale.y)),(st * (1*_scale.x) + ct * (1*_scale.y)),0)+offset;
						vertices[1+extra] = new Vector3((ct * (1*_scale.x) - st * (-1*_scale.y)),(st * (1*_scale.x) + ct * (-1*_scale.y)),0)+offset;
						vertices[2+extra] = new Vector3((ct * (-1*_scale.x) - st * (1*_scale.y)),(st * (-1*_scale.x) + ct * (1*_scale.y)),0)+offset;
						vertices[3+extra] = new Vector3((ct * (-1*_scale.x) - st * (-1*_scale.y)),(st * (-1*_scale.x) + ct * (-1*_scale.y)),0)+offset;
					
					
					}
				
					Color32 _color32 = _color;
					colors[0+extra] = _color32;
					colors[1+extra] = _color32; 
					colors[2+extra] = _color32; 
					colors[3+extra] = _color32;
					
                    count++;
				}
                    break;
                    
				case(ProFlareElement.Type.Multi):
				{
					for(int i2 = 0; i2 < FlareElementsArray[i].subElements.Count; i2++){
						int extra2 = (count+i2) * 4;
                        
						//Check for DisabledPlayMode, then scale to zero. then skip over the rest of the calculations
                        if(FlareElementsArray[i].flare.DisabledPlayMode){
							vertices[0+extra2] = Vector3.zero;
							vertices[1+extra2] = Vector3.zero;
							vertices[2+extra2] = Vector3.zero;
							vertices[3+extra2] = Vector3.zero;
							continue;
						}
                        
                        ////Profiler.BeginSample("Calc Scale");
						_scale = (((FlareElementsArray[i].size*FlareElementsArray[i].Scale*0.01f)*FlareElementsArray[i].flare.GlobalScale)*FlareElementsArray[i].subElements[i2].scale)*FlareElementsArray[i].ScaleFinal;
						//Avoid Negative scaling
					
						_scale = _scale*scaleMulti;
						if((_scale.x < 0)||(_scale.y < 0))
							_scale = Vector3.zero;
						////Profiler.EndSample();
					
						////Profiler.BeginSample("Calc Extras");
						Vector3 offset = FlareElementsArray[i].subElements[i2].offset;
                        
						float angle = FlareElementsArray[i].FinalAngle;
						
						//angle = 0;
						angle += FlareElementsArray[i].subElements[i2].angle;
						
						_color = FlareElementsArray[i].subElements[i2].colorFinal;
                        
						if(useBrightnessThreshold){
							if(_color.a < BrightnessThreshold){
								_scale = Vector2.zero;
							}else if(_color.r+_color.g+_color.b < BrightnessThreshold){
								_scale = Vector2.zero;
							}
						}
                        
						if(overdrawDebug)
							_color = new Color32(20,20,20,100);
                       // //Profiler.EndSample();
						////Profiler.BeginSample("Set Pos and Rot");
						if(!FlareElementsArray[i].flare.DisabledPlayMode){
                            
							//Precalculate some of the RotatePoint function to avoid repeat math.
							float r = angle * (PI_Div180);
							float ct = Mathf.Cos(r);
							float st = Mathf.Sin(r);
						
							vertices[0+extra2] = new Vector3((ct * (1*_scale.x) - st * (1*_scale.y)),(st * (1*_scale.x) + ct * (1*_scale.y)),0)+offset;
							vertices[1+extra2] = new Vector3((ct * (1*_scale.x) - st * (-1*_scale.y)),(st * (1*_scale.x) + ct * (-1*_scale.y)),0)+offset;
							vertices[2+extra2] = new Vector3((ct * (-1*_scale.x) - st * (1*_scale.y)),(st * (-1*_scale.x) + ct * (1*_scale.y)),0)+offset;
							vertices[3+extra2] = new Vector3((ct * (-1*_scale.x) - st * (-1*_scale.y)),(st * (-1*_scale.x) + ct * (-1*_scale.y)),0)+offset;
							
						}
						////Profiler.EndSample();
						////Profiler.BeginSample("SetColors");
						 
							Color32 _color32 = _color;
							colors[0+extra2] = _color32;
							colors[1+extra2] = _color32;
							colors[2+extra2] = _color32;
							colors[3+extra2] = _color32;
 						////Profiler.EndSample();
					}
					count = count+FlareElementsArray[i].subElements.Count;
				}
                break;
			}
		}
		
		//Profiler.EndSample();
//		Debug.Log("updare Done");
    }
}