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); }
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"); } }
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); }