Наследование: Axiom.Core.SceneNode
Пример #1
0
        /* Recursively check for intersection of the given scene node
         * with zone portals.  If the node touches a portal, then the
         * connected zone is assumed to be touched.  The zone adds
         * the node to its node list and the node adds the zone to
         * its visiting zone list.
         *
         * NOTE: This function assumes that the home zone of the node
         *       is correct.  The function "_updateHomeZone" in PCZSceneManager
         *		 takes care of this and should have been called before
         *		 this function.
         */

        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 portal in mPortals)
            {
                if (portal != ignorePortal && portal.intersects(pczsn) != PortalIntersectResult.NO_INTERSECT)
                {
                    connectedZone = portal.getTargetZone();

                    if (connectedZone != pczsn.HomeZone && !pczsn.IsVisitingZone(connectedZone))
                    {
                        pczsn.AddZoneToVisitingZonesMap(connectedZone);

                        connectedZone.AddNode(pczsn);

                        connectedZone.CheckNodeAgainstPortals(pczsn, portal.getTargetPortal());
                    }
                }
            }
        }
        public void TestRecreationOfChildNodeAfterRemovalByReference()
        {
            Node node = new PCZSceneNode( this.fakeSceneManager );
            Node childNode = node.CreateChild( Name );

            node.RemoveChild( childNode );
            node.CreateChild( Name );
        }
Пример #3
0
		public override void RemoveNode( PCZSceneNode n )
		{
			if ( n.HomeZone == this )
			{
				mHomeNodeList.Remove( n );
			}
			else
			{
				mVisitorNodeList.Remove( n );
			}
		}
Пример #4
0
 public override void RemoveNode(PCZSceneNode n)
 {
     if (n.HomeZone == this)
     {
         mHomeNodeList.Remove(n);
     }
     else
     {
         mVisitorNodeList.Remove(n);
     }
 }
Пример #5
0
		// this call adds the given node to either the zone's list
		// of nodes at home in the zone, or to the list of visiting nodes
		// NOTE: The list is decided by the node's homeZone value, so
		// that must be set correctly before calling this function.
		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 );
			}
		}
Пример #6
0
 // this call adds the given node to either the zone's list
 // of nodes at home in the zone, or to the list of visiting nodes
 // NOTE: The list is decided by the node's homeZone value, so
 // that must be set correctly before calling this function.
 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);
     }
 }
Пример #7
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, Vector3.Zero, Quaternion.Identity));
            // attach the entity to the node
            node.AttachObject(ent);
            // set the node as the enclosure node
            SetEnclosureNode(node);
        }
Пример #8
0
        /* The following function checks if a node has left it's current home zone.
         * This is done by checking each portal in the zone.  If the node has crossed
         * the portal, then the current zone is no longer the home zone of the node.  The
         * function then recurses into the connected zones.  Once a zone is found where
         * the node does NOT cross out through a portal, that zone is the new home zone.
         *      NOTE: For this function to work, the node must start out in the proper zone to
         *                begin with!
         */

        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);
        }
Пример #9
0
		/* The following function checks if a node has left it's current home zone.
		* This is done by checking each portal in the zone.  If the node has crossed
		* the portal, then the current zone is no longer the home zone of the node.  The
		* function then recurses into the connected zones.  Once a zone is found where
		* the node does NOT cross out through a portal, that zone is the new home zone.
		NOTE: For this function to work, the node must start out in the proper zone to
			  begin with!
		*/
		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;

		}
Пример #10
0
		public abstract void FindNodes( Ray t, ref List<PCZSceneNode> list, List<Portal> visitedPortals, bool includeVisitors,
		                                bool recurseThruPortals, PCZSceneNode exclude );
Пример #11
0
		public ZoneData( PCZSceneNode node, PCZone zone )
		{
			this.mAssociatedZone = zone;
			this.mAssociatedNode = node;
		}
Пример #12
0
		/** create zone specific data for a node
		*/

		public virtual void CreateNodeZoneData( PCZSceneNode pczsn )
		{
		}
Пример #13
0
		/* Update a node's home zone */
		public abstract PCZone UpdateNodeHomeZone( PCZSceneNode pczsn, bool allowBackTouches );
Пример #14
0
 public ZoneData(PCZSceneNode node, PCZone zone)
 {
     this.mAssociatedZone = zone;
     this.mAssociatedNode = node;
 }
Пример #15
0
		public abstract void RemoveNode( PCZSceneNode n );
Пример #16
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;
                }
            }

            // check nodes at home in this zone
            foreach (PCZSceneNode pczsn in mHomeNodeList)
            {
                if (pczsn != exclude)
                {
                    // make sure node is not already in the list (might have been added in another
                    // zone it was visiting)
                    if (!list.Contains(pczsn))
                    {
                        IntersectResult nsect = t.Intersects(pczsn.WorldAABB);
                        if (nsect.Hit)
                        {
                            list.Add(pczsn);
                        }
                    }
                }
            }

            if (includeVisitors)
            {
                // check visitor nodes
                foreach (PCZSceneNode pczsn in mVisitorNodeList)
                {
                    if (pczsn != exclude)
                    {
                        // make sure node is not already in the list (might have been added in another
                        // zone it was visiting)

                        if (!list.Contains(pczsn))
                        {
                            IntersectResult nsect = t.Intersects(pczsn.WorldAABB);
                            if (nsect.Hit)
                            {
                                list.Add(pczsn);
                            }
                        }
                    }
                }
            }

            // 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);
                        }
                    }
                }
            }
        }
Пример #17
0
 public abstract void FindNodes(Ray t, ref List <PCZSceneNode> list, List <Portal> visitedPortals, bool includeVisitors,
                                bool recurseThruPortals, PCZSceneNode exclude);
Пример #18
0
        /** Set the enclosure node for this Zone
         */

        public override void SetEnclosureNode(PCZSceneNode node)
        {
            mEnclosureNode = node;
            // anchor the node to this zone
            node.AnchorToHomeZone(this);
        }
Пример #19
0
		/** create zone specific data for a node
		*/
		public override void CreateNodeZoneData( PCZSceneNode node )
		{
			OctreeZoneData ozd = new OctreeZoneData( node, this );
			node.SetZoneData( this, ozd );
		}
Пример #20
0
		// create any zone-specific data necessary for all zones for the given node
		public void CreateZoneSpecificNodeData( PCZSceneNode node )
		{
			foreach ( PCZone zone in this.zones )
			{
				if ( zone.RequiresZoneSpecificNodeData )
				{
					zone.CreateNodeZoneData( node );
				}
			}
		}
Пример #21
0
		//* The following function checks if a node has left it's current home zone.
		//* This is done by checking each portal in the zone.  If the node has crossed
		//* the portal, then the current zone is no longer the home zone of the node.  The
		//* function then recurses into the connected zones.  Once a zone is found where
		//* the node does NOT cross out through a portal, that zone is the new home zone.
		//* When this function is done, the node should have the correct home zone already
		//* set.  A pointer is returned to this zone as well.
		//*
		//* NOTE: If the node does not have a home zone when this function is called on it,
		//*       the function will do its best to find the proper zone for the node using
		//*       bounding box volume testing.  This CAN fail to find the correct zone in
		//*		some scenarios, so it is best for the user to EXPLICITLY set the home
		//*		zone of the node when the node is added to the scene using
		//*       PCZSceneNode::setHomeZone()
		//*
		public void UpdateHomeZone( PCZSceneNode pczsn, bool allowBackTouches )
		{
			// Skip if root PCZoneTree has been destroyed (shutdown conditions)
			if ( null == this.defaultZone )
			{
				return;
			}

			PCZone startzone;
			PCZone newHomeZone;

			// start with current home zone of the node
			startzone = pczsn.HomeZone;

			if ( null != startzone )
			{
				if ( !pczsn.IsAnchored )
				{
					newHomeZone = startzone.UpdateNodeHomeZone( pczsn, false );
				}
				else
				{
					newHomeZone = startzone;
				}

				if ( newHomeZone != startzone )
				{
					// add the node to the home zone
					newHomeZone.AddNode( pczsn );
				}
			}
			else
			{
				// the node hasn't had it's home zone set yet, so do our best to
				// find the home zone using volume testing.
				Vector3 nodeCenter = pczsn.DerivedPosition;
				PCZone bestZone = FindZoneForPoint( nodeCenter );
				// set the best zone as the node's home zone
				pczsn.HomeZone = bestZone;
				// add the node to the zone
				bestZone.AddNode( pczsn );
			}

			return;
		}
Пример #22
0
        /* Test if a scene node intersected a portal during the last time delta
         * (from last frame time to current frame time).  This function checks
         * if the node "crossed over" the portal also.
         */

        public PortalIntersectResult intersects(PCZSceneNode pczsn)
        {
            // Only check if portal is open
            if (this.mOpen)
            {
                if (pczsn == this.mNode)
                {
                    // ignore the scene node if it is the node the portal is associated with
                    return(PortalIntersectResult.NO_INTERSECT);
                }
                // most complicated case - if the portal is a quad:
                if (this.mType == PORTAL_TYPE.PORTAL_TYPE_QUAD)
                {
                    // the node is modeled as a line segment (prevPostion to currentPosition)
                    // intersection test is then between the capsule and the line segment.
                    var nodeSegment = new Segment();
                    nodeSegment.Set(pczsn.PreviousPosition, pczsn.DerivedPosition);

                    // we model the portal as a line swept sphere (mPrevDerivedCP to mDerivedCP).
                    var portalCapsule = new Capsule();
                    portalCapsule.Set(this.mPrevDerivedCP, this.mDerivedCP, this.mRadius);

                    if (portalCapsule.Intersects(nodeSegment))
                    {
                        // the portal intersected the node at some time from last frame to this frame.
                        // Now check if node "crossed" the portal
                        // a crossing occurs if the "side" of the final position of the node compared
                        // to the final position of the portal is negative AND the initial position
                        // of the node compared to the initial position of the portal is non-negative
                        if (this.mDerivedPlane.GetSide(pczsn.DerivedPosition) == PlaneSide.Negative &&
                            this.mPrevDerivedPlane.GetSide(pczsn.DerivedPosition) != PlaneSide.Negative)
                        {
                            // safety check - make sure the node has at least one dimension which is
                            // small enough to fit through the portal! (avoid the "elephant fitting
                            // through a mouse hole" case)
                            Vector3 nodeHalfVector = pczsn.WorldAABB.HalfSize;
                            var     portalBox      = new Vector3(this.mRadius, this.mRadius, this.mRadius);
                            portalBox.Floor(nodeHalfVector);
                            if (portalBox.x < this.mRadius)
                            {
                                // crossing occurred!
                                return(PortalIntersectResult.INTERSECT_CROSS);
                            }
                        }
                    }
                    // there was no crossing of the portal by the node, but it might be touching
                    // the portal.  We check for this by checking the bounding box of the node vs.
                    // the sphere of the portal
                    if (this.mDerivedSphere.Intersects(pczsn.WorldAABB) &&
                        this.mDerivedPlane.GetSide(pczsn.WorldAABB) == PlaneSide.Both)
                    {
                        // intersection but no crossing
                        // note this means that the node is CURRENTLY touching the portal.
                        if (this.mDerivedPlane.GetSide(pczsn.DerivedPosition) != PlaneSide.Negative)
                        {
                            // the node is on the positive (front) or exactly on the CP of the portal
                            return(PortalIntersectResult.INTERSECT_NO_CROSS);
                        }
                        else
                        {
                            // the node is on the negative (back) side of the portal - it might be in the wrong zone!
                            return(PortalIntersectResult.INTERSECT_BACK_NO_CROSS);
                        }
                    }
                    // no intersection CURRENTLY.  (there might have been an intersection
                    // during the time between last frame and this frame, but it wasn't a portal
                    // crossing, and it isn't touching anymore, so it doesn't matter.
                    return(PortalIntersectResult.NO_INTERSECT);
                }
                else if (this.mType == PORTAL_TYPE.PORTAL_TYPE_AABB)
                {
                    // for aabb's we check if the center point went from being inside to being outside
                    // the aabb (or vice versa) for crossing.
                    var aabb = new AxisAlignedBox(this.mDerivedCorners[0], this.mDerivedCorners[1]);
                    //bool previousInside = aabb.contains(pczsn->getPrevPosition());
                    bool currentInside = aabb.Contains(pczsn.DerivedPosition);
                    if (this.mDirection == Vector3.UnitZ)
                    {
                        // portal norm is "outward" pointing, look for going from outside to inside
                        //if (previousInside == false &&
                        if (currentInside == true)
                        {
                            return(PortalIntersectResult.INTERSECT_CROSS);
                        }
                    }
                    else
                    {
                        // portal norm is "inward" pointing, look for going from inside to outside
                        //if (previousInside == true &&
                        if (currentInside == false)
                        {
                            return(PortalIntersectResult.INTERSECT_CROSS);
                        }
                    }
                    // doesn't cross, but might be touching.  This is a little tricky because we only
                    // care if the node aab is NOT fully contained in the portal aabb because we consider
                    // the surface of the portal aabb the actual 'portal'.  First, check to see if the
                    // aab of the node intersects the aabb portal
                    if (aabb.Intersects(pczsn.WorldAABB))
                    {
                        // now check if the intersection between the two is not the same as the
                        // full node aabb, if so, then this means that the node is not fully "contained"
                        // which is what we are looking for.
                        AxisAlignedBox overlap = aabb.Intersection(pczsn.WorldAABB);
                        if (overlap != pczsn.WorldAABB)
                        {
                            return(PortalIntersectResult.INTERSECT_NO_CROSS);
                        }
                    }
                    return(PortalIntersectResult.NO_INTERSECT);
                }
                else
                {
                    // for spheres we check if the center point went from being inside to being outside
                    // the sphere surface (or vice versa) for crossing.
                    //Real previousDistance2 = mPrevDerivedCP.squaredDistance(pczsn->getPrevPosition());
                    Real currentDistance2 = this.mDerivedCP.DistanceSquared(pczsn.DerivedPosition);
                    Real mRadius2         = this.mRadius * this.mRadius;
                    if (this.mDirection == Vector3.UnitZ)
                    {
                        // portal norm is "outward" pointing, look for going from outside to inside
                        //if (previousDistance2 >= mRadius2 &&
                        if (currentDistance2 < mRadius2)
                        {
                            return(PortalIntersectResult.INTERSECT_CROSS);
                        }
                    }
                    else
                    {
                        // portal norm is "inward" pointing, look for going from inside to outside
                        //if (previousDistance2 < mRadius2 &&
                        if (currentDistance2 >= mRadius2)
                        {
                            return(PortalIntersectResult.INTERSECT_CROSS);
                        }
                    }
                    // no crossing, but might be touching - check distance
                    if (System.Math.Sqrt(System.Math.Abs(mRadius2 - currentDistance2)) <= this.mRadius)
                    {
                        return(PortalIntersectResult.INTERSECT_NO_CROSS);
                    }
                    return(PortalIntersectResult.NO_INTERSECT);
                }
            }
            return(PortalIntersectResult.NO_INTERSECT);
        }
Пример #23
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 );
			}
		}
Пример #24
0
 /* Update a node's home zone */
 public abstract PCZone UpdateNodeHomeZone(PCZSceneNode pczsn, bool allowBackTouches);
Пример #25
0
 /** (recursive) check the given node against all portals in the zone
  */
 public abstract void CheckNodeAgainstPortals(PCZSceneNode pczsn, Portal ignorePortal);
Пример #26
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() );
					}
				}
			}
		}
Пример #27
0
 public abstract void FindNodes(Sphere t, ref List <PCZSceneNode> nodes, List <Portal> portals, bool includeVisitors,
                                bool recurseThruPortals, PCZSceneNode exclude);
Пример #28
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 == rootOctree )
				return;

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

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

			( (OctreeZoneData)n.GetZoneData( this ) ).Octant = null;
		}
Пример #29
0
 /* called by PCZSM during setZoneGeometry() */
 public abstract void SetZoneGeometry(string filename, PCZSceneNode parentNode);
Пример #30
0
		void AddNodeToOctree( PCZSceneNode n, Octree octant, int depth )
		{

			// Skip if octree has been destroyed (shutdown conditions)
			if ( null == 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 < 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 );
			}
		}
Пример #31
0
		public abstract void AddNode( PCZSceneNode n );
Пример #32
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
			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 );
						}
					}
				}
			}

		}
Пример #33
0
		public abstract void SetEnclosureNode( PCZSceneNode n );
Пример #34
0
		public void AddNode( PCZSceneNode node )
		{
			this.nodeList[ node.Name ] = node;
			( (OctreeZoneData)node.GetZoneData( this.zone ) ).Octant = this;

			//update total counts.
			Ref();
		}
Пример #35
0
		/** (recursive) check the given node against all portals in the zone
		*/
		public abstract void CheckNodeAgainstPortals( PCZSceneNode pczsn, Portal ignorePortal );
Пример #36
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();
		}
Пример #37
0
		public abstract void FindNodes( Sphere t, ref List<PCZSceneNode> nodes, List<Portal> portals, bool includeVisitors,
		                                bool recurseThruPortals, PCZSceneNode exclude );
Пример #38
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 );
			}
		}
Пример #39
0
		/* called by PCZSM during setZoneGeometry() */
		public abstract void SetZoneGeometry( string filename, PCZSceneNode parentNode );
Пример #40
0
		public OctreeZoneData( PCZSceneNode node, PCZone zone )
			: base( node, zone )
		{
			this.mOctant = null;
			this.mOctreeWorldAABB = AxisAlignedBox.Null;
		}
Пример #41
0
		/* Recursively check for intersection of the given scene node
		 * with zone portals.  If the node touches a portal, then the
		 * connected zone is assumed to be touched.  The zone adds
		 * the node to its node list and the node adds the zone to
		 * its visiting zone list.
		 *
		 * NOTE: This function assumes that the home zone of the node
		 *       is correct.  The function "_updateHomeZone" in PCZSceneManager
		 *		 takes care of this and should have been called before
		 *		 this function.
		 */

		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 portal in mPortals )
			{
				if ( portal != ignorePortal && portal.intersects( pczsn ) != PortalIntersectResult.NO_INTERSECT )
				{
					connectedZone = portal.getTargetZone();

					if ( connectedZone != pczsn.HomeZone &&
						!pczsn.IsVisitingZone( connectedZone ) )
					{
						pczsn.AddZoneToVisitingZonesMap( connectedZone );

						connectedZone.AddNode( pczsn );

						connectedZone.CheckNodeAgainstPortals( pczsn, portal.getTargetPortal() );
					}
				}
			}
		}
Пример #42
0
 public abstract void AddNode(PCZSceneNode n);
Пример #43
0
		/** Set the enclosure node for this Zone
		*/
		public override void SetEnclosureNode( PCZSceneNode node )
		{
			mEnclosureNode = node;
			// anchor the node to this zone
			node.AnchorToHomeZone( this );
		}
Пример #44
0
 public abstract void RemoveNode(PCZSceneNode n);
Пример #45
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;
				}
			}

			// check nodes at home in this zone
			foreach ( PCZSceneNode pczsn in mHomeNodeList )
			{
				if ( pczsn != exclude )
				{
					// make sure node is not already in the list (might have been added in another
					// zone it was visiting)
					if ( !list.Contains( pczsn ) )
					{
						IntersectResult nsect = t.Intersects( pczsn.WorldAABB );
						if ( nsect.Hit )
						{
							list.Add( pczsn );
						}
					}
				}
			}

			if ( includeVisitors )
			{
				// check visitor nodes
				foreach ( PCZSceneNode pczsn in mVisitorNodeList )
				{
					if ( pczsn != exclude )
					{
						// make sure node is not already in the list (might have been added in another
						// zone it was visiting)

						if ( !list.Contains( pczsn ) )
						{
							IntersectResult nsect = t.Intersects( pczsn.WorldAABB );
							if ( nsect.Hit )
							{
								list.Add( pczsn );
							}
						}
					}
				}
			}

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

		}
Пример #46
0
 public abstract void SetEnclosureNode(PCZSceneNode n);
Пример #47
0
		//-------------------------------------------------------------------------
		public override void SetZoneGeometry( string filename, PCZSceneNode parentNode )
		{
			String entityName, nodeName;
			entityName = this.Name + "_entity";
			nodeName = this.Name + "_Node";
			Entity ent = mPCZSM.CreateEntity( entityName, filename );
			// create a node for the entity
			PCZSceneNode node;
			node = (PCZSceneNode)( parentNode.CreateChildSceneNode( nodeName, Vector3.Zero, Quaternion.Identity ) );
			// attach the entity to the node
			node.AttachObject( ent );
			// set the node as the enclosure node
			SetEnclosureNode( node );
		}
Пример #48
0
        /** create zone specific data for a node
         */

        public virtual void CreateNodeZoneData(PCZSceneNode pczsn)
        {
        }