| 416 | } |
| 417 | |
| 418 | static size_t kdtreeBuild(size_t offset, KDNode* nodes, size_t node_count, const float* points, size_t stride, unsigned int* indices, size_t count, size_t leaf_size) |
| 419 | { |
| 420 | assert(count > 0); |
| 421 | assert(offset < node_count); |
| 422 | |
| 423 | if (count <= leaf_size) |
| 424 | return kdtreeBuildLeaf(offset, nodes, node_count, indices, count); |
| 425 | |
| 426 | float mean[3] = {}; |
| 427 | float vars[3] = {}; |
| 428 | float runc = 1, runs = 1; |
| 429 | |
| 430 | // gather statistics on the points in the subtree using Welford's algorithm |
| 431 | for (size_t i = 0; i < count; ++i, runc += 1.f, runs = 1.f / runc) |
| 432 | { |
| 433 | const float* point = points + indices[i] * stride; |
| 434 | |
| 435 | for (int k = 0; k < 3; ++k) |
| 436 | { |
| 437 | float delta = point[k] - mean[k]; |
| 438 | mean[k] += delta * runs; |
| 439 | vars[k] += delta * (point[k] - mean[k]); |
| 440 | } |
| 441 | } |
| 442 | |
| 443 | // split axis is one where the variance is largest |
| 444 | unsigned int axis = (vars[0] >= vars[1] && vars[0] >= vars[2]) ? 0 : (vars[1] >= vars[2] ? 1 : 2); |
| 445 | |
| 446 | float split = mean[axis]; |
| 447 | size_t middle = kdtreePartition(indices, count, points, stride, axis, split); |
| 448 | |
| 449 | // when the partition is degenerate simply consolidate the points into a single node |
| 450 | if (middle <= leaf_size / 2 || middle >= count - leaf_size / 2) |
| 451 | return kdtreeBuildLeaf(offset, nodes, node_count, indices, count); |
| 452 | |
| 453 | KDNode& result = nodes[offset]; |
| 454 | |
| 455 | result.split = split; |
| 456 | result.axis = axis; |
| 457 | |
| 458 | // left subtree is right after our node |
| 459 | size_t next_offset = kdtreeBuild(offset + 1, nodes, node_count, points, stride, indices, middle, leaf_size); |
| 460 | |
| 461 | // distance to the right subtree is represented explicitly |
| 462 | result.children = unsigned(next_offset - offset - 1); |
| 463 | |
| 464 | return kdtreeBuild(next_offset, nodes, node_count, points, stride, indices + middle, count - middle, leaf_size); |
| 465 | } |
| 466 | |
| 467 | static void kdtreeNearest(KDNode* nodes, unsigned int root, const float* points, size_t stride, const unsigned char* emitted_flags, const float* position, unsigned int& result, float& limit) |
| 468 | { |
no test coverage detected