/* 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 ); }
public override void RemoveNode( PCZSceneNode n ) { if ( n.HomeZone == this ) { mHomeNodeList.Remove( n ); } else { mVisitorNodeList.Remove( n ); } }
public override void RemoveNode(PCZSceneNode n) { if (n.HomeZone == this) { mHomeNodeList.Remove(n); } else { mVisitorNodeList.Remove(n); } }
// 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 ); } }
// 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); } }
//------------------------------------------------------------------------- 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); }
/* 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); }
/* 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; }
public abstract void FindNodes( Ray t, ref List<PCZSceneNode> list, List<Portal> visitedPortals, bool includeVisitors, bool recurseThruPortals, PCZSceneNode exclude );
public ZoneData( PCZSceneNode node, PCZone zone ) { this.mAssociatedZone = zone; this.mAssociatedNode = node; }
/** create zone specific data for a node */ public virtual void CreateNodeZoneData( PCZSceneNode pczsn ) { }
/* Update a node's home zone */ public abstract PCZone UpdateNodeHomeZone( PCZSceneNode pczsn, bool allowBackTouches );
public ZoneData(PCZSceneNode node, PCZone zone) { this.mAssociatedZone = zone; this.mAssociatedNode = node; }
public abstract void RemoveNode( PCZSceneNode n );
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); } } } } }
public abstract void FindNodes(Ray t, ref List <PCZSceneNode> list, List <Portal> visitedPortals, bool includeVisitors, bool recurseThruPortals, PCZSceneNode exclude);
/** Set the enclosure node for this Zone */ public override void SetEnclosureNode(PCZSceneNode node) { mEnclosureNode = node; // anchor the node to this zone node.AnchorToHomeZone(this); }
/** create zone specific data for a node */ public override void CreateNodeZoneData( PCZSceneNode node ) { OctreeZoneData ozd = new OctreeZoneData( node, this ); node.SetZoneData( this, ozd ); }
// 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 ); } } }
//* 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; }
/* 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); }
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 ); } }
/* Update a node's home zone */ public abstract PCZone UpdateNodeHomeZone(PCZSceneNode pczsn, bool allowBackTouches);
/** (recursive) check the given node against all portals in the zone */ public abstract void CheckNodeAgainstPortals(PCZSceneNode pczsn, Portal ignorePortal);
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() ); } } } }
public abstract void FindNodes(Sphere t, ref List <PCZSceneNode> nodes, List <Portal> portals, bool includeVisitors, bool recurseThruPortals, PCZSceneNode exclude);
/** 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; }
/* called by PCZSM during setZoneGeometry() */ public abstract void SetZoneGeometry(string filename, PCZSceneNode parentNode);
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 ); } }
public abstract void AddNode( PCZSceneNode n );
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 ); } } } } }
public abstract void SetEnclosureNode( PCZSceneNode n );
public void AddNode( PCZSceneNode node ) { this.nodeList[ node.Name ] = node; ( (OctreeZoneData)node.GetZoneData( this.zone ) ).Octant = this; //update total counts. Ref(); }
/** (recursive) check the given node against all portals in the zone */ public abstract void CheckNodeAgainstPortals( PCZSceneNode pczsn, Portal ignorePortal );
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(); }
public abstract void FindNodes( Sphere t, ref List<PCZSceneNode> nodes, List<Portal> portals, bool includeVisitors, bool recurseThruPortals, PCZSceneNode exclude );
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 ); } }
/* called by PCZSM during setZoneGeometry() */ public abstract void SetZoneGeometry( string filename, PCZSceneNode parentNode );
public OctreeZoneData( PCZSceneNode node, PCZone zone ) : base( node, zone ) { this.mOctant = null; this.mOctreeWorldAABB = AxisAlignedBox.Null; }
/* 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 abstract void AddNode(PCZSceneNode n);
/** Set the enclosure node for this Zone */ public override void SetEnclosureNode( PCZSceneNode node ) { mEnclosureNode = node; // anchor the node to this zone node.AnchorToHomeZone( this ); }
public abstract void RemoveNode(PCZSceneNode n);
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 ); } } } } }
public abstract void SetEnclosureNode(PCZSceneNode n);
//------------------------------------------------------------------------- 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 ); }
/** create zone specific data for a node */ public virtual void CreateNodeZoneData(PCZSceneNode pczsn) { }