public override void UpdatePortalsZoneData() { var transferPortalList = new List <Portal>(); // check each portal to see if it's intersecting another portal of greater size foreach (Portal p in mPortals) { Real pRadius = p.getRadius(); // First we check against portals in the SAME zone (and only if they have a // target zone different from the home zone) foreach (Portal p2 in mPortals) { // only check against bigger portals (this will also prevent checking against self) // and only against portals which point to another zone if (pRadius < p2.getRadius() && p2.getTargetZone() != this) { // Portal#2 is bigger than Portal1, check for crossing if (p.crossedPortal(p2)) { // portal#1 crossed portal#2 - flag portal#1 to be moved to portal#2's target zone p.setNewHomeZone(p2.getTargetZone()); transferPortalList.Add(p); break; } } } // Second we check against portals in the target zone (and only if that target // zone is different from the home zone) PCZone tzone = p.getTargetZone(); if (tzone != this) { foreach (Portal p3 in mPortals) { // only check against bigger portals if (pRadius < p3.getRadius()) { // Portal#3 is bigger than Portal#1, check for crossing if (p.crossedPortal(p3) && p.getCurrentHomeZone() != p3.getTargetZone()) { // Portal#1 crossed Portal#3 - switch target zones for Portal#1 p.setTargetZone(p3.getTargetZone()); break; } } } } } // transfer any portals to new zones that have been flagged foreach (Portal p in transferPortalList) { if (null != p.getNewHomeZone()) { RemovePortal(p); p.getNewHomeZone().AddPortal(p); p.setNewHomeZone(null); } } transferPortalList.Clear(); }
public override PCZone UpdateNodeHomeZone(PCZSceneNode pczsn, bool allowBackTouches) { // default to newHomeZone being the current home zone PCZone newHomeZone = pczsn.HomeZone; // Check all portals of the start zone for crossings! foreach (Portal portal in mPortals) { PortalIntersectResult pir = portal.intersects(pczsn); switch (pir) { default: case PortalIntersectResult.NO_INTERSECT: // node does not intersect portal - do nothing case PortalIntersectResult.INTERSECT_NO_CROSS: // node intersects but does not cross portal - do nothing break; case PortalIntersectResult.INTERSECT_BACK_NO_CROSS: // node intersects but on the back of the portal if (allowBackTouches) { // node is on wrong side of the portal - fix if we're allowing backside touches if (portal.getTargetZone() != this && portal.getTargetZone() != pczsn.HomeZone) { // set the home zone of the node to the target zone of the portal pczsn.HomeZone = portal.getTargetZone(); // continue checking for portal crossings in the new zone newHomeZone = portal.getTargetZone().UpdateNodeHomeZone(pczsn, false); } } break; case PortalIntersectResult.INTERSECT_CROSS: // node intersects and crosses the portal - recurse into that zone as new home zone if (portal.getTargetZone() != this && portal.getTargetZone() != pczsn.HomeZone) { // set the home zone of the node to the target zone of the portal pczsn.HomeZone = portal.getTargetZone(); // continue checking for portal crossings in the new zone newHomeZone = portal.getTargetZone().UpdateNodeHomeZone(pczsn, true); } break; } } // return the new home zone return(newHomeZone); }
public Octree(PCZone zone, Octree parent) { this.wireBoundingBox = null; HalfSize = new Vector3(); this.parent = parent; NunodeList = 0; this.zone = zone; //initialize all children to null. for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { this.Children[i, j, k] = null; } } } }
public OctreeZoneData(PCZSceneNode node, PCZone zone) : base(node, zone) { this.mOctant = null; this.mOctreeWorldAABB = AxisAlignedBox.Null; }
public override void CheckLightAgainstPortals(PCZLight light, ulong frameCount, PCZFrustum portalFrustum, Portal ignorePortal) { foreach (Portal p in mPortals) { 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; } } } } }