Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/builders/splitter.h
9912 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#if !defined(RTHWIF_STANDALONE)
7
#include "../common/scene.h"
8
#endif
9
10
#include "../builders/primref.h"
11
12
namespace embree
13
{
14
namespace isa
15
{
16
template<size_t N>
17
__forceinline void splitPolygon(const BBox3fa& bounds,
18
const size_t dim,
19
const float pos,
20
const Vec3fa (&v)[N+1],
21
BBox3fa& left_o,
22
BBox3fa& right_o)
23
{
24
BBox3fa left = empty, right = empty;
25
/* clip triangle to left and right box by processing all edges */
26
for (size_t i=0; i<N; i++)
27
{
28
const Vec3fa &v0 = v[i];
29
const Vec3fa &v1 = v[i+1];
30
const float v0d = v0[dim];
31
const float v1d = v1[dim];
32
33
if (v0d <= pos) left. extend(v0); // this point is on left side
34
if (v0d >= pos) right.extend(v0); // this point is on right side
35
36
if ((v0d < pos && pos < v1d) || (v1d < pos && pos < v0d)) // the edge crosses the splitting location
37
{
38
assert((v1d-v0d) != 0.0f);
39
const float inv_length = 1.0f/(v1d-v0d);
40
const Vec3fa c = madd(Vec3fa((pos-v0d)*inv_length),v1-v0,v0);
41
left.extend(c);
42
right.extend(c);
43
}
44
}
45
46
/* clip against current bounds */
47
left_o = intersect(left,bounds);
48
right_o = intersect(right,bounds);
49
}
50
51
template<size_t N>
52
__forceinline void splitPolygon(const BBox3fa& bounds,
53
const size_t dim,
54
const float pos,
55
const Vec3fa (&v)[N+1],
56
const Vec3fa (&inv_length)[N],
57
BBox3fa& left_o,
58
BBox3fa& right_o)
59
{
60
BBox3fa left = empty, right = empty;
61
/* clip triangle to left and right box by processing all edges */
62
for (size_t i=0; i<N; i++)
63
{
64
const Vec3fa &v0 = v[i];
65
const Vec3fa &v1 = v[i+1];
66
const float v0d = v0[dim];
67
const float v1d = v1[dim];
68
69
if (v0d <= pos) left. extend(v0); // this point is on left side
70
if (v0d >= pos) right.extend(v0); // this point is on right side
71
72
if ((v0d < pos && pos < v1d) || (v1d < pos && pos < v0d)) // the edge crosses the splitting location
73
{
74
assert((v1d-v0d) != 0.0f);
75
const Vec3fa c = madd(Vec3fa((pos-v0d)*inv_length[i][dim]),v1-v0,v0);
76
left.extend(c);
77
right.extend(c);
78
}
79
}
80
81
/* clip against current bounds */
82
left_o = intersect(left,bounds);
83
right_o = intersect(right,bounds);
84
}
85
86
template<size_t N>
87
__forceinline void splitPolygon(const PrimRef& prim,
88
const size_t dim,
89
const float pos,
90
const Vec3fa (&v)[N+1],
91
PrimRef& left_o,
92
PrimRef& right_o)
93
{
94
BBox3fa left = empty, right = empty;
95
for (size_t i=0; i<N; i++)
96
{
97
const Vec3fa &v0 = v[i];
98
const Vec3fa &v1 = v[i+1];
99
const float v0d = v0[dim];
100
const float v1d = v1[dim];
101
102
if (v0d <= pos) left. extend(v0); // this point is on left side
103
if (v0d >= pos) right.extend(v0); // this point is on right side
104
105
if ((v0d < pos && pos < v1d) || (v1d < pos && pos < v0d)) // the edge crosses the splitting location
106
{
107
assert((v1d-v0d) != 0.0f);
108
const float inv_length = 1.0f/(v1d-v0d);
109
const Vec3fa c = madd(Vec3fa((pos-v0d)*inv_length),v1-v0,v0);
110
left.extend(c);
111
right.extend(c);
112
}
113
}
114
115
/* clip against current bounds */
116
new (&left_o ) PrimRef(intersect(left ,prim.bounds()),prim.geomID(), prim.primID());
117
new (&right_o) PrimRef(intersect(right,prim.bounds()),prim.geomID(), prim.primID());
118
}
119
120
#if !defined(RTHWIF_STANDALONE)
121
122
struct TriangleSplitter
123
{
124
__forceinline TriangleSplitter(const Scene* scene, const PrimRef& prim)
125
{
126
const unsigned int mask = 0xFFFFFFFF >> RESERVED_NUM_SPATIAL_SPLITS_GEOMID_BITS;
127
const TriangleMesh* mesh = (const TriangleMesh*) scene->get(prim.geomID() & mask );
128
TriangleMesh::Triangle tri = mesh->triangle(prim.primID());
129
v[0] = mesh->vertex(tri.v[0]);
130
v[1] = mesh->vertex(tri.v[1]);
131
v[2] = mesh->vertex(tri.v[2]);
132
v[3] = mesh->vertex(tri.v[0]);
133
inv_length[0] = Vec3fa(1.0f) / (v[1]-v[0]);
134
inv_length[1] = Vec3fa(1.0f) / (v[2]-v[1]);
135
inv_length[2] = Vec3fa(1.0f) / (v[0]-v[2]);
136
}
137
138
__forceinline void operator() (const PrimRef& prim, const size_t dim, const float pos, PrimRef& left_o, PrimRef& right_o) const {
139
splitPolygon<3>(prim,dim,pos,v,left_o,right_o);
140
}
141
142
__forceinline void operator() (const BBox3fa& prim, const size_t dim, const float pos, BBox3fa& left_o, BBox3fa& right_o) const {
143
splitPolygon<3>(prim,dim,pos,v,inv_length,left_o,right_o);
144
}
145
146
private:
147
Vec3fa v[4];
148
Vec3fa inv_length[3];
149
};
150
151
struct TriangleSplitterFactory
152
{
153
__forceinline TriangleSplitterFactory(const Scene* scene)
154
: scene(scene) {}
155
156
__forceinline TriangleSplitter operator() (const PrimRef& prim) const {
157
return TriangleSplitter(scene,prim);
158
}
159
160
private:
161
const Scene* scene;
162
};
163
164
struct QuadSplitter
165
{
166
__forceinline QuadSplitter(const Scene* scene, const PrimRef& prim)
167
{
168
const unsigned int mask = 0xFFFFFFFF >> RESERVED_NUM_SPATIAL_SPLITS_GEOMID_BITS;
169
const QuadMesh* mesh = (const QuadMesh*) scene->get(prim.geomID() & mask );
170
QuadMesh::Quad quad = mesh->quad(prim.primID());
171
v[0] = mesh->vertex(quad.v[1]);
172
v[1] = mesh->vertex(quad.v[2]);
173
v[2] = mesh->vertex(quad.v[3]);
174
v[3] = mesh->vertex(quad.v[0]);
175
v[4] = mesh->vertex(quad.v[1]);
176
v[5] = mesh->vertex(quad.v[3]);
177
inv_length[0] = Vec3fa(1.0f) / (v[1] - v[0]);
178
inv_length[1] = Vec3fa(1.0f) / (v[2] - v[1]);
179
inv_length[2] = Vec3fa(1.0f) / (v[3] - v[2]);
180
inv_length[3] = Vec3fa(1.0f) / (v[4] - v[3]);
181
inv_length[4] = Vec3fa(1.0f) / (v[5] - v[4]);
182
}
183
184
__forceinline void operator() (const PrimRef& prim, const size_t dim, const float pos, PrimRef& left_o, PrimRef& right_o) const {
185
splitPolygon<5>(prim,dim,pos,v,left_o,right_o);
186
}
187
188
__forceinline void operator() (const BBox3fa& prim, const size_t dim, const float pos, BBox3fa& left_o, BBox3fa& right_o) const {
189
splitPolygon<5>(prim,dim,pos,v,inv_length,left_o,right_o);
190
}
191
192
private:
193
Vec3fa v[6];
194
Vec3fa inv_length[5];
195
};
196
197
struct QuadSplitterFactory
198
{
199
__forceinline QuadSplitterFactory(const Scene* scene)
200
: scene(scene) {}
201
202
__forceinline QuadSplitter operator() (const PrimRef& prim) const {
203
return QuadSplitter(scene,prim);
204
}
205
206
private:
207
const Scene* scene;
208
};
209
210
211
struct DummySplitter
212
{
213
__forceinline DummySplitter(const Scene* scene, const PrimRef& prim)
214
{
215
}
216
217
__forceinline void operator() (const PrimRef& prim, const size_t dim, const float pos, PrimRef& left_o, PrimRef& right_o) const {
218
}
219
220
__forceinline void operator() (const BBox3fa& prim, const size_t dim, const float pos, BBox3fa& left_o, BBox3fa& right_o) const {
221
}
222
223
};
224
225
struct DummySplitterFactory
226
{
227
__forceinline DummySplitterFactory(const Scene* scene)
228
: scene(scene) {}
229
230
__forceinline DummySplitter operator() (const PrimRef& prim) const {
231
return DummySplitter(scene,prim);
232
}
233
234
private:
235
const Scene* scene;
236
};
237
#endif
238
}
239
}
240
241
242