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