Path: blob/master/thirdparty/embree/kernels/geometry/grid_soa_intersector1.h
9905 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "grid_soa.h"6#include "../common/ray.h"7#include "triangle_intersector_pluecker.h"89namespace embree10{11namespace isa12{13class GridSOAIntersector114{15public:16typedef void Primitive;1718class Precalculations19{20public:21__forceinline Precalculations (const Ray& ray, const void* ptr)22: grid(nullptr) {}2324public:25GridSOA* grid;26int itime;27float ftime;28};2930template<typename Loader>31static __forceinline void intersect(RayHit& ray,32RayQueryContext* context,33const float* const grid_x,34const size_t line_offset,35const size_t lines,36Precalculations& pre)37{38typedef typename Loader::vfloat vfloat;39const size_t dim_offset = pre.grid->dim_offset;40const float* const grid_y = grid_x + 1 * dim_offset;41const float* const grid_z = grid_x + 2 * dim_offset;42const float* const grid_uv = grid_x + 3 * dim_offset;43Vec3<vfloat> v0, v1, v2;44Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,v0,v1,v2);45GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);46PlueckerIntersector1<Loader::M> intersector(ray,nullptr);47intersector.intersect(ray,v0,v1,v2,mapUV,Intersect1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));48};4950template<typename Loader>51static __forceinline bool occluded(Ray& ray,52RayQueryContext* context,53const float* const grid_x,54const size_t line_offset,55const size_t lines,56Precalculations& pre)57{58typedef typename Loader::vfloat vfloat;59const size_t dim_offset = pre.grid->dim_offset;60const float* const grid_y = grid_x + 1 * dim_offset;61const float* const grid_z = grid_x + 2 * dim_offset;62const float* const grid_uv = grid_x + 3 * dim_offset;6364Vec3<vfloat> v0, v1, v2;65Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,v0,v1,v2);6667GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);68PlueckerIntersector1<Loader::M> intersector(ray,nullptr);69return intersector.intersect(ray,v0,v1,v2,mapUV,Occluded1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));70}7172/*! Intersect a ray with the primitive. */73static __forceinline void intersect(Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)74{75const size_t line_offset = pre.grid->width;76const size_t lines = pre.grid->height;77const float* const grid_x = pre.grid->decodeLeaf(0,prim);7879#if defined(__AVX__)80intersect<GridSOA::Gather3x3>( ray, context, grid_x, line_offset, lines, pre);81#else82intersect<GridSOA::Gather2x3>(ray, context, grid_x , line_offset, lines, pre);83if (likely(lines > 2))84intersect<GridSOA::Gather2x3>(ray, context, grid_x+line_offset, line_offset, lines, pre);85#endif86}8788/*! Test if the ray is occluded by the primitive */89static __forceinline bool occluded(Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)90{91const size_t line_offset = pre.grid->width;92const size_t lines = pre.grid->height;93const float* const grid_x = pre.grid->decodeLeaf(0,prim);9495#if defined(__AVX__)96return occluded<GridSOA::Gather3x3>( ray, context, grid_x, line_offset, lines, pre);97#else98if (occluded<GridSOA::Gather2x3>(ray, context, grid_x , line_offset, lines, pre)) return true;99if (likely(lines > 2))100if (occluded<GridSOA::Gather2x3>(ray, context, grid_x+line_offset, line_offset, lines, pre)) return true;101#endif102return false;103}104};105106class GridSOAMBIntersector1107{108public:109typedef void Primitive;110typedef GridSOAIntersector1::Precalculations Precalculations;111112template<typename Loader>113static __forceinline void intersect(RayHit& ray, const float ftime,114RayQueryContext* context,115const float* const grid_x,116const size_t line_offset,117const size_t lines,118Precalculations& pre)119{120typedef typename Loader::vfloat vfloat;121const size_t dim_offset = pre.grid->dim_offset;122const size_t grid_offset = pre.grid->gridBytes >> 2;123const float* const grid_y = grid_x + 1 * dim_offset;124const float* const grid_z = grid_x + 2 * dim_offset;125const float* const grid_uv = grid_x + 3 * dim_offset;126127Vec3<vfloat> a0, a1, a2;128Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,a0,a1,a2);129130Vec3<vfloat> b0, b1, b2;131Loader::gather(grid_x+grid_offset,grid_y+grid_offset,grid_z+grid_offset,line_offset,lines,b0,b1,b2);132133Vec3<vfloat> v0 = lerp(a0,b0,vfloat(ftime));134Vec3<vfloat> v1 = lerp(a1,b1,vfloat(ftime));135Vec3<vfloat> v2 = lerp(a2,b2,vfloat(ftime));136137GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);138PlueckerIntersector1<Loader::M> intersector(ray,nullptr);139intersector.intersect(ray,v0,v1,v2,mapUV,Intersect1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));140};141142template<typename Loader>143static __forceinline bool occluded(Ray& ray, const float ftime,144RayQueryContext* context,145const float* const grid_x,146const size_t line_offset,147const size_t lines,148Precalculations& pre)149{150typedef typename Loader::vfloat vfloat;151const size_t dim_offset = pre.grid->dim_offset;152const size_t grid_offset = pre.grid->gridBytes >> 2;153const float* const grid_y = grid_x + 1 * dim_offset;154const float* const grid_z = grid_x + 2 * dim_offset;155const float* const grid_uv = grid_x + 3 * dim_offset;156157Vec3<vfloat> a0, a1, a2;158Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,a0,a1,a2);159160Vec3<vfloat> b0, b1, b2;161Loader::gather(grid_x+grid_offset,grid_y+grid_offset,grid_z+grid_offset,line_offset,lines,b0,b1,b2);162163Vec3<vfloat> v0 = lerp(a0,b0,vfloat(ftime));164Vec3<vfloat> v1 = lerp(a1,b1,vfloat(ftime));165Vec3<vfloat> v2 = lerp(a2,b2,vfloat(ftime));166167GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);168PlueckerIntersector1<Loader::M> intersector(ray,nullptr);169return intersector.intersect(ray,v0,v1,v2,mapUV,Occluded1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));170}171172/*! Intersect a ray with the primitive. */173static __forceinline void intersect(Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)174{175const size_t line_offset = pre.grid->width;176const size_t lines = pre.grid->height;177const float* const grid_x = pre.grid->decodeLeaf(pre.itime,prim);178179#if defined(__AVX__)180intersect<GridSOA::Gather3x3>( ray, pre.ftime, context, grid_x, line_offset, lines, pre);181#else182intersect<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x, line_offset, lines, pre);183if (likely(lines > 2))184intersect<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x+line_offset, line_offset, lines, pre);185#endif186}187188/*! Test if the ray is occluded by the primitive */189static __forceinline bool occluded(Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)190{191const size_t line_offset = pre.grid->width;192const size_t lines = pre.grid->height;193const float* const grid_x = pre.grid->decodeLeaf(pre.itime,prim);194195#if defined(__AVX__)196return occluded<GridSOA::Gather3x3>( ray, pre.ftime, context, grid_x, line_offset, lines, pre);197#else198if (occluded<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x , line_offset, lines, pre)) return true;199if (likely(lines > 2))200if (occluded<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x+line_offset, line_offset, lines, pre)) return true;201#endif202return false;203}204};205}206}207208209