コード例 #1
0
        unsafe static void BuildNode(Node *node, Point3 *points, int offset, int length, int depth)
        {
            // pick median
            int median = length >> 1;

            // pick splitting axis
            int axis = depth % 3;

            // split points by median
            SelectByAxis(median, points + offset, length, axis);

            // calc offsets
            var offsetL = offset;
            var offsetR = offset + median + 1;
            var lengthL = median;
            var lengthR = length - median - 1;
            var stepL   = lengthL > 0 ? 1 : 0;
            var stepR   = lengthR > 0 ? 1 + lengthL : 0;

            // make node
            node->point = offset + median;
            node->stepL = stepL;
            node->stepR = stepR;

            // build subtrees
            if (lengthL > 0)
            {
                BuildNode(node + stepL, points, offsetL, lengthL, depth + 1);
            }
            if (lengthR > 0)
            {
                BuildNode(node + stepR, points, offsetR, lengthR, depth + 1);
            }
        }
コード例 #2
0
        unsafe static void SelectByAxis(int nth, Point3 *points, int length, int axis)
        {
            // note: this function has been adapted from public domain
            //       variants listed in 'KdTree_nth_element.txt'
            const int strideLsh = 2;

            var i = 0;
            var j = length - 1;
            var v = &points->x + axis;

            while (i < j)
            {
                var r = i;
                var w = j;

                float k = v[((r + w) >> 1) << strideLsh];

                while (r < w)
                {
                    if (v[r << strideLsh] >= k)
                    {
                        Point3 pw = points[w];
                        points[w] = points[r];
                        points[r] = pw;
                        w--;
                    }
                    else
                    {
                        r++;
                    }
                }

                if (v[r << strideLsh] > k)
                {
                    r--;
                }

                if (nth <= r)
                {
                    j = r;
                }
                else
                {
                    i = r + 1;
                }
            }
        }
コード例 #3
0
        unsafe static void BuildNodeDeferSubtrees(Node *node, Point3 *points, int offset, int length, int depth)
        {
            // pick median
            int median = length >> 1;

            // pick splitting axis
            int axis = depth % 3;

            // split points by median
            SelectByAxis(median, points + offset, length, axis);

            // calc offsets
            var lengthL = median;
            var lengthR = length - median - 1;
            var stepL   = lengthL > 0 ? 1 : 0;
            var stepR   = lengthR > 0 ? 1 + lengthL : 0;

            // make node
            node->point = offset + median;
            node->stepL = stepL;
            node->stepR = stepR;
        }
コード例 #4
0
        unsafe static void ScheduleNode(ref JobHandle *jobSched, JobHandle *jobDepends, Node *node, Point3 *points, int offset, int length, int depth, int depthSingleThreaded)
        {
            // pick median
            int median = length >> 1;

            // calc offsets
            var offsetL = offset;
            var offsetR = offset + median + 1;
            var lengthL = median;
            var lengthR = length - median - 1;
            var stepL   = lengthL > 0 ? 1 : 0;
            var stepR   = lengthR > 0 ? 1 + lengthL : 0;

            // make job
            var job = new BuildNodeJob()
            {
                node   = node,
                points = points,
                offset = offset,
                length = length,
                depth  = depth,
                leaf   = (depth >= depthSingleThreaded),
            };

            var jobHandle = jobSched++;

            if (jobDepends != null)
            {
                *jobHandle = job.Schedule(*jobDepends);
            }
            else
            {
                *jobHandle = job.Schedule();
            }

            if (depth == 0)
            {
                JobHandle.ScheduleBatchedJobs();
            }

            if (job.leaf)
            {
                return;
            }

            // schedule subtrees
            if (lengthL > 0)
            {
                ScheduleNode(ref jobSched, jobHandle, node + stepL, points, offsetL, lengthL, depth + 1, depthSingleThreaded);
            }
            if (lengthR > 0)
            {
                ScheduleNode(ref jobSched, jobHandle, node + stepR, points, offsetR, lengthR, depth + 1, depthSingleThreaded);
            }
        }
コード例 #5
0
 public unsafe static void Uniform3(int uniformLocation, int count, Point3 *values)
 {
     Delegates.Uniform3ivARB(uniformLocation, count, (int *)values);
 }