// 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); }