public override void CheckLightAgainstPortals( PCZLight light, ulong frameCount, PCZFrustum portalFrustum, Portal ignorePortal )
{
foreach ( Portal p in mPortals )
{
//Portal * p = *it;
if ( p != ignorePortal )
{
// calculate the direction vector from light to portal
Vector3 lightToPortal = p.getDerivedCP() - light.DerivedPosition;
if ( portalFrustum.IsObjectVisible( p ) )
{
// portal is facing the light, but some light types need to
// check illumination radius too.
PCZone targetZone = p.getTargetZone();
switch ( light.Type )
{
case LightType.Point:
// point lights - just check if within illumination range
if ( lightToPortal.Length <= light.AttenuationRange )
{
// if portal is quad portal it must be pointing towards the light
if ( ( p.Type == PORTAL_TYPE.PORTAL_TYPE_QUAD && lightToPortal.Dot( p.getDerivedDirection() ) < 0.0 ) ||
( p.Type != PORTAL_TYPE.PORTAL_TYPE_QUAD ) )
{
if ( !light.AffectsZone( targetZone ) )
{
light.AddZoneToAffectedZonesList( targetZone );
if ( targetZone.LastVisibleFrame == frameCount )
{
light.AffectsVisibleZone = true;
}
// set culling frustum from the portal
portalFrustum.AddPortalCullingPlanes( p );
// recurse into the target zone of the portal
p.getTargetZone().CheckLightAgainstPortals( light,
frameCount,
portalFrustum,
p.getTargetPortal() );
// remove the planes added by this portal
portalFrustum.RemovePortalCullingPlanes( p );
}
}
}
break;
case LightType.Directional:
// directionals have infinite range, so just make sure
// the direction is facing the portal
if ( lightToPortal.Dot( light.DerivedDirection ) >= 0.0 )
{
// if portal is quad portal it must be pointing towards the light
if ( ( p.Type == PORTAL_TYPE.PORTAL_TYPE_QUAD && lightToPortal.Dot( p.getDerivedDirection() ) < 0.0 ) ||
( p.Type == PORTAL_TYPE.PORTAL_TYPE_QUAD ) )
{
if ( !light.AffectsZone( targetZone ) )
{
light.AddZoneToAffectedZonesList( targetZone );
if ( targetZone.LastVisibleFrame == frameCount )
{
light.AffectsVisibleZone = true;
}
// set culling frustum from the portal
portalFrustum.AddPortalCullingPlanes( p );
// recurse into the target zone of the portal
p.getTargetZone().CheckLightAgainstPortals( light,
frameCount,
portalFrustum,
p.getTargetPortal() );
// remove the planes added by this portal
portalFrustum.RemovePortalCullingPlanes( p );
}
}
}
break;
case LightType.Spotlight:
// spotlights - just check if within illumination range
// Technically, we should check if the portal is within
// the cone of illumination, but for now, we'll leave that
// as a future optimisation.
if ( lightToPortal.Length <= light.AttenuationRange )
{
// if portal is quad portal it must be pointing towards the light
if ( ( p.Type == PORTAL_TYPE.PORTAL_TYPE_QUAD && lightToPortal.Dot( p.getDerivedDirection() ) < 0.0 ) ||
( p.Type != PORTAL_TYPE.PORTAL_TYPE_QUAD ) )
{
if ( !light.AffectsZone( targetZone ) )
{
light.AddZoneToAffectedZonesList( targetZone );
if ( targetZone.LastVisibleFrame == frameCount )
{
light.AffectsVisibleZone = true;
}
// set culling frustum from the portal
portalFrustum.AddPortalCullingPlanes( p );
// recurse into the target zone of the portal
p.getTargetZone().CheckLightAgainstPortals( light,
frameCount,
portalFrustum,
p.getTargetPortal() );
// remove the planes added by this portal
portalFrustum.RemovePortalCullingPlanes( p );
}
}
}
break;
}
}
}
}
}