line_intersector.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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. #include "../common/ray.h"
  18. #include "filter.h"
  19. namespace embree
  20. {
  21. namespace isa
  22. {
  23. template<int M>
  24. struct LineIntersectorHitM
  25. {
  26. __forceinline LineIntersectorHitM() {}
  27. __forceinline LineIntersectorHitM(const vfloat<M>& u, const vfloat<M>& v, const vfloat<M>& t, const Vec3<vfloat<M>>& Ng)
  28. : vu(u), vv(v), vt(t), vNg(Ng) {}
  29. __forceinline void finalize() {}
  30. __forceinline Vec2f uv (const size_t i) const { return Vec2f(vu[i],vv[i]); }
  31. __forceinline float t (const size_t i) const { return vt[i]; }
  32. __forceinline Vec3fa Ng(const size_t i) const { return Vec3fa(vNg.x[i],vNg.y[i],vNg.z[i]); }
  33. public:
  34. vfloat<M> vu;
  35. vfloat<M> vv;
  36. vfloat<M> vt;
  37. Vec3<vfloat<M>> vNg;
  38. };
  39. template<int M>
  40. struct LineIntersector1
  41. {
  42. typedef Vec3<vfloat<M>> Vec3vfM;
  43. typedef Vec4<vfloat<M>> Vec4vfM;
  44. struct Precalculations
  45. {
  46. __forceinline Precalculations() {}
  47. __forceinline Precalculations(const Ray& ray, const void* ptr)
  48. {
  49. const float s = rsqrt(dot(ray.dir,ray.dir));
  50. depth_scale = s;
  51. ray_space = frame(s*ray.dir).transposed();
  52. }
  53. vfloat<M> depth_scale;
  54. LinearSpace3<Vec3vfM> ray_space;
  55. };
  56. template<typename Epilog>
  57. static __forceinline bool intersect(const vbool<M>& valid_i,
  58. Ray& ray, const Precalculations& pre,
  59. const Vec4vfM& v0, const Vec4vfM& v1,
  60. const Epilog& epilog)
  61. {
  62. /* transform end points into ray space */
  63. vbool<M> valid = valid_i;
  64. Vec4vfM p0(xfmVector(pre.ray_space,v0.xyz()-Vec3vfM(ray.org)), v0.w);
  65. Vec4vfM p1(xfmVector(pre.ray_space,v1.xyz()-Vec3vfM(ray.org)), v1.w);
  66. /* approximative intersection with cone */
  67. const Vec4vfM v = p1-p0;
  68. const Vec4vfM w = -p0;
  69. const vfloat<M> d0 = madd(w.x,v.x,w.y*v.y);
  70. const vfloat<M> d1 = madd(v.x,v.x,v.y*v.y);
  71. const vfloat<M> u = clamp(d0*rcp(d1),vfloat<M>(zero),vfloat<M>(one));
  72. const Vec4vfM p = madd(u,v,p0);
  73. const vfloat<M> t = p.z*pre.depth_scale;
  74. const vfloat<M> d2 = madd(p.x,p.x,p.y*p.y);
  75. const vfloat<M> r = p.w;
  76. const vfloat<M> r2 = r*r;
  77. valid &= (d2 <= r2) & (vfloat<M>(ray.tnear) < t) & (t < vfloat<M>(ray.tfar));
  78. if (unlikely(none(valid))) return false;
  79. /* ignore denormalized segments */
  80. const Vec3vfM T = v1.xyz()-v0.xyz();
  81. valid &= (T.x != vfloat<M>(zero)) | (T.y != vfloat<M>(zero)) | (T.z != vfloat<M>(zero));
  82. if (unlikely(none(valid))) return false;
  83. /* update hit information */
  84. LineIntersectorHitM<M> hit(u,zero,t,T);
  85. return epilog(valid,hit);
  86. }
  87. };
  88. template<int M, int K>
  89. struct LineIntersectorK
  90. {
  91. typedef Vec3<vfloat<M>> Vec3vfM;
  92. typedef Vec4<vfloat<M>> Vec4vfM;
  93. struct Precalculations
  94. {
  95. __forceinline Precalculations (const vbool<K>& valid, const RayK<K>& ray)
  96. {
  97. size_t mask = movemask(valid);
  98. depth_scale = rsqrt(dot(ray.dir,ray.dir));
  99. while (mask) {
  100. size_t k = __bscf(mask);
  101. ray_space[k] = frame(depth_scale[k]*Vec3fa(ray.dir.x[k],ray.dir.y[k],ray.dir.z[k])).transposed();
  102. }
  103. }
  104. vfloat<K> depth_scale;
  105. LinearSpace3<Vec3vfM> ray_space[K];
  106. };
  107. template<typename Epilog>
  108. static __forceinline bool intersect(const vbool<M>& valid_i,
  109. RayK<K>& ray, size_t k, const Precalculations& pre,
  110. const Vec4vfM& v0, const Vec4vfM& v1,
  111. const Epilog& epilog)
  112. {
  113. /* transform end points into ray space */
  114. vbool<M> valid = valid_i;
  115. const Vec3vfM ray_org(ray.org.x[k],ray.org.y[k],ray.org.z[k]);
  116. const Vec3vfM ray_dir(ray.dir.x[k],ray.dir.y[k],ray.dir.z[k]);
  117. Vec4vfM p0(xfmVector(pre.ray_space[k],v0.xyz()-ray_org), v0.w);
  118. Vec4vfM p1(xfmVector(pre.ray_space[k],v1.xyz()-ray_org), v1.w);
  119. /* approximative intersection with cone */
  120. const Vec4vfM v = p1-p0;
  121. const Vec4vfM w = -p0;
  122. const vfloat<M> d0 = madd(w.x,v.x,w.y*v.y);
  123. const vfloat<M> d1 = madd(v.x,v.x,v.y*v.y);
  124. const vfloat<M> u = clamp(d0*rcp(d1),vfloat<M>(zero),vfloat<M>(one));
  125. const Vec4vfM p = madd(u,v,p0);
  126. const vfloat<M> t = p.z*pre.depth_scale[k];
  127. const vfloat<M> d2 = madd(p.x,p.x,p.y*p.y);
  128. const vfloat<M> r = p.w;
  129. const vfloat<M> r2 = r*r;
  130. valid &= (d2 <= r2) & (vfloat<M>(ray.tnear[k]) < t) & (t < vfloat<M>(ray.tfar[k]));
  131. if (unlikely(none(valid))) return false;
  132. /* ignore denormalized segments */
  133. const Vec3vfM T = v1.xyz()-v0.xyz();
  134. valid &= (T.x != vfloat<M>(zero)) | (T.y != vfloat<M>(zero)) | (T.z != vfloat<M>(zero));
  135. if (unlikely(none(valid))) return false;
  136. /* update hit information */
  137. LineIntersectorHitM<M> hit(u,zero,t,T);
  138. return epilog(valid,hit);
  139. }
  140. };
  141. }
  142. }