Ejemplo n.º 1
0
        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();
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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;
                    }
                }
            }
        }
Ejemplo n.º 4
0
 public OctreeZoneData(PCZSceneNode node, PCZone zone)
     : base(node, zone)
 {
     this.mOctant          = null;
     this.mOctreeWorldAABB = AxisAlignedBox.Null;
 }
Ejemplo n.º 5
0
        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;
                        }
                    }
                }
            }
        }