예제 #1
0
        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);
                    }
                }
            }
        }
예제 #2
0
        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);
                }
            }
        }