camera.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. * DoRayMe - a quick and dirty Raytracer
  3. * Camera implementation
  4. *
  5. * Created by Manoël Trapier
  6. * Copyright (c) 2020 986-Studio.
  7. *
  8. */
  9. #include <matrix.h>
  10. #include <stdint.h>
  11. #include <math.h>
  12. #include <ray.h>
  13. #include <camera.h>
  14. #include <stdio.h>
  15. #include <renderstat.h>
  16. Camera::Camera(uint32_t hsize, uint32_t vsize, double fov) : verticalSize(vsize), horizontalSize(hsize), fieldOfView(fov)
  17. {
  18. double aspectRatio = (double)hsize / (double)vsize;
  19. double halfView = tan(fov / 2.0);
  20. if (aspectRatio >= 1)
  21. {
  22. this->halfWidth = halfView;
  23. this->halfHeight = halfView / aspectRatio;
  24. }
  25. else
  26. {
  27. this->halfWidth = halfView * aspectRatio;
  28. this->halfHeight = halfView;
  29. }
  30. this->pixelSize = (this->halfWidth * 2) / this->horizontalSize;
  31. this->setTransform(Matrix4().identity());
  32. }
  33. void Camera::setTransform(Matrix transform)
  34. {
  35. this->transformMatrix = transform;
  36. this->inverseTransform = transform.inverse();
  37. }
  38. Ray Camera::rayForPixel(uint32_t pixelX, uint32_t pixelY)
  39. {
  40. double xOffset = ((double)pixelX + 0.5) * this->pixelSize;
  41. double yOffset = ((double)pixelY + 0.5) * this->pixelSize;
  42. double worldX = this->halfWidth - xOffset;
  43. double worldY = this->halfHeight - yOffset;
  44. Tuple pixel = this->inverseTransform * Point(worldX, worldY, -1);
  45. Tuple origin = this->inverseTransform * Point(0, 0, 0);
  46. Tuple direction = (pixel - origin).normalise();
  47. return Ray(origin, direction);
  48. }
  49. Canvas Camera::render(World world, uint32_t depth)
  50. {
  51. uint32_t x, y;
  52. Canvas image = Canvas(this->horizontalSize, this->verticalSize);
  53. #pragma omp parallel private(x, y) shared(image, stats)
  54. {
  55. #pragma omp for
  56. for (y = 0 ; y < this->verticalSize ; y++)
  57. {
  58. for (x = 0 ; x < this->horizontalSize ; x++)
  59. {
  60. Ray r = this->rayForPixel(x, y);
  61. Tuple colour = world.colourAt(r, depth);
  62. stats.addPixel();
  63. image.putPixel(x, y, colour);
  64. }
  65. }
  66. }
  67. stats.printStats();
  68. return image;
  69. }