public OctreeZone( PCZSceneManager creator, string name ) : base( creator, name ) { mZoneTypeName = "ZoneType_Octree"; // init octree AxisAlignedBox b = new AxisAlignedBox( new Vector3( -10000, -10000, -10000 ), new Vector3( 10000, 10000, 10000 ) ); int depth = 8; rootOctree = null; Init( b, depth ); }
public void Init( AxisAlignedBox box, int depth ) { if ( null != rootOctree ) rootOctree = null; rootOctree = new Octree( this, null ); maxDepth = depth; this.box = box; rootOctree.Box = box; Vector3 min = box.Minimum; Vector3 max = box.Maximum; rootOctree.HalfSize = ( max - min ) / 2; }
public void Init(AxisAlignedBox box, int depth) { if (null != this.rootOctree) { this.rootOctree = null; } this.rootOctree = new Octree(this, null); this.maxDepth = depth; this.box = box; this.rootOctree.Box = box; Vector3 min = box.Minimum; Vector3 max = box.Maximum; this.rootOctree.HalfSize = (max - min) / 2; }
public Octree(PCZone zone, Octree parent) { this.wireBoundingBox = null; HalfSize = new Vector3(); this.parent = parent; NunodeList = 0; this.zone = zone; //initialize all children to null. for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { this.Children[i, j, k] = null; } } } }
public OctreeZoneData(PCZSceneNode node, PCZone zone) : base(node, zone) { this.mOctant = null; this.mOctreeWorldAABB = AxisAlignedBox.Null; }
public OctreeZoneData( PCZSceneNode node, PCZone zone ) : base( node, zone ) { this.mOctant = null; this.mOctreeWorldAABB = AxisAlignedBox.Null; }
public Octree( PCZone zone, Octree parent ) { this.wireBoundingBox = null; HalfSize = new Vector3(); this.parent = parent; NunodeList = 0; this.zone = zone; //initialize all children to null. for ( int i = 0; i < 2; i++ ) { for ( int j = 0; j < 2; j++ ) { for ( int k = 0; k < 2; k++ ) { this.Children[ i, j, k ] = null; } } } }
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); } }
private void WalkOctree(PCZCamera camera, ref List <PCZSceneNode> visibleNodeList, RenderQueue queue, Octree octant, VisibleObjectsBoundsInfo visibleBounds, bool foundvisible, bool onlyShadowCasters, bool displayNodes, bool showBoundingBoxes) { //return immediately if nothing is in the node. if (octant.NunodeList == 0) { return; } Visibility v = Visibility.None; if (foundvisible) { v = Visibility.Full; } else if (octant == this.rootOctree) { v = Visibility.Partial; } else { AxisAlignedBox box = octant.Box; v = camera.GetVisibility(box); } // if the octant is visible, or if it's the root node... if (v != Visibility.None) { //Add stuff to be rendered; bool vis = true; foreach (PCZSceneNode sn in octant.NodeList.Values) { // if the scene node is already visible, then we can skip it if (sn.LastVisibleFrame != mLastVisibleFrame || sn.LastVisibleFromCamera != camera) { // if this octree is partially visible, manually cull all // scene nodes attached directly to this level. if (v == Visibility.Partial) { vis = camera.IsObjectVisible(sn.WorldAABB); } if (vis) { // add the node to the render queue sn.AddToRenderQueue(camera, queue, onlyShadowCasters, visibleBounds); // add it to the list of visible nodes visibleNodeList.Add(sn); // if we are displaying nodes, add the node renderable to the queue if (displayNodes) { queue.AddRenderable(sn.GetDebugRenderable()); } // if the scene manager or the node wants the bounding box shown, add it to the queue if (sn.ShowBoundingBox || showBoundingBoxes) { sn.AddBoundingBoxToQueue(queue); } // flag the node as being visible this frame sn.LastVisibleFrame = mLastVisibleFrame; sn.LastVisibleFromCamera = camera; } } } Octree child; bool childfoundvisible = (v == Visibility.Full); if ((child = octant.Children[0, 0, 0]) != null) { WalkOctree(camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes); } if ((child = octant.Children[1, 0, 0]) != null) { WalkOctree(camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes); } if ((child = octant.Children[0, 1, 0]) != null) { WalkOctree(camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes); } if ((child = octant.Children[1, 1, 0]) != null) { WalkOctree(camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes); } if ((child = octant.Children[0, 0, 1]) != null) { WalkOctree(camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes); } if ((child = octant.Children[1, 0, 1]) != null) { WalkOctree(camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes); } if ((child = octant.Children[0, 1, 1]) != null) { WalkOctree(camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes); } if ((child = octant.Children[1, 1, 1]) != null) { WalkOctree(camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes); } } }
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 ); } }
private void WalkOctree( PCZCamera camera, ref List<PCZSceneNode> visibleNodeList, RenderQueue queue, Octree octant, VisibleObjectsBoundsInfo visibleBounds, bool foundvisible, bool onlyShadowCasters, bool displayNodes, bool showBoundingBoxes ) { //return immediately if nothing is in the node. if ( octant.NunodeList == 0 ) return; Visibility v = Visibility.None; if ( foundvisible ) { v = Visibility.Full; } else if ( octant == rootOctree ) { v = Visibility.Partial; } else { AxisAlignedBox box = octant.Box; v = camera.GetVisibility( box ); } // if the octant is visible, or if it's the root node... if ( v != Visibility.None ) { //Add stuff to be rendered; bool vis = true; foreach ( PCZSceneNode sn in octant.NodeList.Values ) { // if the scene node is already visible, then we can skip it if ( sn.LastVisibleFrame != mLastVisibleFrame || sn.LastVisibleFromCamera != camera ) { // if this octree is partially visible, manually cull all // scene nodes attached directly to this level. if ( v == Visibility.Partial ) { vis = camera.IsObjectVisible( sn.WorldAABB ); } if ( vis ) { // add the node to the render queue sn.AddToRenderQueue( camera, queue, onlyShadowCasters, visibleBounds ); // add it to the list of visible nodes visibleNodeList.Add( sn ); // if we are displaying nodes, add the node renderable to the queue if ( displayNodes ) { queue.AddRenderable( sn.GetDebugRenderable() ); } // if the scene manager or the node wants the bounding box shown, add it to the queue if ( sn.ShowBoundingBox || showBoundingBoxes ) { sn.AddBoundingBoxToQueue( queue ); } // flag the node as being visible this frame sn.LastVisibleFrame = mLastVisibleFrame; sn.LastVisibleFromCamera = camera; } } } Octree child; bool childfoundvisible = ( v == Visibility.Full ); if ( ( child = octant.Children[ 0, 0, 0 ] ) != null ) WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); if ( ( child = octant.Children[ 1, 0, 0 ] ) != null ) WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); if ( ( child = octant.Children[ 0, 1, 0 ] ) != null ) WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); if ( ( child = octant.Children[ 1, 1, 0 ] ) != null ) WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); if ( ( child = octant.Children[ 0, 0, 1 ] ) != null ) WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); if ( ( child = octant.Children[ 1, 0, 1 ] ) != null ) WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); if ( ( child = octant.Children[ 0, 1, 1 ] ) != null ) WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); if ( ( child = octant.Children[ 1, 1, 1 ] ) != null ) WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); } }
public void Resize( AxisAlignedBox box ) { // delete the octree rootOctree = null; // create a new octree rootOctree = new Octree( this, null ); // set the octree bounding box rootOctree.Box = box; Vector3 min = box.Minimum; Vector3 max = box.Maximum; rootOctree.HalfSize = ( max - min ) * 0.5f; OctreeZoneData ozd; foreach ( PCZSceneNode on in mHomeNodeList ) { ozd = (OctreeZoneData)( on.GetZoneData( this ) ); ozd.Octant = null; UpdateNodeOctant( ozd ); } foreach ( PCZSceneNode on in mVisitorNodeList ) { ozd = (OctreeZoneData)( on.GetZoneData( this ) ); ozd.Octant = null; UpdateNodeOctant( ozd ); } }