unsafe void PushPair(int encodedLeafIndex, BoundingBox *leafBounds, int b, PairToTest *stack, ref int nextToVisit)
 {
     //Potential microoptimizations here
     stack[++nextToVisit] = new PairToTest {
         A = encodedLeafIndex, B = b, LeafBounds = leafBounds
     };
 }
 unsafe void TestDifferent <TResultList>(int a, int b, BoundingBox *aBounds, BoundingBox *bBounds, TestPair *stack, ref int nextToVisit, ref TResultList results) where TResultList : IList <Overlap>
 {
     if (a >= 0)
     {
         if (b >= 0)
         {
             //both internal nodes
             PushDifferent(nodes + a, nodes + b, stack, ref nextToVisit);
         }
         else
         {
             //leaf and internal
             PushLeafInternal(nodes + a, bBounds, b, stack, ref nextToVisit);
         }
     }
     else if (b >= 0)
     {
         //leaf and internal
         PushLeafInternal(nodes + b, aBounds, a, stack, ref nextToVisit);
     }
     else
     {
         //two leaves
         results.Add(new Overlap {
             A = Encode(a), B = Encode(b)
         });
     }
 }
 unsafe void TestDifferentNodes <TResultList>(int childA, int childB, BoundingBox *a, BoundingBox *b,
                                              PairToTest *stack, ref int nextToVisit,
                                              ref TResultList results) where TResultList : IList <Overlap>
 {
     if (childA >= 0)
     {
         if (childB >= 0)
         {
             PushPair(childA, childB, stack, ref nextToVisit);
         }
         else
         {
             //leaf B versus node A.
             PushPair(childB, b, childA, stack, ref nextToVisit);
         }
     }
     else if (childB >= 0)
     {
         //leaf A versus node B.
         PushPair(childA, a, childB, stack, ref nextToVisit);
     }
     else
     {
         //Two leaves.
         results.Add(new Overlap {
             A = Encode(childA), B = Encode(childB)
         });
     }
 }
 unsafe void TestDifferentNodes<TResultList>(BoundingBox* a, BoundingBox* b, int childA, int childB, int leafCountA, int leafCountB,
     ref PriorityQueue queue, ref QuickList<TestPair2> pairsToTest,
     ref TResultList results)
     where TResultList : IList<Overlap>
 {
     if (childA >= 0)
     {
         if (childB >= 0)
         {
             PushDifferent(childA, childB, leafCountA, leafCountB, ref queue, ref pairsToTest);
         }
         else
         {
             //leaf B versus node A.
             PushLeafInternal(childA, leafCountA, b, childB, ref queue, ref pairsToTest);
         }
     }
     else if (childB >= 0)
     {
         //leaf A versus node B.
         PushLeafInternal(childB, leafCountB, a, childA, ref queue, ref pairsToTest);
     }
     else
     {
         //Two leaves.
         results.Add(new Overlap { A = Encode(childA), B = Encode(childB) });
     }
 }
        unsafe void PushLeafInternal(Node *internalNode, BoundingBox *leafBounds, int encodedLeafIndex, TestPair *stack, ref int count)
        {
            var element = stack + count++;

            element->A                = internalNode;
            element->LeafBounds       = leafBounds;
            element->EncodedLeafIndex = encodedLeafIndex;
            element->Type             = PairType.LeafInternal;
        }
示例#6
0
 public unsafe BoundingBoxWide(BoundingBox *boundingBoxes, Vector <int>[] masks)
 {
     Min = new Vector3Wide(ref boundingBoxes[0].Min);
     Max = new Vector3Wide(ref boundingBoxes[0].Max);
     for (int i = 1; i < Vector <float> .Count; ++i)
     {
         BoundingBoxWide wide = new BoundingBoxWide(ref boundingBoxes[i]);
         ConditionalSelect(ref masks[i], ref wide, ref this, out this);
     }
 }
示例#7
0
        unsafe void FindPartitionForAxis(BoundingBox *boundingBoxes, BoundingBox *aMerged, float *centroids, int *indexMap, int count,
                                         out int splitIndex, out float cost, out BoundingBox a, out BoundingBox b, out int leafCountA, out int leafCountB)
        {
            Debug.Assert(count > 1);


            Quicksort(centroids, indexMap, 0, count - 1);

            //Search for the best split.
            //Sweep across from low to high, caching the merged size and leaf count at each point.
            //Index N includes every subtree from 0 to N, inclusive. So index 0 contains subtree 0's information.
            var lastIndex = count - 1;

            aMerged[0] = boundingBoxes[indexMap[0]];
            for (int i = 1; i < lastIndex; ++i)
            {
                var index = indexMap[i];
                BoundingBox.Merge(ref aMerged[i - 1], ref boundingBoxes[index], out aMerged[i]);
            }

            //Sweep from high to low.
            BoundingBox bMerged = new BoundingBox {
                Min = new Vector3(float.MaxValue), Max = new Vector3(float.MinValue)
            };

            cost       = float.MaxValue;
            splitIndex = 0;
            a          = bMerged;
            b          = bMerged;
            leafCountA = 0;
            leafCountB = 0;
            for (int i = lastIndex; i >= 1; --i)
            {
                int aIndex       = i - 1;
                var subtreeIndex = indexMap[i];
                BoundingBox.Merge(ref bMerged, ref boundingBoxes[subtreeIndex], out bMerged);

                var aCost = i * ComputeBoundsMetric(ref aMerged[aIndex]);
                var bCost = (count - i) * ComputeBoundsMetric(ref bMerged);

                var totalCost = aCost + bCost;
                if (totalCost < cost)
                {
                    cost       = totalCost;
                    splitIndex = i;
                    a          = aMerged[aIndex];
                    b          = bMerged;
                    leafCountA = i;
                    leafCountB = count - i;
                }
            }
        }
示例#8
0
 public extern static unsafe CONTAIN_TYPE SDK_v3dxFrustum_WhichContainTypeFastWithTransform(IntPtr frustum, BoundingBox *box, Matrix *matrix, int testInner);
示例#9
0
 public extern static unsafe CONTAIN_TYPE SDK_v3dxFrustum_WhichContainTypeFast(IntPtr frustum, BoundingBox *box, int testInner);
示例#10
0
 public extern static unsafe void SDK_GfxMeshPrimitives_SetAABB(NativePointer self, BoundingBox *box);
示例#11
0
 public extern static unsafe vBOOL SDK_GfxMeshPrimitives_InitFromGeomtryMesh(NativePointer self, CRenderContext.NativePointer rc, CGeometryMesh.NativePointer mesh, UInt32 atom, BoundingBox *box);
示例#12
0
 private extern static unsafe CGeometryMesh.NativePointer SDK_IGeometryMesh_MergeGeoms(CRenderContext.NativePointer rc, CGeometryMesh.NativePointer *meshArray, Matrix *scaleArray, int count, BoundingBox *aabb);
 unsafe void PushLeafInternal(int internalIndex, int leafCount, BoundingBox* leafBounds, int encodedLeafIndex, ref PriorityQueue queue, ref QuickList<TestPair2> pairsToTest)
 {
     queue.Insert(pairsToTest.Count, (float)Math.Log(leafCount));
     //queue.Insert(pairsToTest.Count, leafCount);
     pairsToTest.Add(new TestPair2 { A = internalIndex, LeafBounds = leafBounds, B = encodedLeafIndex, Type = PairType.LeafInternal });
 }
示例#14
0
        unsafe void FindPartitionForAxis(BoundingBox *boundingBoxes, int *leafCounts, float *centroids, int *indexMap, int subtreeCount,
                                         out int splitIndex, out float cost, out BoundingBox a, out BoundingBox b, out int leafCountA, out int leafCountB)
        {
            Debug.Assert(subtreeCount > 1);

            //Sort the index map according to the centroids.
            //for (int i = 1; i < subtreeCount; ++i)
            //{
            //    var index = i;
            //    var previousIndex = index - 1;
            //    while (centroids[indexMap[index]] < centroids[indexMap[previousIndex]])
            //    {

            //        var tempPointer = indexMap[index];
            //        indexMap[index] = indexMap[previousIndex];
            //        indexMap[previousIndex] = tempPointer;


            //        if (previousIndex == 0)
            //            break;
            //        index = previousIndex;
            //        --previousIndex;
            //    }
            //}
            Quicksort(centroids, indexMap, 0, subtreeCount - 1);


            //for (int i = 1; i < subtreeCount; ++i)
            //{
            //    if (centroids[indexMap[i]] < centroids[indexMap[i - 1]])
            //    {
            //        Console.WriteLine("not sorteD");
            //    }
            //}

            //Search for the best split.
            //Sweep across from low to high, caching the merged size and leaf count at each point.
            //Index N includes every subtree from 0 to N, inclusive. So index 0 contains subtree 0's information.
            var lastIndex   = subtreeCount - 1;
            var aLeafCounts = stackalloc int[lastIndex];
            var aMerged     = stackalloc BoundingBox[lastIndex];

            *aLeafCounts = leafCounts[*indexMap];
            *aMerged     = boundingBoxes[*indexMap];
            for (int i = 1; i < lastIndex; ++i)
            {
                var index = indexMap[i];
                aLeafCounts[i] = leafCounts[index] + aLeafCounts[i - 1];
                BoundingBox.Merge(ref aMerged[i - 1], ref boundingBoxes[index], out aMerged[i]);
            }

            //Sweep from high to low.
            BoundingBox bMerged = new BoundingBox {
                Min = new Vector3(float.MaxValue), Max = new Vector3(float.MinValue)
            };

            cost       = float.MaxValue;
            splitIndex = 0;
            int bLeafCount = 0;

            a          = bMerged;
            b          = bMerged;
            leafCountA = 0;
            leafCountB = 0;
            for (int i = lastIndex; i >= 1; --i)
            {
                int aIndex       = i - 1;
                var subtreeIndex = indexMap[i];
                BoundingBox.Merge(ref bMerged, ref boundingBoxes[subtreeIndex], out bMerged);
                bLeafCount += leafCounts[subtreeIndex];

                var aCost = aLeafCounts[aIndex] * ComputeBoundsMetric(ref aMerged[aIndex]);
                var bCost = bLeafCount * ComputeBoundsMetric(ref bMerged);

                var totalCost = aCost + bCost;
                if (totalCost < cost)
                {
                    cost       = totalCost;
                    splitIndex = i;
                    a          = aMerged[aIndex];
                    b          = bMerged;
                    leafCountA = aLeafCounts[aIndex];
                    leafCountB = bLeafCount;
                }
            }
        }
示例#15
0
        unsafe void FindPartitionForAxis(BoundingBox *boundingBoxes, BoundingBox *aMerged, float *centroids, int *indexMap, int count,
                                         out int splitIndex, out float cost, out BoundingBox a, out BoundingBox b, out int leafCountA, out int leafCountB)
        {
            Debug.Assert(count > 1);
            //TODO: Note that sorting at every level isn't necessary. Like in one of the much older spatial splitting implementations we did, you can just sort once, and thereafter
            //just do an O(n) operation to shuffle leaf data to the relevant location on each side of the partition. That allows us to punt all sort work to a prestep.
            //There, we could throw an optimized parallel sort at it. Or just do the three axes independently, hidden alongside some other work maybe.
            //I suspect the usual problems with parallel sorts would be mitigated somewhat by having three of them going on at the same time- more chances for load balancing.
            //Also note that, at each step, both the above partitioning scheme and the sort result in a contiguous block of data to work on.
            //If you're already doing a gather like that, you might as well throw wider SIMD at the problem. This version only goes up to 3 wide, which is unfortunate for AVX2 and AVX512.
            //With those changes, we can probably get the sweep builder to be faster than v1's insertion builder- it's almost there already.
            //(You'll also want to bench it against similarly simd accelerated binned approaches for use in incremental refinement. If it's not much slower, the extra quality benefits
            //might make it faster on net by virtue of speeding up self-tests, which are a dominant cost.)
            var comparer = new IndexMapComparer {
                Centroids = centroids
            };

            QuickSort.Sort(ref indexMap[0], 0, count - 1, ref comparer);

            //Search for the best split.
            //Sweep across from low to high, caching the merged size and leaf count at each point.
            //Index N includes every subtree from 0 to N, inclusive. So index 0 contains subtree 0's information.
            var lastIndex = count - 1;

            aMerged[0] = boundingBoxes[indexMap[0]];
            for (int i = 1; i < lastIndex; ++i)
            {
                var index = indexMap[i];
                BoundingBox.CreateMerged(aMerged[i - 1], boundingBoxes[index], out aMerged[i]);
            }

            //Sweep from high to low.
            BoundingBox bMerged = new BoundingBox {
                Min = new Vector3(float.MaxValue), Max = new Vector3(float.MinValue)
            };

            cost       = float.MaxValue;
            splitIndex = 0;
            a          = bMerged;
            b          = bMerged;
            leafCountA = 0;
            leafCountB = 0;
            for (int i = lastIndex; i >= 1; --i)
            {
                int aIndex       = i - 1;
                var subtreeIndex = indexMap[i];
                BoundingBox.CreateMerged(bMerged, boundingBoxes[subtreeIndex], out bMerged);

                var aCost = i * ComputeBoundsMetric(ref aMerged[aIndex]);
                var bCost = (count - i) * ComputeBoundsMetric(ref bMerged);

                var totalCost = aCost + bCost;
                if (totalCost < cost)
                {
                    cost       = totalCost;
                    splitIndex = i;
                    a          = aMerged[aIndex];
                    b          = bMerged;
                    leafCountA = i;
                    leafCountB = count - i;
                }
            }
        }
示例#16
0
 internal static extern unsafe void Detect(IntPtr matPtr, int matRows, int matCols, float thresh, bool useMean, out BoundingBox *elems, out int elemsSize);
        unsafe void CollapseTree(int depthRemaining, TempNode *tempNodes, int tempNodeIndex, int *nodeChildren, ref int childCount, BoundingBox *nodeBounds, int *leafCounts)
        {
            var tempNode = tempNodes + tempNodeIndex;

            if (tempNode->A >= 0)
            {
                //Internal node.
                if (depthRemaining > 0)
                {
                    depthRemaining -= 1;
                    CollapseTree(depthRemaining, tempNodes, tempNode->A, nodeChildren, ref childCount, nodeBounds, leafCounts);
                    CollapseTree(depthRemaining, tempNodes, tempNode->B, nodeChildren, ref childCount, nodeBounds, leafCounts);
                }
                else
                {
                    //Reached the bottom of the recursion. Add the collected children.
                    int a = childCount++;
                    int b = childCount++;

                    nodeBounds[a] = tempNodes[tempNode->A].BoundingBox;
                    nodeBounds[b] = tempNodes[tempNode->B].BoundingBox;
                    //If the child is a leaf, collapse it. Slightly less annoying to handle it here than later.
                    //This is a byproduct of the awkward data layout for tempnodes...
                    if (tempNodes[tempNode->A].A >= 0)
                    {
                        nodeChildren[a] = tempNode->A;
                    }
                    else
                    {
                        nodeChildren[a] = tempNodes[tempNode->A].A; //It's a leaf.
                    }
                    if (tempNodes[tempNode->B].A >= 0)
                    {
                        nodeChildren[b] = tempNode->B;
                    }
                    else
                    {
                        nodeChildren[b] = tempNodes[tempNode->B].A; //It's a leaf. Leaf index is always stored in A...
                    }
                    leafCounts[a] = tempNodes[tempNode->A].LeafCount;
                    leafCounts[b] = tempNodes[tempNode->B].LeafCount;
                }
            }
            else
            {
                //Leaf node.
                var index = childCount++;
                nodeBounds[index]   = tempNode->BoundingBox;
                nodeChildren[index] = tempNode->A;
                leafCounts[index]   = tempNode->LeafCount;
            }
        }
示例#18
0
        private unsafe BoundingBox GetChildBoundingBox(BoundingBox parentBoundingBox, int childIndex)
        {
            Vector3 vector;

            switch (childIndex)
            {
            case 0:
                vector = new Vector3(0f, 0f, 0f);
                break;

            case 1:
                vector = new Vector3(1f, 0f, 0f);
                break;

            case 2:
                vector = new Vector3(1f, 0f, 1f);
                break;

            case 3:
                vector = new Vector3(0f, 0f, 1f);
                break;

            case 4:
                vector = new Vector3(0f, 1f, 0f);
                break;

            case 5:
                vector = new Vector3(1f, 1f, 0f);
                break;

            case 6:
                vector = new Vector3(1f, 1f, 1f);
                break;

            case 7:
                vector = new Vector3(0f, 1f, 1f);
                break;

            default:
                throw new InvalidBranchException();
            }
            Vector3     vector2 = (parentBoundingBox.Max - parentBoundingBox.Min) / 2f;
            BoundingBox box     = new BoundingBox {
                Min = parentBoundingBox.Min + (vector * vector2)
            };
            BoundingBox *boxPtr1 = (BoundingBox *)ref box;

            boxPtr1->Max = box.Min + vector2;
            Vector3 *vectorPtr1 = (Vector3 *)ref box.Min;

            vectorPtr1[0] -= vector2 * 0.3f;
            Vector3 *vectorPtr2 = (Vector3 *)ref box.Max;

            vectorPtr2[0] += vector2 * 0.3f;
            BoundingBox *boxPtr2 = (BoundingBox *)ref box;

            boxPtr2->Min = Vector3.Max(box.Min, parentBoundingBox.Min);
            BoundingBox *boxPtr3 = (BoundingBox *)ref box;

            boxPtr3->Max = Vector3.Min(box.Max, parentBoundingBox.Max);
            return(box);
        }