// remove culling planes created from the given portal public void RemovePortalCullingPlanes(Portal portal) { for (int i = 0; i < this.mActiveCullingPlanes.Count; i++) { PCPlane plane = this.mActiveCullingPlanes[i]; if (plane.Portal == portal) { this.mCullingPlaneReservoir.Add(plane); this.mActiveCullingPlanes.Remove(plane); } } }
// get an unused PCPlane from the CullingPlane Reservoir // note that this removes the PCPlane from the reservoir! public PCPlane GetUnusedCullingPlane() { PCPlane plane = null; if (this.mCullingPlaneReservoir.Count > 0) { plane = this.mCullingPlaneReservoir[0]; this.mCullingPlaneReservoir.RemoveAt(0); return(plane); } // no available planes! create one plane = new PCPlane(); return(plane); }
// get an unused PCPlane from the CullingPlane Reservoir // note that this removes the PCPlane from the reservoir! public PCPlane GetUnusedCullingPlane() { PCPlane plane = null; if ( mCullingPlaneReservoir.Count > 0 ) { plane = mCullingPlaneReservoir[ 0 ]; mCullingPlaneReservoir.RemoveAt( 0 ); return plane; } // no available planes! create one plane = new PCPlane(); return plane; }
// calculate culling planes from portal and frustum // origin and add to list of culling planes // NOTE: returns 0 if portal was completely culled by existing planes // returns > 0 if culling planes are added (# is planes added) 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(this.mOriginPlane); newPlane.Portal = portal; this.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 this.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 (this.projType == Projection.Orthographic) // use camera direction if projection is orthographic. { newPlane.Redefine(portal.getDerivedCorner(j) + this.mOriginPlane.Normal, portal.getDerivedCorner(j), portal.getDerivedCorner(i)); } else { newPlane.Redefine(this.mOrigin, portal.getDerivedCorner(j), portal.getDerivedCorner(i)); } newPlane.Portal = portal; this.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; this.mActiveCullingPlanes.Add(newPlane); addedcullingplanes++; } return(addedcullingplanes); }