Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/geometry/quadv_intersector.h
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "quadv.h"
7
#include "quad_intersector_moeller.h"
8
#include "quad_intersector_pluecker.h"
9
10
namespace embree
11
{
12
namespace isa
13
{
14
/*! Intersects M quads with 1 ray */
15
template<int M, bool filter>
16
struct QuadMvIntersector1Moeller
17
{
18
typedef QuadMv<M> Primitive;
19
typedef QuadMIntersector1MoellerTrumbore<M,filter> Precalculations;
20
21
/*! Intersect a ray with the M quads and updates the hit. */
22
static __forceinline void intersect(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& quad)
23
{
24
STAT3(normal.trav_prims,1,1,1);
25
pre.intersect(ray,context,quad.v0,quad.v1,quad.v2,quad.v3,quad.geomID(),quad.primID());
26
}
27
28
/*! Test if the ray is occluded by one of M quads. */
29
static __forceinline bool occluded(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& quad)
30
{
31
STAT3(shadow.trav_prims,1,1,1);
32
return pre.occluded(ray,context, quad.v0,quad.v1,quad.v2,quad.v3,quad.geomID(),quad.primID());
33
}
34
35
static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& quad)
36
{
37
return PrimitivePointQuery1<Primitive>::pointQuery(query, context, quad);
38
}
39
};
40
41
/*! Intersects M triangles with K rays. */
42
template<int M, int K, bool filter>
43
struct QuadMvIntersectorKMoeller
44
{
45
typedef QuadMv<M> Primitive;
46
typedef QuadMIntersectorKMoellerTrumbore<M,K,filter> Precalculations;
47
48
/*! Intersects K rays with M triangles. */
49
static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, RayQueryContext* context, const QuadMv<M>& quad)
50
{
51
for (size_t i=0; i<QuadMv<M>::max_size(); i++)
52
{
53
if (!quad.valid(i)) break;
54
STAT3(normal.trav_prims,1,popcnt(valid_i),K);
55
const Vec3vf<K> p0 = broadcast<vfloat<K>>(quad.v0,i);
56
const Vec3vf<K> p1 = broadcast<vfloat<K>>(quad.v1,i);
57
const Vec3vf<K> p2 = broadcast<vfloat<K>>(quad.v2,i);
58
const Vec3vf<K> p3 = broadcast<vfloat<K>>(quad.v3,i);
59
pre.intersectK(valid_i,ray,p0,p1,p2,p3,IntersectKEpilogM<M,K,filter>(ray,context,quad.geomID(),quad.primID(),i));
60
}
61
}
62
63
/*! Test for K rays if they are occluded by any of the M triangles. */
64
static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, RayQueryContext* context, const QuadMv<M>& quad)
65
{
66
vbool<K> valid0 = valid_i;
67
68
for (size_t i=0; i<QuadMv<M>::max_size(); i++)
69
{
70
if (!quad.valid(i)) break;
71
STAT3(shadow.trav_prims,1,popcnt(valid0),K);
72
const Vec3vf<K> p0 = broadcast<vfloat<K>>(quad.v0,i);
73
const Vec3vf<K> p1 = broadcast<vfloat<K>>(quad.v1,i);
74
const Vec3vf<K> p2 = broadcast<vfloat<K>>(quad.v2,i);
75
const Vec3vf<K> p3 = broadcast<vfloat<K>>(quad.v3,i);
76
if (pre.intersectK(valid0,ray,p0,p1,p2,p3,OccludedKEpilogM<M,K,filter>(valid0,ray,context,quad.geomID(),quad.primID(),i)))
77
break;
78
}
79
return !valid0;
80
}
81
82
/*! Intersect a ray with M triangles and updates the hit. */
83
static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, RayQueryContext* context, const QuadMv<M>& quad)
84
{
85
STAT3(normal.trav_prims,1,1,1);
86
pre.intersect1(ray,k,context,quad.v0,quad.v1,quad.v2,quad.v3,quad.geomID(),quad.primID());
87
}
88
89
/*! Test if the ray is occluded by one of the M triangles. */
90
static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, RayQueryContext* context, const QuadMv<M>& quad)
91
{
92
STAT3(shadow.trav_prims,1,1,1);
93
return pre.occluded1(ray,k,context,quad.v0,quad.v1,quad.v2,quad.v3,quad.geomID(),quad.primID());
94
}
95
};
96
97
/*! Intersects M quads with 1 ray */
98
template<int M, bool filter>
99
struct QuadMvIntersector1Pluecker
100
{
101
typedef QuadMv<M> Primitive;
102
typedef QuadMIntersector1Pluecker<M,filter> Precalculations;
103
104
/*! Intersect a ray with the M quads and updates the hit. */
105
static __forceinline void intersect(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& quad)
106
{
107
STAT3(normal.trav_prims,1,1,1);
108
pre.intersect(ray,context,quad.v0,quad.v1,quad.v2,quad.v3,quad.geomID(),quad.primID());
109
}
110
111
/*! Test if the ray is occluded by one of M quads. */
112
static __forceinline bool occluded(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& quad)
113
{
114
STAT3(shadow.trav_prims,1,1,1);
115
return pre.occluded(ray,context, quad.v0,quad.v1,quad.v2,quad.v3,quad.geomID(),quad.primID());
116
}
117
118
static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& quad)
119
{
120
return PrimitivePointQuery1<Primitive>::pointQuery(query, context, quad);
121
}
122
};
123
124
/*! Intersects M triangles with K rays. */
125
template<int M, int K, bool filter>
126
struct QuadMvIntersectorKPluecker
127
{
128
typedef QuadMv<M> Primitive;
129
typedef QuadMIntersectorKPluecker<M,K,filter> Precalculations;
130
131
/*! Intersects K rays with M triangles. */
132
static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, RayQueryContext* context, const QuadMv<M>& quad)
133
{
134
for (size_t i=0; i<QuadMv<M>::max_size(); i++)
135
{
136
if (!quad.valid(i)) break;
137
STAT3(normal.trav_prims,1,popcnt(valid_i),K);
138
const Vec3vf<K> p0 = broadcast<vfloat<K>>(quad.v0,i);
139
const Vec3vf<K> p1 = broadcast<vfloat<K>>(quad.v1,i);
140
const Vec3vf<K> p2 = broadcast<vfloat<K>>(quad.v2,i);
141
const Vec3vf<K> p3 = broadcast<vfloat<K>>(quad.v3,i);
142
pre.intersectK(valid_i,ray,p0,p1,p2,p3,IntersectKEpilogM<M,K,filter>(ray,context,quad.geomID(),quad.primID(),i));
143
}
144
}
145
146
/*! Test for K rays if they are occluded by any of the M triangles. */
147
static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, RayQueryContext* context, const QuadMv<M>& quad)
148
{
149
vbool<K> valid0 = valid_i;
150
151
for (size_t i=0; i<QuadMv<M>::max_size(); i++)
152
{
153
if (!quad.valid(i)) break;
154
STAT3(shadow.trav_prims,1,popcnt(valid0),K);
155
const Vec3vf<K> p0 = broadcast<vfloat<K>>(quad.v0,i);
156
const Vec3vf<K> p1 = broadcast<vfloat<K>>(quad.v1,i);
157
const Vec3vf<K> p2 = broadcast<vfloat<K>>(quad.v2,i);
158
const Vec3vf<K> p3 = broadcast<vfloat<K>>(quad.v3,i);
159
if (pre.intersectK(valid0,ray,p0,p1,p2,p3,OccludedKEpilogM<M,K,filter>(valid0,ray,context,quad.geomID(),quad.primID(),i)))
160
break;
161
}
162
return !valid0;
163
}
164
165
/*! Intersect a ray with M triangles and updates the hit. */
166
static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, RayQueryContext* context, const QuadMv<M>& quad)
167
{
168
STAT3(normal.trav_prims,1,1,1);
169
pre.intersect1(ray,k,context,quad.v0,quad.v1,quad.v2,quad.v3,quad.geomID(),quad.primID());
170
}
171
172
/*! Test if the ray is occluded by one of the M triangles. */
173
static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, RayQueryContext* context, const QuadMv<M>& quad)
174
{
175
STAT3(shadow.trav_prims,1,1,1);
176
return pre.occluded1(ray,k,context,quad.v0,quad.v1,quad.v2,quad.v3,quad.geomID(),quad.primID());
177
}
178
};
179
}
180
}
181
182
183