Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/common/scene_triangle_mesh.cpp
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#include "scene_triangle_mesh.h"
5
#include "scene.h"
6
7
namespace embree
8
{
9
#if defined(EMBREE_LOWEST_ISA)
10
11
TriangleMesh::TriangleMesh (Device* device)
12
: Geometry(device,GTY_TRIANGLE_MESH,0,1)
13
{
14
vertices.resize(numTimeSteps);
15
}
16
17
void TriangleMesh::setMask (unsigned mask)
18
{
19
this->mask = mask;
20
Geometry::update();
21
}
22
23
void TriangleMesh::setNumTimeSteps (unsigned int numTimeSteps)
24
{
25
vertices.resize(numTimeSteps);
26
Geometry::setNumTimeSteps(numTimeSteps);
27
}
28
29
void TriangleMesh::setVertexAttributeCount (unsigned int N)
30
{
31
vertexAttribs.resize(N);
32
Geometry::update();
33
}
34
35
void TriangleMesh::setBuffer(RTCBufferType type, unsigned int slot, RTCFormat format, const Ref<Buffer>& buffer, size_t offset, size_t stride, unsigned int num)
36
{
37
/* verify that all accesses are 4 bytes aligned */
38
if (((size_t(buffer->getHostPtr()) + offset) & 0x3) || (stride & 0x3))
39
throw_RTCError(RTC_ERROR_INVALID_OPERATION, "data must be 4 bytes aligned");
40
41
if (type == RTC_BUFFER_TYPE_VERTEX)
42
{
43
if (format != RTC_FORMAT_FLOAT3)
44
throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid vertex buffer format");
45
46
/* if buffer is larger than 16GB the premultiplied index optimization does not work */
47
if (stride*num > 16ll*1024ll*1024ll*1024ll)
48
throw_RTCError(RTC_ERROR_INVALID_OPERATION, "vertex buffer can be at most 16GB large");
49
50
if (slot >= vertices.size())
51
throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid vertex buffer slot");
52
53
vertices[slot].set(buffer, offset, stride, num, format);
54
vertices[slot].checkPadding16();
55
vertices0 = vertices[0];
56
}
57
else if (type == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE)
58
{
59
if (format < RTC_FORMAT_FLOAT || format > RTC_FORMAT_FLOAT16)
60
throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid vertex attribute buffer format");
61
62
if (slot >= vertexAttribs.size())
63
throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid vertex attribute buffer slot");
64
65
vertexAttribs[slot].set(buffer, offset, stride, num, format);
66
vertexAttribs[slot].checkPadding16();
67
}
68
else if (type == RTC_BUFFER_TYPE_INDEX)
69
{
70
if (slot != 0)
71
throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");
72
if (format != RTC_FORMAT_UINT3)
73
throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid index buffer format");
74
75
triangles.set(buffer, offset, stride, num, format);
76
setNumPrimitives(num);
77
}
78
else
79
throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "unknown buffer type");
80
}
81
82
void* TriangleMesh::getBufferData(RTCBufferType type, unsigned int slot, BufferDataPointerType pointerType)
83
{
84
if (type == RTC_BUFFER_TYPE_INDEX)
85
{
86
if (slot != 0)
87
throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");
88
return triangles.getPtr(pointerType);
89
}
90
else if (type == RTC_BUFFER_TYPE_VERTEX)
91
{
92
if (slot >= vertices.size())
93
throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");
94
return vertices[slot].getPtr(pointerType);
95
}
96
else if (type == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE)
97
{
98
if (slot >= vertexAttribs.size())
99
throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");
100
return vertexAttribs[slot].getPtr(pointerType);
101
}
102
else
103
{
104
throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "unknown buffer type");
105
return nullptr;
106
}
107
}
108
109
void TriangleMesh::updateBuffer(RTCBufferType type, unsigned int slot)
110
{
111
if (type == RTC_BUFFER_TYPE_INDEX)
112
{
113
if (slot != 0)
114
throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");
115
triangles.setModified();
116
}
117
else if (type == RTC_BUFFER_TYPE_VERTEX)
118
{
119
if (slot >= vertices.size())
120
throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");
121
vertices[slot].setModified();
122
}
123
else if (type == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE)
124
{
125
if (slot >= vertexAttribs.size())
126
throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");
127
vertexAttribs[slot].setModified();
128
}
129
else
130
{
131
throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "unknown buffer type");
132
}
133
134
Geometry::update();
135
}
136
137
void TriangleMesh::commit()
138
{
139
/* verify that stride of all time steps are identical */
140
for (unsigned int t=0; t<numTimeSteps; t++) {
141
if (vertices[t].getStride() != vertices[0].getStride())
142
throw_RTCError(RTC_ERROR_INVALID_OPERATION,"stride of vertex buffers have to be identical for each time step");
143
if (vertices[t]) vertices[t].buffer->commitIfNeeded();
144
}
145
if (triangles) triangles.buffer->commitIfNeeded();
146
Geometry::commit();
147
}
148
149
void TriangleMesh::addElementsToCount (GeometryCounts & counts) const
150
{
151
if (numTimeSteps == 1) counts.numTriangles += numPrimitives;
152
else counts.numMBTriangles += numPrimitives;
153
}
154
155
bool TriangleMesh::verify()
156
{
157
/*! verify size of vertex arrays */
158
if (vertices.size() == 0) return false;
159
for (const auto& buffer : vertices)
160
if (buffer.size() != numVertices())
161
return false;
162
163
/*! verify size of user vertex arrays */
164
for (const auto& buffer : vertexAttribs)
165
if (buffer.size() != numVertices())
166
return false;
167
168
/*! verify triangle indices */
169
for (size_t i=0; i<size(); i++) {
170
if (triangles[i].v[0] >= numVertices()) return false;
171
if (triangles[i].v[1] >= numVertices()) return false;
172
if (triangles[i].v[2] >= numVertices()) return false;
173
}
174
175
/*! verify vertices */
176
for (const auto& buffer : vertices)
177
for (size_t i=0; i<buffer.size(); i++)
178
if (!isvalid(buffer[i]))
179
return false;
180
181
return true;
182
}
183
184
void TriangleMesh::interpolate(const RTCInterpolateArguments* const args) {
185
interpolate_impl<4>(args);
186
}
187
188
size_t TriangleMesh::getGeometryDataDeviceByteSize() const {
189
size_t byte_size = sizeof(TriangleMesh);
190
byte_size += numTimeSteps * sizeof(BufferView<Vec3fa>);
191
return 16 * ((byte_size + 15) / 16);
192
}
193
194
void TriangleMesh::convertToDeviceRepresentation(size_t offset, char* data_host, char* data_device) const {
195
TriangleMesh* mesh = (TriangleMesh*)(data_host + offset);
196
std::memcpy(data_host + offset, (void*)this, sizeof(TriangleMesh));
197
offset += sizeof(TriangleMesh);
198
199
// store offset for overriding vertices pointer with device pointer after copying
200
const size_t offsetVertices = offset;
201
// copy vertices BufferViews for each time step
202
for (size_t t = 0; t < numTimeSteps; ++t) {
203
std::memcpy(data_host + offset, &(vertices[t]), sizeof(BufferView<Vec3fa>));
204
offset += sizeof(BufferView<Vec3fa>);
205
}
206
// override vertices pointer with device ptr
207
mesh->vertices.setDataPtr((BufferView<Vec3fa>*)(data_device + offsetVertices));
208
}
209
210
#endif
211
212
namespace isa
213
{
214
TriangleMesh* createTriangleMesh(Device* device) {
215
return new TriangleMeshISA(device);
216
}
217
}
218
}
219
220