camera.cpp 1.8 KB

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