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); } }
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; } } }
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; }
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); } }
public unsafe static void Uniform3(int uniformLocation, int count, Point3 *values) { Delegates.Uniform3ivARB(uniformLocation, count, (int *)values); }