intersection.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * DoRayMe - a quick and dirty Raytracer
  3. * Intersection implementation
  4. *
  5. * Created by Manoël Trapier
  6. * Copyright (c) 2020 986-Studio.
  7. *
  8. */
  9. #include <intersection.h>
  10. #include <shape.h>
  11. #include <list.h>
  12. double Computation::schlick()
  13. {
  14. /* Find the cos of the angle betzeen the eye and normal vector */
  15. double cos = this->eyeVector.dot(this->normalVector);
  16. double r0;
  17. /* Total internal reflection can only occur when n1 > n2 */
  18. if (this->n1 > this->n2)
  19. {
  20. double n, sin2_t;
  21. n = this->n1 / this->n2;
  22. sin2_t = (n * n) * (1.0 - (cos * cos));
  23. if (sin2_t > 1.0)
  24. {
  25. return 1.0;
  26. }
  27. /* Compute the cos of theta */
  28. cos = sqrt(1.0 - sin2_t);
  29. }
  30. r0 = ((this->n1 - this->n2) / (this->n1 + this->n2));
  31. r0 = r0 * r0;
  32. return r0 + (1 - r0) * ((1 - cos)*(1 - cos)*(1 - cos)*(1 - cos)*(1 - cos));
  33. };
  34. Computation Intersection::prepareComputation(Ray r, Intersect *xs)
  35. {
  36. double n1 = 1.0;
  37. double n2 = 1.0;
  38. Tuple hitP = r.position(this->t);
  39. Tuple normalV;
  40. if (xs != nullptr)
  41. {
  42. Intersection hit = xs->hit();
  43. normalV = this->object->normalAt(hitP, &hit);
  44. }
  45. else
  46. {
  47. normalV = this->object->normalAt(hitP, nullptr);
  48. }
  49. Tuple eyeV = -r.direction;
  50. bool inside = false;
  51. if (normalV.dot(eyeV) < 0)
  52. {
  53. inside = true;
  54. normalV = -normalV;
  55. }
  56. Tuple overHitP = hitP + normalV * getEpsilon();
  57. Tuple underHitP = hitP - normalV * getEpsilon();
  58. Tuple reflectV = r.direction.reflect(normalV);
  59. /* If the hit object is not transparent, there is no need to do that. I think .*/
  60. if ((xs != nullptr) && (xs->hit().object->getMaterial()->transparency > 0))
  61. {
  62. List containers;
  63. int j;
  64. for (j = 0 ; j < xs->count() ; j++)
  65. {
  66. Intersection i = ( *xs )[j];
  67. if (*this == i)
  68. {
  69. if (!containers.isEmpty())
  70. {
  71. n1 = containers.last()->getMaterial()->refractiveIndex;
  72. }
  73. }
  74. if (containers.doesInclude(i.object))
  75. {
  76. containers.remove(i.object);
  77. }
  78. else
  79. {
  80. containers.append(i.object);
  81. }
  82. if (*this == i)
  83. {
  84. if (!containers.isEmpty())
  85. {
  86. n2 = containers.last()->getMaterial()->refractiveIndex;
  87. }
  88. /* End the loop */
  89. break;
  90. }
  91. }
  92. }
  93. Material *m = this->object->getMaterial();
  94. return Computation(this->object,
  95. this->t,
  96. hitP,
  97. eyeV,
  98. normalV,
  99. overHitP,
  100. inside,
  101. reflectV,
  102. n1,
  103. n2,
  104. underHitP,
  105. m);
  106. }