Compute the intersection between grid cells and the ray. Args: ray_origins: (b, m, 3) ray_directions: (b, m, 3) ray_radius: (b,) grid_size: (b, 3) long, xyz grid_center: (b, 3), xyz grid_width: (b, 3), xyz Returns: list of list of list: b -> ray_idx -> grid_idx (including -1, outside the grid) Algorithm: for each ray (px, py, pz, dx, dy, dz) if dx.abs() < 1e-8: # use y=c plane else: # use x=c
| 548 | // surrounding the point. |
| 549 | // |
| 550 | std::vector<idxmap> grid_ray_intersection_v2( |
| 551 | const torch::Tensor & ray_origins, // (b, m, 3), float |
| 552 | const torch::Tensor & ray_directions, // (b, m, 3), float |
| 553 | const torch::Tensor & ray_radius, // (b, )m float |
| 554 | const torch::Tensor & grid_size, // (b, 3), long |
| 555 | const torch::Tensor & grid_center, // (b, 3) float |
| 556 | const torch::Tensor & grid_width // (b, 3) float |
| 557 | ) { |
| 558 | |
| 559 | assert(grid_size.dtype() == torch::kLong); |
| 560 | |
| 561 | auto batch_size = ray_origins.size(0); |
| 562 | auto n_rays = ray_origins.size(1); |
| 563 | auto device = ray_origins.device(); |
| 564 | |
| 565 | auto grid_from = grid_center - grid_width * 0.5; // (b, 3) |
| 566 | auto cell_width = grid_width / grid_size; // (b, 3) |
| 567 | auto total_cells = torch::prod(grid_size, -1); // (b,) |
| 568 | |
| 569 | // determine whether to intersect with x=c plane, y=c plane, or z=c plane. |
| 570 | // It is important to select a direction so that the intersection point on two nearby planes |
| 571 | // do not exceed one grid in one of the rest of the two directions. |
| 572 | // Fortunately, it can be shown that it will always happen when we select wisely. |
| 573 | |
| 574 | // Let inv_tx = |dx / wx| (1 / time to travel one x grid) |
| 575 | // inv_ty = |dy / wy| (1 / time to travel one y grid) |
| 576 | // inv_tz = |dz / wz| (1 / time to travel one z grid) |
| 577 | // If inv_tx is the largest of (inv_tx, inv_ty, inv_tz) -> we will intersect with x=c planes. |
| 578 | // vise versa for inv_ty and inv_tz. |
| 579 | // When we select inv_tx, it ensures we move in the x direction in 1 grid, y and z in <= 1 grid. |
| 580 | |
| 581 | auto inv_t = (ray_directions / cell_width.unsqueeze(-2)).abs(); // (b, m, 3) |
| 582 | auto idx_to_use = torch::argmax(inv_t, -1); // (b, m) (0, 1, 2) |
| 583 | |
| 584 | // std::cout<<"idx_to_use:"<<std::endl; |
| 585 | // std::cout<<idx_to_use<<std::endl; |
| 586 | |
| 587 | |
| 588 | // create accessors to each tensor |
| 589 | // auto start = high_resolution_clock::now(); |
| 590 | auto a_ray_directions = ray_directions.accessor<float, 3>(); // (b, m, 3) |
| 591 | auto a_ray_radius = ray_radius.accessor<float, 1>(); // (b,) |
| 592 | auto a_grid_from = grid_from.accessor<float, 2>(); // (b, 3) |
| 593 | auto a_cell_width = cell_width.accessor<float, 2>(); // (b, 3) |
| 594 | auto a_grid_size = grid_size.accessor<int64_t, 2>(); // (b, 3) |
| 595 | auto a_idx_to_use = idx_to_use.accessor<int64_t, 2>(); // (b, m) 0, 1, 2 |
| 596 | // auto stop = high_resolution_clock::now(); |
| 597 | // auto duration = duration_cast<microseconds>(stop - start); |
| 598 | // std::cout<<"accessor_time: "<<duration.count()<<std::endl; |
| 599 | |
| 600 | auto l_options = torch::TensorOptions().dtype(torch::kLong).device(device); |
| 601 | auto f_options = torch::TensorOptions().dtype(torch::kFloat32).device(device); |
| 602 | |
| 603 | |
| 604 | std::vector<idxmap> all_grid_idxs; |
| 605 | all_grid_idxs.reserve(batch_size); |
| 606 | for (auto b = 0; b < batch_size; ++b) { |
| 607 |
no test coverage detected