1// Copyright 2009-2021 Intel Corporation
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include "subgrid_intersector.h"
7
8namespace embree
9{
10 namespace isa
11 {
12 template<int N, bool filter>
13 struct SubGridMBIntersector1Pluecker
14 {
15 typedef SubGridMBQBVHN<N> Primitive;
16 typedef SubGridQuadMIntersector1Pluecker<4,filter> Precalculations;
17
18 static __forceinline void intersect(const Precalculations& pre, RayHit& ray, IntersectContext* context, const SubGrid& subgrid)
19 {
20 STAT3(normal.trav_prims,1,1,1);
21 const GridMesh* mesh = context->scene->get<GridMesh>(i: subgrid.geomID());
22 const GridMesh::Grid &g = mesh->grid(i: subgrid.primID());
23
24 float ftime;
25 const int itime = mesh->timeSegment(time: ray.time(), ftime);
26 Vec3vf4 v0,v1,v2,v3; subgrid.gatherMB(p0&: v0,p1&: v1,p2&: v2,p3&: v3,scene: context->scene,itime,ftime);
27 pre.intersect(ray,context,v0,v1,v2,v3,g,subgrid);
28 }
29
30 static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const SubGrid& subgrid)
31 {
32 STAT3(shadow.trav_prims,1,1,1);
33 const GridMesh* mesh = context->scene->get<GridMesh>(i: subgrid.geomID());
34 const GridMesh::Grid &g = mesh->grid(i: subgrid.primID());
35
36 float ftime;
37 const int itime = mesh->timeSegment(time: ray.time(), ftime);
38
39 Vec3vf4 v0,v1,v2,v3; subgrid.gatherMB(p0&: v0,p1&: v1,p2&: v2,p3&: v3,scene: context->scene,itime,ftime);
40 return pre.occluded(ray,context,v0,v1,v2,v3,g,subgrid);
41 }
42
43 static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const SubGrid& subgrid)
44 {
45 return PrimitivePointQuery1<Primitive>::pointQuery(query, context, subgrid);
46 }
47
48 template<bool robust>
49 static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node)
50 {
51 BVHNQuantizedBaseNodeIntersector1<N,robust> isec1;
52 for (size_t i=0;i<num;i++)
53 {
54 vfloat<N> dist;
55 const float time = prim[i].adjustTime(ray.time());
56
57 assert(time <= 1.0f);
58 size_t mask = isec1.intersect(&prim[i].qnode,tray,time,dist);
59#if defined(__AVX__)
60 STAT3(normal.trav_hit_boxes[popcnt(mask)],1,1,1);
61#endif
62 while(mask != 0)
63 {
64 const size_t ID = bscf(v&: mask);
65 if (unlikely(dist[ID] > ray.tfar)) continue;
66 intersect(pre,ray,context,prim[i].subgrid(ID));
67 }
68 }
69 }
70
71 template<bool robust>
72 static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node)
73 {
74 BVHNQuantizedBaseNodeIntersector1<N,robust> isec1;
75 for (size_t i=0;i<num;i++)
76 {
77 const float time = prim[i].adjustTime(ray.time());
78 assert(time <= 1.0f);
79 vfloat<N> dist;
80 size_t mask = isec1.intersect(&prim[i].qnode,tray,time,dist);
81 while(mask != 0)
82 {
83 const size_t ID = bscf(v&: mask);
84 if (occluded(pre,ray,context,prim[i].subgrid(ID)))
85 return true;
86 }
87 }
88 return false;
89 }
90
91 static __forceinline bool pointQuery(const Accel::Intersectors* This, PointQuery* query, PointQueryContext* context, const Primitive* prim, size_t num, const TravPointQuery<N> &tquery, size_t& lazy_node)
92 {
93 assert(false && "not implemented");
94 return false;
95 }
96 };
97
98
99 template<int N, int K, bool filter>
100 struct SubGridMBIntersectorKPluecker
101 {
102 typedef SubGridMBQBVHN<N> Primitive;
103 typedef SubGridQuadMIntersectorKPluecker<4,K,filter> Precalculations;
104
105 static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const SubGrid& subgrid)
106 {
107 size_t m_valid = movemask(valid_i);
108 while(m_valid)
109 {
110 size_t ID = bscf(v&: m_valid);
111 intersect(pre,ray,ID,context,subgrid);
112 }
113 }
114
115 static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const SubGrid& subgrid)
116 {
117 vbool<K> valid0 = valid_i;
118 size_t m_valid = movemask(valid_i);
119 while(m_valid)
120 {
121 size_t ID = bscf(v&: m_valid);
122 if (occluded(pre,ray,ID,context,subgrid))
123 clear(valid0,ID);
124 }
125 return !valid0;
126 }
127
128 static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const SubGrid& subgrid)
129 {
130 STAT3(normal.trav_prims,1,1,1);
131 const GridMesh* mesh = context->scene->get<GridMesh>(i: subgrid.geomID());
132 const GridMesh::Grid &g = mesh->grid(i: subgrid.primID());
133
134 vfloat<K> ftime;
135 const vint<K> itime = mesh->timeSegment<K>(ray.time(), ftime);
136 Vec3vf4 v0,v1,v2,v3; subgrid.gatherMB(v0,v1,v2,v3,context->scene,itime[k],ftime[k]);
137 pre.intersect1(ray,k,context,v0,v1,v2,v3,g,subgrid);
138 }
139
140 static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const SubGrid& subgrid)
141 {
142 STAT3(shadow.trav_prims,1,1,1);
143 const GridMesh* mesh = context->scene->get<GridMesh>(i: subgrid.geomID());
144 const GridMesh::Grid &g = mesh->grid(i: subgrid.primID());
145
146 vfloat<K> ftime;
147 const vint<K> itime = mesh->timeSegment<K>(ray.time(), ftime);
148 Vec3vf4 v0,v1,v2,v3; subgrid.gatherMB(v0,v1,v2,v3,context->scene,itime[k],ftime[k]);
149 return pre.occluded1(ray,k,context,v0,v1,v2,v3,g,subgrid);
150 }
151
152 template<bool robust>
153 static __forceinline void intersect(const vbool<K>& valid, const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRayK<K, robust> &tray, size_t& lazy_node)
154 {
155 BVHNQuantizedBaseNodeIntersectorK<N,K,robust> isecK;
156 for (size_t j=0;j<num;j++)
157 {
158 size_t m_valid = movemask(prim[j].qnode.validMask());
159 const vfloat<K> time = prim[j].template adjustTime<K>(ray.time());
160
161 vfloat<K> dist;
162 while(m_valid)
163 {
164 const size_t i = bscf(v&: m_valid);
165 if (none(valid & isecK.intersectK(&prim[j].qnode,i,tray,time,dist))) continue;
166 intersect(valid,pre,ray,context,prim[j].subgrid(i));
167 }
168 }
169 }
170
171 template<bool robust>
172 static __forceinline vbool<K> occluded(const vbool<K>& valid, const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRayK<K, robust> &tray, size_t& lazy_node)
173 {
174 BVHNQuantizedBaseNodeIntersectorK<N,K,robust> isecK;
175
176 vbool<K> valid0 = valid;
177 for (size_t j=0;j<num;j++)
178 {
179 size_t m_valid = movemask(prim[j].qnode.validMask());
180 const vfloat<K> time = prim[j].template adjustTime<K>(ray.time());
181 vfloat<K> dist;
182 while(m_valid)
183 {
184 const size_t i = bscf(v&: m_valid);
185 if (none(valid0 & isecK.intersectK(&prim[j].qnode,i,tray,time,dist))) continue;
186 valid0 &= !occluded(valid0,pre,ray,context,prim[j].subgrid(i));
187 if (none(valid0)) break;
188 }
189 }
190 return !valid0;
191 }
192
193 template<bool robust>
194 static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node)
195 {
196 BVHNQuantizedBaseNodeIntersector1<N,robust> isec1;
197 for (size_t i=0;i<num;i++)
198 {
199 vfloat<N> dist;
200 const float time = prim[i].adjustTime(ray.time()[k]);
201 assert(time <= 1.0f);
202
203 size_t mask = isec1.intersect(&prim[i].qnode,tray,time,dist);
204 while(mask != 0)
205 {
206 const size_t ID = bscf(v&: mask);
207 if (unlikely(dist[ID] > ray.tfar[k])) continue;
208 intersect(pre,ray,k,context,prim[i].subgrid(ID));
209 }
210 }
211 }
212
213 template<bool robust>
214 static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node)
215 {
216 BVHNQuantizedBaseNodeIntersector1<N,robust> isec1;
217
218 for (size_t i=0;i<num;i++)
219 {
220 vfloat<N> dist;
221 const float time = prim[i].adjustTime(ray.time()[k]);
222 assert(time <= 1.0f);
223
224 size_t mask = isec1.intersect(&prim[i].qnode,tray,time,dist);
225 while(mask != 0)
226 {
227 const size_t ID = bscf(v&: mask);
228 if (occluded(pre,ray,k,context,prim[i].subgrid(ID)))
229 return true;
230 }
231 }
232 return false;
233 }
234 };
235 }
236}
237

source code of qtquick3d/src/3rdparty/embree/kernels/geometry/subgrid_mb_intersector.h