Exemple #1
0
 public unsafe void Refit()
 {
     //Go through each level, refitting as you go.
     //Note that the deepest level is skipped. It does not need to be tested; it's all leaves that were already updated.
     for (int levelIndex = maximumDepth - 1; levelIndex >= 0; --levelIndex)
     {
         //consider testing caching Levels[levelIndex]. It may have a minor effect.
         for (int nodeIndex = 0; nodeIndex < Levels[levelIndex].Count; ++nodeIndex)
         {
             for (int childIndex = 0; childIndex < Vector <int> .Count; ++childIndex)
             {
                 var childNodeIndex = Levels[levelIndex].Nodes[nodeIndex].Children[childIndex];
                 if (childNodeIndex >= 0)
                 {
                     BoundingBoxWide merged;
                     ComputeBoundingBox(ref Levels[levelIndex + 1].Nodes[childNodeIndex].BoundingBoxes, out merged);
                     BoundingBoxWide.ConditionalSelect(ref singleMasks[childIndex],
                                                       ref merged,
                                                       ref Levels[levelIndex].Nodes[nodeIndex].BoundingBoxes,
                                                       out Levels[levelIndex].Nodes[nodeIndex].BoundingBoxes);
                 }
             }
         }
     }
 }
            public void Add(ref StreamingLeafGroup parent, int sourceIndex, int destinationIndex, Vector <int>[] masks)
            {
                //This is basically: a[i] = b[j]
                var             leavesBroadcast = new Vector <int>(parent.Leaves[sourceIndex]);
                BoundingBoxWide boundsBroadcast;

                BoundingBoxWide.GetBoundingBox(ref parent.BoundingBoxes, sourceIndex, out boundsBroadcast);
                Leaves = Vector.ConditionalSelect(masks[destinationIndex], leavesBroadcast, Leaves);
                BoundingBoxWide.ConditionalSelect(ref masks[destinationIndex], ref boundsBroadcast, ref BoundingBoxes, out BoundingBoxes);
            }
Exemple #3
0
        public unsafe void RefitLeaves()
        {
            //Update the bounding boxes of every leaf-owner.
            //Note the scalar-ness of this. It seems like there should exist some way to vectorize it properly, though it may require changing things around.
            for (int i = 0; i < leafCount; ++i)
            {
                BoundingBox box;
                leaves[i].Bounded.GetBoundingBox(out box);
                BoundingBoxWide wideBox = new BoundingBoxWide(ref box);
                //Console.WriteLine($"index reached: {i}, child index: {leaves[i].ChildIndex}, level: {leaves[i].LevelIndex}, node: { leaves[i].NodeIndex}");

                BoundingBoxWide.ConditionalSelect(ref singleMasks[leaves[i].ChildIndex],
                                                  ref wideBox,
                                                  ref Levels[leaves[i].LevelIndex].Nodes[leaves[i].NodeIndex].BoundingBoxes,
                                                  out Levels[leaves[i].LevelIndex].Nodes[leaves[i].NodeIndex].BoundingBoxes);
                //Console.WriteLine($"comp");
            }
        }
Exemple #4
0
        public unsafe void Insert(T leaf)
        {
            int         levelIndex = 0;
            int         nodeIndex  = 0;
            BoundingBox aosBox;

            leaf.GetBoundingBox(out aosBox);
            var box = new BoundingBoxWide(ref aosBox);

#if OUTPUT
            List <int> choices = new List <int>();
#endif
            while (true)
            {
                var level = Levels[levelIndex];
                //Which child should the leaf belong to?
                Vector <float> originalVolumes;
                BoundingBoxWide.ComputeVolume(ref level.Nodes[nodeIndex].BoundingBoxes, out originalVolumes);
                originalVolumes = Vector.Max(originalVolumes, Vector <float> .Zero);
                BoundingBoxWide merged;
                BoundingBoxWide.Merge(ref level.Nodes[nodeIndex].BoundingBoxes, ref box, out merged);
                Vector <float> mergedVolumes;
                BoundingBoxWide.ComputeVolume(ref merged, out mergedVolumes);

                //Give the leaf to whichever node had the least volume change.
                var volumeIncreases = mergedVolumes - originalVolumes;
                int minimumIndex    = 0;
                var minimum         = volumeIncreases[0];
                for (int i = 1; i < Vector <float> .Count; ++i)
                {
                    if (volumeIncreases[i] < minimum)
                    {
                        minimumIndex = i;
                        minimum      = volumeIncreases[i];
                    }
                }

                //var volumeIncreases = mergedVolumes - originalVolumes;
                //int minimumIndex = 0;
                //var minimum = float.MaxValue;
                //for (int i = 0; i < Vector<float>.Count; ++i)
                //{
                //    if (level.Nodes[nodeIndex].Children[i] == -1)
                //    {
                //        minimumIndex = i;
                //        break;
                //    }
                //    if (volumeIncreases[i] < minimum)
                //    {
                //        minimumIndex = i;
                //        minimum = volumeIncreases[i];
                //    }
                //}
#if OUTPUT
                Console.WriteLine($"Minimum index: {minimumIndex}, minimum volume increase: {minimum}");
                choices.Add(minimumIndex);
#endif

                var childIndex = level.Nodes[nodeIndex].Children[minimumIndex];

                if (childIndex < -1)
                {
                    //It's a leaf node.
                    //Create a new internal node with the new leaf and the old leaf as children.
                    var nextLevel = levelIndex + 1;
                    //this is the only place where a new level could potentially be created.
                    EnsureLevel(nextLevel);
                    Node newNode;
                    InitializeNode(out newNode);
                    //The first child of the new node is the old leaf. Insert its bounding box.
                    //Since we don't have a great way of shuffling yet, just let it be in the same index.
                    BoundingBoxWide.ConditionalSelect(
                        ref singleMasks[minimumIndex],
                        ref level.Nodes[nodeIndex].BoundingBoxes,
                        ref newNode.BoundingBoxes,
                        out newNode.BoundingBoxes);
                    newNode.Children = Vector.ConditionalSelect(singleMasks[minimumIndex], level.Nodes[nodeIndex].Children, newNode.Children);

                    //Insert the new leaf into the second child slot.
                    //Just put it in the next slot over from the minimum.
                    var newLeafChildIndex = (minimumIndex + 1) & (Vector <float> .Count - 1);
                    BoundingBoxWide.ConditionalSelect(
                        ref singleMasks[newLeafChildIndex],
                        ref box,
                        ref newNode.BoundingBoxes,
                        out newNode.BoundingBoxes);
                    var newNodeIndex    = Levels[nextLevel].Add(ref newNode);
                    var leafIndex       = AddLeaf(leaf, nextLevel, newNodeIndex, newLeafChildIndex);
                    var leafIndexVector = new Vector <int>(Encode(leafIndex));
                    Levels[nextLevel].Nodes[newNodeIndex].Children = Vector.ConditionalSelect(singleMasks[newLeafChildIndex], leafIndexVector, newNode.Children);

                    //Update the old leaf node with the new index information.
                    var oldLeafIndex = Encode(childIndex);
                    leaves[oldLeafIndex].LevelIndex = nextLevel;
                    leaves[oldLeafIndex].NodeIndex  = newNodeIndex;
                    //Since we inserted it into the same slot of the new node as it was in in the old node, there is no change to the child index.

                    //Update the original node's child pointer and bounding box.
                    var newNodeIndexVector = new Vector <int>(newNodeIndex);
                    level.Nodes[nodeIndex].Children = Vector.ConditionalSelect(singleMasks[minimumIndex], newNodeIndexVector, level.Nodes[nodeIndex].Children);
                    BoundingBoxWide.ConditionalSelect(ref singleMasks[minimumIndex], ref merged, ref level.Nodes[nodeIndex].BoundingBoxes, out level.Nodes[nodeIndex].BoundingBoxes);

#if OUTPUT
                    Console.WriteLine($"Leaf {leafIndex} merged with existing leaf.");// New Node Children: {newNode.Children}, Old Node children: {level.Nodes[nodeIndex].Children}");
                    Console.WriteLine($"Choices: {GetChoiceList(choices)}");
#endif

                    break;
                }
                if (childIndex == -1)
                {
                    //There is no child at all.
                    //Put the new leaf here.
                    var leafIndex       = AddLeaf(leaf, levelIndex, nodeIndex, minimumIndex);
                    var leafIndexVector = new Vector <int>(Encode(leafIndex));
                    level.Nodes[nodeIndex].Children = Vector.ConditionalSelect(singleMasks[minimumIndex], leafIndexVector, level.Nodes[nodeIndex].Children);
                    BoundingBoxWide.ConditionalSelect(ref singleMasks[minimumIndex], ref merged, ref level.Nodes[nodeIndex].BoundingBoxes, out level.Nodes[nodeIndex].BoundingBoxes);

#if OUTPUT
                    Console.WriteLine($"Leaf {leafIndex} inserted in empty slot.");
                    Console.WriteLine($"Choices: {GetChoiceList(choices)}");
#endif
                    break;
                }
                //It's an internal node. Traverse to the next node.
                BoundingBoxWide.ConditionalSelect(ref singleMasks[minimumIndex], ref merged, ref level.Nodes[nodeIndex].BoundingBoxes, out level.Nodes[nodeIndex].BoundingBoxes);
                nodeIndex = level.Nodes[nodeIndex].Children[minimumIndex];
                ++levelIndex;
            }
        }
 public void Add(ref BoundingBoxWide boundingBox, ref Vector <int> leafIndex, ref Vector <int> destinationMask)
 {
     Leaves = Vector.ConditionalSelect(destinationMask, leafIndex, Leaves);
     BoundingBoxWide.ConditionalSelect(ref destinationMask, ref boundingBox, ref BoundingBoxes, out BoundingBoxes);
 }