Exemplo n.º 1
0
        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;
        }
Exemplo n.º 2
0
        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 );
                        }
                    }
                }
            }
        }
Exemplo n.º 3
0
        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." );
                } );
        }