Пример #1
0
        public void Remove(BoundingVolumeNode node)
        {
            if (!dictionary.Contains(node))
            {
                return;
            }
            dictionary.Remove(node);

            if (node == root)
            {
                root = null;
            }
            else
            {
                bool onLeft = node.Parent.LeftChild == node;
                BoundingVolumeNode brother;
                if (onLeft)
                {
                    brother = (BoundingVolumeNode)node.Parent.RightChild;
                }
                else
                {
                    brother = (BoundingVolumeNode)node.Parent.LeftChild;
                }

                if (node.Parent == root)
                {
                    root           = brother;
                    brother.Parent = null;
                }
                else
                {
                    bool onRootLeft = brother.Parent.Parent.LeftChild == brother.Parent;
                    if (onRootLeft)
                    {
                        brother.Parent.Parent.LeftChild = brother;
                    }
                    else
                    {
                        brother.Parent.Parent.RightChild = brother;
                    }
                    brother.Parent = brother.Parent.Parent;
                }

                var cur = brother;
                while (cur.Parent != null)
                {
                    cur.Parent.Value = cur.Parent.LeftChild.Value + cur.Parent.RightChild.Value;
                    cur = (BoundingVolumeNode)cur.Parent;
                }
            }
        }
Пример #2
0
        public void Insert(BoundingVolumeNode node)
        {
            if (dictionary.Contains(node))
            {
                return;
            }

            dictionary.Add(node);

            if (root == null)
            {
                root = node;
            }
            else
            {
                float score = -1;
                BoundingVolumeNode candidate = null;
                InsertHierarchy(root, node, score, 0, ref candidate);

                if (candidate != null)
                {
                    var newNode = new BoundingVolumeNode(node.Value + candidate.Value);
                    if (candidate.Parent == null) //现节点是根节点
                    {
                        root = newNode;
                    }
                    else
                    {
                        if (candidate == candidate.Parent.LeftChild)
                        {
                            candidate.Parent.LeftChild = newNode;
                        }
                        else
                        {
                            candidate.Parent.RightChild = newNode;
                        }
                    }
                    newNode.Parent     = candidate.Parent;
                    newNode.LeftChild  = candidate;
                    newNode.RightChild = node;
                    candidate.Parent   = newNode;
                    node.Parent        = newNode;

                    var cur = newNode;
                    while (cur.Parent != null)
                    {
                        cur.Parent.Value += cur.Value;
                        cur = (BoundingVolumeNode)cur.Parent;
                    }
                }
            }
        }
Пример #3
0
        private void InsertHierarchy(BoundingVolumeNode current, BoundingVolumeNode target, float bestcost, float inheritedcost, ref BoundingVolumeNode candidate)
        {
            bool  isLeaf  = current.LeftChild == null; // 必定是二叉树判断一边就行
            var   newVol  = current.Value + target.Value;
            float curCost = inheritedcost + newVol.Volume;

            inheritedcost += newVol.Volume - current.Value.Volume;

            if (curCost <= bestcost || bestcost < 0)
            {
                bestcost  = curCost;
                candidate = current;

                if (!isLeaf)
                {
                    InsertHierarchy((BoundingVolumeNode)current.LeftChild, target, bestcost, inheritedcost, ref candidate);
                    InsertHierarchy((BoundingVolumeNode)current.RightChild, target, bestcost, inheritedcost, ref candidate);
                }
            }
        }
Пример #4
0
 public bool Intersect(BoundingVolumeNode another)
 {
     return(this.Value.Intersect(another.Value));
 }