Пример #1
0
        //-------------------------------------------------------------------------
        public void SetupTerrainZonePages(PCZSceneNode parentNode)
        {
            //create a root terrain node.
            if (null == this.mTerrainRoot)
            {
                this.mTerrainRoot = (PCZSceneNode)(parentNode.CreateChildSceneNode(Name + "_Node"));
                SetEnclosureNode(this.mTerrainRoot);
            }
            //setup the page array.
            var    pageSlots = (ushort)(1 + (this.mBufferedPageMargin * 2));
            ushort i, j;

            for (i = 0; i < pageSlots; ++i)
            {
                this.mTerrainZonePages.Add(new TerrainZonePageRow());
                ;
                for (j = 0; j < pageSlots; ++j)
                {
                    this.mTerrainZonePages[i].Add(null);
                }
            }

            // If we're not paging, load immediate for convenience
            if (this.mActivePageSource != null && !this.mPagingEnabled)
            {
                this.mActivePageSource.RequestPage(0, 0);
            }
        }
Пример #2
0
        //-------------------------------------------------------------------------
        public void SetZoneGeometry(Stream stream, PCZSceneNode parentNode, string typeName)
        {
            // Clear out any existing world resources (if not default)
            if (ResourceGroupManager.Instance.WorldResourceGroupName != ResourceGroupManager.DefaultResourceGroupName)
            {
                ResourceGroupManager.Instance.ClearResourceGroup(ResourceGroupManager.Instance.WorldResourceGroupName);
            }
            DestroyLevelIndexes();
            this.mTerrainZonePages.Clear();
            // Load the configuration
            LoadConfig(stream);
            InitLevelIndexes();


            SetupTerrainMaterial();

            SetupTerrainZonePages(parentNode);

            // Resize the octree allow for 1 page for now
            float max_x = Options.scale.x * Options.pageSize;
            float max_y = Options.scale.y;
            float max_z = Options.scale.z * Options.pageSize;

            Resize(new AxisAlignedBox(new Vector3(0, 0, 0), new Vector3(max_x, max_y, max_z)));
        }
Пример #3
0
 //-------------------------------------------------------------------------
 public void ClearZone()
 {
     this.mTerrainZonePages.Clear();
     DestroyLevelIndexes();
     // Octree has destroyed our root
     this.mTerrainRoot = null;
 }
Пример #4
0
        //-------------------------------------------------------------------------
        public override void SetZoneGeometry(string filename, PCZSceneNode parentNode)
        {
            // try to open in the current folder first
            FileStream fs = null;

            try
            {
                fs = File.Open(filename, FileMode.Open);
            }
            catch
            {
            }

            if (null != fs)
            {
                // Wrap as a stream
                SetZoneGeometry(fs, parentNode, null);
            }
            else
            {
                // otherwise try resource system
                Stream stream = ResourceGroupManager.Instance.OpenResource(filename,
                                                                           ResourceGroupManager.Instance.WorldResourceGroupName);

                SetZoneGeometry(stream, parentNode, null);
            }
        }
Пример #5
0
        public override void CheckNodeAgainstPortals(PCZSceneNode pczsn, Portal ignorePortal)
        {
            if (pczsn == mEnclosureNode || pczsn.AllowToVisit == false)
            {
                // don't do any checking of enclosure node versus portals
                return;
            }

            PCZone connectedZone;

            foreach (Portal p in mPortals)
            {
                //Check if the portal intersects the node
                if (p != ignorePortal && p.intersects(pczsn) != PortalIntersectResult.NO_INTERSECT)
                {
                    // node is touching this portal
                    connectedZone = p.getTargetZone();
                    // add zone to the nodes visiting zone list unless it is the home zone of the node
                    if (connectedZone != pczsn.HomeZone && !pczsn.IsVisitingZone(connectedZone))
                    {
                        pczsn.AddZoneToVisitingZonesMap(connectedZone);
                        // tell the connected zone that the node is visiting it
                        connectedZone.AddNode(pczsn);
                        //recurse into the connected zone
                        connectedZone.CheckNodeAgainstPortals(pczsn, p.getTargetPortal());
                    }
                }
            }
        }
Пример #6
0
        public void TestReaddingOfChildNodeAfterRemovalByReference()
        {
            Node node      = new PCZSceneNode(this.sceneManager);
            Node childNode = node.CreateChild(Name);

            node.RemoveChild(childNode);
            node.AddChild(childNode);
        }
        public void TestRecreationOfChildNodeAfterRemovalByReference()
        {
            Node node      = new PCZSceneNode(this.fakeSceneManager);
            Node childNode = node.CreateChild(Name);

            node.RemoveChild(childNode);
            node.CreateChild(Name);
        }
Пример #8
0
        public void AddNode(PCZSceneNode node)
        {
            this.nodeList[node.Name] = node;
            ((OctreeZoneData)node.GetZoneData(this.zone)).Octant = this;

            //update total counts.
            Ref();
        }
Пример #9
0
        public void TestRecreationOfChildNodeAfterRemovalByName()
        {
            Node node = new PCZSceneNode(this.sceneManager);

            node.CreateChild(Name);

            node.RemoveChild(Name);
            node.CreateChild(Name);
        }
Пример #10
0
 public override void AddNode(PCZSceneNode n)
 {
     if (n.HomeZone == this)
     {
         // add a reference to this node in the "nodes at home in this zone" list
         mHomeNodeList.Add(n);
     }
     else
     {
         // add a reference to this node in the "nodes visiting this zone" list
         mVisitorNodeList.Add(n);
     }
 }
Пример #11
0
 public TerrainZone(PCZSceneManager creator, string name)
     : base(creator, name)
 {
     mZoneTypeName                   = "ZoneType_Terrain";
     this.mUseCustomMaterial         = false;
     this.mUseNamedParameterLodMorph = false;
     this.mLodMorphParamIndex        = 3;
     this.mTerrainRoot               = null;
     this.mActivePageSource          = null;
     this.mPagingEnabled             = false;
     this.mLivePageMargin            = 0;
     this.mBufferedPageMargin        = 0;
 }
Пример #12
0
 public override void SetEnclosureNode(PCZSceneNode node)
 {
     mEnclosureNode = node;
     if (null != node)
     {
         // anchor the node to this zone
         node.AnchorToHomeZone(this);
         // make sure node world bounds are up to date
         //node._updateBounds();
         // resize the octree to the same size as the enclosure node bounding box
         Resize(node.WorldAABB);
     }
 }
Пример #13
0
        public void UpdateNodeOctant(OctreeZoneData zoneData)
        {
            AxisAlignedBox box = zoneData.OctreeWorldAABB;

            if (box.IsNull)
            {
                return;
            }

            // Skip if octree has been destroyed (shutdown conditions)
            if (null == this.rootOctree)
            {
                return;
            }

            PCZSceneNode node = zoneData.mAssociatedNode;

            if (null == zoneData.Octant)
            {
                //if outside the octree, force into the root node.
                if (!zoneData._isIn(this.rootOctree.Box))
                {
                    this.rootOctree.AddNode(node);
                }
                else
                {
                    AddNodeToOctree(node, this.rootOctree, 0);
                }
                return;
            }

            if (!zoneData._isIn(zoneData.Octant.Box))
            {
                //if outside the octree, force into the root node.
                if (!zoneData._isIn(this.rootOctree.Box))
                {
                    // skip if it's already in the root node.
                    if (((OctreeZoneData)node.GetZoneData(this)).Octant == this.rootOctree)
                    {
                        return;
                    }

                    RemoveNodeFromOctree(node);
                    this.rootOctree.AddNode(node);
                }
                else
                {
                    AddNodeToOctree(node, this.rootOctree, 0);
                }
            }
        }
Пример #14
0
        /** Set the enclosure node for this TerrainZone
         */

        public override void SetEnclosureNode(PCZSceneNode node)
        {
            mEnclosureNode = node;
            if (null != node)
            {
                // anchor the node to this zone
                node.AnchorToHomeZone(this);
                // make sure node world bounds are up to date
                //node._updateBounds();
                // DON'T resize the octree to the same size as the enclosure node bounding box
                // resize(node->_getWorldAABB());
                // EXPERIMENTAL - prevent terrain zone enclosure node from visiting other zones
                node.AllowToVisit = false;
            }
        }
Пример #15
0
        public override void RemoveNode(PCZSceneNode n)
        {
            if (null != n)
            {
                RemoveNodeFromOctree(n);
            }

            if (n.HomeZone == this)
            {
                mHomeNodeList.Remove(n);
            }
            else
            {
                mVisitorNodeList.Remove(n);
            }
        }
Пример #16
0
        public override void SetZoneGeometry(string filename, PCZSceneNode parentNode)
        {
            string entityName, nodeName;

            entityName = Name + "_entity";
            nodeName   = Name + "_Node";
            Entity ent = mPCZSM.CreateEntity(entityName, filename);
            // create a node for the entity
            PCZSceneNode node;

            node = (PCZSceneNode)parentNode.CreateChildSceneNode(nodeName);
            // attach the entity to the node
            node.AttachObject(ent);
            // set the node as the enclosure node
            SetEnclosureNode(node);
        }
Пример #17
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);
        }
Пример #18
0
        /** Only removes the node from the octree.  It leaves the octree, even if it's empty.
         */

        public void RemoveNodeFromOctree(PCZSceneNode n)
        {
            // Skip if octree has been destroyed (shutdown conditions)
            if (null == this.rootOctree)
            {
                return;
            }

            Octree oct = ((OctreeZoneData)n.GetZoneData(this)).Octant;

            if (null != oct)
            {
                oct.RemoveNode(n);
            }

            ((OctreeZoneData)n.GetZoneData(this)).Octant = null;
        }
Пример #19
0
        public override void FindNodes(Ray t, ref List <PCZSceneNode> list, List <Portal> visitedPortals, bool includeVisitors,
                                       bool recurseThruPortals, PCZSceneNode exclude)
        {
            // if this zone has an enclosure, check against the enclosure AABB first
            if (null != mEnclosureNode)
            {
                IntersectResult nsect = t.Intersects(mEnclosureNode.WorldAABB);
                if (!nsect.Hit)
                {
                    // AABB of zone does not intersect t, just return.
                    return;
                }
            }

            // use the Octree to more efficiently find nodes intersecting the ray
            this.rootOctree._findNodes(t, ref list, exclude, includeVisitors, false);

            // if asked to, recurse through portals
            if (recurseThruPortals)
            {
                foreach (Portal portal in mPortals)
                {
                    // check portal versus boundign box
                    if (portal.intersects(t))
                    {
                        // make sure portal hasn't already been recursed through

                        if (!visitedPortals.Contains(portal))
                        {
                            // save portal to the visitedPortals list
                            visitedPortals.Add(portal);
                            // recurse into the connected zone
                            portal.getTargetZone().FindNodes(t, ref list, visitedPortals, includeVisitors, recurseThruPortals, exclude);
                        }
                    }
                }
            }
        }
Пример #20
0
        public void RemoveNode(PCZSceneNode node)
        {
            //PCZSceneNode check;
            //int i;
            //int Index;

            //Index = NodeList.Count - 1;

            //for ( i = Index; i >= 0; i-- )
            //{
            //    check = ( PCZSceneNode ) NodeList.Values[ i ];

            //    if ( check == node )
            //    {
            //        ( ( OctreeZoneData ) node.GetZoneData( zone ) ).Octant = null;
            //        NodeList.RemoveAt( i );
            //        UnRef();
            //    }
            //}

            ((OctreeZoneData)node.GetZoneData(this.zone)).Octant = null;
            NodeList.Remove(node);
            UnRef();
        }
Пример #21
0
 public OctreeZoneData(PCZSceneNode node, PCZone zone)
     : base(node, zone)
 {
     this.mOctant          = null;
     this.mOctreeWorldAABB = AxisAlignedBox.Null;
 }
Пример #22
0
        public void _findNodes(PlaneBoundedVolume t, ref List <PCZSceneNode> list, PCZSceneNode exclude, bool includeVisitors,
                               bool full)
        {
            if (!full)
            {
                AxisAlignedBox obox;
                _getCullBounds(out obox);

                Intersection isect = intersect(t, obox);

                if (isect == Intersection.OUTSIDE)
                {
                    return;
                }

                full = (isect == Intersection.INSIDE);
            }


            foreach (PCZSceneNode on in this.nodeList.Values)
            {
                if (on != exclude && (on.HomeZone == this.zone || includeVisitors))
                {
                    if (full)
                    {
                        // make sure the node isn't already on the list
                        list.Add(on);
                    }

                    else
                    {
                        Intersection nsect = intersect(t, on.WorldAABB);

                        if (nsect != Intersection.OUTSIDE)
                        {
                            // make sure the node isn't already on the list
                            list.Add(on);
                        }
                    }
                }
            }

            Octree child;

            if ((child = this.Children[0, 0, 0]) != null)
            {
                child._findNodes(t, ref list, exclude, includeVisitors, full);
            }

            if ((child = this.Children[1, 0, 0]) != null)
            {
                child._findNodes(t, ref list, exclude, includeVisitors, full);
            }

            if ((child = this.Children[0, 1, 0]) != null)
            {
                child._findNodes(t, ref list, exclude, includeVisitors, full);
            }

            if ((child = this.Children[1, 1, 0]) != null)
            {
                child._findNodes(t, ref list, exclude, includeVisitors, full);
            }

            if ((child = this.Children[0, 0, 1]) != null)
            {
                child._findNodes(t, ref list, exclude, includeVisitors, full);
            }

            if ((child = this.Children[1, 0, 1]) != null)
            {
                child._findNodes(t, ref list, exclude, includeVisitors, full);
            }

            if ((child = this.Children[0, 1, 1]) != null)
            {
                child._findNodes(t, ref list, exclude, includeVisitors, full);
            }

            if ((child = this.Children[1, 1, 1]) != null)
            {
                child._findNodes(t, ref list, exclude, includeVisitors, full);
            }
        }
Пример #23
0
        /** create zone specific data for a node
         */

        public override void CreateNodeZoneData(PCZSceneNode node)
        {
            var ozd = new OctreeZoneData(node, this);

            node.SetZoneData(this, ozd);
        }
Пример #24
0
        private void AddNodeToOctree(PCZSceneNode n, Octree octant, int depth)
        {
            // Skip if octree has been destroyed (shutdown conditions)
            if (null == this.rootOctree)
            {
                return;
            }

            AxisAlignedBox bx = n.WorldAABB;


            //if the octree is twice as big as the scene node,
            //we will add it to a child.
            if ((depth < this.maxDepth) && octant.IsTwiceSize(bx))
            {
                int x = 0, y = 0, z = 0;
                octant._getChildIndexes(bx, ref x, ref y, ref z);

                if (octant.Children[x, y, z] == null)
                {
                    octant.Children[x, y, z] = new Octree(this, octant);
                    Vector3 octantMin = octant.Box.Minimum;
                    Vector3 octantMax = octant.Box.Maximum;
                    Vector3 min, max;

                    if (x == 0)
                    {
                        min.x = octantMin.x;
                        max.x = (octantMin.x + octantMax.x) / 2;
                    }

                    else
                    {
                        min.x = (octantMin.x + octantMax.x) / 2;
                        max.x = octantMax.x;
                    }

                    if (y == 0)
                    {
                        min.y = octantMin.y;
                        max.y = (octantMin.y + octantMax.y) / 2;
                    }

                    else
                    {
                        min.y = (octantMin.y + octantMax.y) / 2;
                        max.y = octantMax.y;
                    }

                    if (z == 0)
                    {
                        min.z = octantMin.z;
                        max.z = (octantMin.z + octantMax.z) / 2;
                    }

                    else
                    {
                        min.z = (octantMin.z + octantMax.z) / 2;
                        max.z = octantMax.z;
                    }

                    octant.Children[x, y, z].Box.SetExtents(min, max);
                    octant.Children[x, y, z].HalfSize = (max - min) / 2;
                }

                AddNodeToOctree(n, octant.Children[x, y, z], ++depth);
            }
            else
            {
                if (((OctreeZoneData)n.GetZoneData(this)).Octant == octant)
                {
                    return;
                }

                RemoveNodeFromOctree(n);
                octant.AddNode(n);
            }
        }