camera_test.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * DoRayMe - a quick and dirty Raytracer
  3. * Camera unit tests
  4. *
  5. * Created by Manoël Trapier
  6. * Copyright (c) 2020 986-Studio.
  7. *
  8. */
  9. #include <camera.h>
  10. #include <math.h>
  11. #include <math_helper.h>
  12. #include <matrix.h>
  13. #include <tuple.h>
  14. #include <ray.h>
  15. #include <world.h>
  16. #include <canvas.h>
  17. #include <colour.h>
  18. #include <worldbuilder.h>
  19. #include <transformation.h>
  20. #include <stdint.h>
  21. #include <gtest/gtest.h>
  22. TEST(CameraTest, Constructing_a_camera)
  23. {
  24. uint32_t hsize = 160;
  25. uint32_t vsize = 120;
  26. double field_of_view = M_PI / 2;
  27. Camera c = Camera(hsize, vsize, field_of_view);
  28. ASSERT_EQ(c.horizontalSize, 160);
  29. ASSERT_EQ(c.verticalSize, 120);
  30. ASSERT_TRUE(double_equal(c.fieldOfView, M_PI / 2));
  31. ASSERT_EQ(c.transformMatrix, Matrix4().identity());
  32. }
  33. TEST(CameraTest, Pixel_size_for_a_horizontal_canvas)
  34. {
  35. Camera c = Camera(200, 125, M_PI / 2);
  36. ASSERT_TRUE(double_equal(c.pixelSize, 0.01));
  37. }
  38. TEST(CameraTest, Pixel_size_for_a_vertical_canvas)
  39. {
  40. Camera c = Camera(125, 200, M_PI / 2);
  41. ASSERT_TRUE(double_equal(c.pixelSize, 0.01));
  42. }
  43. TEST(CameraTest, Constructing_a_ray_through_the_center_of_the_canvas)
  44. {
  45. Camera c = Camera(201, 101, M_PI / 2);
  46. Ray r = c.rayForPixel(100, 50);
  47. ASSERT_EQ(r.origin, Point(0, 0, 0));
  48. ASSERT_EQ(r.direction, Vector(0, 0, -1));
  49. }
  50. TEST(CameraTest, Constructing_a_ray_through_a_corner_of_the_canvas)
  51. {
  52. Camera c = Camera(201, 101, M_PI / 2);
  53. Ray r = c.rayForPixel(0, 0);
  54. ASSERT_EQ(r.origin, Point(0, 0, 0));
  55. /* Temporary lower the precision */
  56. set_equal_precision(0.00001);
  57. ASSERT_EQ(r.direction, Vector(0.66519, 0.33259, -0.66851));
  58. set_equal_precision(FLT_EPSILON);
  59. }
  60. TEST(CameraTest, Constructing_a_ray_when_the_camera_is_transformed)
  61. {
  62. Camera c = Camera(201, 101, M_PI / 2);
  63. c.setTransform(rotationY(M_PI / 4) * translation(0, -2, 5));
  64. Ray r = c.rayForPixel(100, 50);
  65. ASSERT_EQ(r.origin, Point(0, 2, -5));
  66. ASSERT_EQ(r.direction, Vector(sqrt(2)/2, 0, -sqrt(2)/2));
  67. }
  68. TEST(CameraTest, Rendering_a_world_with_a_camera)
  69. {
  70. World w = DefaultWorld();
  71. Camera c = Camera(11, 11, M_PI / 2);
  72. Tuple from = Point(0, 0, -5);
  73. Tuple to = Point(0, 0, 0);
  74. Tuple up = Vector(0, 1, 0);
  75. c.setTransform(viewTransform(from, to, up));
  76. Canvas image = c.render(w);
  77. /* Temporary lower the precision */
  78. /* We need to lower a lot as Canvas is not keeping the
  79. * floating point value, but a value between 0 and 255 per channel,
  80. * as it is storing the actual frame buffer, so there is a more big different
  81. * between the value.
  82. */
  83. set_equal_precision(0.005);
  84. Colour col = image.getPixel(5, 5);
  85. ASSERT_EQ(col, Colour(0.38066, 0.47583, 0.2855));
  86. set_equal_precision(FLT_EPSILON);
  87. }