diff options
Diffstat (limited to 'thirdparty/embree/kernels/geometry/quad_intersector.h')
-rw-r--r-- | thirdparty/embree/kernels/geometry/quad_intersector.h | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/thirdparty/embree/kernels/geometry/quad_intersector.h b/thirdparty/embree/kernels/geometry/quad_intersector.h new file mode 100644 index 0000000000..93c9526912 --- /dev/null +++ b/thirdparty/embree/kernels/geometry/quad_intersector.h @@ -0,0 +1,76 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +namespace embree +{ + namespace isa + { + /*! Intersects a ray with a quad with backface culling + * enabled. The quad v0,v1,v2,v3 is split into two triangles + * v0,v1,v3 and v2,v3,v1. The edge v1,v2 decides which of the two + * triangles gets intersected. */ + template<int N> + __forceinline vbool<N> intersect_quad_backface_culling(const vbool<N>& valid0, + const Vec3fa& ray_org, + const Vec3fa& ray_dir, + const float ray_tnear, + const float ray_tfar, + const Vec3vf<N>& quad_v0, + const Vec3vf<N>& quad_v1, + const Vec3vf<N>& quad_v2, + const Vec3vf<N>& quad_v3, + vfloat<N>& u_o, + vfloat<N>& v_o, + vfloat<N>& t_o) + { + /* calculate vertices relative to ray origin */ + vbool<N> valid = valid0; + const Vec3vf<N> O = Vec3vf<N>(ray_org); + const Vec3vf<N> D = Vec3vf<N>(ray_dir); + const Vec3vf<N> va = quad_v0-O; + const Vec3vf<N> vb = quad_v1-O; + const Vec3vf<N> vc = quad_v2-O; + const Vec3vf<N> vd = quad_v3-O; + + const Vec3vf<N> edb = vb-vd; + const vfloat<N> WW = dot(cross(vd,edb),D); + const Vec3vf<N> v0 = select(WW <= 0.0f,va,vc); + const Vec3vf<N> v1 = select(WW <= 0.0f,vb,vd); + const Vec3vf<N> v2 = select(WW <= 0.0f,vd,vb); + + /* calculate edges */ + const Vec3vf<N> e0 = v2-v0; + const Vec3vf<N> e1 = v0-v1; + + /* perform edge tests */ + const vfloat<N> U = dot(cross(v0,e0),D); + const vfloat<N> V = dot(cross(v1,e1),D); + valid &= max(U,V) <= 0.0f; + if (unlikely(none(valid))) return false; + + /* calculate geometry normal and denominator */ + const Vec3vf<N> Ng = cross(e1,e0); + const vfloat<N> den = dot(Ng,D); + const vfloat<N> rcpDen = rcp(den); + + /* perform depth test */ + const vfloat<N> t = rcpDen*dot(v0,Ng); + valid &= vfloat<N>(ray_tnear) <= t & t <= vfloat<N>(ray_tfar); + if (unlikely(none(valid))) return false; + + /* avoid division by 0 */ + valid &= den != vfloat<N>(zero); + if (unlikely(none(valid))) return false; + + /* update hit information */ + t_o = t; + u_o = U * rcpDen; + v_o = V * rcpDen; + u_o = select(WW <= 0.0f,u_o,1.0f-u_o); + v_o = select(WW <= 0.0f,v_o,1.0f-v_o); + return valid; + } + } +} |