quad_intersector.h 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. namespace embree
  5. {
  6. namespace isa
  7. {
  8. /*! Intersects a ray with a quad with backface culling
  9. * enabled. The quad v0,v1,v2,v3 is split into two triangles
  10. * v0,v1,v3 and v2,v3,v1. The edge v1,v2 decides which of the two
  11. * triangles gets intersected. */
  12. template<int N>
  13. __forceinline vbool<N> intersect_quad_backface_culling(const vbool<N>& valid0,
  14. const Vec3fa& ray_org,
  15. const Vec3fa& ray_dir,
  16. const float ray_tnear,
  17. const float ray_tfar,
  18. const Vec3vf<N>& quad_v0,
  19. const Vec3vf<N>& quad_v1,
  20. const Vec3vf<N>& quad_v2,
  21. const Vec3vf<N>& quad_v3,
  22. vfloat<N>& u_o,
  23. vfloat<N>& v_o,
  24. vfloat<N>& t_o)
  25. {
  26. /* calculate vertices relative to ray origin */
  27. vbool<N> valid = valid0;
  28. const Vec3vf<N> O = Vec3vf<N>(ray_org);
  29. const Vec3vf<N> D = Vec3vf<N>(ray_dir);
  30. const Vec3vf<N> va = quad_v0-O;
  31. const Vec3vf<N> vb = quad_v1-O;
  32. const Vec3vf<N> vc = quad_v2-O;
  33. const Vec3vf<N> vd = quad_v3-O;
  34. const Vec3vf<N> edb = vb-vd;
  35. const vfloat<N> WW = dot(cross(vd,edb),D);
  36. const Vec3vf<N> v0 = select(WW <= 0.0f,va,vc);
  37. const Vec3vf<N> v1 = select(WW <= 0.0f,vb,vd);
  38. const Vec3vf<N> v2 = select(WW <= 0.0f,vd,vb);
  39. /* calculate edges */
  40. const Vec3vf<N> e0 = v2-v0;
  41. const Vec3vf<N> e1 = v0-v1;
  42. /* perform edge tests */
  43. const vfloat<N> U = dot(cross(v0,e0),D);
  44. const vfloat<N> V = dot(cross(v1,e1),D);
  45. valid &= max(U,V) <= 0.0f;
  46. if (unlikely(none(valid))) return false;
  47. /* calculate geometry normal and denominator */
  48. const Vec3vf<N> Ng = cross(e1,e0);
  49. const vfloat<N> den = dot(Ng,D);
  50. const vfloat<N> rcpDen = rcp(den);
  51. /* perform depth test */
  52. const vfloat<N> t = rcpDen*dot(v0,Ng);
  53. valid &= vfloat<N>(ray_tnear) <= t & t <= vfloat<N>(ray_tfar);
  54. if (unlikely(none(valid))) return false;
  55. /* avoid division by 0 */
  56. valid &= den != vfloat<N>(zero);
  57. if (unlikely(none(valid))) return false;
  58. /* update hit information */
  59. t_o = t;
  60. u_o = U * rcpDen;
  61. v_o = V * rcpDen;
  62. u_o = select(WW <= 0.0f,u_o,1.0f-u_o);
  63. v_o = select(WW <= 0.0f,v_o,1.0f-v_o);
  64. return valid;
  65. }
  66. }
  67. }