Axiom.SceneManagers.PortalConnected.PCZFrustum.AddPortalCullingPlanes C# (CSharp) Method

AddPortalCullingPlanes() public method

public AddPortalCullingPlanes ( Portal portal ) : int
portal Portal
return int
		public int AddPortalCullingPlanes( Portal portal )
		{
			int addedcullingplanes = 0;

			// If portal is of type aabb or sphere, add a plane which is same as frustum
			// origin plane (ie. redundant).  We do this because we need the plane as a flag
			// to prevent infinite recursion
			if ( portal.Type == PORTAL_TYPE.PORTAL_TYPE_AABB ||
				portal.Type == PORTAL_TYPE.PORTAL_TYPE_SPHERE )
			{
				PCPlane newPlane = GetUnusedCullingPlane();
				newPlane.SetFromAxiomPlane( mOriginPlane );
				newPlane.Portal = portal;
				mActiveCullingPlanes.Add( newPlane );
				addedcullingplanes++;
				return addedcullingplanes;
			}

			// For portal Quads: Up to 4 planes can be added by the sides of a portal quad.
			// Each plane is created from 2 corners (world space) of the portal and the
			// frustum origin (world space).
			int i, j;
			PlaneSide pt0_side, pt1_side;
			bool visible;
			for ( i = 0; i < 4; i++ )
			{
				// first check if both corners are outside of one of the existing planes
				j = i + 1;
				if ( j > 3 )
				{
					j = 0;
				}
				visible = true;

				foreach ( PCPlane plane in mActiveCullingPlanes )
				{
					pt0_side = plane.GetSide( portal.getDerivedCorner( i ) );
					pt1_side = plane.GetSide( portal.getDerivedCorner( j ) );
					if ( pt0_side == PlaneSide.Negative &&
						pt1_side == PlaneSide.Negative )
					{
						// the portal edge was actually completely culled by one of  culling planes
						visible = false;
					}
				}
				if ( visible )
				{
					// add the plane created from the two portal corner points and the frustum location
					// to the  culling plane
					PCPlane newPlane = GetUnusedCullingPlane();
					if ( projType == Projection.Orthographic ) // use camera direction if projection is orthographic.
					{
						newPlane.Redefine( portal.getDerivedCorner( j ) + mOriginPlane.Normal,
							portal.getDerivedCorner( j ), portal.getDerivedCorner( i ) );
					}
					else
					{
						newPlane.Redefine( mOrigin, portal.getDerivedCorner( j ), portal.getDerivedCorner( i ) );
					}
					newPlane.Portal = portal;
					mActiveCullingPlanes.Add( newPlane );
					addedcullingplanes++;
				}
			}
			// if we added ANY planes from the quad portal, we should add the plane of the
			// portal itself as an additional culling plane.
			if ( addedcullingplanes > 0 )
			{
				PCPlane newPlane = GetUnusedCullingPlane();
				newPlane.Redefine( portal.getDerivedCorner( 2 ), portal.getDerivedCorner( 1 ), portal.getDerivedCorner( 0 ) );
				newPlane.Portal = portal;
				mActiveCullingPlanes.Add( newPlane );
				addedcullingplanes++;
			}
			return addedcullingplanes;
		}

Usage Example

Ejemplo n.º 1
0
		/** (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;
						}
					}
				}
			}
		}
All Usage Examples Of Axiom.SceneManagers.PortalConnected.PCZFrustum::AddPortalCullingPlanes