public override void OnSceneManagementGetLightsForCamera( Camera camera, List<RenderingLowLevelMethods.LightItem> outLights )
        {
            Frustum frustum = FrustumUtils.GetFrustumByCamera( camera );
            if( EngineDebugSettings.FrustumTest && camera.AllowFrustumTestMode )
            {
                frustum.HalfWidth *= .5f;
                frustum.HalfHeight *= .5f;
            }

            ConvexPolyhedron frustumPolyhedron = GetConvexPolyhedronFromFrustum( ref frustum );

            ICollection<RenderLight> lightsToCheck;
            if( SceneManager.Instance.OverrideVisibleObjects != null )
            {
                lightsToCheck = SceneManager.Instance.OverrideVisibleObjects.Lights;
            }
            else
            {
                List<RenderLight> list = new List<RenderLight>( 64 );
                lightsToCheck = list;

                bool usePortalSystem =
                    EngineApp.Instance.ApplicationType != EngineApp.ApplicationTypes.ResourceEditor &&
                    Map.Instance != null && Map.Instance.Zones.Count != 0 &&
                    camera.AllowZonesAndPortalsSceneManagement &&
                    EngineDebugSettings.AllowPortalSystem &&
                    camera.ProjectionType == ProjectionTypes.Perspective;

                if( usePortalSystem )
                {
                    //use portal system
                    Map.Instance.WalkUsePortalSystem( camera, false, null, null, list );
                }
                else
                {
                    //use frustum culling

                    //add directional lights
                    foreach( RenderLight light in SceneManager.Instance.RenderLights )
                    {
                        if( light.Type == RenderLightType.Directional && light.Visible )
                            list.Add( light );
                    }

                    uint groupMask = 0;
                    groupMask |= 1 << (int)SceneManager.SceneGraphGroups.Light;

                    int[] sceneGraphIndexes = SceneManager.Instance.SceneGraph.GetObjects( frustum, groupMask );

                    foreach( int sceneGraphIndex in sceneGraphIndexes )
                    {
                        SceneManager.SceneGraphObjectData data = SceneManager.Instance.SceneGraphObjects[ sceneGraphIndex ];

                        //Light
                        RenderLight light = data.Light;
                        if( light != null && light.Visible )
                        {
                            //clip volumes
                            if( !IsTotalClipVolumesContainsBounds( light.GetWorldBounds() ) )
                                list.Add( light );
                        }
                    }
                }

                //add objects never culled by the frustum
                if( SceneManager.Instance.OverrideVisibleObjects == null && Map.Instance != null )
                    Map.Instance.Walk_AddObjectsWithDisabled_AllowSceneManagementCulling_Property( false, null, null, list );
            }

            foreach( RenderLight light in lightsToCheck )
            {
                if( !light.Visible )
                    continue;

                bool allowCastShadows = light.CastShadows;

                if( light.Type == RenderLightType.Point || light.Type == RenderLightType.Spot )
                {
                    if( light.AttenuationFar <= .01f )
                        continue;

                    Sphere lightSphere = new Sphere( light.Position, light.AttenuationFar );

                    //fast culling. not cull everything.
                    if( !frustum.IsIntersectsFast( lightSphere ) )
                        continue;

                    //generate convex polyhedron for light volume
                    //and check intersection with camera frustum.
                    ConvexPolyhedron lightPolyhedron = light.GetInclusiveVolumeForCulling();

                    //draw light bounds
                    //RendererWorld.Instance.DefaultCamera.DebugGeometry.Color = new ColorValue( 1, 0, 1, .5f );
                    //RendererWorld.Instance.DefaultCamera.DebugGeometry.AddBounds( light.GetWorldBounds() );

                    //visualize light volumes
                    //{
                    //   int[] i = new int[ lightPolyhedron.Faces.Length * 3 ];
                    //   for( int n = 0; n < lightPolyhedron.Faces.Length; n++ )
                    //   {
                    //      i[ n * 3 + 0 ] = lightPolyhedron.Faces[ n ].Vertex0;
                    //      i[ n * 3 + 1 ] = lightPolyhedron.Faces[ n ].Vertex1;
                    //      i[ n * 3 + 2 ] = lightPolyhedron.Faces[ n ].Vertex2;
                    //   }
                    //   RendererWorld.Instance.DefaultCamera.DebugGeometry.Color = new ColorValue( 1, 1, 0, .3f );
                    //   RendererWorld.Instance.DefaultCamera.DebugGeometry.AddVertexIndexBuffer(
                    //      lightPolyhedron.Vertices, i, Mat4.Identity, false, true );
                    //}

                    if( !ConvexPolyhedron.IsIntersects( frustumPolyhedron, lightPolyhedron ) )
                        continue;

                    //allowCastShadows
                    if( allowCastShadows )
                    {
                        Sphere frustumShadowSphere = new Sphere( camera.DerivedPosition,
                            SceneManager.Instance.ShadowFarDistance );

                        if( frustumShadowSphere.IsIntersectsSphere( lightSphere ) )
                        {
                            if( light.Type == RenderLightType.Spot )
                            {
                                Cone cone = new Cone( light.Position, light.Direction,
                                    light.SpotlightOuterAngle / 2 );

                                if( !cone.IsIntersectsSphere( frustumShadowSphere ) )
                                    allowCastShadows = false;
                            }
                        }
                        else
                            allowCastShadows = false;
                    }
                }

                outLights.Add( new RenderingLowLevelMethods.LightItem( light, allowCastShadows ) );
            }
        }
		public override void OnSceneManagementGetLightsForCamera( Camera camera,
			List<RenderingLowLevelMethods.LightItem> outLights )
		{
			Frustum frustum = FrustumUtils.GetFrustumByCamera( camera );
			if( EngineDebugSettings.FrustumTest && camera.AllowFrustumTestMode )
			{
				frustum.HalfWidth *= .5f;
				frustum.HalfHeight *= .5f;
			}

			ConvexPolyhedron frustumPolyhedron = GetConvexPolyhedronFromFrustum( ref frustum );

			ICollection<RenderLight> list;
			if( SceneManager.Instance.OverrideVisibleObjects != null )
				list = SceneManager.Instance.OverrideVisibleObjects.Lights;
			else
				list = SceneManager.Instance.RenderLights;

			foreach( RenderLight light in list )
			{
				if( !light.Visible )
					continue;

				bool allowCastShadows = true;

				if( light.Type == RenderLightType.Point || light.Type == RenderLightType.Spot )
				{
					if( light.AttenuationFar <= .01f )
						continue;

					Sphere lightSphere = new Sphere( light.Position, light.AttenuationFar );

					//fast culling. not cull everything.
					if( !frustum.IsIntersectsFast( lightSphere ) )
						continue;

					//generate convex polyhedron for light volume 
					//and check intersection with camera frustum.
					ConvexPolyhedron lightPolyhedron = null;
					if( light.Type == RenderLightType.Point )
						lightPolyhedron = MakeConvexPolyhedronForPointLight( light );
					else if( light.Type == RenderLightType.Spot )
						lightPolyhedron = MakeConvexPolyhedronForSpotLight( light );

					if( !ConvexPolyhedron.IsIntersects( frustumPolyhedron, lightPolyhedron ) )
						continue;

					//allowCastShadows
					if( light.CastShadows )
					{
						Sphere frustumShadowSphere = new Sphere( camera.DerivedPosition,
							SceneManager.Instance.ShadowFarDistance );

						if( frustumShadowSphere.IsIntersectsSphere( lightSphere ) )
						{
							if( light.Type == RenderLightType.Spot )
							{
								Cone cone = new Cone( light.Position, light.Direction,
									light.SpotlightOuterAngle / 2 );

								if( !cone.IsIntersectsSphere( frustumShadowSphere ) )
									allowCastShadows = false;
							}
						}
						else
							allowCastShadows = false;
					}
				}

				outLights.Add( new RenderingLowLevelMethods.LightItem( light, allowCastShadows ) );
			}
		}