world_test.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * DoRayMe - a quick and dirty Raytracer
  3. * World unit tests
  4. *
  5. * Created by Manoël Trapier
  6. * Copyright (c) 2020 986-Studio.
  7. *
  8. */
  9. #include <world.h>
  10. #include <light.h>
  11. #include <sphere.h>
  12. #include <material.h>
  13. #include <transformation.h>
  14. #include <worldbuilder.h>
  15. #include <math.h>
  16. #include <gtest/gtest.h>
  17. TEST(WorldTest, Creating_a_world)
  18. {
  19. World w;
  20. ASSERT_EQ(w.lightCount, 0);
  21. ASSERT_EQ(w.objectCount, 0);
  22. }
  23. TEST(WorldTest, The_default_world)
  24. {
  25. World w = DefaultWorld();
  26. Light l = Light(POINT_LIGHT, Point(-10, 10, -10), Colour(1, 1, 1));
  27. Sphere s1 = Sphere();
  28. Sphere s2 = Sphere();
  29. Material s1Mat = Material();
  30. s1Mat.colour = Colour(0.8, 1.0, 0.6);
  31. s1Mat.diffuse = 0.7;
  32. s1Mat.specular = 0.2;
  33. s1.setMaterial(s1Mat);
  34. s2.setTransform(scaling(0.5, 0.5,0.5));
  35. ASSERT_TRUE(w.lightIsIn(l));
  36. ASSERT_TRUE(w.objectIsIn(s1));
  37. ASSERT_TRUE(w.objectIsIn(s2));
  38. };
  39. TEST(WorldTest, Intersect_a_world_with_a_ray)
  40. {
  41. World w = DefaultWorld();
  42. Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1));
  43. Intersect xs = w.intersect(r);
  44. ASSERT_EQ(xs.count(), 4);
  45. ASSERT_EQ(xs[0].t, 4);
  46. ASSERT_EQ(xs[1].t, 4.5);
  47. ASSERT_EQ(xs[2].t, 5.5);
  48. ASSERT_EQ(xs[3].t, 6);
  49. }
  50. TEST(WorldTest, Shading_an_intersection)
  51. {
  52. World w = DefaultWorld();
  53. Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1));
  54. Shape *s = w.getObject(0);
  55. Intersection i = Intersection(4, s);
  56. Computation comps = i.prepareComputation(r);
  57. Tuple c = w.shadeHit(comps);
  58. /* Temporary lower the precision */
  59. set_equal_precision(0.00001);
  60. ASSERT_EQ(c, Colour(0.38066, 0.47583, 0.2855));
  61. set_equal_precision(FLT_EPSILON);
  62. }
  63. TEST(WorldTest, The_when_ray_miss)
  64. {
  65. World w = DefaultWorld();
  66. Ray r = Ray(Point(0, 0, -5), Vector(0, 1, 0));
  67. Tuple c = w.colourAt(r);
  68. ASSERT_EQ(c, Colour(0, 0, 0));
  69. }
  70. TEST(WorldTest, The_when_ray_hit)
  71. {
  72. World w = DefaultWorld();
  73. Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1));
  74. Tuple c = w.colourAt(r);
  75. /* Temporary lower the precision */
  76. set_equal_precision(0.00001);
  77. ASSERT_EQ(c, Colour(0.38066, 0.47583, 0.2855));
  78. set_equal_precision(FLT_EPSILON);
  79. }
  80. TEST(WorldTest, The_colour_with_an_intersection_behind_the_ray)
  81. {
  82. World w = DefaultWorld();
  83. Shape *outer = w.getObject(0);
  84. outer->material.ambient = 1;
  85. Shape *inner = w.getObject(1);
  86. inner->material.ambient = 1;
  87. Ray r = Ray(Point(0, 0, 0.75), Vector(0, 0, -1));
  88. Tuple c = w.colourAt(r);
  89. ASSERT_EQ(c, inner->material.colour);
  90. }
  91. TEST(WorldTest, There_is_no_shadow_when_nothing_is_collinear_with_point_and_light)
  92. {
  93. World w = DefaultWorld();
  94. Tuple p = Point(0, 10, 0);
  95. ASSERT_FALSE(w.isShadowed(p));
  96. }
  97. TEST(WorldTest, The_shadow_when_an_object_is_between_the_point_and_the_light)
  98. {
  99. World w = DefaultWorld();
  100. Tuple p = Point(10, -10, 10);
  101. ASSERT_TRUE(w.isShadowed(p));
  102. }
  103. TEST(WorldTest, There_is_no_shadow_whne_an_object_is_behing_the_light)
  104. {
  105. World w = DefaultWorld();
  106. Tuple p = Point(-20, 20, -20);
  107. ASSERT_FALSE(w.isShadowed(p));
  108. }
  109. TEST(WorldTest, There_is_no_shadow_when_an_object_is_behing_the_point)
  110. {
  111. World w = DefaultWorld();
  112. Tuple p = Point(-2, 2, -2);
  113. ASSERT_FALSE(w.isShadowed(p));
  114. }
  115. TEST(WorldTest, Shade_hit_is_given_an_intersection_in_shadow)
  116. {
  117. World w = World();
  118. Light l = Light(POINT_LIGHT, Point(0, 0, -10), Colour(1, 1, 1));
  119. w.addLight(&l);
  120. Sphere s1 = Sphere();
  121. w.addObject(&s1);
  122. Sphere s2 = Sphere();
  123. s2.setTransform(translation(0, 0, 10));
  124. w.addObject(&s2);
  125. Ray r = Ray(Point(0, 0, 5), Vector(0, 0, 1));
  126. Intersection i = Intersection(4, &s2);
  127. Computation comps = i.prepareComputation(r);
  128. Tuple c = w.shadeHit(comps);
  129. ASSERT_EQ(c, Colour(0.1, 0.1, 0.1));
  130. };