예제 #1
0
        /// <summary>
        /// This is static to make this a non-virtual call
        /// </summary>
        /// <param name="nodeData"></param>
        /// <param name="value"></param>
        private static void setVisibility(CompactQuadTree <bool> .Node nodeData, ref CullingInfo info, bool value)
        {
            // Check if visiblity has changed. This shouldnt be relevant, since only non-leaf nodes, without cullables
            //  can have this status called
            if (nodeData.Get(info.Tree) == value)
            {
                return;
            }
            nodeData.Set(info.Tree, value);


            int modifier;

            if (value)
            {
                modifier = 1;
            }
            else
            {
                modifier = -1;
            }

            var cullables = info.Culler.GetCullNode(nodeData.Index).Cullables;

            for (int i = 0; i < cullables.Count; i++)
            {
                info.CullablesReferenceCounts[cullables[i].Index] += modifier;
            }
        }
예제 #2
0
        private static void setInvisibleRecursive(ref CullingInfo info, ref BoundingBox bb, CompactQuadTree <bool> .Node nodeData, bool isLeaf)
        {
            if (nodeData.Get(info.Tree) == false)
            {
                return;
            }
            setVisibility(nodeData, ref info, false);

            if (isLeaf)
            {
                return;
            }
            //Note that, these calls are not strictly necessary. EDIT: are prohibited, this is exactly the speedup of using a quadtree struct
            // When traversing the tree from top to bottom, a invisible node will be reached,
            // lower nodes need not be updated.
            updateVisibility(nodeData, CompactQuadTreeChild.LowerLeft, ref info, ref bb, true);
            updateVisibility(nodeData, CompactQuadTreeChild.LowerRight, ref info, ref bb, true);
            updateVisibility(nodeData, CompactQuadTreeChild.UpperLeft, ref info, ref bb, true);
            updateVisibility(nodeData, CompactQuadTreeChild.UpperRight, ref info, ref bb, true);
        }
예제 #3
0
        /// <summary>
        /// This is static to make this a non-virtual call
        /// </summary>
        /// <param name="nodeData"></param>
        /// <param name="info"></param>
        /// <param name="bb"></param>
        /// <param name="skipFrustumCheck"></param>
        private static void updateVisibility(CompactQuadTree <bool> .Node nodeData, ref CullingInfo info, ref BoundingBox bb, bool skipFrustumCheck)
        {
            var isLeaf = nodeData.IsLeaf(info.Tree);

            //if (info.Culler.GetCullNode(nodeData.Index).Tag != null) System.Diagnostics.Debugger.Break();

            if (skipFrustumCheck)
            {
                if (nodeData.Get(info.Tree) == nodeData.Parent.Get(info.Tree))
                {
                    return;
                }
                setVisibility(nodeData, ref info, nodeData.Parent.Get(info.Tree));

                if (isLeaf)
                {
                    return;
                }
                updateVisibility(nodeData, CompactQuadTreeChild.LowerLeft, ref info, ref bb, true);
                updateVisibility(nodeData, CompactQuadTreeChild.LowerRight, ref info, ref bb, true);
                updateVisibility(nodeData, CompactQuadTreeChild.UpperLeft, ref info, ref bb, true);
                updateVisibility(nodeData, CompactQuadTreeChild.UpperRight, ref info, ref bb, true);

                return;
            }

            // This optimization is mainly for the pointlight shadow frustum, but probably also good for large trees
            var firstResult = info.FrustumBoundingBox.xna().Intersects(bb.xna()); // NOTE: possible slowdown due to xna() conversion

            if (!firstResult)
            {
                // The node is not in the viewing frustum, so it is surely invisible
                setInvisibleRecursive(ref info, ref bb, nodeData, isLeaf);
                return;
            }


            var result = info.Frustum.Contains(bb);

            if (result == ContainmentType.Disjoint)
            {
                setInvisibleRecursive(ref info, ref bb, nodeData, isLeaf);
                return;
            }

            if (result == ContainmentType.Contains)
            {
                if (nodeData.Get(info.Tree))
                {
                    return;
                }

                skipFrustumCheck = true;
            }

            setVisibility(nodeData, ref info, true);
            if (isLeaf)
            {
                return;
            }

            updateVisibility(nodeData, CompactQuadTreeChild.LowerLeft, ref info, ref bb, skipFrustumCheck);
            updateVisibility(nodeData, CompactQuadTreeChild.LowerRight, ref info, ref bb, skipFrustumCheck);
            updateVisibility(nodeData, CompactQuadTreeChild.UpperLeft, ref info, ref bb, skipFrustumCheck);
            updateVisibility(nodeData, CompactQuadTreeChild.UpperRight, ref info, ref bb, skipFrustumCheck);
        }