1// Copyright 2009-2021 Intel Corporation
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include "triangle.h"
7#include "triangle_intersector_pluecker.h"
8#include "triangle_intersector_moeller.h"
9#include "triangle_intersector_woop.h"
10
11namespace embree
12{
13 namespace isa
14 {
15 /*! Intersects M triangles with 1 ray */
16 template<int M, bool filter>
17 struct TriangleMvIntersector1Moeller
18 {
19 typedef TriangleMv<M> Primitive;
20 typedef MoellerTrumboreIntersector1<M> Precalculations;
21
22 /*! Intersect a ray with M triangles and updates the hit. */
23 static __forceinline void intersect(Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& tri)
24 {
25 STAT3(normal.trav_prims,1,1,1);
26 pre.intersect(ray,tri.v0,tri.v1,tri.v2,/*UVIdentity<M>(),*/Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID()));
27 }
28
29 /*! Test if the ray is occluded by one of the M triangles. */
30 static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& tri)
31 {
32 STAT3(shadow.trav_prims,1,1,1);
33 return pre.intersect(ray,tri.v0,tri.v1,tri.v2,/*UVIdentity<M>(),*/Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID()));
34 }
35
36 static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri)
37 {
38 return PrimitivePointQuery1<Primitive>::pointQuery(query, context, tri);
39 }
40 };
41
42
43 template<int M, bool filter>
44 struct TriangleMvIntersector1Woop
45 {
46 typedef TriangleMv<M> Primitive;
47 typedef WoopIntersector1<M> intersec;
48 typedef WoopPrecalculations1<M> Precalculations;
49
50 /*! Intersect a ray with M triangles and updates the hit. */
51 static __forceinline void intersect(const Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& tri)
52 {
53 STAT3(normal.trav_prims,1,1,1);
54 intersec::intersect(ray,pre,tri.v0,tri.v1,tri.v2,Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID()));
55 }
56
57 /*! Test if the ray is occluded by one of the M triangles. */
58 static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& tri)
59 {
60 STAT3(shadow.trav_prims,1,1,1);
61 return intersec::intersect(ray,pre,tri.v0,tri.v1,tri.v2,Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID()));
62 }
63
64 static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri)
65 {
66 return PrimitivePointQuery1<Primitive>::pointQuery(query, context, tri);
67 }
68 };
69
70
71 /*! Intersects M triangles with K rays */
72 template<int M, int K, bool filter>
73 struct TriangleMvIntersectorKMoeller
74 {
75 typedef TriangleMv<M> Primitive;
76 typedef MoellerTrumboreIntersectorK<M,K> Precalculations;
77
78 /*! Intersects K rays with M triangles. */
79 static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const Primitive& tri)
80 {
81 for (size_t i=0; i<M; i++)
82 {
83 if (!tri.valid(i)) break;
84 STAT3(normal.trav_prims,1,popcnt(valid_i),K);
85 const Vec3vf<K> v0 = broadcast<vfloat<K>>(tri.v0,i);
86 const Vec3vf<K> v1 = broadcast<vfloat<K>>(tri.v1,i);
87 const Vec3vf<K> v2 = broadcast<vfloat<K>>(tri.v2,i);
88 pre.intersectK(valid_i,ray,v0,v1,v2,/*UVIdentity<K>(),*/IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i));
89 }
90 }
91
92 /*! Test for K rays if they are occluded by any of the M triangles. */
93 static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive& tri)
94 {
95 vbool<K> valid0 = valid_i;
96
97 for (size_t i=0; i<M; i++)
98 {
99 if (!tri.valid(i)) break;
100 STAT3(shadow.trav_prims,1,popcnt(valid_i),K);
101 const Vec3vf<K> v0 = broadcast<vfloat<K>>(tri.v0,i);
102 const Vec3vf<K> v1 = broadcast<vfloat<K>>(tri.v1,i);
103 const Vec3vf<K> v2 = broadcast<vfloat<K>>(tri.v2,i);
104 pre.intersectK(valid0,ray,v0,v1,v2,/*UVIdentity<K>(),*/OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i));
105 if (none(valid0)) break;
106 }
107 return !valid0;
108 }
109
110 /*! Intersect a ray with M triangles and updates the hit. */
111 static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive& tri)
112 {
113 STAT3(normal.trav_prims,1,1,1);
114 pre.intersect(ray,k,tri.v0,tri.v1,tri.v2,/*UVIdentity<M>(),*/Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); //FIXME: M
115 }
116
117 /*! Test if the ray is occluded by one of the M triangles. */
118 static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive& tri)
119 {
120 STAT3(shadow.trav_prims,1,1,1);
121 return pre.intersect(ray,k,tri.v0,tri.v1,tri.v2,/*UVIdentity<M>(),*/Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); //FIXME: M
122 }
123 };
124
125 /*! Intersects M triangles with 1 ray */
126 template<int M, bool filter>
127 struct TriangleMvIntersector1Pluecker
128 {
129 typedef TriangleMv<M> Primitive;
130 typedef PlueckerIntersector1<M> Precalculations;
131
132 /*! Intersect a ray with M triangles and updates the hit. */
133 static __forceinline void intersect(Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& tri)
134 {
135 STAT3(normal.trav_prims,1,1,1);
136 pre.intersect(ray,tri.v0,tri.v1,tri.v2,UVIdentity<M>(),Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID()));
137 }
138
139 /*! Test if the ray is occluded by one of the M triangles. */
140 static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& tri)
141 {
142 STAT3(shadow.trav_prims,1,1,1);
143 return pre.intersect(ray,tri.v0,tri.v1,tri.v2,UVIdentity<M>(),Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID()));
144 }
145
146 static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri)
147 {
148 return PrimitivePointQuery1<Primitive>::pointQuery(query, context, tri);
149 }
150 };
151
152 /*! Intersects M triangles with K rays */
153 template<int M, int K, bool filter>
154 struct TriangleMvIntersectorKPluecker
155 {
156 typedef TriangleMv<M> Primitive;
157 typedef PlueckerIntersectorK<M,K> Precalculations;
158
159 /*! Intersects K rays with M triangles. */
160 static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const Primitive& tri)
161 {
162 for (size_t i=0; i<M; i++)
163 {
164 if (!tri.valid(i)) break;
165 STAT3(normal.trav_prims,1,popcnt(valid_i),K);
166 const Vec3vf<K> v0 = broadcast<vfloat<K>>(tri.v0,i);
167 const Vec3vf<K> v1 = broadcast<vfloat<K>>(tri.v1,i);
168 const Vec3vf<K> v2 = broadcast<vfloat<K>>(tri.v2,i);
169 pre.intersectK(valid_i,ray,v0,v1,v2,UVIdentity<K>(),IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i));
170 }
171 }
172
173 /*! Test for K rays if they are occluded by any of the M triangles. */
174 static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive& tri)
175 {
176 vbool<K> valid0 = valid_i;
177
178 for (size_t i=0; i<M; i++)
179 {
180 if (!tri.valid(i)) break;
181 STAT3(shadow.trav_prims,1,popcnt(valid_i),K);
182 const Vec3vf<K> v0 = broadcast<vfloat<K>>(tri.v0,i);
183 const Vec3vf<K> v1 = broadcast<vfloat<K>>(tri.v1,i);
184 const Vec3vf<K> v2 = broadcast<vfloat<K>>(tri.v2,i);
185 pre.intersectK(valid0,ray,v0,v1,v2,UVIdentity<K>(),OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i));
186 if (none(valid0)) break;
187 }
188 return !valid0;
189 }
190
191 /*! Intersect a ray with M triangles and updates the hit. */
192 static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive& tri)
193 {
194 STAT3(normal.trav_prims,1,1,1);
195 pre.intersect(ray,k,tri.v0,tri.v1,tri.v2,UVIdentity<M>(),Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID()));
196 }
197
198 /*! Test if the ray is occluded by one of the M triangles. */
199 static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive& tri)
200 {
201 STAT3(shadow.trav_prims,1,1,1);
202 return pre.intersect(ray,k,tri.v0,tri.v1,tri.v2,UVIdentity<M>(),Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID()));
203 }
204 };
205 }
206}
207