diff options
Diffstat (limited to 'Assets/ProFlares/Scripts/ProFlareBatch.cs')
-rw-r--r-- | Assets/ProFlares/Scripts/ProFlareBatch.cs | 1318 |
1 files changed, 1318 insertions, 0 deletions
diff --git a/Assets/ProFlares/Scripts/ProFlareBatch.cs b/Assets/ProFlares/Scripts/ProFlareBatch.cs new file mode 100644 index 0000000..3063111 --- /dev/null +++ b/Assets/ProFlares/Scripts/ProFlareBatch.cs @@ -0,0 +1,1318 @@ +/// ProFlares - v1.08 - Copyright 2014-2015 All rights reserved - ProFlares.com + +/// <summary> +/// ProFlareBatch.cs +/// Processes all the ProFlares in a scene, converts them into geometry that can be rendered. +/// </summary> + +using UnityEngine; +using System.Collections; +using System.Collections.Generic; + + + +[System.Serializable] +public class FlareData { + public ProFlare flare; + public FlareOcclusion occlusion; +} + +[System.Serializable] +public class FlareOcclusion { + public bool occluded = false; + public float occlusionScale = 1; + + public CullingState _CullingState; + public float CullTimer = 0; + public float cullFader = 1; + + public enum CullingState{ + Visible, + CullCountDown, + CanCull, + Culled, + NeverCull + } +} + +[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<ProFlare> Flares = new List<ProFlare>(); + + public List<FlareData> FlaresList = new List<FlareData>(); + + //List of FlareElements + + public List<ProFlareElement> FlareElements = new List<ProFlareElement>(); + 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; + + //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; + + void Reset(){ + if(helperTransform == null) + CreateHelperTransform(); + + + mat = new Material(Shader.Find("ProFlares/Textured Flare Shader")); + + if(meshFilter == null) + meshFilter = GetComponent<MeshFilter>(); + + if(meshFilter == null) + meshFilter = gameObject.AddComponent<MeshFilter>(); + + meshRender = gameObject.GetComponent<MeshRenderer>(); + + if(meshRender == null) + meshRender = gameObject.AddComponent<MeshRenderer>(); + + + if(FlareCamera == null){ + FlareCamera = transform.root.GetComponentInChildren<Camera>(); + } + + 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]); + } + + } + + void Start () { + //Turn off overdraw debug mode. + if(Application.isPlaying){ + overdrawDebug = false; + //dirty = true; + } + + if(GameCamera == null){ + GameObject GameCameraGo = GameObject.FindWithTag("MainCamera"); + +#if UNITY_5 + if(GameCameraGo) + if(GameCameraGo.GetComponent<Camera>()) + GameCamera = GameCameraGo.GetComponent<Camera>(); + +#else + if(GameCameraGo) + if(GameCameraGo.GetComponent<Camera>()) + GameCamera = GameCameraGo.GetComponent<Camera>(); +#endif + } + + if(GameCamera) + GameCameraTrans = GameCamera.transform; + + //Make sure we have the transform cached + thisTransform = transform; + + SetupMeshes(); + + } + + void CreateMat(){ +// Debug.LogError("CreateMat"); + mat = new Material(Shader.Find("ProFlares/Textured Flare Shader")); + 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){ + if(FlaresList[F].occlusion.occluded) + FlaresList[F].occlusion.occlusionScale = 0; + + } + } + + } + + 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; + + 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_); + + + dirty = true; + } + } + + void CreateHelperTransform(){ + + GameObject HelpTransformGo = new GameObject("_HelperTransform"); + + helperTransform = HelpTransformGo.transform; + helperTransform.parent = transform; + helperTransform.localScale = Vector3.one; + helperTransform.localPosition = Vector3.zero; + } + + void Update(){ + + 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<MeshRenderer>(); + + 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"); + + 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 FixedUpdate(){ + + + 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; + + + if(flare_.RaycastPhysics){ + + RaycastHit hit; + + Vector3 direction = GameCameraTrans.position-flare_.thisTransform.position; + + float distanceRay = Vector3.Distance(GameCameraTrans.position,flare_.thisTransform.position); + + data.occluded = true; + + if(flare_.isVisible){ + + Ray ray = new Ray(flare_.thisTransform.position,direction); + + if (Physics.Raycast(ray, out hit,distanceRay,flare_.mask)){ + + //Flares[F].Occluded = true; + + data.occluded = true; + + #if UNITY_EDITOR + Debug.DrawRay(flare_.thisTransform.position,direction,Color.red); + + flare_.OccludingObject = hit.collider.gameObject; + #endif + }else{ + data.occluded = false; + + #if UNITY_EDITOR + flare_.OccludingObject = null; + + + Debug.DrawRay(flare_.thisTransform.position,direction); + #endif + } + } + } + } + } + + + + 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; + +// Debug.Log("UpdateGeometry"); + + + flare_.LensPosition = GameCamera.WorldToViewportPoint(flare_.thisTransform.position); + + Vector3 LensPosition = flare_.LensPosition; + + //LensPosition = new Vector3(Random.Range(-1f,1f),Random.Range(-1f,1f),Random.Range(-1f,1f)); + + 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) + if(data.occluded){ + + data.occlusionScale = Mathf.Lerp(data.occlusionScale,0,Time.deltaTime*16); + }else{ + data.occlusionScale = Mathf.Lerp(data.occlusionScale,1,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.occlusionScale; + + 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.occlusionScale; + + 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; + + + //Apply final screen position. + if(isVisible) + switch(_element.type){ + case(ProFlareElement.Type.Single):{ + Vector3 pos = LensPosition*-_element.position; + + + 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; + + }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; + + + 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; + + + } + 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 += 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"); + } +}
\ No newline at end of file |