Path: blob/master/thirdparty/embree/kernels/geometry/quad_intersector.h
9905 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45namespace embree6{7namespace isa8{9/*! Intersects a ray with a quad with backface culling10* enabled. The quad v0,v1,v2,v3 is split into two triangles11* v0,v1,v3 and v2,v3,v1. The edge v1,v2 decides which of the two12* triangles gets intersected. */13template<int N>14__forceinline vbool<N> intersect_quad_backface_culling(const vbool<N>& valid0,15const Vec3fa& ray_org,16const Vec3fa& ray_dir,17const float ray_tnear,18const float ray_tfar,19const Vec3vf<N>& quad_v0,20const Vec3vf<N>& quad_v1,21const Vec3vf<N>& quad_v2,22const Vec3vf<N>& quad_v3,23vfloat<N>& u_o,24vfloat<N>& v_o,25vfloat<N>& t_o)26{27/* calculate vertices relative to ray origin */28vbool<N> valid = valid0;29const Vec3vf<N> O = Vec3vf<N>(ray_org);30const Vec3vf<N> D = Vec3vf<N>(ray_dir);31const Vec3vf<N> va = quad_v0-O;32const Vec3vf<N> vb = quad_v1-O;33const Vec3vf<N> vc = quad_v2-O;34const Vec3vf<N> vd = quad_v3-O;3536const Vec3vf<N> edb = vb-vd;37const vfloat<N> WW = dot(cross(vd,edb),D);38const Vec3vf<N> v0 = select(WW <= 0.0f,va,vc);39const Vec3vf<N> v1 = select(WW <= 0.0f,vb,vd);40const Vec3vf<N> v2 = select(WW <= 0.0f,vd,vb);4142/* calculate edges */43const Vec3vf<N> e0 = v2-v0;44const Vec3vf<N> e1 = v0-v1;4546/* perform edge tests */47const vfloat<N> U = dot(cross(v0,e0),D);48const vfloat<N> V = dot(cross(v1,e1),D);49valid &= max(U,V) <= 0.0f;50if (unlikely(none(valid))) return false;5152/* calculate geometry normal and denominator */53const Vec3vf<N> Ng = cross(e1,e0);54const vfloat<N> den = dot(Ng,D);55const vfloat<N> rcpDen = rcp(den);5657/* perform depth test */58const vfloat<N> t = rcpDen*dot(v0,Ng);59valid &= vfloat<N>(ray_tnear) <= t & t <= vfloat<N>(ray_tfar);60if (unlikely(none(valid))) return false;6162/* avoid division by 0 */63valid &= den != vfloat<N>(zero);64if (unlikely(none(valid))) return false;6566/* update hit information */67t_o = t;68u_o = U * rcpDen;69v_o = V * rcpDen;70u_o = select(WW <= 0.0f,u_o,1.0f-u_o);71v_o = select(WW <= 0.0f,v_o,1.0f-v_o);72return valid;73}74}75}767778