cone_test.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * DoRayMe - a quick and dirty Raytracer
  3. * Cone unit tests
  4. *
  5. * Created by Manoël Trapier
  6. * Copyright (c) 2020 986-Studio.
  7. *
  8. */
  9. #include <intersect.h>
  10. #include <intersection.h>
  11. #include <cone.h>
  12. #include <transformation.h>
  13. #include <gtest/gtest.h>
  14. class ConeTest : public Cone
  15. {
  16. public:
  17. Tuple doLocalNormalAt(Tuple point)
  18. {
  19. return localNormalAt(point);
  20. }
  21. };
  22. TEST(ConeTest, Intersecting_a_cone_with_a_ray)
  23. {
  24. Cone cone = Cone();
  25. Point Origins[] = {
  26. Point(0, 0, -5),
  27. Point(0, 0, -5),
  28. Point(1, 1, -5),
  29. };
  30. Vector Directions[] = {
  31. Vector(0, 0, 1),
  32. Vector(1, 1, 1),
  33. Vector(-0.5, -1, 1),
  34. };
  35. double t0s[] = { 5, 8.66025, 4.55006 };
  36. double t1s[] = { 5, 8.66025, 49.44994 };
  37. int i;
  38. for(i = 0; i < 3; i++)
  39. {
  40. Tuple direction = Directions[i].normalise();
  41. Ray r = Ray(Origins[i], direction);
  42. Intersect xs; cone.intersect(r, xs);
  43. /* Temporary lower the precision */
  44. set_equal_precision(0.00001);
  45. ASSERT_EQ(xs.count(), 2);
  46. EXPECT_TRUE(double_equal(xs[0].t, t0s[i]));
  47. EXPECT_TRUE(double_equal(xs[1].t, t1s[i]));
  48. set_equal_precision(FLT_EPSILON);
  49. }
  50. }
  51. TEST(ConeTest, Intersecting_a_cone_with_a_ray_parall_to_one_of_its_halves)
  52. {
  53. Cone cone = Cone();
  54. Tuple direction = Vector(0, 1, 1).normalise();
  55. Ray r = Ray(Point(0, 0, -1), direction);
  56. Intersect xs; cone.intersect(r, xs);
  57. ASSERT_EQ(xs.count(), 1);
  58. /* Temporary lower the precision */
  59. set_equal_precision(0.00001);
  60. ASSERT_TRUE(double_equal(xs[0].t, 0.35355));
  61. set_equal_precision(FLT_EPSILON);
  62. }
  63. TEST(ConeTest, Intersecting_a_cone_end_cap)
  64. {
  65. Point Origins[] = {
  66. Point(0, 0, -5),
  67. Point(0, 0, -0.25),
  68. Point(0, 0, -0.25),
  69. };
  70. Vector Directions[] = {
  71. Vector(0, 1, 0),
  72. Vector(0, 1, 1),
  73. Vector(0, 1, 0),
  74. };
  75. uint32_t Counts[] = { 0, 2, 4 };
  76. Cone cone = Cone();
  77. cone.minCap = -0.5;
  78. cone.maxCap = 0.5;
  79. cone.isClosed = true;
  80. int i;
  81. for(i = 0; i < 3; i++)
  82. {
  83. Tuple direction = Directions[i].normalise();
  84. Ray r = Ray(Origins[i], direction);
  85. Intersect xs;
  86. cone.intersect(r, xs);
  87. ASSERT_EQ(xs.count(), Counts[i]);
  88. }
  89. }
  90. TEST(ConeTest, Computing_the_normal_vector_on_a_cone)
  91. {
  92. ConeTest cone = ConeTest();
  93. Point HitPointss[] = {
  94. Point(0, 0, 0),
  95. Point(1, 1, 1),
  96. Point(-1, -1, 0),
  97. };
  98. Vector Normals[] = {
  99. Vector(0, 0, 0),
  100. Vector(1, -sqrt(2), 1),
  101. Vector(-1, 1, 0),
  102. };
  103. int i;
  104. for(i = 0; i < 3; i++)
  105. {
  106. ASSERT_EQ(cone.doLocalNormalAt(HitPointss[i]), Normals[i]);
  107. }
  108. }
  109. TEST(ConeTest, The_bounding_box_of_a_cut_cone)
  110. {
  111. Cone t = Cone();
  112. BoundingBox b = BoundingBox(Point(-8, -5, -8), Point(8, 8, 8));
  113. t.minCap = -5;
  114. t.maxCap = 8;
  115. BoundingBox res = t.getBounds();
  116. ASSERT_EQ(res.min, b.min);
  117. ASSERT_EQ(res.max, b.max);
  118. }
  119. TEST(ConeTest, The_bounding_box_of_a_uncut_cone)
  120. {
  121. /* This one is tricky. Infinite size don't cope well with transformations */
  122. Cone t = Cone();
  123. BoundingBox res = t.getBounds();
  124. ASSERT_FALSE(res.min.isRepresentable());
  125. ASSERT_FALSE(res.max.isRepresentable());
  126. }
  127. TEST(ConeTest, An_uncut_cone_have_infinite_bounds)
  128. {
  129. Cone t = Cone();
  130. ASSERT_FALSE(t.haveFiniteBounds());
  131. }
  132. TEST(ConeTest, A_cut_cone_have_finite_bounds)
  133. {
  134. Cone t = Cone();
  135. t.minCap = -5;
  136. t.maxCap = 3;
  137. BoundingBox res = t.getBounds();
  138. ASSERT_TRUE(t.haveFiniteBounds());
  139. ASSERT_EQ(res.min, Point(-5, -5, -5));
  140. ASSERT_EQ(res.max, Point(5, 3, 5));
  141. }