public void registerGeometry(FS_ShadowSimple s, FS_MeshKey meshKey){
		FS_ShadowManagerMesh m;
		if (meshKey.isStatic){
			if (!shadowMeshesStatic.ContainsKey(meshKey)){
				GameObject g = new GameObject("ShadowMeshStatic_" + meshKey.mat.name);
				g.transform.parent = transform;
				m = g.AddComponent<FS_ShadowManagerMesh>();
				m.shadowMaterial = s.shadowMaterial;
				m.isStatic = true;
				shadowMeshesStatic.Add(meshKey,m);				
			} else {
				m = (FS_ShadowManagerMesh) shadowMeshesStatic[meshKey];	
			}
		} else {
			if (!shadowMeshes.ContainsKey(meshKey)){
				GameObject g = new GameObject("ShadowMesh_" + meshKey.mat.name);
				g.transform.parent = transform;
				m = g.AddComponent<FS_ShadowManagerMesh>();
				m.shadowMaterial = s.shadowMaterial;
				m.isStatic = false;
				shadowMeshes.Add(meshKey,m);
			} else {
				m = (FS_ShadowManagerMesh) shadowMeshes[meshKey];	
			}
		}
		m.registerGeometry(s);		
	}
예제 #2
0
 void Update()
 {
     if (_isStatic != isStatic)
     {
         if (isStatic == true)              //becoming static
         {
             meshKey = new FS_MeshKey(shadowMaterial, isStatic);
             CalculateShadowGeometry();
             FS_ShadowManager.Manager().RecalculateStaticGeometry(null, meshKey);
         }
         else                 //becoming dynamic
         {
             FS_MeshKey oldMeshKey = meshKey;
             meshKey = new FS_MeshKey(shadowMaterial, isStatic);
             FS_ShadowManager.Manager().RecalculateStaticGeometry(this, oldMeshKey);
         }
         _isStatic = isStatic;
     }
     if (!isStatic)
     {
         UnityEngine.Profiling.Profiler.BeginSample("CalculateShadowGeometry");
         CalculateShadowGeometry();
         UnityEngine.Profiling.Profiler.EndSample();
     }
 }
예제 #3
0
    public override bool Equals(object obj)
    {
        if (!(obj is FS_MeshKey))
        {
            return(false);
        }
        FS_MeshKey fS_MeshKey = (FS_MeshKey)obj;

        return(fS_MeshKey.isStatic == this.isStatic && fS_MeshKey.mat == this.mat);
    }
예제 #4
0
 public void RecalculateStaticGeometry(FS_ShadowSimple removeShadow, FS_MeshKey meshKey)
 {
     if (shadowMeshesStatic.ContainsKey(meshKey.mat))
     {
         FS_ShadowManagerMesh sm = shadowMeshesStatic[meshKey.mat] as FS_ShadowManagerMesh;
         if (removeShadow != null)
         {
             sm.removeShadow(removeShadow);
         }
         sm.recreateStaticGeometry();
     }
 }
예제 #5
0
 public void RecalculateStaticGeometry(FS_ShadowSimple removeShadow, FS_MeshKey meshKey)
 {
     if (this.shadowMeshesStatic.ContainsKey(meshKey.mat))
     {
         FS_ShadowManagerMesh fS_ShadowManagerMesh = this.shadowMeshesStatic[meshKey.mat];
         if (removeShadow != null)
         {
             fS_ShadowManagerMesh.removeShadow(removeShadow);
         }
         fS_ShadowManagerMesh.recreateStaticGeometry();
     }
 }
 public override bool Equals(object obj)
 {
     if (!(obj is FS_MeshKey))
     {
         return(false);
     }
     else
     {
         FS_MeshKey mk = (FS_MeshKey)obj;
         if (mk.isStatic == isStatic && mk.mat == mat)
         {
             return(true);
         }
     }
     return(false);
 }
예제 #7
0
    public void registerGeometry(FS_ShadowSimple s, FS_MeshKey meshKey)
    {
        FS_ShadowManagerMesh fS_ShadowManagerMesh;

        if (meshKey.isStatic)
        {
            if (!this.shadowMeshesStatic.ContainsKey(meshKey.mat))
            {
                fS_ShadowManagerMesh = new GameObject("ShadowMeshStatic_" + meshKey.mat.name)
                {
                    transform =
                    {
                        parent = base.transform
                    }
                }.AddComponent <FS_ShadowManagerMesh>();
                fS_ShadowManagerMesh.shadowMaterial = s.shadowMaterial;
                fS_ShadowManagerMesh.isStatic       = true;
                this.shadowMeshesStatic.Add(meshKey.mat, fS_ShadowManagerMesh);
            }
            else
            {
                fS_ShadowManagerMesh = this.shadowMeshesStatic[meshKey.mat];
            }
        }
        else if (!this.shadowMeshes.ContainsKey(meshKey.mat))
        {
            fS_ShadowManagerMesh = new GameObject("ShadowMesh_" + meshKey.mat.name)
            {
                transform =
                {
                    parent = base.transform
                }
            }.AddComponent <FS_ShadowManagerMesh>();
            fS_ShadowManagerMesh.shadowMaterial = s.shadowMaterial;
            fS_ShadowManagerMesh.isStatic       = false;
            this.shadowMeshes.Add(meshKey.mat, fS_ShadowManagerMesh);
        }
        else
        {
            fS_ShadowManagerMesh = this.shadowMeshes[meshKey.mat];
        }
        fS_ShadowManagerMesh.registerGeometry(s);
    }
예제 #8
0
    public void registerGeometry(FS_ShadowSimple s, FS_MeshKey meshKey)
    {
        FS_ShadowManagerMesh m;

        if (meshKey.isStatic)
        {
            if (!shadowMeshesStatic.ContainsKey(meshKey.mat))
            {
                GameObject g = new GameObject("ShadowMeshStatic_" + meshKey.mat.name);
                g.transform.parent = transform;
                m = g.AddComponent <FS_ShadowManagerMesh>();
                m.shadowMaterial = s.shadowMaterial;
                m.isStatic       = true;
                shadowMeshesStatic.Add(meshKey.mat, m);
            }
            else
            {
                m = (FS_ShadowManagerMesh)shadowMeshesStatic[meshKey.mat];
            }
        }
        else
        {
            if (!shadowMeshes.ContainsKey(meshKey.mat))
            {
                GameObject g = new GameObject("ShadowMesh_" + meshKey.mat.name);
                g.transform.parent = transform;
                m = g.AddComponent <FS_ShadowManagerMesh>();
                m.shadowMaterial = s.shadowMaterial;
                m.isStatic       = false;
                shadowMeshes.Add(meshKey.mat, m);
            }
            else
            {
                m = (FS_ShadowManagerMesh)shadowMeshes[meshKey.mat];
            }
        }
        m.registerGeometry(s);
    }
예제 #9
0
 void Update()
 {
     if (_isStatic != isStatic)
     {
         if (isStatic == true)              //becoming static
         {
             meshKey = new FS_MeshKey(shadowMaterial, isStatic);
             CalculateShadowGeometry();
             FS_ShadowManager.Manager().RecalculateStaticGeometry(null, meshKey);
         }
         else                 //becoming dynamic
         {
             FS_MeshKey oldMeshKey = meshKey;
             meshKey = new FS_MeshKey(shadowMaterial, isStatic);
             FS_ShadowManager.Manager().RecalculateStaticGeometry(this, oldMeshKey);
         }
         _isStatic = isStatic;
     }
     if (!isStatic)
     {
         CalculateShadowGeometry();
     }
 }
예제 #10
0
 private void Update()
 {
     if (this._isStatic != this.isStatic)
     {
         if (this.isStatic)
         {
             this.meshKey = new FS_MeshKey(this.shadowMaterial, this.isStatic);
             this.CalculateShadowGeometry();
             FS_ShadowManager.Manager().RecalculateStaticGeometry(null, this.meshKey);
         }
         else
         {
             FS_MeshKey fS_MeshKey = this.meshKey;
             this.meshKey = new FS_MeshKey(this.shadowMaterial, this.isStatic);
             FS_ShadowManager.Manager().RecalculateStaticGeometry(this, fS_MeshKey);
         }
         this._isStatic = this.isStatic;
     }
     if (!this.isStatic)
     {
         this.CalculateShadowGeometry();
     }
 }
예제 #11
0
    public void RecalculateStaticGeometry(FS_ShadowSimple removeShadow)
    {
        FS_MeshKey mk = new FS_MeshKey(removeShadow.shadowMaterial, true);

        RecalculateStaticGeometry(removeShadow, mk);
    }
예제 #12
0
    public void CalculateShadowGeometry()
    {
        Vector3 proj;

        if (shadowMaterial == null)
        {
            return;
        }

        if (useLightSource && lightSource == null)
        {
            useLightSource = false;
            Debug.LogWarning("No light source object given using light direction vector.");
        }
        if (useLightSource)
        {
            Vector3 ls  = transform.position - lightSource.transform.position;
            float   mag = ls.magnitude;
            if (mag != 0f)
            {
                lightDirection = ls / mag;
            }
            else
            {
                return;                 //object is on top of light source
            }
        }
        else if (lightDirection != _lightDirection || lightDirection == Vector3.zero)            //light direction is dirty
        {
            if (lightDirection == Vector3.zero)
            {
                Debug.LogWarning("Light Direction vector cannot be zero. assuming -y.");
                lightDirection = -Vector3.up;
            }
            lightDirection.Normalize();
            _lightDirection = lightDirection;
        }

        if (shadowCaster == null || girth != _girth)
        {
            if (shadowCaster == null)
            {
                shadowCaster = new GameObject("shadowSimple");
                cornerGOs    = new GameObject[4];
                for (int i = 0; i < 4; i++)
                {
                    GameObject c = cornerGOs[i] = new GameObject("c" + i);
                    c.transform.parent = shadowCaster.transform;
                }
                shadowCaster.transform.parent        = transform;
                shadowCaster.transform.localPosition = shadowpostion;

                shadowCaster.transform.localRotation = Quaternion.identity;
                shadowCaster.transform.localScale    = Vector3.one;
            }
            if (Mathf.Abs(Vector3.Dot(transform.forward, lightDirection)) < .9f)
            {
                proj = transform.forward - Vector3.Dot(transform.forward, lightDirection) * lightDirection;
            }
            else
            {
                proj = transform.up - Vector3.Dot(transform.up, lightDirection) * lightDirection;
            }
            shadowCaster.transform.rotation = Quaternion.LookRotation(proj, -lightDirection);
            cornerGOs[0].transform.position = shadowCaster.transform.position + girth * (shadowCaster.transform.forward - shadowCaster.transform.right);
            cornerGOs[1].transform.position = shadowCaster.transform.position + girth * (shadowCaster.transform.forward + shadowCaster.transform.right);
            cornerGOs[2].transform.position = shadowCaster.transform.position + girth * (-shadowCaster.transform.forward + shadowCaster.transform.right);
            cornerGOs[3].transform.position = shadowCaster.transform.position + girth * (-shadowCaster.transform.forward - shadowCaster.transform.right);
            _girth = girth;
        }
        Transform t = shadowCaster.transform;

        r.origin    = t.position;
        r.direction = lightDirection;

        if (maxProjectionDistance > 0f && Physics.Raycast(r, out rh, maxProjectionDistance, layerMask))
        {
            if (doVisibilityCulling && !isPerspectiveProjection)
            {
                Plane[] camPlanes = FS_ShadowManager.Manager().getCameraFustrumPlanes();
                bounds.center = rh.point;
                bounds.size   = new Vector3(2f * girth, 2f * girth, 2f * girth);
                if (!GeometryUtility.TestPlanesAABB(camPlanes, bounds))
                {
                    return;
                }
            }

            // Rotate Shadowcaster
            //project forward or up vector onto a plane whos normal is lightDirection
            if (Mathf.Abs(Vector3.Dot(transform.forward, lightDirection)) < .9f)
            {
                proj = transform.forward - Vector3.Dot(transform.forward, lightDirection) * lightDirection;
            }
            else
            {
                proj = transform.up - Vector3.Dot(transform.up, lightDirection) * lightDirection;
            }
            shadowCaster.transform.rotation = Quaternion.Lerp(shadowCaster.transform.rotation, Quaternion.LookRotation(proj, -lightDirection), .01f);

            float alpha;
            float dist = rh.distance - shadowHoverHeight;
            alpha = 1.0f - dist / maxProjectionDistance;
            if (alpha < 0f)
            {
                return;
            }
            alpha    = Mathf.Clamp01(alpha);
            _color.a = alpha;

            _normal = rh.normal;
            Vector3 hitPoint = rh.point - shadowHoverHeight * lightDirection;
            shadowPlane.SetNormalAndPosition(_normal, hitPoint);

            isGoodPlaneIntersect = true;

            float rayDist = 0f;
            float mag     = 0f;
            if (useLightSource && isPerspectiveProjection)
            {
                r.origin = lightSource.transform.position;
                Vector3 lightSource2Corner = cornerGOs[0].transform.position - lightSource.transform.position;
                mag                  = lightSource2Corner.magnitude;
                r.direction          = lightSource2Corner / mag;
                isGoodPlaneIntersect = isGoodPlaneIntersect && shadowPlane.Raycast(r, out rayDist);
                _corners[0]          = r.origin + r.direction * rayDist;

                lightSource2Corner   = cornerGOs[1].transform.position - lightSource.transform.position;
                r.direction          = lightSource2Corner / mag;
                isGoodPlaneIntersect = isGoodPlaneIntersect && shadowPlane.Raycast(r, out rayDist);
                _corners[1]          = r.origin + r.direction * rayDist;

                lightSource2Corner   = cornerGOs[2].transform.position - lightSource.transform.position;
                r.direction          = lightSource2Corner / mag;
                isGoodPlaneIntersect = isGoodPlaneIntersect && shadowPlane.Raycast(r, out rayDist);
                _corners[2]          = r.origin + r.direction * rayDist;

                lightSource2Corner   = cornerGOs[3].transform.position - lightSource.transform.position;
                r.direction          = lightSource2Corner / mag;
                isGoodPlaneIntersect = isGoodPlaneIntersect && shadowPlane.Raycast(r, out rayDist);
                _corners[3]          = r.origin + r.direction * rayDist;
                if (doVisibilityCulling)
                {
                    Plane[] camPlanes = FS_ShadowManager.Manager().getCameraFustrumPlanes();
                    bounds.center = rh.point;
                    bounds.size   = Vector3.zero;
                    bounds.Encapsulate(_corners[0]);
                    bounds.Encapsulate(_corners[1]);
                    bounds.Encapsulate(_corners[2]);
                    bounds.Encapsulate(_corners[3]);
                    if (!GeometryUtility.TestPlanesAABB(camPlanes, bounds))
                    {
                        return;
                    }
                }
            }
            else
            {
                //r.origin = cornerGOs[0].transform.position;
                //isGoodPlaneIntersect = shadowPlane.Raycast(r, out rayDist);
                //if (isGoodPlaneIntersect == false && rayDist == 0f)
                //    return;
                //else
                //    isGoodPlaneIntersect = true;
                //_corners[0] = r.origin + r.direction * rayDist;

                //r.origin = cornerGOs[1].transform.position;
                //isGoodPlaneIntersect = shadowPlane.Raycast(r, out rayDist);
                //if (isGoodPlaneIntersect == false && rayDist == 0f)
                //    return;
                //else
                //    isGoodPlaneIntersect = true;
                //_corners[1] = r.origin + r.direction * rayDist;

                //r.origin = cornerGOs[2].transform.position;
                //isGoodPlaneIntersect = shadowPlane.Raycast(r, out rayDist);
                //if (isGoodPlaneIntersect == false && rayDist == 0f)
                //    return;
                //else
                //    isGoodPlaneIntersect = true;
                //_corners[2] = r.origin + r.direction * rayDist;

                //r.origin = cornerGOs[3].transform.position;
                //isGoodPlaneIntersect = shadowPlane.Raycast(r, out rayDist);
                //if (isGoodPlaneIntersect == false && rayDist == 0f)
                //    return;
                //else
                //    isGoodPlaneIntersect = true;
                //_corners[3] = r.origin + r.direction * rayDist;

                r.origin    = cornerGOs[0].transform.position;
                _corners[0] = r.origin;
                r.origin    = cornerGOs[1].transform.position;
                _corners[1] = r.origin;
                r.origin    = cornerGOs[2].transform.position;
                _corners[2] = r.origin;
                r.origin    = cornerGOs[3].transform.position;
                _corners[3] = r.origin;
            }

            if (isGoodPlaneIntersect)
            {
                if (meshKey == null || meshKey.mat != shadowMaterial || meshKey.isStatic != isStatic)
                {
                    meshKey = new FS_MeshKey(shadowMaterial, isStatic);
                }
                FS_ShadowManager.Manager().registerGeometry(this, meshKey);
                gizmoColor = Color.white;
            }
            else
            {
                gizmoColor = Color.magenta;
            }
        }
        else
        {
            isGoodPlaneIntersect = false;
            gizmoColor           = Color.red;
        }
    }
예제 #13
0
	void CalculateShadowGeometry(){
		Vector3 proj;
		if (shadowMaterial == null){
			return;
		}
		
		if (useLightSource && lightSource == null){
			useLightSource = false;
			Debug.LogWarning("No light source object given using light direction vector.");
		}
		if (useLightSource){
			Vector3 ls = transform.position - lightSource.transform.position;
			float mag = ls.magnitude;
			if (mag != 0f){
				lightDirection = ls / mag;
			} else {
				return; //object is on top of light source	
			}
		} else if (lightDirection != _lightDirection || lightDirection == Vector3.zero){ //light direction is dirty
			if (lightDirection == Vector3.zero){
				Debug.LogWarning("Light Direction vector cannot be zero. assuming -y.");
				lightDirection = -Vector3.up;
			}
			lightDirection.Normalize();	
			_lightDirection = lightDirection;
		}
		
		if (shadowCaster == null || girth != _girth){
			if (shadowCaster == null){
				shadowCaster = new GameObject("shadowSimple");
				cornerGOs = new GameObject[4];
				for (int i = 0; i < 4; i++){
					GameObject c = cornerGOs[i] = new GameObject("c" + i);	
					c.transform.parent = shadowCaster.transform;
				}
				shadowCaster.transform.parent = transform;		
				shadowCaster.transform.localPosition = Vector3.zero;
				shadowCaster.transform.localRotation = Quaternion.identity;
				shadowCaster.transform.localScale = Vector3.one;
			}
			if (Mathf.Abs(Vector3.Dot(transform.forward, lightDirection)) < .9f){
				proj = transform.forward - Vector3.Dot(transform.forward, lightDirection) * lightDirection; 
			} else {
				proj = transform.up - Vector3.Dot(transform.up, lightDirection) * lightDirection;
			}
			shadowCaster.transform.rotation = Quaternion.LookRotation(proj, -lightDirection);			
			cornerGOs[0].transform.position =  shadowCaster.transform.position + girth * (shadowCaster.transform.forward - shadowCaster.transform.right);
			cornerGOs[1].transform.position =  shadowCaster.transform.position + girth * (shadowCaster.transform.forward + shadowCaster.transform.right);
			cornerGOs[2].transform.position =  shadowCaster.transform.position + girth * (-shadowCaster.transform.forward + shadowCaster.transform.right);
			cornerGOs[3].transform.position =  shadowCaster.transform.position + girth * (-shadowCaster.transform.forward - shadowCaster.transform.right);						
			_girth = girth;
		}		
		Transform t = shadowCaster.transform;		
		
		r.origin = t.position;
		r.direction = lightDirection;
		
		if (maxProjectionDistance > 0f && Physics.Raycast(r, out rh, maxProjectionDistance, layerMask)){
			if (doVisibilityCulling && !isPerspectiveProjection){
				Plane[] camPlanes = FS_ShadowManager.Manager().getCameraFustrumPlanes();
				bounds.center = rh.point;
				bounds.size = new Vector3(2f*girth,2f*girth,2f*girth);
				if (!GeometryUtility.TestPlanesAABB(camPlanes,bounds)){
					return;	
				}
			}
			
			// Rotate Shadowcaster 
			//project forward or up vector onto a plane whos normal is lightDirection
			if (Mathf.Abs(Vector3.Dot(transform.forward, lightDirection)) < .9f){
				proj = transform.forward - Vector3.Dot(transform.forward, lightDirection) * lightDirection;
			} else {
				Debug.Log(lightDirection);
				proj = transform.up - Vector3.Dot(transform.up, lightDirection) * lightDirection;
			}
			shadowCaster.transform.rotation = Quaternion.Lerp(shadowCaster.transform.rotation, Quaternion.LookRotation(proj, -lightDirection), .01f);			
			
			float alpha;
			float dist = rh.distance - shadowHoverHeight;
			alpha = 1.0f - dist / maxProjectionDistance;
			if (alpha < 0f)
				return;
			alpha = Mathf.Clamp01(alpha);
			_color.a = alpha;
			
			_normal = rh.normal;
			Vector3 hitPoint = rh.point - shadowHoverHeight * lightDirection;
			shadowPlane.SetNormalAndPosition(_normal, hitPoint);
			
			isGoodPlaneIntersect = true;
			
			float rayDist;
			float mag = 0f;
			if (useLightSource && isPerspectiveProjection){
				r.origin = lightSource.transform.position;
				Vector3 lightSource2Corner = cornerGOs[0].transform.position - lightSource.transform.position;
				mag = lightSource2Corner.magnitude;
				r.direction = lightSource2Corner / mag;
				isGoodPlaneIntersect = isGoodPlaneIntersect && shadowPlane.Raycast(r, out rayDist);
				_corners[0] = r.origin + r.direction * rayDist;	
				
				lightSource2Corner = cornerGOs[1].transform.position - lightSource.transform.position;
				r.direction = lightSource2Corner / mag;
				isGoodPlaneIntersect = isGoodPlaneIntersect && shadowPlane.Raycast(r, out rayDist);
				_corners[1] = r.origin + r.direction * rayDist;
				
				lightSource2Corner = cornerGOs[2].transform.position - lightSource.transform.position;
				r.direction = lightSource2Corner / mag;
				isGoodPlaneIntersect = isGoodPlaneIntersect && shadowPlane.Raycast(r, out rayDist);
				_corners[2] = r.origin + r.direction * rayDist;

				lightSource2Corner = cornerGOs[3].transform.position - lightSource.transform.position;
				r.direction = lightSource2Corner / mag;
				isGoodPlaneIntersect = isGoodPlaneIntersect && shadowPlane.Raycast(r, out rayDist);
				_corners[3] = r.origin + r.direction * rayDist;
				if (doVisibilityCulling){
					Plane[] camPlanes = FS_ShadowManager.Manager().getCameraFustrumPlanes();
					bounds.center = rh.point;
					bounds.size = Vector3.zero;
					bounds.Encapsulate(_corners[0]);
					bounds.Encapsulate(_corners[1]);
					bounds.Encapsulate(_corners[2]);
					bounds.Encapsulate(_corners[3]);
					if (!GeometryUtility.TestPlanesAABB(camPlanes,bounds)){
						return;	
					}
				}
			} else {
				r.origin = cornerGOs[0].transform.position;
				isGoodPlaneIntersect = shadowPlane.Raycast(r, out rayDist);
				if (isGoodPlaneIntersect == false && rayDist == 0f){ 
					return;
				} else {
					isGoodPlaneIntersect = true;	
				}
				_corners[0] = r.origin + r.direction * rayDist;

				r.origin = cornerGOs[1].transform.position;
				isGoodPlaneIntersect = shadowPlane.Raycast(r, out rayDist);
				if (isGoodPlaneIntersect == false && rayDist == 0f){ 
					return;
				} else {
					isGoodPlaneIntersect = true;	
				}
				_corners[1] = r.origin + r.direction * rayDist;	

				r.origin = cornerGOs[2].transform.position;
				isGoodPlaneIntersect = shadowPlane.Raycast(r, out rayDist);
				if (isGoodPlaneIntersect == false && rayDist == 0f){ 
					return;
				} else {
					isGoodPlaneIntersect = true;	
				}
				_corners[2] = r.origin + r.direction * rayDist;	

				r.origin = cornerGOs[3].transform.position;
				isGoodPlaneIntersect = shadowPlane.Raycast(r, out rayDist);
				if (isGoodPlaneIntersect == false && rayDist == 0f){ 
					return;
				} else {
					isGoodPlaneIntersect = true;	
				}
				_corners[3] = r.origin + r.direction * rayDist;					
			}
			
			if (isGoodPlaneIntersect){
				if (meshKey == null || meshKey.mat != shadowMaterial || meshKey.isStatic != isStatic) meshKey = new FS_MeshKey(shadowMaterial, isStatic);
				FS_ShadowManager.Manager().registerGeometry(this, meshKey);	
				gizmoColor = Color.white;
			} else {
				gizmoColor = Color.magenta;
			}
		} else {
			isGoodPlaneIntersect = false;
			gizmoColor = Color.red;	
		}
	}
예제 #14
0
    private void CalculateShadowGeometry()
    {
        if (this.shadowMaterial == null)
        {
            return;
        }
        if (this.useLightSource && this.lightSource == null)
        {
            this.useLightSource = false;
            Debug.LogWarning("No light source object given using light direction vector.");
        }
        if (this.useLightSource)
        {
            Vector3 a         = base.transform.position - this.lightSource.transform.position;
            float   magnitude = a.magnitude;
            if (magnitude == 0f)
            {
                return;
            }
            this.lightDirection = a / magnitude;
        }
        else if (this.lightDirection != this._lightDirection || this.lightDirection == Vector3.zero)
        {
            if (this.lightDirection == Vector3.zero)
            {
                Debug.LogWarning("Light Direction vector cannot be zero. assuming -y.");
                this.lightDirection = -Vector3.up;
            }
            this.lightDirection.Normalize();
            this._lightDirection = this.lightDirection;
        }
        if (this.shadowCaster == null || this.girth != this._girth)
        {
            if (this.shadowCaster == null)
            {
                this.shadowCaster = new GameObject("shadowSimple");
                this.cornerGOs    = new GameObject[4];
                for (int i = 0; i < 4; i++)
                {
                    GameObject gameObject = this.cornerGOs[i] = new GameObject("c" + i);
                    gameObject.transform.parent = this.shadowCaster.transform;
                }
                this.shadowCaster.transform.parent        = base.transform;
                this.shadowCaster.transform.localPosition = Vector3.zero;
                this.shadowCaster.transform.localRotation = Quaternion.identity;
                this.shadowCaster.transform.localScale    = Vector3.one;
            }
            Vector3 forward;
            if (Mathf.Abs(Vector3.Dot(base.transform.forward, this.lightDirection)) < 0.9f)
            {
                forward = base.transform.forward - Vector3.Dot(base.transform.forward, this.lightDirection) * this.lightDirection;
            }
            else
            {
                forward = base.transform.up - Vector3.Dot(base.transform.up, this.lightDirection) * this.lightDirection;
            }
            this.shadowCaster.transform.rotation = Quaternion.LookRotation(forward, -this.lightDirection);
            this.cornerGOs[0].transform.position = this.shadowCaster.transform.position + this.girth * (this.shadowCaster.transform.forward - this.shadowCaster.transform.right);
            this.cornerGOs[1].transform.position = this.shadowCaster.transform.position + this.girth * (this.shadowCaster.transform.forward + this.shadowCaster.transform.right);
            this.cornerGOs[2].transform.position = this.shadowCaster.transform.position + this.girth * (-this.shadowCaster.transform.forward + this.shadowCaster.transform.right);
            this.cornerGOs[3].transform.position = this.shadowCaster.transform.position + this.girth * (-this.shadowCaster.transform.forward - this.shadowCaster.transform.right);
            this._girth = this.girth;
        }
        Transform transform = this.shadowCaster.transform;

        this.r.origin    = transform.position;
        this.r.direction = this.lightDirection;
        if (this.maxProjectionDistance > 0f && Physics.Raycast(this.r, out this.rh, this.maxProjectionDistance, this.layerMask))
        {
            if (this.doVisibilityCulling && !this.isPerspectiveProjection)
            {
                Plane[] cameraFustrumPlanes = FS_ShadowManager.Manager().getCameraFustrumPlanes();
                this.bounds.center = this.rh.point;
                this.bounds.size   = new Vector3(2f * this.girth, 2f * this.girth, 2f * this.girth);
                if (!GeometryUtility.TestPlanesAABB(cameraFustrumPlanes, this.bounds))
                {
                    return;
                }
            }
            Vector3 forward;
            if (Mathf.Abs(Vector3.Dot(base.transform.forward, this.lightDirection)) < 0.9f)
            {
                forward = base.transform.forward - Vector3.Dot(base.transform.forward, this.lightDirection) * this.lightDirection;
            }
            else
            {
                forward = base.transform.up - Vector3.Dot(base.transform.up, this.lightDirection) * this.lightDirection;
            }
            this.shadowCaster.transform.rotation = Quaternion.Lerp(this.shadowCaster.transform.rotation, Quaternion.LookRotation(forward, -this.lightDirection), 0.01f);
            float num  = this.rh.distance - this.shadowHoverHeight;
            float num2 = 1f - num / this.maxProjectionDistance;
            if (num2 < 0f)
            {
                return;
            }
            num2          = Mathf.Clamp01(num2);
            this._color.a = num2;
            this._normal  = this.rh.normal;
            Vector3 inPoint = this.rh.point - this.shadowHoverHeight * this.lightDirection;
            this.shadowPlane.SetNormalAndPosition(this._normal, inPoint);
            this.isGoodPlaneIntersect = true;
            float num3 = 0f;
            if (this.useLightSource && this.isPerspectiveProjection)
            {
                this.r.origin = this.lightSource.transform.position;
                Vector3 a2         = this.cornerGOs[0].transform.position - this.lightSource.transform.position;
                float   magnitude2 = a2.magnitude;
                this.r.direction          = a2 / magnitude2;
                this.isGoodPlaneIntersect = (this.isGoodPlaneIntersect && this.shadowPlane.Raycast(this.r, out num3));
                this._corners[0]          = this.r.origin + this.r.direction * num3;
                a2 = this.cornerGOs[1].transform.position - this.lightSource.transform.position;
                this.r.direction          = a2 / magnitude2;
                this.isGoodPlaneIntersect = (this.isGoodPlaneIntersect && this.shadowPlane.Raycast(this.r, out num3));
                this._corners[1]          = this.r.origin + this.r.direction * num3;
                a2 = this.cornerGOs[2].transform.position - this.lightSource.transform.position;
                this.r.direction          = a2 / magnitude2;
                this.isGoodPlaneIntersect = (this.isGoodPlaneIntersect && this.shadowPlane.Raycast(this.r, out num3));
                this._corners[2]          = this.r.origin + this.r.direction * num3;
                a2 = this.cornerGOs[3].transform.position - this.lightSource.transform.position;
                this.r.direction          = a2 / magnitude2;
                this.isGoodPlaneIntersect = (this.isGoodPlaneIntersect && this.shadowPlane.Raycast(this.r, out num3));
                this._corners[3]          = this.r.origin + this.r.direction * num3;
                if (this.doVisibilityCulling)
                {
                    Plane[] cameraFustrumPlanes2 = FS_ShadowManager.Manager().getCameraFustrumPlanes();
                    this.bounds.center = this.rh.point;
                    this.bounds.size   = Vector3.zero;
                    this.bounds.Encapsulate(this._corners[0]);
                    this.bounds.Encapsulate(this._corners[1]);
                    this.bounds.Encapsulate(this._corners[2]);
                    this.bounds.Encapsulate(this._corners[3]);
                    if (!GeometryUtility.TestPlanesAABB(cameraFustrumPlanes2, this.bounds))
                    {
                        return;
                    }
                }
            }
            else
            {
                this.r.origin             = this.cornerGOs[0].transform.position;
                this.isGoodPlaneIntersect = this.shadowPlane.Raycast(this.r, out num3);
                if (!this.isGoodPlaneIntersect && num3 == 0f)
                {
                    return;
                }
                this.isGoodPlaneIntersect = true;
                this._corners[0]          = this.r.origin + this.r.direction * num3;
                this.r.origin             = this.cornerGOs[1].transform.position;
                this.isGoodPlaneIntersect = this.shadowPlane.Raycast(this.r, out num3);
                if (!this.isGoodPlaneIntersect && num3 == 0f)
                {
                    return;
                }
                this.isGoodPlaneIntersect = true;
                this._corners[1]          = this.r.origin + this.r.direction * num3;
                this.r.origin             = this.cornerGOs[2].transform.position;
                this.isGoodPlaneIntersect = this.shadowPlane.Raycast(this.r, out num3);
                if (!this.isGoodPlaneIntersect && num3 == 0f)
                {
                    return;
                }
                this.isGoodPlaneIntersect = true;
                this._corners[2]          = this.r.origin + this.r.direction * num3;
                this.r.origin             = this.cornerGOs[3].transform.position;
                this.isGoodPlaneIntersect = this.shadowPlane.Raycast(this.r, out num3);
                if (!this.isGoodPlaneIntersect && num3 == 0f)
                {
                    return;
                }
                this.isGoodPlaneIntersect = true;
                this._corners[3]          = this.r.origin + this.r.direction * num3;
            }
            if (this.isGoodPlaneIntersect)
            {
                if (this.meshKey == null || this.meshKey.mat != this.shadowMaterial || this.meshKey.isStatic != this.isStatic)
                {
                    this.meshKey = new FS_MeshKey(this.shadowMaterial, this.isStatic);
                }
                FS_ShadowManager.Manager().registerGeometry(this, this.meshKey);
                this.gizmoColor = Color.white;
            }
            else
            {
                this.gizmoColor = Color.magenta;
            }
        }
        else
        {
            this.isGoodPlaneIntersect = false;
            this.gizmoColor           = Color.red;
        }
    }