Path: blob/master/thirdparty/embree/kernels/geometry/quadi_intersector.h
9905 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "quadi.h"6#include "quad_intersector_moeller.h"7#include "quad_intersector_pluecker.h"89namespace embree10{11namespace isa12{13/*! Intersects M quads with 1 ray */14template<int M, bool filter>15struct QuadMiIntersector1Moeller16{17typedef QuadMi<M> Primitive;18typedef QuadMIntersector1MoellerTrumbore<M,filter> Precalculations;1920/*! Intersect a ray with the M quads and updates the hit. */21static __forceinline void intersect(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& quad)22{23STAT3(normal.trav_prims,1,1,1);24Vec3vf<M> v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene);25pre.intersect(ray,context,v0,v1,v2,v3,quad.geomID(),quad.primID());26}2728/*! Test if the ray is occluded by one of M quads. */29static __forceinline bool occluded(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& quad)30{31STAT3(shadow.trav_prims,1,1,1);32Vec3vf<M> v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene);33return pre.occluded(ray,context,v0,v1,v2,v3,quad.geomID(),quad.primID());34}3536static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& quad)37{38return PrimitivePointQuery1<Primitive>::pointQuery(query, context, quad);39}40};4142/*! Intersects M triangles with K rays. */43template<int M, int K, bool filter>44struct QuadMiIntersectorKMoeller45{46typedef QuadMi<M> Primitive;47typedef QuadMIntersectorKMoellerTrumbore<M,K,filter> Precalculations;4849/*! Intersects K rays with M triangles. */50static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, RayQueryContext* context, const QuadMi<M>& quad)51{52Scene* scene = context->scene;53for (size_t i=0; i<QuadMi<M>::max_size(); i++)54{55if (!quad.valid(i)) break;56STAT3(normal.trav_prims,1,popcnt(valid_i),K);57const Vec3vf<K> p0 = quad.template getVertex<0>(i,scene);58const Vec3vf<K> p1 = quad.template getVertex<1>(i,scene);59const Vec3vf<K> p2 = quad.template getVertex<2>(i,scene);60const Vec3vf<K> p3 = quad.template getVertex<3>(i,scene);61pre.intersectK(valid_i,ray,p0,p1,p2,p3,IntersectKEpilogM<M,K,filter>(ray,context,quad.geomID(),quad.primID(),i));62}63}6465/*! Test for K rays if they are occluded by any of the M triangles. */66static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, RayQueryContext* context, const QuadMi<M>& quad)67{68Scene* scene = context->scene;69vbool<K> valid0 = valid_i;70for (size_t i=0; i<QuadMi<M>::max_size(); i++)71{72if (!quad.valid(i)) break;73STAT3(shadow.trav_prims,1,popcnt(valid0),K);74const Vec3vf<K> p0 = quad.template getVertex<0>(i,scene);75const Vec3vf<K> p1 = quad.template getVertex<1>(i,scene);76const Vec3vf<K> p2 = quad.template getVertex<2>(i,scene);77const Vec3vf<K> p3 = quad.template getVertex<3>(i,scene);78if (pre.intersectK(valid0,ray,p0,p1,p2,p3,OccludedKEpilogM<M,K,filter>(valid0,ray,context,quad.geomID(),quad.primID(),i)))79break;80}81return !valid0;82}8384/*! Intersect a ray with M triangles and updates the hit. */85static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, RayQueryContext* context, const QuadMi<M>& quad)86{87STAT3(normal.trav_prims,1,1,1);88Vec3vf4 v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene);89pre.intersect1(ray,k,context,v0,v1,v2,v3,quad.geomID(),quad.primID());90}9192/*! Test if the ray is occluded by one of the M triangles. */93static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, RayQueryContext* context, const QuadMi<M>& quad)94{95STAT3(shadow.trav_prims,1,1,1);96Vec3vf4 v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene);97return pre.occluded1(ray,k,context,v0,v1,v2,v3,quad.geomID(),quad.primID());98}99};100101/*! Intersects M quads with 1 ray */102template<int M, bool filter>103struct QuadMiIntersector1Pluecker104{105typedef QuadMi<M> Primitive;106typedef QuadMIntersector1Pluecker<M,filter> Precalculations;107108/*! Intersect a ray with the M quads and updates the hit. */109static __forceinline void intersect(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& quad)110{111STAT3(normal.trav_prims,1,1,1);112Vec3vf<M> v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene);113pre.intersect(ray,context,v0,v1,v2,v3,quad.geomID(),quad.primID());114}115116/*! Test if the ray is occluded by one of M quads. */117static __forceinline bool occluded(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& quad)118{119STAT3(shadow.trav_prims,1,1,1);120Vec3vf<M> v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene);121return pre.occluded(ray,context,v0,v1,v2,v3,quad.geomID(),quad.primID());122}123124static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& quad)125{126return PrimitivePointQuery1<Primitive>::pointQuery(query, context, quad);127}128};129130/*! Intersects M triangles with K rays. */131template<int M, int K, bool filter>132struct QuadMiIntersectorKPluecker133{134typedef QuadMi<M> Primitive;135typedef QuadMIntersectorKPluecker<M,K,filter> Precalculations;136137/*! Intersects K rays with M triangles. */138static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, RayQueryContext* context, const QuadMi<M>& quad)139{140Scene* scene = context->scene;141for (size_t i=0; i<QuadMi<M>::max_size(); i++)142{143if (!quad.valid(i)) break;144STAT3(normal.trav_prims,1,popcnt(valid_i),K);145const Vec3vf<K> p0 = quad.template getVertex<0>(i,scene);146const Vec3vf<K> p1 = quad.template getVertex<1>(i,scene);147const Vec3vf<K> p2 = quad.template getVertex<2>(i,scene);148const Vec3vf<K> p3 = quad.template getVertex<3>(i,scene);149pre.intersectK(valid_i,ray,p0,p1,p2,p3,IntersectKEpilogM<M,K,filter>(ray,context,quad.geomID(),quad.primID(),i));150}151}152153/*! Test for K rays if they are occluded by any of the M triangles. */154static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, RayQueryContext* context, const QuadMi<M>& quad)155{156Scene* scene = context->scene;157vbool<K> valid0 = valid_i;158for (size_t i=0; i<QuadMi<M>::max_size(); i++)159{160if (!quad.valid(i)) break;161STAT3(shadow.trav_prims,1,popcnt(valid0),K);162const Vec3vf<K> p0 = quad.template getVertex<0>(i,scene);163const Vec3vf<K> p1 = quad.template getVertex<1>(i,scene);164const Vec3vf<K> p2 = quad.template getVertex<2>(i,scene);165const Vec3vf<K> p3 = quad.template getVertex<3>(i,scene);166if (pre.intersectK(valid0,ray,p0,p1,p2,p3,OccludedKEpilogM<M,K,filter>(valid0,ray,context,quad.geomID(),quad.primID(),i)))167break;168}169return !valid0;170}171172/*! Intersect a ray with M triangles and updates the hit. */173static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, RayQueryContext* context, const QuadMi<M>& quad)174{175STAT3(normal.trav_prims,1,1,1);176Vec3vf4 v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene);177pre.intersect1(ray,k,context,v0,v1,v2,v3,quad.geomID(),quad.primID());178}179180/*! Test if the ray is occluded by one of the M triangles. */181static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, RayQueryContext* context, const QuadMi<M>& quad)182{183STAT3(shadow.trav_prims,1,1,1);184Vec3vf4 v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene);185return pre.occluded1(ray,k,context,v0,v1,v2,v3,quad.geomID(),quad.primID());186}187};188189/*! Intersects M motion blur quads with 1 ray */190template<int M, bool filter>191struct QuadMiMBIntersector1Moeller192{193typedef QuadMi<M> Primitive;194typedef QuadMIntersector1MoellerTrumbore<M,filter> Precalculations;195196/*! Intersect a ray with the M quads and updates the hit. */197static __forceinline void intersect(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& quad)198{199STAT3(normal.trav_prims,1,1,1);200Vec3vf<M> v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene,ray.time());201pre.intersect(ray,context,v0,v1,v2,v3,quad.geomID(),quad.primID());202}203204/*! Test if the ray is occluded by one of M quads. */205static __forceinline bool occluded(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& quad)206{207STAT3(shadow.trav_prims,1,1,1);208Vec3vf<M> v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene,ray.time());209return pre.occluded(ray,context,v0,v1,v2,v3,quad.geomID(),quad.primID());210}211212static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& quad)213{214return PrimitivePointQuery1<Primitive>::pointQuery(query, context, quad);215}216};217218/*! Intersects M motion blur quads with K rays. */219template<int M, int K, bool filter>220struct QuadMiMBIntersectorKMoeller221{222typedef QuadMi<M> Primitive;223typedef QuadMIntersectorKMoellerTrumbore<M,K,filter> Precalculations;224225/*! Intersects K rays with M quads. */226static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, RayQueryContext* context, const QuadMi<M>& quad)227{228for (size_t i=0; i<QuadMi<M>::max_size(); i++)229{230if (!quad.valid(i)) break;231STAT3(normal.trav_prims,1,popcnt(valid_i),K);232Vec3vf<K> v0,v1,v2,v3; quad.template gather<K>(valid_i,v0,v1,v2,v3,i,context->scene,ray.time());233pre.intersectK(valid_i,ray,v0,v1,v2,v3,IntersectKEpilogM<M,K,filter>(ray,context,quad.geomID(),quad.primID(),i));234}235}236237/*! Test for K rays if they are occluded by any of the M quads. */238static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, RayQueryContext* context, const QuadMi<M>& quad)239{240vbool<K> valid0 = valid_i;241for (size_t i=0; i<QuadMi<M>::max_size(); i++)242{243if (!quad.valid(i)) break;244STAT3(shadow.trav_prims,1,popcnt(valid0),K);245Vec3vf<K> v0,v1,v2,v3; quad.template gather<K>(valid_i,v0,v1,v2,v3,i,context->scene,ray.time());246if (pre.intersectK(valid0,ray,v0,v1,v2,v3,OccludedKEpilogM<M,K,filter>(valid0,ray,context,quad.geomID(),quad.primID(),i)))247break;248}249return !valid0;250}251252/*! Intersect a ray with M quads and updates the hit. */253static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, RayQueryContext* context, const QuadMi<M>& quad)254{255STAT3(normal.trav_prims,1,1,1);256Vec3vf<M> v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene,ray.time()[k]);257pre.intersect1(ray,k,context,v0,v1,v2,v3,quad.geomID(),quad.primID());258}259260/*! Test if the ray is occluded by one of the M quads. */261static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, RayQueryContext* context, const QuadMi<M>& quad)262{263STAT3(shadow.trav_prims,1,1,1);264Vec3vf<M> v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene,ray.time()[k]);265return pre.occluded1(ray,k,context,v0,v1,v2,v3,quad.geomID(),quad.primID());266}267};268269/*! Intersects M motion blur quads with 1 ray */270template<int M, bool filter>271struct QuadMiMBIntersector1Pluecker272{273typedef QuadMi<M> Primitive;274typedef QuadMIntersector1Pluecker<M,filter> Precalculations;275276/*! Intersect a ray with the M quads and updates the hit. */277static __forceinline void intersect(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& quad)278{279STAT3(normal.trav_prims,1,1,1);280Vec3vf<M> v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene,ray.time());281pre.intersect(ray,context,v0,v1,v2,v3,quad.geomID(),quad.primID());282}283284/*! Test if the ray is occluded by one of M quads. */285static __forceinline bool occluded(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& quad)286{287STAT3(shadow.trav_prims,1,1,1);288Vec3vf<M> v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene,ray.time());289return pre.occluded(ray,context,v0,v1,v2,v3,quad.geomID(),quad.primID());290}291292static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& quad)293{294return PrimitivePointQuery1<Primitive>::pointQuery(query, context, quad);295}296};297298/*! Intersects M motion blur quads with K rays. */299template<int M, int K, bool filter>300struct QuadMiMBIntersectorKPluecker301{302typedef QuadMi<M> Primitive;303typedef QuadMIntersectorKPluecker<M,K,filter> Precalculations;304305/*! Intersects K rays with M quads. */306static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, RayQueryContext* context, const QuadMi<M>& quad)307{308for (size_t i=0; i<QuadMi<M>::max_size(); i++)309{310if (!quad.valid(i)) break;311STAT3(normal.trav_prims,1,popcnt(valid_i),K);312Vec3vf<K> v0,v1,v2,v3; quad.template gather<K>(valid_i,v0,v1,v2,v3,i,context->scene,ray.time());313pre.intersectK(valid_i,ray,v0,v1,v2,v3,IntersectKEpilogM<M,K,filter>(ray,context,quad.geomID(),quad.primID(),i));314}315}316317/*! Test for K rays if they are occluded by any of the M quads. */318static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, RayQueryContext* context, const QuadMi<M>& quad)319{320vbool<K> valid0 = valid_i;321for (size_t i=0; i<QuadMi<M>::max_size(); i++)322{323if (!quad.valid(i)) break;324STAT3(shadow.trav_prims,1,popcnt(valid0),K);325Vec3vf<K> v0,v1,v2,v3; quad.template gather<K>(valid_i,v0,v1,v2,v3,i,context->scene,ray.time());326if (pre.intersectK(valid0,ray,v0,v1,v2,v3,OccludedKEpilogM<M,K,filter>(valid0,ray,context,quad.geomID(),quad.primID(),i)))327break;328}329return !valid0;330}331332/*! Intersect a ray with M quads and updates the hit. */333static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, RayQueryContext* context, const QuadMi<M>& quad)334{335STAT3(normal.trav_prims,1,1,1);336Vec3vf<M> v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene,ray.time()[k]);337pre.intersect1(ray,k,context,v0,v1,v2,v3,quad.geomID(),quad.primID());338}339340/*! Test if the ray is occluded by one of the M quads. */341static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, RayQueryContext* context, const QuadMi<M>& quad)342{343STAT3(shadow.trav_prims,1,1,1);344Vec3vf<M> v0,v1,v2,v3; quad.gather(v0,v1,v2,v3,context->scene,ray.time()[k]);345return pre.occluded1(ray,k,context,v0,v1,v2,v3,quad.geomID(),quad.primID());346}347};348}349}350351352