public override void FindVisibleNodes(PCZCamera camera, ref List <PCZSceneNode> visibleNodeList, RenderQueue queue, VisibleObjectsBoundsInfo visibleBounds, bool onlyShadowCasters, bool displayNodes, bool showBoundingBoxes) { //return immediately if nothing is in the zone. if (mHomeNodeList.Count == 0 && mVisitorNodeList.Count == 0 && mPortals.Count == 0) { return; } // Else, the zone is automatically assumed to be visible since either // it is the camera the zone is in, or it was reached because // a connecting portal was deemed visible to the camera. // enable sky if called to do so for this zone if (mHasSky) { // enable sky mPCZSM.EnableSky(true); } // Recursively find visible nodes in the zone WalkOctree(camera, ref visibleNodeList, queue, this.rootOctree, visibleBounds, false, onlyShadowCasters, displayNodes, showBoundingBoxes); // find visible portals in the zone and recurse into them bool vis; foreach (Portal portal in mPortals) { // for portal, check visibility using world bounding sphere & direction FrustumPlane pl = FrustumPlane.None; vis = camera.IsObjectVisible(portal, out pl); if (vis) { // portal is visible. Add the portal as extra culling planes to camera int planes_added = camera.AddPortalCullingPlanes(portal); // tell target zone it's visible this frame portal.getTargetZone().LastVisibleFrame = mLastVisibleFrame; portal.getTargetZone().LastVisibleFromCamera = camera; // recurse into the connected zone portal.getTargetZone().FindVisibleNodes(camera, ref visibleNodeList, queue, visibleBounds, onlyShadowCasters, displayNodes, showBoundingBoxes); if (planes_added > 0) { // Then remove the extra culling planes added before going to the next portal in this zone. camera.RemovePortalCullingPlanes(portal); } } } }
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); } } }