1// Copyright 2009-2021 Intel Corporation
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include "grid_soa.h"
7#include "../common/ray.h"
8#include "triangle_intersector_pluecker.h"
9
10namespace embree
11{
12 namespace isa
13 {
14 class GridSOAIntersector1
15 {
16 public:
17 typedef void Primitive;
18
19 class Precalculations
20 {
21 public:
22 __forceinline Precalculations (const Ray& ray, const void* ptr)
23 : grid(nullptr) {}
24
25 public:
26 GridSOA* grid;
27 int itime;
28 float ftime;
29 };
30
31 template<typename Loader>
32 static __forceinline void intersect(RayHit& ray,
33 IntersectContext* context,
34 const float* const grid_x,
35 const size_t line_offset,
36 const size_t lines,
37 Precalculations& pre)
38 {
39 typedef typename Loader::vfloat vfloat;
40 const size_t dim_offset = pre.grid->dim_offset;
41 const float* const grid_y = grid_x + 1 * dim_offset;
42 const float* const grid_z = grid_x + 2 * dim_offset;
43 const float* const grid_uv = grid_x + 3 * dim_offset;
44 Vec3<vfloat> v0, v1, v2;
45 Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,v0,v1,v2);
46 GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
47 PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
48 intersector.intersect(ray,v0,v1,v2,mapUV,Intersect1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
49 };
50
51 template<typename Loader>
52 static __forceinline bool occluded(Ray& ray,
53 IntersectContext* context,
54 const float* const grid_x,
55 const size_t line_offset,
56 const size_t lines,
57 Precalculations& pre)
58 {
59 typedef typename Loader::vfloat vfloat;
60 const size_t dim_offset = pre.grid->dim_offset;
61 const float* const grid_y = grid_x + 1 * dim_offset;
62 const float* const grid_z = grid_x + 2 * dim_offset;
63 const float* const grid_uv = grid_x + 3 * dim_offset;
64
65 Vec3<vfloat> v0, v1, v2;
66 Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,v0,v1,v2);
67
68 GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
69 PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
70 return intersector.intersect(ray,v0,v1,v2,mapUV,Occluded1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
71 }
72
73 /*! Intersect a ray with the primitive. */
74 static __forceinline void intersect(Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t& lazy_node)
75 {
76 const size_t line_offset = pre.grid->width;
77 const size_t lines = pre.grid->height;
78 const float* const grid_x = pre.grid->decodeLeaf(0,prim);
79
80#if defined(__AVX__)
81 intersect<GridSOA::Gather3x3>( ray, context, grid_x, line_offset, lines, pre);
82#else
83 intersect<GridSOA::Gather2x3>(ray, context, grid_x , line_offset, lines, pre);
84 if (likely(lines > 2))
85 intersect<GridSOA::Gather2x3>(ray, context, grid_x+line_offset, line_offset, lines, pre);
86#endif
87 }
88
89 /*! Test if the ray is occluded by the primitive */
90 static __forceinline bool occluded(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t& lazy_node)
91 {
92 const size_t line_offset = pre.grid->width;
93 const size_t lines = pre.grid->height;
94 const float* const grid_x = pre.grid->decodeLeaf(0,prim);
95
96#if defined(__AVX__)
97 return occluded<GridSOA::Gather3x3>( ray, context, grid_x, line_offset, lines, pre);
98#else
99 if (occluded<GridSOA::Gather2x3>(ray, context, grid_x , line_offset, lines, pre)) return true;
100 if (likely(lines > 2))
101 if (occluded<GridSOA::Gather2x3>(ray, context, grid_x+line_offset, line_offset, lines, pre)) return true;
102#endif
103 return false;
104 }
105 };
106
107 class GridSOAMBIntersector1
108 {
109 public:
110 typedef void Primitive;
111 typedef GridSOAIntersector1::Precalculations Precalculations;
112
113 template<typename Loader>
114 static __forceinline void intersect(RayHit& ray, const float ftime,
115 IntersectContext* context,
116 const float* const grid_x,
117 const size_t line_offset,
118 const size_t lines,
119 Precalculations& pre)
120 {
121 typedef typename Loader::vfloat vfloat;
122 const size_t dim_offset = pre.grid->dim_offset;
123 const size_t grid_offset = pre.grid->gridBytes >> 2;
124 const float* const grid_y = grid_x + 1 * dim_offset;
125 const float* const grid_z = grid_x + 2 * dim_offset;
126 const float* const grid_uv = grid_x + 3 * dim_offset;
127
128 Vec3<vfloat> a0, a1, a2;
129 Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,a0,a1,a2);
130
131 Vec3<vfloat> b0, b1, b2;
132 Loader::gather(grid_x+grid_offset,grid_y+grid_offset,grid_z+grid_offset,line_offset,lines,b0,b1,b2);
133
134 Vec3<vfloat> v0 = lerp(a0,b0,vfloat(ftime));
135 Vec3<vfloat> v1 = lerp(a1,b1,vfloat(ftime));
136 Vec3<vfloat> v2 = lerp(a2,b2,vfloat(ftime));
137
138 GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
139 PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
140 intersector.intersect(ray,v0,v1,v2,mapUV,Intersect1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
141 };
142
143 template<typename Loader>
144 static __forceinline bool occluded(Ray& ray, const float ftime,
145 IntersectContext* context,
146 const float* const grid_x,
147 const size_t line_offset,
148 const size_t lines,
149 Precalculations& pre)
150 {
151 typedef typename Loader::vfloat vfloat;
152 const size_t dim_offset = pre.grid->dim_offset;
153 const size_t grid_offset = pre.grid->gridBytes >> 2;
154 const float* const grid_y = grid_x + 1 * dim_offset;
155 const float* const grid_z = grid_x + 2 * dim_offset;
156 const float* const grid_uv = grid_x + 3 * dim_offset;
157
158 Vec3<vfloat> a0, a1, a2;
159 Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,a0,a1,a2);
160
161 Vec3<vfloat> b0, b1, b2;
162 Loader::gather(grid_x+grid_offset,grid_y+grid_offset,grid_z+grid_offset,line_offset,lines,b0,b1,b2);
163
164 Vec3<vfloat> v0 = lerp(a0,b0,vfloat(ftime));
165 Vec3<vfloat> v1 = lerp(a1,b1,vfloat(ftime));
166 Vec3<vfloat> v2 = lerp(a2,b2,vfloat(ftime));
167
168 GridSOA::MapUV<Loader> mapUV(grid_uv,line_offset,lines);
169 PlueckerIntersector1<Loader::M> intersector(ray,nullptr);
170 return intersector.intersect(ray,v0,v1,v2,mapUV,Occluded1EpilogMU<Loader::M,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
171 }
172
173 /*! Intersect a ray with the primitive. */
174 static __forceinline void intersect(Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t& lazy_node)
175 {
176 const size_t line_offset = pre.grid->width;
177 const size_t lines = pre.grid->height;
178 const float* const grid_x = pre.grid->decodeLeaf(pre.itime,prim);
179
180#if defined(__AVX__)
181 intersect<GridSOA::Gather3x3>( ray, pre.ftime, context, grid_x, line_offset, lines, pre);
182#else
183 intersect<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x, line_offset, lines, pre);
184 if (likely(lines > 2))
185 intersect<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x+line_offset, line_offset, lines, pre);
186#endif
187 }
188
189 /*! Test if the ray is occluded by the primitive */
190 static __forceinline bool occluded(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t& lazy_node)
191 {
192 const size_t line_offset = pre.grid->width;
193 const size_t lines = pre.grid->height;
194 const float* const grid_x = pre.grid->decodeLeaf(pre.itime,prim);
195
196#if defined(__AVX__)
197 return occluded<GridSOA::Gather3x3>( ray, pre.ftime, context, grid_x, line_offset, lines, pre);
198#else
199 if (occluded<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x , line_offset, lines, pre)) return true;
200 if (likely(lines > 2))
201 if (occluded<GridSOA::Gather2x3>(ray, pre.ftime, context, grid_x+line_offset, line_offset, lines, pre)) return true;
202#endif
203 return false;
204 }
205 };
206 }
207}
208