quad_intersector.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #pragma once
  17. namespace embree
  18. {
  19. namespace isa
  20. {
  21. /*! Intersects a ray with a quad with backface culling
  22. * enabled. The quad v0,v1,v2,v3 is split into two triangles
  23. * v0,v1,v3 and v2,v3,v1. The edge v1,v2 decides which of the two
  24. * triangles gets intersected. */
  25. template<int N>
  26. __forceinline vbool<N> intersect_quad_backface_culling(const vbool<N>& valid0,
  27. const Vec3fa& ray_org,
  28. const Vec3fa& ray_dir,
  29. const float ray_tnear,
  30. const float ray_tfar,
  31. const Vec3<vfloat<N>>& quad_v0,
  32. const Vec3<vfloat<N>>& quad_v1,
  33. const Vec3<vfloat<N>>& quad_v2,
  34. const Vec3<vfloat<N>>& quad_v3,
  35. vfloat<N>& u_o,
  36. vfloat<N>& v_o,
  37. vfloat<N>& t_o)
  38. {
  39. /* calculate vertices relative to ray origin */
  40. vbool<N> valid = valid0;
  41. typedef Vec3<vfloat<N>> Vec3vfN;
  42. const Vec3vfN O = Vec3vfN(ray_org);
  43. const Vec3vfN D = Vec3vfN(ray_dir);
  44. const Vec3vfN va = quad_v0-O;
  45. const Vec3vfN vb = quad_v1-O;
  46. const Vec3vfN vc = quad_v2-O;
  47. const Vec3vfN vd = quad_v3-O;
  48. const Vec3vfN edb = vb-vd;
  49. const vfloat<N> WW = dot(cross(vd,edb),D);
  50. const Vec3vfN v0 = select(WW <= 0.0f,va,vc);
  51. const Vec3vfN v1 = select(WW <= 0.0f,vb,vd);
  52. const Vec3vfN v2 = select(WW <= 0.0f,vd,vb);
  53. /* calculate edges */
  54. const Vec3vfN e0 = v2-v0;
  55. const Vec3vfN e1 = v0-v1;
  56. /* perform edge tests */
  57. const vfloat<N> U = dot(cross(v0,e0),D);
  58. const vfloat<N> V = dot(cross(v1,e1),D);
  59. valid &= max(U,V) <= 0.0f;
  60. if (unlikely(none(valid))) return false;
  61. /* calculate geometry normal and denominator */
  62. const Vec3vfN Ng = cross(e1,e0);
  63. const vfloat<N> den = dot(Ng,D);
  64. const vfloat<N> absDen = abs(den);
  65. const vfloat<N> sgnDen = signmsk(den);
  66. /* perform depth test */
  67. const vfloat<N> T = dot(v0,Ng);
  68. valid &= ((T^sgnDen) >= absDen*vfloat<N>(ray_tnear));
  69. valid &=(absDen*vfloat<N>(ray_tfar) >= (T^sgnDen));
  70. if (unlikely(none(valid))) return false;
  71. /* avoid division by 0 */
  72. valid &= den != vfloat<N>(zero);
  73. if (unlikely(none(valid))) return false;
  74. /* update hit information */
  75. const vfloat<N> rcpDen = rcp(den);
  76. t_o = T * rcpDen;
  77. u_o = U * rcpDen;
  78. v_o = V * rcpDen;
  79. u_o = select(WW <= 0.0f,u_o,1.0f-u_o);
  80. v_o = select(WW <= 0.0f,v_o,1.0f-v_o);
  81. return valid;
  82. }
  83. }
  84. }