Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/common/scene_triangle_mesh.h
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "geometry.h"
7
#include "buffer.h"
8
9
namespace embree
10
{
11
/*! Triangle Mesh */
12
struct TriangleMesh : public Geometry
13
{
14
/*! type of this geometry */
15
static const Geometry::GTypeMask geom_type = Geometry::MTY_TRIANGLE_MESH;
16
17
/*! triangle indices */
18
struct Triangle
19
{
20
uint32_t v[3];
21
22
/*! outputs triangle indices */
23
__forceinline friend embree_ostream operator<<(embree_ostream cout, const Triangle& t) {
24
return cout << "Triangle { " << t.v[0] << ", " << t.v[1] << ", " << t.v[2] << " }";
25
}
26
};
27
28
public:
29
30
/*! triangle mesh construction */
31
TriangleMesh (Device* device);
32
33
/* geometry interface */
34
public:
35
virtual void setMask(unsigned mask) override;
36
virtual void setNumTimeSteps (unsigned int numTimeSteps) override;
37
virtual void setVertexAttributeCount (unsigned int N) override;
38
virtual void setBuffer(RTCBufferType type, unsigned int slot, RTCFormat format, const Ref<Buffer>& buffer, size_t offset, size_t stride, unsigned int num) override;
39
virtual void* getBufferData(RTCBufferType type, unsigned int slot, BufferDataPointerType pointerType) override;
40
virtual void updateBuffer(RTCBufferType type, unsigned int slot) override;
41
virtual void commit() override;
42
virtual bool verify() override;
43
virtual void interpolate(const RTCInterpolateArguments* const args) override;
44
virtual void addElementsToCount (GeometryCounts & counts) const override;
45
virtual size_t getGeometryDataDeviceByteSize() const override;
46
virtual void convertToDeviceRepresentation(size_t offset, char* data_host, char* data_device) const override;
47
48
template<int N>
49
void interpolate_impl(const RTCInterpolateArguments* const args)
50
{
51
unsigned int primID = args->primID;
52
float u = args->u;
53
float v = args->v;
54
RTCBufferType bufferType = args->bufferType;
55
unsigned int bufferSlot = args->bufferSlot;
56
float* P = args->P;
57
float* dPdu = args->dPdu;
58
float* dPdv = args->dPdv;
59
float* ddPdudu = args->ddPdudu;
60
float* ddPdvdv = args->ddPdvdv;
61
float* ddPdudv = args->ddPdudv;
62
unsigned int valueCount = args->valueCount;
63
64
/* calculate base pointer and stride */
65
assert((bufferType == RTC_BUFFER_TYPE_VERTEX && bufferSlot < numTimeSteps) ||
66
(bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE && bufferSlot <= vertexAttribs.size()));
67
const char* src = nullptr;
68
size_t stride = 0;
69
if (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) {
70
src = vertexAttribs[bufferSlot].getPtr();
71
stride = vertexAttribs[bufferSlot].getStride();
72
} else {
73
src = vertices[bufferSlot].getPtr();
74
stride = vertices[bufferSlot].getStride();
75
}
76
77
for (unsigned int i=0; i<valueCount; i+=N)
78
{
79
size_t ofs = i*sizeof(float);
80
const float w = 1.0f-u-v;
81
const Triangle& tri = triangle(primID);
82
const vbool<N> valid = vint<N>((int)i)+vint<N>(step) < vint<N>(int(valueCount));
83
const vfloat<N> p0 = mem<vfloat<N>>::loadu(valid,(float*)&src[tri.v[0]*stride+ofs]);
84
const vfloat<N> p1 = mem<vfloat<N>>::loadu(valid,(float*)&src[tri.v[1]*stride+ofs]);
85
const vfloat<N> p2 = mem<vfloat<N>>::loadu(valid,(float*)&src[tri.v[2]*stride+ofs]);
86
87
if (P) {
88
mem<vfloat<N>>::storeu(valid,P+i,madd(w,p0,madd(u,p1,v*p2)));
89
}
90
if (dPdu) {
91
assert(dPdu); mem<vfloat<N>>::storeu(valid,dPdu+i,p1-p0);
92
assert(dPdv); mem<vfloat<N>>::storeu(valid,dPdv+i,p2-p0);
93
}
94
if (ddPdudu) {
95
assert(ddPdudu); mem<vfloat<N>>::storeu(valid,ddPdudu+i,vfloat<N>(zero));
96
assert(ddPdvdv); mem<vfloat<N>>::storeu(valid,ddPdvdv+i,vfloat<N>(zero));
97
assert(ddPdudv); mem<vfloat<N>>::storeu(valid,ddPdudv+i,vfloat<N>(zero));
98
}
99
}
100
}
101
102
public:
103
104
/*! returns number of vertices */
105
__forceinline size_t numVertices() const {
106
return vertices[0].size();
107
}
108
109
/*! returns i'th triangle*/
110
__forceinline const Triangle& triangle(size_t i) const {
111
return triangles[i];
112
}
113
114
/*! returns i'th vertex of the first time step */
115
__forceinline const Vec3fa vertex(size_t i) const {
116
return vertices0[i];
117
}
118
119
/*! returns i'th vertex of the first time step */
120
__forceinline const char* vertexPtr(size_t i) const {
121
return vertices0.getPtr(i);
122
}
123
124
/*! returns i'th vertex of itime'th timestep */
125
__forceinline const Vec3fa vertex(size_t i, size_t itime) const {
126
return vertices[itime][i];
127
}
128
129
/*! returns i'th vertex of itime'th timestep */
130
__forceinline const char* vertexPtr(size_t i, size_t itime) const {
131
return vertices[itime].getPtr(i);
132
}
133
134
/*! returns i'th vertex of for specified time */
135
__forceinline Vec3fa vertex(size_t i, float time) const
136
{
137
float ftime;
138
const size_t itime = timeSegment(time, ftime);
139
const float t0 = 1.0f - ftime;
140
const float t1 = ftime;
141
Vec3fa v0 = vertex(i, itime+0);
142
Vec3fa v1 = vertex(i, itime+1);
143
return madd(Vec3fa(t0),v0,t1*v1);
144
}
145
146
/*! calculates the bounds of the i'th triangle */
147
__forceinline BBox3fa bounds(size_t i) const
148
{
149
const Triangle& tri = triangle(i);
150
const Vec3fa v0 = vertex(tri.v[0]);
151
const Vec3fa v1 = vertex(tri.v[1]);
152
const Vec3fa v2 = vertex(tri.v[2]);
153
return BBox3fa(min(v0,v1,v2),max(v0,v1,v2));
154
}
155
156
/*! calculates the bounds of the i'th triangle at the itime'th timestep */
157
__forceinline BBox3fa bounds(size_t i, size_t itime) const
158
{
159
const Triangle& tri = triangle(i);
160
const Vec3fa v0 = vertex(tri.v[0],itime);
161
const Vec3fa v1 = vertex(tri.v[1],itime);
162
const Vec3fa v2 = vertex(tri.v[2],itime);
163
return BBox3fa(min(v0,v1,v2),max(v0,v1,v2));
164
}
165
166
/*! check if the i'th primitive is valid at the itime'th timestep */
167
__forceinline bool valid(size_t i, size_t itime) const {
168
return valid(i, make_range(itime, itime));
169
}
170
171
/*! check if the i'th primitive is valid between the specified time range */
172
__forceinline bool valid(size_t i, const range<size_t>& itime_range) const
173
{
174
const Triangle& tri = triangle(i);
175
if (unlikely(tri.v[0] >= numVertices())) return false;
176
if (unlikely(tri.v[1] >= numVertices())) return false;
177
if (unlikely(tri.v[2] >= numVertices())) return false;
178
179
for (size_t itime = itime_range.begin(); itime <= itime_range.end(); itime++)
180
{
181
if (!isvalid(vertex(tri.v[0],itime))) return false;
182
if (!isvalid(vertex(tri.v[1],itime))) return false;
183
if (!isvalid(vertex(tri.v[2],itime))) return false;
184
}
185
186
return true;
187
}
188
189
/*! calculates the linear bounds of the i'th primitive at the itimeGlobal'th time segment */
190
__forceinline LBBox3fa linearBounds(size_t i, size_t itime) const {
191
return LBBox3fa(bounds(i,itime+0),bounds(i,itime+1));
192
}
193
194
/*! calculates the build bounds of the i'th primitive, if it's valid */
195
__forceinline bool buildBounds(size_t i, BBox3fa* bbox = nullptr) const
196
{
197
const Triangle& tri = triangle(i);
198
if (unlikely(tri.v[0] >= numVertices())) return false;
199
if (unlikely(tri.v[1] >= numVertices())) return false;
200
if (unlikely(tri.v[2] >= numVertices())) return false;
201
202
for (size_t t=0; t<numTimeSteps; t++)
203
{
204
const Vec3fa v0 = vertex(tri.v[0],t);
205
const Vec3fa v1 = vertex(tri.v[1],t);
206
const Vec3fa v2 = vertex(tri.v[2],t);
207
if (unlikely(!isvalid(v0) || !isvalid(v1) || !isvalid(v2)))
208
return false;
209
}
210
211
if (likely(bbox))
212
*bbox = bounds(i);
213
214
return true;
215
}
216
217
/*! calculates the build bounds of the i'th primitive at the itime'th time segment, if it's valid */
218
__forceinline bool buildBounds(size_t i, size_t itime, BBox3fa& bbox) const
219
{
220
const Triangle& tri = triangle(i);
221
if (unlikely(tri.v[0] >= numVertices())) return false;
222
if (unlikely(tri.v[1] >= numVertices())) return false;
223
if (unlikely(tri.v[2] >= numVertices())) return false;
224
225
assert(itime+1 < numTimeSteps);
226
const Vec3fa a0 = vertex(tri.v[0],itime+0); if (unlikely(!isvalid(a0))) return false;
227
const Vec3fa a1 = vertex(tri.v[1],itime+0); if (unlikely(!isvalid(a1))) return false;
228
const Vec3fa a2 = vertex(tri.v[2],itime+0); if (unlikely(!isvalid(a2))) return false;
229
const Vec3fa b0 = vertex(tri.v[0],itime+1); if (unlikely(!isvalid(b0))) return false;
230
const Vec3fa b1 = vertex(tri.v[1],itime+1); if (unlikely(!isvalid(b1))) return false;
231
const Vec3fa b2 = vertex(tri.v[2],itime+1); if (unlikely(!isvalid(b2))) return false;
232
233
/* use bounds of first time step in builder */
234
bbox = BBox3fa(min(a0,a1,a2),max(a0,a1,a2));
235
return true;
236
}
237
238
/*! calculates the linear bounds of the i'th primitive for the specified time range */
239
__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& dt) const {
240
return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, dt, time_range, fnumTimeSegments);
241
}
242
243
/*! calculates the linear bounds of the i'th primitive for the specified time range */
244
__forceinline bool linearBounds(size_t i, const BBox1f& dt, LBBox3fa& bbox) const {
245
if (!valid(i, timeSegmentRange(dt))) return false;
246
bbox = linearBounds(i, dt);
247
return true;
248
}
249
250
/*! get fast access to first vertex buffer */
251
__forceinline float * getCompactVertexArray () const override {
252
return (float*) vertices0.getPtr();
253
}
254
255
/* gets version info of topology */
256
unsigned int getTopologyVersion() const {
257
return triangles.modCounter;
258
}
259
260
/* returns true if topology changed */
261
bool topologyChanged(unsigned int otherVersion) const {
262
return triangles.isModified(otherVersion); // || numPrimitivesChanged;
263
}
264
265
/* returns the projected area */
266
__forceinline float projectedPrimitiveArea(const size_t i) const {
267
const Triangle& tri = triangle(i);
268
const Vec3fa v0 = vertex(tri.v[0]);
269
const Vec3fa v1 = vertex(tri.v[1]);
270
const Vec3fa v2 = vertex(tri.v[2]);
271
return areaProjectedTriangle(v0,v1,v2);
272
}
273
274
public:
275
BufferView<Triangle> triangles; //!< array of triangles
276
BufferView<Vec3fa> vertices0; //!< fast access to first vertex buffer
277
Device::vector<BufferView<Vec3fa>> vertices = device; //!< vertex array for each timestep
278
Device::vector<RawBufferView> vertexAttribs = device; //!< vertex attributes
279
};
280
281
namespace isa
282
{
283
struct TriangleMeshISA : public TriangleMesh
284
{
285
TriangleMeshISA (Device* device)
286
: TriangleMesh(device) {}
287
288
#if !defined(__SYCL_DEVICE_ONLY__)
289
LBBox3fa vlinearBounds(size_t primID, const BBox1f& time_range) const {
290
return linearBounds(primID,time_range);
291
}
292
293
PrimInfo createPrimRefArray(PrimRef* prims, const range<size_t>& r, size_t k, unsigned int geomID) const
294
{
295
PrimInfo pinfo(empty);
296
for (size_t j=r.begin(); j<r.end(); j++)
297
{
298
BBox3fa bounds = empty;
299
if (!buildBounds(j,&bounds)) continue;
300
const PrimRef prim(bounds,geomID,unsigned(j));
301
pinfo.add_center2(prim);
302
prims[k++] = prim;
303
}
304
return pinfo;
305
}
306
307
PrimInfo createPrimRefArrayMB(mvector<PrimRef>& prims, size_t itime, const range<size_t>& r, size_t k, unsigned int geomID) const
308
{
309
PrimInfo pinfo(empty);
310
for (size_t j=r.begin(); j<r.end(); j++)
311
{
312
BBox3fa bounds = empty;
313
if (!buildBounds(j,itime,bounds)) continue;
314
const PrimRef prim(bounds,geomID,unsigned(j));
315
pinfo.add_center2(prim);
316
prims[k++] = prim;
317
}
318
return pinfo;
319
}
320
321
PrimInfo createPrimRefArrayMB(PrimRef* prims, const BBox1f& time_range, const range<size_t>& r, size_t k, unsigned int geomID) const
322
{
323
PrimInfo pinfo(empty);
324
const BBox1f t0t1 = BBox1f::intersect(getTimeRange(), time_range);
325
if (t0t1.empty()) return pinfo;
326
327
for (size_t j = r.begin(); j < r.end(); j++) {
328
LBBox3fa lbounds = empty;
329
if (!linearBounds(j, t0t1, lbounds))
330
continue;
331
const PrimRef prim(lbounds.bounds(), geomID, unsigned(j));
332
pinfo.add_center2(prim);
333
prims[k++] = prim;
334
}
335
return pinfo;
336
}
337
338
PrimInfoMB createPrimRefMBArray(mvector<PrimRefMB>& prims, const BBox1f& t0t1, const range<size_t>& r, size_t k, unsigned int geomID) const
339
{
340
PrimInfoMB pinfo(empty);
341
for (size_t j=r.begin(); j<r.end(); j++)
342
{
343
if (!valid(j, timeSegmentRange(t0t1))) continue;
344
const PrimRefMB prim(linearBounds(j,t0t1),this->numTimeSegments(),this->time_range,this->numTimeSegments(),geomID,unsigned(j));
345
pinfo.add_primref(prim);
346
prims[k++] = prim;
347
}
348
return pinfo;
349
}
350
#endif
351
};
352
}
353
354
DECLARE_ISA_FUNCTION(TriangleMesh*, createTriangleMesh, Device*);
355
}
356
357