//------------------------------------------------------------------------- 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); } }
//------------------------------------------------------------------------- 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))); }
//------------------------------------------------------------------------- public void ClearZone() { this.mTerrainZonePages.Clear(); DestroyLevelIndexes(); // Octree has destroyed our root this.mTerrainRoot = null; }
//------------------------------------------------------------------------- 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); } }
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 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); }
public void AddNode(PCZSceneNode node) { this.nodeList[node.Name] = node; ((OctreeZoneData)node.GetZoneData(this.zone)).Octant = this; //update total counts. Ref(); }
public void TestRecreationOfChildNodeAfterRemovalByName() { Node node = new PCZSceneNode(this.sceneManager); node.CreateChild(Name); node.RemoveChild(Name); node.CreateChild(Name); }
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 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; }
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); } }
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); } } }
/** 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; } }
public override void RemoveNode(PCZSceneNode n) { if (null != n) { RemoveNodeFromOctree(n); } if (n.HomeZone == this) { mHomeNodeList.Remove(n); } else { mVisitorNodeList.Remove(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); // attach the entity to the node node.AttachObject(ent); // set the node as the enclosure node SetEnclosureNode(node); }
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); }
/** 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; }
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); } } } } }
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 OctreeZoneData(PCZSceneNode node, PCZone zone) : base(node, zone) { this.mOctant = null; this.mOctreeWorldAABB = AxisAlignedBox.Null; }
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); } }
/** create zone specific data for a node */ public override void CreateNodeZoneData(PCZSceneNode node) { var ozd = new OctreeZoneData(node, this); node.SetZoneData(this, ozd); }
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); } }