123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980 |
- // 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;
- IntersectContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Intersect1Epilog1(RayHit& ray,
- IntersectContext* 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);
- return true;
- }
- };
- template<bool filter>
- struct Occluded1Epilog1
- {
- Ray& ray;
- IntersectContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Occluded1Epilog1(Ray& ray,
- IntersectContext* 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;
- IntersectContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Intersect1KEpilog1(RayHitK<K>& ray, size_t k,
- IntersectContext* 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);
- return true;
- }
- };
-
- template<int K, bool filter>
- struct Occluded1KEpilog1
- {
- RayK<K>& ray;
- size_t k;
- IntersectContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Occluded1KEpilog1(RayK<K>& ray, size_t k,
- IntersectContext* 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;
- IntersectContext* context;
- const vuint<M>& geomIDs;
- const vuint<M>& primIDs;
- __forceinline Intersect1EpilogM(RayHit& ray,
- IntersectContext* 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);
- return true;
- }
- };
- template<int M, bool filter>
- struct Occluded1EpilogM
- {
- Ray& ray;
- IntersectContext* context;
- const vuint<M>& geomIDs;
- const vuint<M>& primIDs;
- __forceinline Occluded1EpilogM(Ray& ray,
- IntersectContext* 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;
- IntersectContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Intersect1EpilogMU(RayHit& ray,
- IntersectContext* 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);
- return true;
- }
- };
-
- template<int M, bool filter>
- struct Occluded1EpilogMU
- {
- Ray& ray;
- IntersectContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Occluded1EpilogMU(Ray& ray,
- IntersectContext* 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;
- IntersectContext* context;
- const vuint<M>& geomIDs;
- const vuint<M>& primIDs;
- const size_t i;
- __forceinline IntersectKEpilogM(RayHitK<K>& ray,
- IntersectContext* 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);
- return valid;
- }
- };
-
- template<int M, int K, bool filter>
- struct OccludedKEpilogM
- {
- vbool<K>& valid0;
- RayK<K>& ray;
- IntersectContext* context;
- const vuint<M>& geomIDs;
- const vuint<M>& primIDs;
- const size_t i;
- __forceinline OccludedKEpilogM(vbool<K>& valid0,
- RayK<K>& ray,
- IntersectContext* 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;
- IntersectContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline IntersectKEpilogMU(RayHitK<K>& ray,
- IntersectContext* 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);
- return valid;
- }
- };
-
- template<int M, int K, bool filter>
- struct OccludedKEpilogMU
- {
- vbool<K>& valid0;
- RayK<K>& ray;
- IntersectContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline OccludedKEpilogMU(vbool<K>& valid0,
- RayK<K>& ray,
- IntersectContext* 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;
- IntersectContext* context;
- const vuint<M>& geomIDs;
- const vuint<M>& primIDs;
- __forceinline Intersect1KEpilogM(RayHitK<K>& ray, size_t k,
- IntersectContext* 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);
- return true;
- }
- };
-
- template<int M, int K, bool filter>
- struct Occluded1KEpilogM
- {
- RayK<K>& ray;
- size_t k;
- IntersectContext* context;
- const vuint<M>& geomIDs;
- const vuint<M>& primIDs;
- __forceinline Occluded1KEpilogM(RayK<K>& ray, size_t k,
- IntersectContext* 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;
- IntersectContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Intersect1KEpilogMU(RayHitK<K>& ray, size_t k,
- IntersectContext* 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);
- return true;
- }
- };
-
- template<int M, int K, bool filter>
- struct Occluded1KEpilogMU
- {
- RayK<K>& ray;
- size_t k;
- IntersectContext* context;
- const unsigned int geomID;
- const unsigned int primID;
- __forceinline Occluded1KEpilogMU(RayK<K>& ray, size_t k,
- IntersectContext* 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;
- }
- };
- }
- }
|