Beispiel #1
0
 internal override bool Remove(BroadPhaseEntry entry, out LeafNode leafNode, out Node replacementNode)
 {
     replacementNode = null;
     if (element == entry)
     {
         leafNode = this;
         return(true);
     }
     leafNode = null;
     return(false);
 }
Beispiel #2
0
 internal override bool RemoveFast(BroadPhaseEntry entry, out LeafNode leafNode, out Node replacementNode)
 {
     //The fastremove leaf node procedure is identical to the brute force approach.
     //We don't need to perform any bounding box test here; if they're equal, they're equal!
     replacementNode = null;
     if (element == entry)
     {
         leafNode = this;
         return(true);
     }
     leafNode = null;
     return(false);
 }
Beispiel #3
0
        internal override bool TryToInsert(LeafNode node, out Node treeNode)
        {
            var newTreeNode = InternalNode.nodePool.Take();

            BoundingBox.CreateMerged(ref BoundingBox, ref node.BoundingBox, out newTreeNode.BoundingBox);
            Vector3f offset;

            Vector3f.Subtract(ref newTreeNode.BoundingBox.Max, ref newTreeNode.BoundingBox.Min, out offset);
            newTreeNode.currentVolume = offset.X * offset.Y * offset.Z;
            //newTreeNode.maximumVolume = newTreeNode.currentVolume * InternalNode.MaximumVolumeScale;
            newTreeNode.childA = this;
            newTreeNode.childB = node;
            treeNode           = newTreeNode;
            return(true);
        }
Beispiel #4
0
        internal override bool RemoveFast(BroadPhaseEntry entry, out LeafNode leafNode, out Node replacementNode)
        {
            //Only bother checking deeper in the path if the entry and child have overlapping bounding boxes.
            bool intersects;

            childA.BoundingBox.Intersects(ref entry.boundingBox, out intersects);
            if (intersects && childA.RemoveFast(entry, out leafNode, out replacementNode))
            {
                if (childA.IsLeaf)
                {
                    replacementNode = childB;
                }
                else
                {
                    //It was not a leaf node, but a child found the leaf.
                    //Change the child to the replacement node.
                    childA          = replacementNode;
                    replacementNode = this; //We don't need to be replaced!
                }
                return(true);
            }
            childB.BoundingBox.Intersects(ref entry.boundingBox, out intersects);
            if (intersects && childB.RemoveFast(entry, out leafNode, out replacementNode))
            {
                if (childB.IsLeaf)
                {
                    replacementNode = childA;
                }
                else
                {
                    //It was not a leaf node, but a child found the leaf.
                    //Change the child to the replacement node.
                    childB          = replacementNode;
                    replacementNode = this; //We don't need to be replaced!
                }
                return(true);
            }
            replacementNode = this;
            leafNode        = null;
            return(false);
        }
Beispiel #5
0
 internal abstract bool RemoveFast(BroadPhaseEntry entry, out LeafNode leafNode, out Node replacementNode);
Beispiel #6
0
 internal abstract bool TryToInsert(LeafNode node, out Node treeNode);
Beispiel #7
0
        internal override bool TryToInsert(LeafNode node, out Node treeNode)
        {
            //Since we are an internal node, we know we have two children.
            //Regardless of what kind of nodes they are, figure out which would be a better choice to merge the new node with.

            //Use the path which produces the smallest 'volume.'
            BoundingBox mergedA, mergedB;

            BoundingBox.CreateMerged(ref childA.BoundingBox, ref node.BoundingBox, out mergedA);
            BoundingBox.CreateMerged(ref childB.BoundingBox, ref node.BoundingBox, out mergedB);

            Vector3f offset;
            float    originalAVolume, originalBVolume;

            Vector3f.Subtract(ref childA.BoundingBox.Max, ref childA.BoundingBox.Min, out offset);
            originalAVolume = offset.X * offset.Y * offset.Z;
            Vector3f.Subtract(ref childB.BoundingBox.Max, ref childB.BoundingBox.Min, out offset);
            originalBVolume = offset.X * offset.Y * offset.Z;

            float mergedAVolume, mergedBVolume;

            Vector3f.Subtract(ref mergedA.Max, ref mergedA.Min, out offset);
            mergedAVolume = offset.X * offset.Y * offset.Z;
            Vector3f.Subtract(ref mergedB.Max, ref mergedB.Min, out offset);
            mergedBVolume = offset.X * offset.Y * offset.Z;

            //Could use factor increase or absolute difference
            if (mergedAVolume - originalAVolume < mergedBVolume - originalBVolume)
            {
                //merging A produces a better result.
                if (childA.IsLeaf)
                {
                    var newChildA = nodePool.Take();
                    newChildA.BoundingBox   = mergedA;
                    newChildA.childA        = this.childA;
                    newChildA.childB        = node;
                    newChildA.currentVolume = mergedAVolume;
                    //newChildA.maximumVolume = newChildA.currentVolume * MaximumVolumeScale;
                    childA   = newChildA;
                    treeNode = null;
                    return(true);
                }
                else
                {
                    childA.BoundingBox = mergedA;
                    var internalNode = (InternalNode)childA;
                    internalNode.currentVolume = mergedAVolume;
                    //internalNode.maximumVolume = internalNode.currentVolume * MaximumVolumeScale;
                    treeNode = childA;
                    return(false);
                }
            }
            else
            {
                //merging B produces a better result.
                if (childB.IsLeaf)
                {
                    //Target is a leaf! Return.
                    var newChildB = nodePool.Take();
                    newChildB.BoundingBox   = mergedB;
                    newChildB.childA        = node;
                    newChildB.childB        = this.childB;
                    newChildB.currentVolume = mergedBVolume;
                    //newChildB.maximumVolume = newChildB.currentVolume * MaximumVolumeScale;
                    childB   = newChildB;
                    treeNode = null;
                    return(true);
                }
                else
                {
                    childB.BoundingBox = mergedB;
                    treeNode           = childB;
                    var internalNode = (InternalNode)childB;
                    internalNode.currentVolume = mergedBVolume;
                    //internalNode.maximumVolume = internalNode.currentVolume * MaximumVolumeScale;
                    return(false);
                }
            }
        }