static bool IsIntersects( RenderLight light, Bounds bounds ) { if( light.Type == RenderLightType.Point || light.Type == RenderLightType.Spot ) { //check by bounding sphere { Sphere lightSphere = new Sphere( light.Position, light.AttenuationFar ); if( !lightSphere.IsIntersectsBounds( ref bounds ) ) return false; } //check by spot light clip planes if( light.Type == RenderLightType.Spot ) { Vec3 boundsCenter = bounds.GetCenter(); Vec3 boundsHalfSize = boundsCenter - bounds.Minimum; foreach( Plane plane in light.SpotLightClipPlanes ) { if( plane.GetSide( ref boundsCenter, ref boundsHalfSize ) == Plane.Side.Positive ) return false; } } } return true; }
static void WalkPointLightShadowGeneration( Camera mainCamera, RenderLight light, Vec3 pointLightFaceDirection, List<SceneNode> outSceneNodes, List<StaticMeshObject> outStaticMeshObjects ) { Sphere lightSphere = new Sphere( light.Position, light.AttenuationFar ); if( !pointLightFaceDirection.Equals( Vec3.Zero, .001f ) ) { //shadowmap. 6 render targets. int[] sceneGraphIndexes; if( SceneManager.Instance.OverrideVisibleObjects != null ) { sceneGraphIndexes = GetOverrideVisibleObjectsSceneGraphIndexes(); } else { Plane[] clipPlanes; { //add point light clip planes Plane[] array1 = GetClipPlanesForPointLightShadowGeneration( mainCamera, light, pointLightFaceDirection ); //add main frustum clip planes and light position Plane[] array2 = GetClipPlanesOfConvexHullAroundMainCameraAndLightPosition( mainCamera, light ); clipPlanes = new Plane[ array1.Length + array2.Length ]; Array.Copy( array1, 0, clipPlanes, 0, array1.Length ); Array.Copy( array2, 0, clipPlanes, array1.Length, array2.Length ); } Bounds clipBounds = lightSphere.ToBounds(); uint groupMask = 0; if( outSceneNodes != null ) groupMask |= 1 << (int)SceneManager.SceneGraphGroups.SceneNode; if( outStaticMeshObjects != null ) groupMask |= 1 << (int)SceneManager.SceneGraphGroups.StaticMeshObject; sceneGraphIndexes = SceneManager.Instance.SceneGraph.GetObjects( clipPlanes, clipBounds, groupMask ); } foreach( int sceneGraphIndex in sceneGraphIndexes ) { SceneManager.SceneGraphObjectData data = SceneManager.Instance.SceneGraphObjects[ sceneGraphIndex ]; //SceneNode SceneNode sceneNode = data.SceneNode; if( sceneNode != null && sceneNode.Visible && sceneNode.IsContainsObjectWithCastsShadowsEnabled() ) { Bounds sceneNodeBounds = sceneNode.GetWorldBounds(); //clip by sphere if( lightSphere.IsIntersectsBounds( sceneNodeBounds ) ) { //clip volumes if( !IsTotalClipVolumesContainsBounds( sceneNodeBounds ) ) outSceneNodes.Add( sceneNode ); } } //StaticMeshObject StaticMeshObject staticMeshObject = data.StaticMeshObject; if( staticMeshObject != null && staticMeshObject.Visible && staticMeshObject.CastShadows ) { //clip by sphere if( lightSphere.IsIntersectsBounds( staticMeshObject.Bounds ) ) { //clip volumes if( !IsTotalClipVolumesContainsBounds( staticMeshObject.Bounds ) ) outStaticMeshObjects.Add( staticMeshObject ); } } } } else { //stencil shadows. //check by sphere volume. int[] sceneGraphIndexes; if( SceneManager.Instance.OverrideVisibleObjects != null ) { sceneGraphIndexes = GetOverrideVisibleObjectsSceneGraphIndexes(); } else { Plane[] clipPlanes; { //add main frustum clip planes and light position Plane[] array1 = GetClipPlanesOfConvexHullAroundMainCameraAndLightPosition( mainCamera, light ); clipPlanes = new Plane[ 6 + array1.Length ]; //add 6 light clip planes. clipPlanes[ 0 ] = new Plane( Vec3.XAxis, lightSphere.Origin.X + lightSphere.Radius ); clipPlanes[ 1 ] = new Plane( -Vec3.XAxis, -( lightSphere.Origin.X - lightSphere.Radius ) ); clipPlanes[ 2 ] = new Plane( Vec3.YAxis, lightSphere.Origin.Y + lightSphere.Radius ); clipPlanes[ 3 ] = new Plane( -Vec3.YAxis, -( lightSphere.Origin.Y - lightSphere.Radius ) ); clipPlanes[ 4 ] = new Plane( Vec3.ZAxis, lightSphere.Origin.Z + lightSphere.Radius ); clipPlanes[ 5 ] = new Plane( -Vec3.ZAxis, -( lightSphere.Origin.Z - lightSphere.Radius ) ); Array.Copy( array1, 0, clipPlanes, 6, array1.Length ); } Bounds clipBounds = lightSphere.ToBounds(); uint groupMask = 0; if( outSceneNodes != null ) groupMask |= 1 << (int)SceneManager.SceneGraphGroups.SceneNode; if( outStaticMeshObjects != null ) groupMask |= 1 << (int)SceneManager.SceneGraphGroups.StaticMeshObject; sceneGraphIndexes = SceneManager.Instance.SceneGraph.GetObjects( clipPlanes, clipBounds, groupMask ); } foreach( int sceneGraphIndex in sceneGraphIndexes ) { SceneManager.SceneGraphObjectData data = SceneManager.Instance.SceneGraphObjects[ sceneGraphIndex ]; //SceneNode SceneNode sceneNode = data.SceneNode; if( sceneNode != null && sceneNode.Visible && sceneNode.IsContainsObjectWithCastsShadowsEnabled() ) { Bounds sceneNodeBounds = sceneNode.GetWorldBounds(); //clip by sphere if( lightSphere.IsIntersectsBounds( sceneNodeBounds ) ) { //clip volumes if( !IsTotalClipVolumesContainsBounds( sceneNodeBounds ) ) outSceneNodes.Add( sceneNode ); } } //StaticMeshObject StaticMeshObject staticMeshObject = data.StaticMeshObject; if( staticMeshObject != null && staticMeshObject.Visible && staticMeshObject.CastShadows ) { //clip by sphere if( lightSphere.IsIntersectsBounds( staticMeshObject.Bounds ) ) { //clip volumes if( !IsTotalClipVolumesContainsBounds( staticMeshObject.Bounds ) ) outStaticMeshObjects.Add( staticMeshObject ); } } } } }
static void WalkSpotLightShadowGeneration( Camera mainCamera, RenderLight light, List<SceneNode> outSceneNodes, List<StaticMeshObject> outStaticMeshObjects ) { Sphere lightSphere = new Sphere( light.Position, light.AttenuationFar ); int[] sceneGraphIndexes; if( SceneManager.Instance.OverrideVisibleObjects != null ) { sceneGraphIndexes = GetOverrideVisibleObjectsSceneGraphIndexes(); } else { Plane[] clipPlanes; { //add spot light clip planes Plane[] array1 = light.SpotLightClipPlanes; //add main frustum clip planes and light position Plane[] array2 = GetClipPlanesOfConvexHullAroundMainCameraAndLightPosition( mainCamera, light ); clipPlanes = new Plane[ array1.Length + array2.Length ]; Array.Copy( array1, 0, clipPlanes, 0, array1.Length ); Array.Copy( array2, 0, clipPlanes, array1.Length, array2.Length ); } Bounds clipBounds = lightSphere.ToBounds(); uint groupMask = 0; if( outSceneNodes != null ) groupMask |= 1 << (int)SceneManager.SceneGraphGroups.SceneNode; if( outStaticMeshObjects != null ) groupMask |= 1 << (int)SceneManager.SceneGraphGroups.StaticMeshObject; sceneGraphIndexes = SceneManager.Instance.SceneGraph.GetObjects( clipPlanes, clipBounds, groupMask ); } foreach( int sceneGraphIndex in sceneGraphIndexes ) { SceneManager.SceneGraphObjectData data = SceneManager.Instance.SceneGraphObjects[ sceneGraphIndex ]; //SceneNode SceneNode sceneNode = data.SceneNode; if( sceneNode != null && sceneNode.Visible && sceneNode.IsContainsObjectWithCastsShadowsEnabled() ) { Bounds sceneNodeBounds = sceneNode.GetWorldBounds(); //clip by sphere if( lightSphere.IsIntersectsBounds( sceneNodeBounds ) ) { //clip volumes if( !IsTotalClipVolumesContainsBounds( sceneNodeBounds ) ) outSceneNodes.Add( sceneNode ); } } //StaticMeshObject StaticMeshObject staticMeshObject = data.StaticMeshObject; if( staticMeshObject != null && staticMeshObject.Visible && staticMeshObject.CastShadows ) { //clip by sphere if( lightSphere.IsIntersectsBounds( staticMeshObject.Bounds ) ) { //clip volumes if( !IsTotalClipVolumesContainsBounds( staticMeshObject.Bounds ) ) outStaticMeshObjects.Add( staticMeshObject ); } } } }
static void WalkSpotLightShadowGeneration( Camera camera, RenderLight light, Set<SceneNode> outSceneNodes, Set<StaticMeshObject> outStaticMeshObjects) { Plane[] clipPlanes = GetClipPlanesForSpotLightShadowGeneration( camera, light ); Sphere clipSphere = new Sphere( light.Position, light.AttenuationRange ); SceneManager.Instance._SceneGraph.GetObjects( clipPlanes, _SceneObjectGroups.SceneNode | _SceneObjectGroups.StaticMeshObject, delegate( _ISceneObject sceneObject ) { //clip by sphere if( !clipSphere.IsIntersectsBounds( sceneObject._SceneData.Bounds ) ) return; _SceneObjectGroups objGroups = sceneObject._SceneData.Groups; //StaticMeshObject if( ( objGroups & _SceneObjectGroups.StaticMeshObject ) != 0 ) { StaticMeshObject staticMeshObject = (StaticMeshObject)sceneObject; if( !staticMeshObject.Visible ) return; if( !staticMeshObject.CastShadows ) return; outStaticMeshObjects.Add( staticMeshObject ); return; } //SceneNode if( ( objGroups & _SceneObjectGroups.SceneNode ) != 0 ) { SceneNode sceneNode = (SceneNode)sceneObject; if( !sceneNode.Visible ) return; //if( !x.CastShadows ) //{ // can be optimized //} outSceneNodes.Add( sceneNode ); return; } Log.Fatal( "InternalSceneManagement: WalkSpotLightShadowGeneration: invalid sceneObject." ); } ); }