1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003 |
- // Copyright 2009-2021 Intel Corporation
- // SPDX-License-Identifier: Apache-2.0
- #pragma once
- #include "../common/ray.h"
- #include "../common/context.h"
- #include "filter.h"
- namespace embree
- {
- namespace isa
- {
- template<int M>
- struct UVIdentity {
- __forceinline void operator() (vfloat<M>& u, vfloat<M>& v, Vec3vf<M>& Ng) const {}
- };
- template<bool filter>
- struct Intersect1Epilog1
- {
- RayHit& ray;
- RayQueryContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Intersect1Epilog1(RayHit& ray,
- RayQueryContext* context,
- const unsigned int geomID,
- const unsigned int primID)
- : ray(ray), context(context), geomID(geomID), primID(primID) {}
- template<typename Hit>
- __forceinline bool operator() (Hit& hit) const
- {
- /* ray mask test */
- Scene* scene MAYBE_UNUSED = context->scene;
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- #if defined(EMBREE_RAY_MASK)
- if ((geometry->mask & ray.mask) == 0) return false;
- #endif
- hit.finalize();
- /* intersection filter test */
- #if defined(EMBREE_FILTER_FUNCTION)
- if (filter) {
- if (unlikely(context->hasContextFilter() || geometry->hasIntersectionFilter())) {
- HitK<1> h(context->user,geomID,primID,hit.u,hit.v,hit.Ng);
- const float old_t = ray.tfar;
- ray.tfar = hit.t;
- bool found = runIntersectionFilter1(geometry,ray,context,h);
- if (!found) ray.tfar = old_t;
- return found;
- }
- }
- #endif
- /* update hit information */
- ray.tfar = hit.t;
- ray.Ng = hit.Ng;
- ray.u = hit.u;
- ray.v = hit.v;
- ray.primID = primID;
- ray.geomID = geomID;
- instance_id_stack::copy_UU(context->user->instID, ray.instID);
- #if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
- instance_id_stack::copy_UU(context->user->instPrimID, ray.instPrimID);
- #endif
- return true;
- }
- };
- template<bool filter>
- struct Occluded1Epilog1
- {
- Ray& ray;
- RayQueryContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Occluded1Epilog1(Ray& ray,
- RayQueryContext* context,
- const unsigned int geomID,
- const unsigned int primID)
- : ray(ray), context(context), geomID(geomID), primID(primID) {}
- template<typename Hit>
- __forceinline bool operator() (Hit& hit) const
- {
- /* ray mask test */
- Scene* scene MAYBE_UNUSED = context->scene;
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- #if defined(EMBREE_RAY_MASK)
- if ((geometry->mask & ray.mask) == 0) return false;
- #endif
- hit.finalize();
- /* intersection filter test */
- #if defined(EMBREE_FILTER_FUNCTION)
- if (filter) {
- if (unlikely(context->hasContextFilter() || geometry->hasOcclusionFilter())) {
- HitK<1> h(context->user,geomID,primID,hit.u,hit.v,hit.Ng);
- const float old_t = ray.tfar;
- ray.tfar = hit.t;
- const bool found = runOcclusionFilter1(geometry,ray,context,h);
- if (!found) ray.tfar = old_t;
- return found;
- }
- }
- #endif
- return true;
- }
- };
- template<int K, bool filter>
- struct Intersect1KEpilog1
- {
- RayHitK<K>& ray;
- size_t k;
- RayQueryContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Intersect1KEpilog1(RayHitK<K>& ray, size_t k,
- RayQueryContext* context,
- const unsigned int geomID,
- const unsigned int primID)
- : ray(ray), k(k), context(context), geomID(geomID), primID(primID) {}
- template<typename Hit>
- __forceinline bool operator() (Hit& hit) const
- {
- /* ray mask test */
- Scene* scene MAYBE_UNUSED = context->scene;
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- #if defined(EMBREE_RAY_MASK)
- if ((geometry->mask & ray.mask[k]) == 0)
- return false;
- #endif
- hit.finalize();
- /* intersection filter test */
- #if defined(EMBREE_FILTER_FUNCTION)
- if (filter) {
- if (unlikely(context->hasContextFilter() || geometry->hasIntersectionFilter())) {
- HitK<K> h(context->user,geomID,primID,hit.u,hit.v,hit.Ng);
- const float old_t = ray.tfar[k];
- ray.tfar[k] = hit.t;
- const bool found = any(runIntersectionFilter(vbool<K>(1<<k),geometry,ray,context,h));
- if (!found) ray.tfar[k] = old_t;
- return found;
- }
- }
- #endif
- /* update hit information */
- ray.tfar[k] = hit.t;
- ray.Ng.x[k] = hit.Ng.x;
- ray.Ng.y[k] = hit.Ng.y;
- ray.Ng.z[k] = hit.Ng.z;
- ray.u[k] = hit.u;
- ray.v[k] = hit.v;
- ray.primID[k] = primID;
- ray.geomID[k] = geomID;
- instance_id_stack::copy_UV<K>(context->user->instID, ray.instID, k);
- #if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
- instance_id_stack::copy_UV<K>(context->user->instPrimID, ray.instPrimID, k);
- #endif
- return true;
- }
- };
-
- template<int K, bool filter>
- struct Occluded1KEpilog1
- {
- RayK<K>& ray;
- size_t k;
- RayQueryContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Occluded1KEpilog1(RayK<K>& ray, size_t k,
- RayQueryContext* context,
- const unsigned int geomID,
- const unsigned int primID)
- : ray(ray), k(k), context(context), geomID(geomID), primID(primID) {}
- template<typename Hit>
- __forceinline bool operator() (Hit& hit) const
- {
- /* ray mask test */
- Scene* scene MAYBE_UNUSED = context->scene;
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- #if defined(EMBREE_RAY_MASK)
- if ((geometry->mask & ray.mask[k]) == 0)
- return false;
- #endif
- /* intersection filter test */
- #if defined(EMBREE_FILTER_FUNCTION)
- if (filter) {
- if (unlikely(context->hasContextFilter() || geometry->hasOcclusionFilter())) {
- hit.finalize();
- HitK<K> h(context->user,geomID,primID,hit.u,hit.v,hit.Ng);
- const float old_t = ray.tfar[k];
- ray.tfar[k] = hit.t;
- const bool found = any(runOcclusionFilter(vbool<K>(1<<k),geometry,ray,context,h));
- if (!found) ray.tfar[k] = old_t;
- return found;
- }
- }
- #endif
- return true;
- }
- };
-
- template<int M, bool filter>
- struct Intersect1EpilogM
- {
- RayHit& ray;
- RayQueryContext* context;
- const vuint<M>& geomIDs;
- const vuint<M>& primIDs;
- __forceinline Intersect1EpilogM(RayHit& ray,
- RayQueryContext* context,
- const vuint<M>& geomIDs,
- const vuint<M>& primIDs)
- : ray(ray), context(context), geomIDs(geomIDs), primIDs(primIDs) {}
- template<typename Hit>
- __forceinline bool operator() (const vbool<M>& valid_i, Hit& hit) const
- {
- Scene* scene MAYBE_UNUSED = context->scene;
- vbool<M> valid = valid_i;
- hit.finalize();
- size_t i = select_min(valid,hit.vt);
- unsigned int geomID = geomIDs[i];
- /* intersection filter test */
- #if defined(EMBREE_FILTER_FUNCTION) || defined(EMBREE_RAY_MASK)
- bool foundhit = false;
- goto entry;
- while (true)
- {
- if (unlikely(none(valid))) return foundhit;
- i = select_min(valid,hit.vt);
- geomID = geomIDs[i];
- entry:
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- #if defined(EMBREE_RAY_MASK)
- /* goto next hit if mask test fails */
- if ((geometry->mask & ray.mask) == 0) {
- clear(valid,i);
- continue;
- }
- #endif
- #if defined(EMBREE_FILTER_FUNCTION)
- /* call intersection filter function */
- if (filter) {
- if (unlikely(context->hasContextFilter() || geometry->hasIntersectionFilter())) {
- const Vec2f uv = hit.uv(i);
- HitK<1> h(context->user,geomID,primIDs[i],uv.x,uv.y,hit.Ng(i));
- const float old_t = ray.tfar;
- ray.tfar = hit.t(i);
- const bool found = runIntersectionFilter1(geometry,ray,context,h);
- if (!found) ray.tfar = old_t;
- foundhit |= found;
- clear(valid,i);
- valid &= hit.vt <= ray.tfar; // intersection filters may modify tfar value
- continue;
- }
- }
- #endif
- break;
- }
- #endif
- /* update hit information */
- const Vec2f uv = hit.uv(i);
- ray.tfar = hit.vt[i];
- ray.Ng.x = hit.vNg.x[i];
- ray.Ng.y = hit.vNg.y[i];
- ray.Ng.z = hit.vNg.z[i];
- ray.u = uv.x;
- ray.v = uv.y;
- ray.primID = primIDs[i];
- ray.geomID = geomID;
- instance_id_stack::copy_UU(context->user->instID, ray.instID);
- #if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
- instance_id_stack::copy_UU(context->user->instPrimID, ray.instPrimID);
- #endif
- return true;
- }
- };
- template<int M, bool filter>
- struct Occluded1EpilogM
- {
- Ray& ray;
- RayQueryContext* context;
- const vuint<M>& geomIDs;
- const vuint<M>& primIDs;
- __forceinline Occluded1EpilogM(Ray& ray,
- RayQueryContext* context,
- const vuint<M>& geomIDs,
- const vuint<M>& primIDs)
- : ray(ray), context(context), geomIDs(geomIDs), primIDs(primIDs) {}
- template<typename Hit>
- __forceinline bool operator() (const vbool<M>& valid_i, Hit& hit) const
- {
- Scene* scene MAYBE_UNUSED = context->scene;
- /* intersection filter test */
- #if defined(EMBREE_FILTER_FUNCTION) || defined(EMBREE_RAY_MASK)
- if (unlikely(filter))
- hit.finalize(); /* called only once */
- vbool<M> valid = valid_i;
- size_t m=movemask(valid);
- goto entry;
- while (true)
- {
- if (unlikely(m == 0)) return false;
- entry:
- size_t i=bsf(m);
- const unsigned int geomID = geomIDs[i];
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- #if defined(EMBREE_RAY_MASK)
- /* goto next hit if mask test fails */
- if ((geometry->mask & ray.mask) == 0) {
- m=btc(m,i);
- continue;
- }
- #endif
- #if defined(EMBREE_FILTER_FUNCTION)
- /* if we have no filter then the test passed */
- if (filter) {
- if (unlikely(context->hasContextFilter() || geometry->hasOcclusionFilter()))
- {
- const Vec2f uv = hit.uv(i);
- HitK<1> h(context->user,geomID,primIDs[i],uv.x,uv.y,hit.Ng(i));
- const float old_t = ray.tfar;
- ray.tfar = hit.t(i);
- if (runOcclusionFilter1(geometry,ray,context,h)) return true;
- ray.tfar = old_t;
- m=btc(m,i);
- continue;
- }
- }
- #endif
- break;
- }
- #endif
- return true;
- }
- };
- template<int M, bool filter>
- struct Intersect1EpilogMU
- {
- RayHit& ray;
- RayQueryContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Intersect1EpilogMU(RayHit& ray,
- RayQueryContext* context,
- const unsigned int geomID,
- const unsigned int primID)
- : ray(ray), context(context), geomID(geomID), primID(primID) {}
- template<typename Hit>
- __forceinline bool operator() (const vbool<M>& valid_i, Hit& hit) const
- {
- /* ray mask test */
- Scene* scene MAYBE_UNUSED = context->scene;
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- #if defined(EMBREE_RAY_MASK)
- if ((geometry->mask & ray.mask) == 0) return false;
- #endif
- vbool<M> valid = valid_i;
- hit.finalize();
- size_t i = select_min(valid,hit.vt);
- /* intersection filter test */
- #if defined(EMBREE_FILTER_FUNCTION)
- if (unlikely(context->hasContextFilter() || geometry->hasIntersectionFilter()))
- {
- bool foundhit = false;
- while (true)
- {
- /* call intersection filter function */
- Vec2f uv = hit.uv(i);
- const float old_t = ray.tfar;
- ray.tfar = hit.t(i);
- HitK<1> h(context->user,geomID,primID,uv.x,uv.y,hit.Ng(i));
- const bool found = runIntersectionFilter1(geometry,ray,context,h);
- if (!found) ray.tfar = old_t;
- foundhit |= found;
- clear(valid,i);
- valid &= hit.vt <= ray.tfar; // intersection filters may modify tfar value
- if (unlikely(none(valid))) break;
- i = select_min(valid,hit.vt);
- }
- return foundhit;
- }
- #endif
- /* update hit information */
- const Vec2f uv = hit.uv(i);
- const Vec3fa Ng = hit.Ng(i);
- ray.tfar = hit.t(i);
- ray.Ng.x = Ng.x;
- ray.Ng.y = Ng.y;
- ray.Ng.z = Ng.z;
- ray.u = uv.x;
- ray.v = uv.y;
- ray.primID = primID;
- ray.geomID = geomID;
- instance_id_stack::copy_UU(context->user->instID, ray.instID);
- #if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
- instance_id_stack::copy_UU(context->user->instPrimID, ray.instPrimID);
- #endif
- return true;
- }
- };
-
- template<int M, bool filter>
- struct Occluded1EpilogMU
- {
- Ray& ray;
- RayQueryContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Occluded1EpilogMU(Ray& ray,
- RayQueryContext* context,
- const unsigned int geomID,
- const unsigned int primID)
- : ray(ray), context(context), geomID(geomID), primID(primID) {}
- template<typename Hit>
- __forceinline bool operator() (const vbool<M>& valid, Hit& hit) const
- {
- /* ray mask test */
- Scene* scene MAYBE_UNUSED = context->scene;
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- #if defined(EMBREE_RAY_MASK)
- if ((geometry->mask & ray.mask) == 0) return false;
- #endif
- /* intersection filter test */
- #if defined(EMBREE_FILTER_FUNCTION)
- if (unlikely(context->hasContextFilter() || geometry->hasOcclusionFilter()))
- {
- hit.finalize();
- for (size_t m=movemask(valid), i=bsf(m); m!=0; m=btc(m,i), i=bsf(m))
- {
- const Vec2f uv = hit.uv(i);
- const float old_t = ray.tfar;
- ray.tfar = hit.t(i);
- HitK<1> h(context->user,geomID,primID,uv.x,uv.y,hit.Ng(i));
- if (runOcclusionFilter1(geometry,ray,context,h)) return true;
- ray.tfar = old_t;
- }
- return false;
- }
- #endif
- return true;
- }
- };
-
- template<int M, int K, bool filter>
- struct IntersectKEpilogM
- {
- RayHitK<K>& ray;
- RayQueryContext* context;
- const vuint<M>& geomIDs;
- const vuint<M>& primIDs;
- const size_t i;
- __forceinline IntersectKEpilogM(RayHitK<K>& ray,
- RayQueryContext* context,
- const vuint<M>& geomIDs,
- const vuint<M>& primIDs,
- size_t i)
- : ray(ray), context(context), geomIDs(geomIDs), primIDs(primIDs), i(i) {}
- template<typename Hit>
- __forceinline vbool<K> operator() (const vbool<K>& valid_i, const Hit& hit) const
- {
- Scene* scene MAYBE_UNUSED = context->scene;
- vfloat<K> u, v, t;
- Vec3vf<K> Ng;
- vbool<K> valid = valid_i;
- std::tie(u,v,t,Ng) = hit();
- const unsigned int geomID = geomIDs[i];
- const unsigned int primID = primIDs[i];
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- /* ray masking test */
- #if defined(EMBREE_RAY_MASK)
- valid &= (geometry->mask & ray.mask) != 0;
- if (unlikely(none(valid))) return false;
- #endif
- /* occlusion filter test */
- #if defined(EMBREE_FILTER_FUNCTION)
- if (filter) {
- if (unlikely(context->hasContextFilter() || geometry->hasIntersectionFilter())) {
- HitK<K> h(context->user,geomID,primID,u,v,Ng);
- const vfloat<K> old_t = ray.tfar;
- ray.tfar = select(valid,t,ray.tfar);
- const vbool<K> m_accept = runIntersectionFilter(valid,geometry,ray,context,h);
- ray.tfar = select(m_accept,ray.tfar,old_t);
- return m_accept;
- }
- }
- #endif
- /* update hit information */
- vfloat<K>::store(valid,&ray.tfar,t);
- vfloat<K>::store(valid,&ray.Ng.x,Ng.x);
- vfloat<K>::store(valid,&ray.Ng.y,Ng.y);
- vfloat<K>::store(valid,&ray.Ng.z,Ng.z);
- vfloat<K>::store(valid,&ray.u,u);
- vfloat<K>::store(valid,&ray.v,v);
- vuint<K>::store(valid,&ray.primID,primID);
- vuint<K>::store(valid,&ray.geomID,geomID);
- instance_id_stack::copy_UV<K>(context->user->instID, ray.instID, valid);
- #if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
- instance_id_stack::copy_UV<K>(context->user->instPrimID, ray.instPrimID, valid);
- #endif
- return valid;
- }
- };
-
- template<int M, int K, bool filter>
- struct OccludedKEpilogM
- {
- vbool<K>& valid0;
- RayK<K>& ray;
- RayQueryContext* context;
- const vuint<M>& geomIDs;
- const vuint<M>& primIDs;
- const size_t i;
- __forceinline OccludedKEpilogM(vbool<K>& valid0,
- RayK<K>& ray,
- RayQueryContext* context,
- const vuint<M>& geomIDs,
- const vuint<M>& primIDs,
- size_t i)
- : valid0(valid0), ray(ray), context(context), geomIDs(geomIDs), primIDs(primIDs), i(i) {}
- template<typename Hit>
- __forceinline vbool<K> operator() (const vbool<K>& valid_i, const Hit& hit) const
- {
- vbool<K> valid = valid_i;
- /* ray masking test */
- Scene* scene MAYBE_UNUSED = context->scene;
- const unsigned int geomID MAYBE_UNUSED = geomIDs[i];
- const unsigned int primID MAYBE_UNUSED = primIDs[i];
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- #if defined(EMBREE_RAY_MASK)
- valid &= (geometry->mask & ray.mask) != 0;
- if (unlikely(none(valid))) return valid;
- #endif
- /* intersection filter test */
- #if defined(EMBREE_FILTER_FUNCTION)
- if (filter) {
- if (unlikely(context->hasContextFilter() || geometry->hasOcclusionFilter()))
- {
- vfloat<K> u, v, t;
- Vec3vf<K> Ng;
- std::tie(u,v,t,Ng) = hit();
- HitK<K> h(context->user,geomID,primID,u,v,Ng);
- const vfloat<K> old_t = ray.tfar;
- ray.tfar = select(valid,t,ray.tfar);
- valid = runOcclusionFilter(valid,geometry,ray,context,h);
- ray.tfar = select(valid,ray.tfar,old_t);
- }
- }
- #endif
- /* update occlusion */
- valid0 = valid0 & !valid;
- return valid;
- }
- };
-
- template<int M, int K, bool filter>
- struct IntersectKEpilogMU
- {
- RayHitK<K>& ray;
- RayQueryContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline IntersectKEpilogMU(RayHitK<K>& ray,
- RayQueryContext* context,
- const unsigned int geomID,
- const unsigned int primID)
- : ray(ray), context(context), geomID(geomID), primID(primID) {}
- template<typename Hit>
- __forceinline vbool<K> operator() (const vbool<K>& valid_org, const Hit& hit) const
- {
- vbool<K> valid = valid_org;
- vfloat<K> u, v, t;
- Vec3vf<K> Ng;
- std::tie(u,v,t,Ng) = hit();
- Scene* scene MAYBE_UNUSED = context->scene;
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- /* ray masking test */
- #if defined(EMBREE_RAY_MASK)
- valid &= (geometry->mask & ray.mask) != 0;
- if (unlikely(none(valid))) return false;
- #endif
- /* intersection filter test */
- #if defined(EMBREE_FILTER_FUNCTION)
- if (filter) {
- if (unlikely(context->hasContextFilter() || geometry->hasIntersectionFilter())) {
- HitK<K> h(context->user,geomID,primID,u,v,Ng);
- const vfloat<K> old_t = ray.tfar;
- ray.tfar = select(valid,t,ray.tfar);
- const vbool<K> m_accept = runIntersectionFilter(valid,geometry,ray,context,h);
- ray.tfar = select(m_accept,ray.tfar,old_t);
- return m_accept;
- }
- }
- #endif
- /* update hit information */
- vfloat<K>::store(valid,&ray.tfar,t);
- vfloat<K>::store(valid,&ray.Ng.x,Ng.x);
- vfloat<K>::store(valid,&ray.Ng.y,Ng.y);
- vfloat<K>::store(valid,&ray.Ng.z,Ng.z);
- vfloat<K>::store(valid,&ray.u,u);
- vfloat<K>::store(valid,&ray.v,v);
- vuint<K>::store(valid,&ray.primID,primID);
- vuint<K>::store(valid,&ray.geomID,geomID);
- instance_id_stack::copy_UV<K>(context->user->instID, ray.instID, valid);
- #if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
- instance_id_stack::copy_UV<K>(context->user->instPrimID, ray.instPrimID, valid);
- #endif
- return valid;
- }
- };
-
- template<int M, int K, bool filter>
- struct OccludedKEpilogMU
- {
- vbool<K>& valid0;
- RayK<K>& ray;
- RayQueryContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline OccludedKEpilogMU(vbool<K>& valid0,
- RayK<K>& ray,
- RayQueryContext* context,
- const unsigned int geomID,
- const unsigned int primID)
- : valid0(valid0), ray(ray), context(context), geomID(geomID), primID(primID) {}
- template<typename Hit>
- __forceinline vbool<K> operator() (const vbool<K>& valid_i, const Hit& hit) const
- {
- vbool<K> valid = valid_i;
- Scene* scene MAYBE_UNUSED = context->scene;
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- #if defined(EMBREE_RAY_MASK)
- valid &= (geometry->mask & ray.mask) != 0;
- if (unlikely(none(valid))) return false;
- #endif
- /* occlusion filter test */
- #if defined(EMBREE_FILTER_FUNCTION)
- if (filter) {
- if (unlikely(context->hasContextFilter() || geometry->hasOcclusionFilter()))
- {
- vfloat<K> u, v, t;
- Vec3vf<K> Ng;
- std::tie(u,v,t,Ng) = hit();
- HitK<K> h(context->user,geomID,primID,u,v,Ng);
- const vfloat<K> old_t = ray.tfar;
- ray.tfar = select(valid,t,ray.tfar);
- valid = runOcclusionFilter(valid,geometry,ray,context,h);
- ray.tfar = select(valid,ray.tfar,old_t);
- }
- }
- #endif
- /* update occlusion */
- valid0 = valid0 & !valid;
- return valid;
- }
- };
-
- template<int M, int K, bool filter>
- struct Intersect1KEpilogM
- {
- RayHitK<K>& ray;
- size_t k;
- RayQueryContext* context;
- const vuint<M>& geomIDs;
- const vuint<M>& primIDs;
- __forceinline Intersect1KEpilogM(RayHitK<K>& ray, size_t k,
- RayQueryContext* context,
- const vuint<M>& geomIDs,
- const vuint<M>& primIDs)
- : ray(ray), k(k), context(context), geomIDs(geomIDs), primIDs(primIDs) {}
- template<typename Hit>
- __forceinline bool operator() (const vbool<M>& valid_i, Hit& hit) const
- {
- Scene* scene MAYBE_UNUSED = context->scene;
- vbool<M> valid = valid_i;
- hit.finalize();
- size_t i = select_min(valid,hit.vt);
- assert(i<M);
- unsigned int geomID = geomIDs[i];
- /* intersection filter test */
- #if defined(EMBREE_FILTER_FUNCTION) || defined(EMBREE_RAY_MASK)
- bool foundhit = false;
- goto entry;
- while (true)
- {
- if (unlikely(none(valid))) return foundhit;
- i = select_min(valid,hit.vt);
- assert(i<M);
- geomID = geomIDs[i];
- entry:
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- #if defined(EMBREE_RAY_MASK)
- /* goto next hit if mask test fails */
- if ((geometry->mask & ray.mask[k]) == 0) {
- clear(valid,i);
- continue;
- }
- #endif
- #if defined(EMBREE_FILTER_FUNCTION)
- /* call intersection filter function */
- if (filter) {
- if (unlikely(context->hasContextFilter() || geometry->hasIntersectionFilter())) {
- assert(i<M);
- const Vec2f uv = hit.uv(i);
- HitK<K> h(context->user,geomID,primIDs[i],uv.x,uv.y,hit.Ng(i));
- const float old_t = ray.tfar[k];
- ray.tfar[k] = hit.t(i);
- const bool found = any(runIntersectionFilter(vbool<K>(1<<k),geometry,ray,context,h));
- if (!found) ray.tfar[k] = old_t;
- foundhit = foundhit | found;
- clear(valid,i);
- valid &= hit.vt <= ray.tfar[k]; // intersection filters may modify tfar value
- continue;
- }
- }
- #endif
- break;
- }
- #endif
- assert(i<M);
- /* update hit information */
- const Vec2f uv = hit.uv(i);
- ray.tfar[k] = hit.t(i);
- ray.Ng.x[k] = hit.vNg.x[i];
- ray.Ng.y[k] = hit.vNg.y[i];
- ray.Ng.z[k] = hit.vNg.z[i];
- ray.u[k] = uv.x;
- ray.v[k] = uv.y;
- ray.primID[k] = primIDs[i];
- ray.geomID[k] = geomID;
- instance_id_stack::copy_UV<K>(context->user->instID, ray.instID, k);
- #if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
- instance_id_stack::copy_UV<K>(context->user->instPrimID, ray.instPrimID, k);
- #endif
- return true;
- }
- };
-
- template<int M, int K, bool filter>
- struct Occluded1KEpilogM
- {
- RayK<K>& ray;
- size_t k;
- RayQueryContext* context;
- const vuint<M>& geomIDs;
- const vuint<M>& primIDs;
- __forceinline Occluded1KEpilogM(RayK<K>& ray, size_t k,
- RayQueryContext* context,
- const vuint<M>& geomIDs,
- const vuint<M>& primIDs)
- : ray(ray), k(k), context(context), geomIDs(geomIDs), primIDs(primIDs) {}
- template<typename Hit>
- __forceinline bool operator() (const vbool<M>& valid_i, Hit& hit) const
- {
- Scene* scene MAYBE_UNUSED = context->scene;
- /* intersection filter test */
- #if defined(EMBREE_FILTER_FUNCTION) || defined(EMBREE_RAY_MASK)
- if (unlikely(filter))
- hit.finalize(); /* called only once */
- vbool<M> valid = valid_i;
- size_t m=movemask(valid);
- goto entry;
- while (true)
- {
- if (unlikely(m == 0)) return false;
- entry:
- size_t i=bsf(m);
- const unsigned int geomID = geomIDs[i];
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- #if defined(EMBREE_RAY_MASK)
- /* goto next hit if mask test fails */
- if ((geometry->mask & ray.mask[k]) == 0) {
- m=btc(m,i);
- continue;
- }
- #endif
- #if defined(EMBREE_FILTER_FUNCTION)
- /* execute occlusion filer */
- if (filter) {
- if (unlikely(context->hasContextFilter() || geometry->hasOcclusionFilter()))
- {
- const Vec2f uv = hit.uv(i);
- const float old_t = ray.tfar[k];
- ray.tfar[k] = hit.t(i);
- HitK<K> h(context->user,geomID,primIDs[i],uv.x,uv.y,hit.Ng(i));
- if (any(runOcclusionFilter(vbool<K>(1<<k),geometry,ray,context,h))) return true;
- ray.tfar[k] = old_t;
- m=btc(m,i);
- continue;
- }
- }
- #endif
- break;
- }
- #endif
- return true;
- }
- };
-
- template<int M, int K, bool filter>
- struct Intersect1KEpilogMU
- {
- RayHitK<K>& ray;
- size_t k;
- RayQueryContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Intersect1KEpilogMU(RayHitK<K>& ray, size_t k,
- RayQueryContext* context,
- const unsigned int geomID,
- const unsigned int primID)
- : ray(ray), k(k), context(context), geomID(geomID), primID(primID) {}
- template<typename Hit>
- __forceinline bool operator() (const vbool<M>& valid_i, Hit& hit) const
- {
- Scene* scene MAYBE_UNUSED = context->scene;
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- #if defined(EMBREE_RAY_MASK)
- /* ray mask test */
- if ((geometry->mask & ray.mask[k]) == 0)
- return false;
- #endif
- /* finalize hit calculation */
- vbool<M> valid = valid_i;
- hit.finalize();
- size_t i = select_min(valid,hit.vt);
- /* intersection filter test */
- #if defined(EMBREE_FILTER_FUNCTION)
- if (filter) {
- if (unlikely(context->hasContextFilter() || geometry->hasIntersectionFilter()))
- {
- bool foundhit = false;
- while (true)
- {
- const Vec2f uv = hit.uv(i);
- const float old_t = ray.tfar[k];
- ray.tfar[k] = hit.t(i);
- HitK<K> h(context->user,geomID,primID,uv.x,uv.y,hit.Ng(i));
- const bool found = any(runIntersectionFilter(vbool<K>(1<<k),geometry,ray,context,h));
- if (!found) ray.tfar[k] = old_t;
- foundhit = foundhit | found;
- clear(valid,i);
- valid &= hit.vt <= ray.tfar[k]; // intersection filters may modify tfar value
- if (unlikely(none(valid))) break;
- i = select_min(valid,hit.vt);
- }
- return foundhit;
- }
- }
- #endif
- /* update hit information */
- const Vec2f uv = hit.uv(i);
- const Vec3fa Ng = hit.Ng(i);
- ray.tfar[k] = hit.t(i);
- ray.Ng.x[k] = Ng.x;
- ray.Ng.y[k] = Ng.y;
- ray.Ng.z[k] = Ng.z;
- ray.u[k] = uv.x;
- ray.v[k] = uv.y;
- ray.primID[k] = primID;
- ray.geomID[k] = geomID;
- instance_id_stack::copy_UV<K>(context->user->instID, ray.instID, k);
- #if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
- instance_id_stack::copy_UV<K>(context->user->instPrimID, ray.instPrimID, k);
- #endif
- return true;
- }
- };
-
- template<int M, int K, bool filter>
- struct Occluded1KEpilogMU
- {
- RayK<K>& ray;
- size_t k;
- RayQueryContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Occluded1KEpilogMU(RayK<K>& ray, size_t k,
- RayQueryContext* context,
- const unsigned int geomID,
- const unsigned int primID)
- : ray(ray), k(k), context(context), geomID(geomID), primID(primID) {}
- template<typename Hit>
- __forceinline bool operator() (const vbool<M>& valid_i, Hit& hit) const
- {
- Scene* scene MAYBE_UNUSED = context->scene;
- Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
- #if defined(EMBREE_RAY_MASK)
- /* ray mask test */
- if ((geometry->mask & ray.mask[k]) == 0)
- return false;
- #endif
- /* intersection filter test */
- #if defined(EMBREE_FILTER_FUNCTION)
- if (filter) {
- if (unlikely(context->hasContextFilter() || geometry->hasOcclusionFilter()))
- {
- hit.finalize();
- for (size_t m=movemask(valid_i), i=bsf(m); m!=0; m=btc(m,i), i=bsf(m))
- {
- const Vec2f uv = hit.uv(i);
- const float old_t = ray.tfar[k];
- ray.tfar[k] = hit.t(i);
- HitK<K> h(context->user,geomID,primID,uv.x,uv.y,hit.Ng(i));
- if (any(runOcclusionFilter(vbool<K>(1<<k),geometry,ray,context,h))) return true;
- ray.tfar[k] = old_t;
- }
- return false;
- }
- }
- #endif
- return true;
- }
- };
- }
- }
|