Finds the tightest bounding sphere by calling add_points() multiple times on the same randomly ordered positions. Uses a seed dependent on initial positions to guarantee stable results.
| 420 | // randomly ordered positions. Uses a seed dependent on initial positions to guarantee stable |
| 421 | // results. |
| 422 | static Sphere sphere(Geometry &g) |
| 423 | { |
| 424 | const u32 MAX_TRIES = 256; |
| 425 | Sphere sphere; |
| 426 | sphere::reset(sphere); |
| 427 | |
| 428 | if (array::size(g._positions) != 0) { |
| 429 | const u16 seed = (u16)murmur64(array::begin(g._positions) |
| 430 | , array::size(g._positions)*sizeof(g._positions[0]) |
| 431 | , 0u |
| 432 | ); |
| 433 | Random random((s32)seed); |
| 434 | |
| 435 | Array<f32> positions(default_allocator()); |
| 436 | Array<u32> indices(default_allocator()); |
| 437 | array::resize(positions, array::size(g._positions)); |
| 438 | array::resize(indices, array::size(g._positions) / 3); |
| 439 | |
| 440 | for (u32 j = 0; j < array::size(indices); ++j) |
| 441 | indices[j] = j; |
| 442 | |
| 443 | Sphere s; |
| 444 | for (u32 i = 0; i < MAX_TRIES; ++i) { |
| 445 | sphere::reset(s); |
| 446 | |
| 447 | // Shuffle index. |
| 448 | for (u32 i = 0; i < array::size(indices); ++i) { |
| 449 | s32 k = random.integer(array::size(indices)); |
| 450 | exchange(indices[i], indices[k]); |
| 451 | } |
| 452 | |
| 453 | // TODO: just add a sphere::add_points() that supports index buffers. |
| 454 | for (u32 i = 0; i < array::size(indices); ++i) { |
| 455 | positions[i*3 + 0] = g._positions[indices[i]*3 + 0]; |
| 456 | positions[i*3 + 1] = g._positions[indices[i]*3 + 1]; |
| 457 | positions[i*3 + 2] = g._positions[indices[i]*3 + 2]; |
| 458 | } |
| 459 | |
| 460 | sphere::add_points(s |
| 461 | , array::size(g._positions) / 3 |
| 462 | , sizeof(g._positions[0]) * 3 |
| 463 | , array::begin(positions) |
| 464 | ); |
| 465 | |
| 466 | if (sphere::volume(s) < sphere::volume(sphere) || i == 0) |
| 467 | sphere = s; |
| 468 | } |
| 469 | } |
| 470 | |
| 471 | return sphere; |
| 472 | } |
| 473 | |
| 474 | s32 write(Mesh &m, CompileOptions &opts) |
| 475 | { |