123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- // Copyright 2009-2021 Intel Corporation
- // SPDX-License-Identifier: Apache-2.0
- #pragma once
- #include "grid_soa.h"
- #include "../common/ray.h"
- #include "triangle_intersector_pluecker.h"
- namespace embree
- {
- namespace isa
- {
- class GridSOAIntersector1
- {
- public:
- typedef void Primitive;
-
- class Precalculations
- {
- public:
- __forceinline Precalculations (const Ray& ray, const void* ptr)
- : grid(nullptr) {}
-
- public:
- GridSOA* grid;
- int itime;
- float ftime;
- };
-
- template<typename Loader>
- static __forceinline void intersect(RayHit& ray,
- RayQueryContext* context,
- const float* const grid_x,
- const size_t line_offset,
- const size_t lines,
- Precalculations& pre)
- {
- typedef typename Loader::vfloat vfloat;
- const size_t dim_offset = pre.grid->dim_offset;
- const float* const grid_y = grid_x + 1 * dim_offset;
- const float* const grid_z = grid_x + 2 * dim_offset;
- const float* const grid_uv = grid_x + 3 * dim_offset;
- Vec3<vfloat> v0, v1, v2;
- Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,v0,v1,v2);
- GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
- PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
- intersector.intersect(ray,v0,v1,v2,mapUV,Intersect1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
- };
-
- template<typename Loader>
- static __forceinline bool occluded(Ray& ray,
- RayQueryContext* context,
- const float* const grid_x,
- const size_t line_offset,
- const size_t lines,
- Precalculations& pre)
- {
- typedef typename Loader::vfloat vfloat;
- const size_t dim_offset = pre.grid->dim_offset;
- const float* const grid_y = grid_x + 1 * dim_offset;
- const float* const grid_z = grid_x + 2 * dim_offset;
- const float* const grid_uv = grid_x + 3 * dim_offset;
- Vec3<vfloat> v0, v1, v2;
- Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,v0,v1,v2);
-
- GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
- PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
- return intersector.intersect(ray,v0,v1,v2,mapUV,Occluded1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
- }
-
- /*! Intersect a ray with the primitive. */
- static __forceinline void intersect(Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
- {
- const size_t line_offset = pre.grid->width;
- const size_t lines = pre.grid->height;
- const float* const grid_x = pre.grid->decodeLeaf(0,prim);
-
- #if defined(__AVX__)
- intersect<GridSOA::Gather3x3>( ray, context, grid_x, line_offset, lines, pre);
- #else
- intersect<GridSOA::Gather2x3>(ray, context, grid_x , line_offset, lines, pre);
- if (likely(lines > 2))
- intersect<GridSOA::Gather2x3>(ray, context, grid_x+line_offset, line_offset, lines, pre);
- #endif
- }
-
- /*! Test if the ray is occluded by the primitive */
- static __forceinline bool occluded(Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
- {
- const size_t line_offset = pre.grid->width;
- const size_t lines = pre.grid->height;
- const float* const grid_x = pre.grid->decodeLeaf(0,prim);
-
- #if defined(__AVX__)
- return occluded<GridSOA::Gather3x3>( ray, context, grid_x, line_offset, lines, pre);
- #else
- if (occluded<GridSOA::Gather2x3>(ray, context, grid_x , line_offset, lines, pre)) return true;
- if (likely(lines > 2))
- if (occluded<GridSOA::Gather2x3>(ray, context, grid_x+line_offset, line_offset, lines, pre)) return true;
- #endif
- return false;
- }
- };
- class GridSOAMBIntersector1
- {
- public:
- typedef void Primitive;
- typedef GridSOAIntersector1::Precalculations Precalculations;
-
- template<typename Loader>
- static __forceinline void intersect(RayHit& ray, const float ftime,
- RayQueryContext* context,
- const float* const grid_x,
- const size_t line_offset,
- const size_t lines,
- Precalculations& pre)
- {
- typedef typename Loader::vfloat vfloat;
- const size_t dim_offset = pre.grid->dim_offset;
- const size_t grid_offset = pre.grid->gridBytes >> 2;
- const float* const grid_y = grid_x + 1 * dim_offset;
- const float* const grid_z = grid_x + 2 * dim_offset;
- const float* const grid_uv = grid_x + 3 * dim_offset;
- Vec3<vfloat> a0, a1, a2;
- Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,a0,a1,a2);
- Vec3<vfloat> b0, b1, b2;
- Loader::gather(grid_x+grid_offset,grid_y+grid_offset,grid_z+grid_offset,line_offset,lines,b0,b1,b2);
- Vec3<vfloat> v0 = lerp(a0,b0,vfloat(ftime));
- Vec3<vfloat> v1 = lerp(a1,b1,vfloat(ftime));
- Vec3<vfloat> v2 = lerp(a2,b2,vfloat(ftime));
- GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
- PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
- intersector.intersect(ray,v0,v1,v2,mapUV,Intersect1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
- };
-
- template<typename Loader>
- static __forceinline bool occluded(Ray& ray, const float ftime,
- RayQueryContext* context,
- const float* const grid_x,
- const size_t line_offset,
- const size_t lines,
- Precalculations& pre)
- {
- typedef typename Loader::vfloat vfloat;
- const size_t dim_offset = pre.grid->dim_offset;
- const size_t grid_offset = pre.grid->gridBytes >> 2;
- const float* const grid_y = grid_x + 1 * dim_offset;
- const float* const grid_z = grid_x + 2 * dim_offset;
- const float* const grid_uv = grid_x + 3 * dim_offset;
- Vec3<vfloat> a0, a1, a2;
- Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,a0,a1,a2);
- Vec3<vfloat> b0, b1, b2;
- Loader::gather(grid_x+grid_offset,grid_y+grid_offset,grid_z+grid_offset,line_offset,lines,b0,b1,b2);
-
- Vec3<vfloat> v0 = lerp(a0,b0,vfloat(ftime));
- Vec3<vfloat> v1 = lerp(a1,b1,vfloat(ftime));
- Vec3<vfloat> v2 = lerp(a2,b2,vfloat(ftime));
-
- GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
- PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
- return intersector.intersect(ray,v0,v1,v2,mapUV,Occluded1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
- }
-
- /*! Intersect a ray with the primitive. */
- static __forceinline void intersect(Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
- {
- const size_t line_offset = pre.grid->width;
- const size_t lines = pre.grid->height;
- const float* const grid_x = pre.grid->decodeLeaf(pre.itime,prim);
-
- #if defined(__AVX__)
- intersect<GridSOA::Gather3x3>( ray, pre.ftime, context, grid_x, line_offset, lines, pre);
- #else
- intersect<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x, line_offset, lines, pre);
- if (likely(lines > 2))
- intersect<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x+line_offset, line_offset, lines, pre);
- #endif
- }
-
- /*! Test if the ray is occluded by the primitive */
- static __forceinline bool occluded(Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
- {
- const size_t line_offset = pre.grid->width;
- const size_t lines = pre.grid->height;
- const float* const grid_x = pre.grid->decodeLeaf(pre.itime,prim);
-
- #if defined(__AVX__)
- return occluded<GridSOA::Gather3x3>( ray, pre.ftime, context, grid_x, line_offset, lines, pre);
- #else
- if (occluded<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x , line_offset, lines, pre)) return true;
- if (likely(lines > 2))
- if (occluded<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x+line_offset, line_offset, lines, pre)) return true;
- #endif
- return false;
- }
- };
- }
- }
|