/** (recursive) check the given light against all portals in the zone * NOTE: This is the default implementation, which doesn't take advantage * of any zone-specific optimizations for checking portal visibility */ 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.GetDerivedPosition(); 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; } } } } }
/** (recursive) check the given light against all portals in the zone * NOTE: This is the default implementation, which doesn't take advantage * of any zone-specific optimizations for checking portal visibility */ 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.GetDerivedPosition(); 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; } } } } }