* @brief Camera struct * * Contains all the data pertaining to the parameters for the image as seen from * the camera * */
| 627 | * |
| 628 | */ |
| 629 | struct Camera { |
| 630 | af::array position; |
| 631 | af::array lookat; |
| 632 | double fov; |
| 633 | double focal_length; |
| 634 | uint32_t width; |
| 635 | uint32_t height; |
| 636 | |
| 637 | af::array direction; |
| 638 | af::array vertical; |
| 639 | af::array horizontal; |
| 640 | double aspect_ratio; |
| 641 | |
| 642 | Camera(const af::array& position_, const af::array& lookat_, double fov_, |
| 643 | double focal_length_, uint32_t viewport_width_, |
| 644 | uint32_t viewport_height_) |
| 645 | : position(position_) |
| 646 | , lookat(lookat_) |
| 647 | , fov(fov_) |
| 648 | , focal_length(focal_length_) |
| 649 | , width(viewport_width_) |
| 650 | , height(viewport_height_) { |
| 651 | auto global_vertical = af::array(3, {0.0, 0.0, 1.0}); |
| 652 | |
| 653 | // Compute the camera three main axes |
| 654 | direction = normalize3(lookat - position); |
| 655 | horizontal = normalize3(cross_product(direction, global_vertical)); |
| 656 | vertical = normalize3(cross_product(direction, horizontal)); |
| 657 | |
| 658 | aspect_ratio = (double)width / (double)height; |
| 659 | } |
| 660 | |
| 661 | /** |
| 662 | * @brief Generates the initial rays 4-vector position and velocities |
| 663 | * (direction) for the simulation |
| 664 | * |
| 665 | * @return std::pair<af::array, af::array> (pos4, vel4) |
| 666 | */ |
| 667 | std::pair<af::array, af::array> generate_viewport_4rays() { |
| 668 | auto& camera_direction = direction; |
| 669 | auto& camera_horizontal = horizontal; |
| 670 | auto& camera_vertical = vertical; |
| 671 | auto& camera_position = position; |
| 672 | auto vfov = fov; |
| 673 | |
| 674 | double viewport_height = 2.0 * focal_length * std::tan(vfov / 2.0); |
| 675 | double viewport_width = aspect_ratio * viewport_height; |
| 676 | |
| 677 | // Create rays in equally spaced directions of the viewport |
| 678 | af::array viewport_rays = af::constant(0, 3, width, height, f64); |
| 679 | viewport_rays += |
| 680 | (af::iota(af::dim4(1, width, 1), af::dim4(1, 1, height), f64) / |
| 681 | (width - 1) - |
| 682 | 0.5) * |
| 683 | viewport_width * camera_horizontal; |
| 684 | viewport_rays += |
| 685 | (af::iota(af::dim4(1, 1, height), af::dim4(1, width, 1), f64) / |
| 686 | (height - 1) - |