public void AddCullable(ICullable cullable)
        {
            if (cullables.Contains(cullable))
            {
                throw new InvalidOperationException();
            }
            cullables.Add(cullable);
            var item = new CullableItem {
                Cullable = cullable, Index = cullablesLookup.Count
            };

            cullablesLookup.Add(item);
            cullableItemMap[cullable] = item;


            CullNode node = RootNode.FindContainingNode(cullable);

            cullableContainingNodes[cullable] = node;

            if (node == null)
            {
                node = RootNode;
            }
            node.PlaceCullable(item);


            if (viewCullablesBufferSize <= cullablesLookup.Count)
            {
                expandCullablesBuffer();
            }
        }
        /// <summary>
        /// TODO: test this, i think this doesnt work correctly. Objects seem to remain in the tree
        /// </summary>
        /// <param name="cullable"></param>
        public void RemoveCullable(ICullable cullable)
        {
            cullables.Remove(cullable);

            CullNode node = cullableContainingNodes[cullable];

            node.RemoveCullable(cullableItemMap[cullable]);
        }
 private void buildCullNodeArray(CullNode node, CompactQuadTree <bool> .Node cNode)
 {
     cullNodes[cNode.Index] = node;
     node.Index             = cNode.Index;
     if (QuadTree.IsLeafNode(node))
     {
         return;
     }
     buildCullNodeArray(node.NodeData.LowerLeft, cNode.LowerLeft);
     buildCullNodeArray(node.NodeData.LowerRight, cNode.LowerRight);
     buildCullNodeArray(node.NodeData.UpperLeft, cNode.UpperLeft);
     buildCullNodeArray(node.NodeData.UpperRight, cNode.UpperRight);
 }
        public FrustumCuller(BoundingBox quadtreeBounding, int numberLevels)
        {
            TreeBounding = quadtreeBounding;
            NumberLevels = numberLevels;
            RootNode     = new CullNode();
            QuadTreeNodeData <CullNode> data = new QuadTreeNodeData <CullNode>();

            data.BoundingBox  = quadtreeBounding;
            RootNode.NodeData = data;

            QuadTree.Split(RootNode, numberLevels - 1);

            cullNodes = new CullNode[CompactQuadTree <bool> .CalculateNbNodes(numberLevels)];
            buildCullNodeArray(RootNode, new CompactQuadTree <bool> .Node(0));

            expandCullablesBuffer();
        }
        public void UpdateCullable(ICullable cullable)
        {
            CullNode oldNode = cullableContainingNodes[cullable];
            CullNode newNode;

            //This check is cheatfix and this bug should be fixed
            if (oldNode == null)
            {
                newNode = null;
            }
            else
            {
                newNode = oldNode.FindEncapsulatingNodeUpwards(cullable);
                newNode = newNode.FindContainingNode(cullable);
            }

            if (newNode == null)
            {
                newNode = RootNode;
            }

            if (newNode == oldNode)
            {
                return;
            }

            cullableContainingNodes[cullable] = newNode;

            var item = cullableItemMap[cullable];

            //This check is cheatfix and this bug should be fixed
            if (oldNode != null)
            {
                oldNode.RemoveCullable(item);
            }
            newNode.PlaceCullable(item);
        }