camera.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. Camera::Camera(uint32_t hsize, uint32_t vsize, double fov) : verticalSize(vsize), horizontalSize(hsize), fieldOfView(fov)
  16. {
  17. double aspectRatio = (double)hsize / (double)vsize;
  18. double halfView = tan(fov / 2.0);
  19. if (aspectRatio >= 1)
  20. {
  21. this->halfWidth = halfView;
  22. this->halfHeight = halfView / aspectRatio;
  23. }
  24. else
  25. {
  26. this->halfWidth = halfView * aspectRatio;
  27. this->halfHeight = halfView;
  28. }
  29. this->pixelSize = (this->halfWidth * 2) / this->horizontalSize;
  30. this->setTransform(Matrix4().identity());
  31. }
  32. void Camera::setTransform(Matrix transform)
  33. {
  34. this->transformMatrix = transform;
  35. this->inverseTransform = transform.inverse();
  36. }
  37. Ray Camera::rayForPixel(uint32_t pixelX, uint32_t pixelY)
  38. {
  39. double xOffset = ((double)pixelX + 0.5) * this->pixelSize;
  40. double yOffset = ((double)pixelY + 0.5) * this->pixelSize;
  41. double worldX = this->halfWidth - xOffset;
  42. double worldY = this->halfHeight - yOffset;
  43. Tuple pixel = this->inverseTransform * Point(worldX, worldY, -1);
  44. Tuple origin = this->inverseTransform * Point(0, 0, 0);
  45. Tuple direction = (pixel - origin).normalise();
  46. return Ray(origin, direction);
  47. }
  48. Canvas Camera::render(World world, uint32_t depth)
  49. {
  50. uint32_t x, y;
  51. Canvas image = Canvas(this->horizontalSize, this->verticalSize);
  52. for(y = 0; y < this->verticalSize; y++)
  53. {
  54. #pragma omp parallel for
  55. for(x = 0; x < this->horizontalSize; x++)
  56. {
  57. Ray r = this->rayForPixel(x, y);
  58. Tuple colour = world.colourAt(r, depth);
  59. image.putPixel(x, y, colour);
  60. }
  61. }
  62. return image;
  63. }