1// Copyright 2009-2021 Intel Corporation
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include "../common/geometry.h"
7#include "../common/ray.h"
8#include "../common/hit.h"
9#include "../common/context.h"
10
11namespace embree
12{
13 namespace isa
14 {
15 __forceinline bool runIntersectionFilter1Helper(RTCFilterFunctionNArguments* args, const Geometry* const geometry, IntersectContext* context)
16 {
17 if (geometry->intersectionFilterN)
18 {
19 assert(context->scene->hasGeometryFilterFunction());
20 geometry->intersectionFilterN(args);
21
22 if (args->valid[0] == 0)
23 return false;
24 }
25
26 if (context->user->filter) {
27 assert(context->scene->hasContextFilterFunction());
28 context->user->filter(args);
29
30 if (args->valid[0] == 0)
31 return false;
32 }
33
34 copyHitToRay(*(RayHit*)args->ray,*(Hit*)args->hit);
35 return true;
36 }
37
38 __forceinline bool runIntersectionFilter1(const Geometry* const geometry, RayHit& ray, IntersectContext* context, Hit& hit)
39 {
40 RTCFilterFunctionNArguments args;
41 int mask = -1;
42 args.valid = &mask;
43 args.geometryUserPtr = geometry->userPtr;
44 args.context = context->user;
45 args.ray = (RTCRayN*)&ray;
46 args.hit = (RTCHitN*)&hit;
47 args.N = 1;
48 return runIntersectionFilter1Helper(&args,geometry,context);
49 }
50
51 __forceinline void reportIntersection1(IntersectFunctionNArguments* args, const RTCFilterFunctionNArguments* filter_args)
52 {
53#if defined(EMBREE_FILTER_FUNCTION)
54 if (args->geometry->intersectionFilterN)
55 args->geometry->intersectionFilterN(filter_args);
56
57 if (args->context->filter)
58 args->context->filter(filter_args);
59#endif
60 }
61
62 __forceinline bool runOcclusionFilter1Helper(RTCFilterFunctionNArguments* args, const Geometry* const geometry, IntersectContext* context)
63 {
64 if (geometry->occlusionFilterN)
65 {
66 assert(context->scene->hasGeometryFilterFunction());
67 geometry->occlusionFilterN(args);
68
69 if (args->valid[0] == 0)
70 return false;
71 }
72
73 if (context->user->filter) {
74 assert(context->scene->hasContextFilterFunction());
75 context->user->filter(args);
76
77 if (args->valid[0] == 0)
78 return false;
79 }
80 return true;
81 }
82
83 __forceinline bool runOcclusionFilter1(const Geometry* const geometry, Ray& ray, IntersectContext* context, Hit& hit)
84 {
85 RTCFilterFunctionNArguments args;
86 int mask = -1;
87 args.valid = &mask;
88 args.geometryUserPtr = geometry->userPtr;
89 args.context = context->user;
90 args.ray = (RTCRayN*)&ray;
91 args.hit = (RTCHitN*)&hit;
92 args.N = 1;
93 return runOcclusionFilter1Helper(&args,geometry,context);
94 }
95
96 __forceinline void reportOcclusion1(OccludedFunctionNArguments* args, const RTCFilterFunctionNArguments* filter_args)
97 {
98#if defined(EMBREE_FILTER_FUNCTION)
99 if (args->geometry->occlusionFilterN)
100 args->geometry->occlusionFilterN(filter_args);
101
102 if (args->context->filter)
103 args->context->filter(filter_args);
104#endif
105 }
106
107 template<int K>
108 __forceinline vbool<K> runIntersectionFilterHelper(RTCFilterFunctionNArguments* args, const Geometry* const geometry, IntersectContext* context)
109 {
110 vint<K>* mask = (vint<K>*) args->valid;
111 if (geometry->intersectionFilterN)
112 {
113 assert(context->scene->hasGeometryFilterFunction());
114 geometry->intersectionFilterN(args);
115 }
116
117 vbool<K> valid_o = *mask != vint<K>(zero);
118 if (none(valid_o)) return valid_o;
119
120 if (context->user->filter) {
121 assert(context->scene->hasContextFilterFunction());
122 context->user->filter(args);
123 }
124
125 valid_o = *mask != vint<K>(zero);
126 if (none(valid_o)) return valid_o;
127
128 copyHitToRay(valid_o,*(RayHitK<K>*)args->ray,*(HitK<K>*)args->hit);
129 return valid_o;
130 }
131
132 template<int K>
133 __forceinline vbool<K> runIntersectionFilter(const vbool<K>& valid, const Geometry* const geometry, RayHitK<K>& ray, IntersectContext* context, HitK<K>& hit)
134 {
135 RTCFilterFunctionNArguments args;
136 vint<K> mask = valid.mask32();
137 args.valid = (int*)&mask;
138 args.geometryUserPtr = geometry->userPtr;
139 args.context = context->user;
140 args.ray = (RTCRayN*)&ray;
141 args.hit = (RTCHitN*)&hit;
142 args.N = K;
143 return runIntersectionFilterHelper<K>(&args,geometry,context);
144 }
145
146 template<int K>
147 __forceinline vbool<K> runOcclusionFilterHelper(RTCFilterFunctionNArguments* args, const Geometry* const geometry, IntersectContext* context)
148 {
149 vint<K>* mask = (vint<K>*) args->valid;
150 if (geometry->occlusionFilterN)
151 {
152 assert(context->scene->hasGeometryFilterFunction());
153 geometry->occlusionFilterN(args);
154 }
155
156 vbool<K> valid_o = *mask != vint<K>(zero);
157
158 if (none(valid_o)) return valid_o;
159
160 if (context->user->filter) {
161 assert(context->scene->hasContextFilterFunction());
162 context->user->filter(args);
163 }
164
165 valid_o = *mask != vint<K>(zero);
166
167 RayK<K>* ray = (RayK<K>*) args->ray;
168 ray->tfar = select(valid_o, vfloat<K>(neg_inf), ray->tfar);
169 return valid_o;
170 }
171
172 template<int K>
173 __forceinline vbool<K> runOcclusionFilter(const vbool<K>& valid, const Geometry* const geometry, RayK<K>& ray, IntersectContext* context, HitK<K>& hit)
174 {
175 RTCFilterFunctionNArguments args;
176 vint<K> mask = valid.mask32();
177 args.valid = (int*)&mask;
178 args.geometryUserPtr = geometry->userPtr;
179 args.context = context->user;
180 args.ray = (RTCRayN*)&ray;
181 args.hit = (RTCHitN*)&hit;
182 args.N = K;
183 return runOcclusionFilterHelper<K>(&args,geometry,context);
184 }
185 }
186}
187