camera.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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. stats.addCastedRay();
  48. return Ray(origin, direction);
  49. }
  50. Canvas Camera::render(World world, uint32_t depth)
  51. {
  52. uint32_t x, y;
  53. Canvas image = Canvas(this->horizontalSize, this->verticalSize);
  54. #pragma omp parallel default(shared) private(x, y) shared(image, stats)
  55. {
  56. #pragma omp for schedule(dynamic, 5)
  57. for (y = 0 ; y < this->verticalSize ; y++)
  58. {
  59. for (x = 0 ; x < this->horizontalSize ; x++)
  60. {
  61. Ray r = this->rayForPixel(x, y);
  62. Tuple colour = world.colourAt(r, depth);
  63. stats.addPixel();
  64. image.putPixel(x, y, colour);
  65. }
  66. }
  67. }
  68. stats.printStats();
  69. return image;
  70. }