Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/common/geometry.cpp
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#include "geometry.h"
5
#include "scene.h"
6
7
namespace embree
8
{
9
const char* Geometry::gtype_names[Geometry::GTY_END] =
10
{
11
"flat_linear_curve",
12
"round_linear_curve",
13
"oriented_linear_curve",
14
"",
15
"flat_bezier_curve",
16
"round_bezier_curve",
17
"oriented_bezier_curve",
18
"",
19
"flat_bspline_curve",
20
"round_bspline_curve",
21
"oriented_bspline_curve",
22
"",
23
"flat_hermite_curve",
24
"round_hermite_curve",
25
"oriented_hermite_curve",
26
"",
27
"flat_catmull_rom_curve",
28
"round_catmull_rom_curve",
29
"oriented_catmull_rom_curve",
30
"",
31
"triangles",
32
"quads",
33
"grid",
34
"subdivs",
35
"",
36
"sphere",
37
"disc",
38
"oriented_disc",
39
"",
40
"usergeom",
41
"instance_cheap",
42
"instance_expensive",
43
};
44
45
Geometry::Geometry (Device* device, GType gtype, unsigned int numPrimitives, unsigned int numTimeSteps)
46
: device(device), userPtr(nullptr),
47
numPrimitives(numPrimitives), numTimeSteps(unsigned(numTimeSteps)), fnumTimeSegments(float(numTimeSteps-1)), time_range(0.0f,1.0f),
48
mask(1),
49
gtype(gtype),
50
gsubtype(GTY_SUBTYPE_DEFAULT),
51
quality(RTC_BUILD_QUALITY_MEDIUM),
52
state((unsigned)State::MODIFIED),
53
enabled(true),
54
argumentFilterEnabled(false),
55
intersectionFilterN(nullptr), occlusionFilterN(nullptr), pointQueryFunc(nullptr)
56
{
57
device->refInc();
58
}
59
60
Geometry::~Geometry()
61
{
62
device->refDec();
63
}
64
65
void Geometry::setNumPrimitives(unsigned int numPrimitives_in)
66
{
67
if (numPrimitives_in == numPrimitives) return;
68
69
numPrimitives = numPrimitives_in;
70
71
Geometry::update();
72
}
73
74
void Geometry::setNumTimeSteps (unsigned int numTimeSteps_in)
75
{
76
if (numTimeSteps_in == numTimeSteps) {
77
return;
78
}
79
80
numTimeSteps = numTimeSteps_in;
81
fnumTimeSegments = float(numTimeSteps_in-1);
82
83
Geometry::update();
84
}
85
86
void Geometry::setTimeRange (const BBox1f range)
87
{
88
time_range = range;
89
Geometry::update();
90
}
91
92
BBox1f Geometry::getTimeRange () const
93
{
94
return time_range;
95
}
96
97
void Geometry::update()
98
{
99
++modCounter_; // FIXME: required?
100
state = (unsigned)State::MODIFIED;
101
}
102
103
void Geometry::commit()
104
{
105
++modCounter_;
106
state = (unsigned)State::COMMITTED;
107
}
108
109
void Geometry::preCommit()
110
{
111
if (State::MODIFIED == (State)state)
112
throw_RTCError(RTC_ERROR_INVALID_OPERATION,"geometry not committed");
113
}
114
115
void Geometry::postCommit()
116
{
117
}
118
119
void Geometry::enable ()
120
{
121
if (isEnabled())
122
return;
123
124
enabled = true;
125
++modCounter_;
126
}
127
128
void Geometry::disable ()
129
{
130
if (isDisabled())
131
return;
132
133
enabled = false;
134
++modCounter_;
135
}
136
137
void Geometry::setUserData (void* ptr)
138
{
139
userPtr = ptr;
140
}
141
142
void Geometry::setIntersectionFilterFunctionN (RTCFilterFunctionN filter)
143
{
144
if (!(getTypeMask() & (MTY_TRIANGLE_MESH | MTY_QUAD_MESH | MTY_CURVES | MTY_SUBDIV_MESH | MTY_USER_GEOMETRY | MTY_GRID_MESH)))
145
throw_RTCError(RTC_ERROR_INVALID_OPERATION,"filter functions not supported for this geometry");
146
147
intersectionFilterN = filter;
148
}
149
150
void Geometry::setOcclusionFilterFunctionN (RTCFilterFunctionN filter)
151
{
152
if (!(getTypeMask() & (MTY_TRIANGLE_MESH | MTY_QUAD_MESH | MTY_CURVES | MTY_SUBDIV_MESH | MTY_USER_GEOMETRY | MTY_GRID_MESH)))
153
throw_RTCError(RTC_ERROR_INVALID_OPERATION,"filter functions not supported for this geometry");
154
155
occlusionFilterN = filter;
156
}
157
158
void Geometry::setPointQueryFunction (RTCPointQueryFunction func)
159
{
160
pointQueryFunc = func;
161
}
162
163
void Geometry::interpolateN(const RTCInterpolateNArguments* const args)
164
{
165
const void* valid_i = args->valid;
166
const unsigned* primIDs = args->primIDs;
167
const float* u = args->u;
168
const float* v = args->v;
169
unsigned int N = args->N;
170
RTCBufferType bufferType = args->bufferType;
171
unsigned int bufferSlot = args->bufferSlot;
172
float* P = args->P;
173
float* dPdu = args->dPdu;
174
float* dPdv = args->dPdv;
175
float* ddPdudu = args->ddPdudu;
176
float* ddPdvdv = args->ddPdvdv;
177
float* ddPdudv = args->ddPdudv;
178
unsigned int valueCount = args->valueCount;
179
180
if (valueCount > 256) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"maximally 256 floating point values can be interpolated per vertex");
181
const int* valid = (const int*) valid_i;
182
183
__aligned(64) float P_tmp[256];
184
__aligned(64) float dPdu_tmp[256];
185
__aligned(64) float dPdv_tmp[256];
186
__aligned(64) float ddPdudu_tmp[256];
187
__aligned(64) float ddPdvdv_tmp[256];
188
__aligned(64) float ddPdudv_tmp[256];
189
190
float* Pt = P ? P_tmp : nullptr;
191
float* dPdut = nullptr, *dPdvt = nullptr;
192
if (dPdu) { dPdut = dPdu_tmp; dPdvt = dPdv_tmp; }
193
float* ddPdudut = nullptr, *ddPdvdvt = nullptr, *ddPdudvt = nullptr;
194
if (ddPdudu) { ddPdudut = ddPdudu_tmp; ddPdvdvt = ddPdvdv_tmp; ddPdudvt = ddPdudv_tmp; }
195
196
for (unsigned int i=0; i<N; i++)
197
{
198
if (valid && !valid[i]) continue;
199
200
RTCInterpolateArguments iargs;
201
iargs.primID = primIDs[i];
202
iargs.u = u[i];
203
iargs.v = v[i];
204
iargs.bufferType = bufferType;
205
iargs.bufferSlot = bufferSlot;
206
iargs.P = Pt;
207
iargs.dPdu = dPdut;
208
iargs.dPdv = dPdvt;
209
iargs.ddPdudu = ddPdudut;
210
iargs.ddPdvdv = ddPdvdvt;
211
iargs.ddPdudv = ddPdudvt;
212
iargs.valueCount = valueCount;
213
interpolate(&iargs);
214
215
if (likely(P)) {
216
for (unsigned int j=0; j<valueCount; j++)
217
P[j*N+i] = Pt[j];
218
}
219
if (likely(dPdu))
220
{
221
for (unsigned int j=0; j<valueCount; j++) {
222
dPdu[j*N+i] = dPdut[j];
223
dPdv[j*N+i] = dPdvt[j];
224
}
225
}
226
if (likely(ddPdudu))
227
{
228
for (unsigned int j=0; j<valueCount; j++) {
229
ddPdudu[j*N+i] = ddPdudut[j];
230
ddPdvdv[j*N+i] = ddPdvdvt[j];
231
ddPdudv[j*N+i] = ddPdudvt[j];
232
}
233
}
234
}
235
}
236
237
bool Geometry::pointQuery(PointQuery* query, PointQueryContext* context)
238
{
239
assert(context->primID < size());
240
241
RTCPointQueryFunctionArguments args;
242
args.query = (RTCPointQuery*)context->query_ws;
243
args.userPtr = context->userPtr;
244
args.primID = context->primID;
245
args.geomID = context->geomID;
246
args.context = context->userContext;
247
args.similarityScale = context->similarityScale;
248
249
bool update = false;
250
if(context->func) update |= context->func(&args);
251
if(pointQueryFunc) update |= pointQueryFunc(&args);
252
253
if (update && context->userContext->instStackSize > 0)
254
{
255
// update point query
256
if (context->query_type == POINT_QUERY_TYPE_AABB) {
257
context->updateAABB();
258
} else {
259
assert(context->similarityScale > 0.f);
260
query->radius = context->query_ws->radius * context->similarityScale;
261
}
262
}
263
return update;
264
}
265
}
266
267