@@ -126,6 +126,92 @@ class NBL_API2 CPolygonGeometryManipulator
126
126
const_cast <IGeometryBase::SAABBStorage&>(geo->getAABBStorage ()) = computeAABB (geo);
127
127
}
128
128
129
+ static inline core::smart_refctd_ptr<ICPUPolygonGeometry> createTriangleListIndexing (const ICPUPolygonGeometry* geo)
130
+ {
131
+ const auto * indexing = geo->getIndexingCallback ();
132
+ if (!indexing) return nullptr ;
133
+ if (indexing->degree () != 3 ) return nullptr ;
134
+
135
+ const auto originalView = geo->getIndexView ();
136
+ const auto originalIndexSize = originalView ? originalView.composed .stride : 0 ;
137
+ const auto primCount = geo->getPrimitiveCount ();
138
+ const auto maxIndex = geo->getPositionView ().getElementCount () - 1 ;
139
+ const uint8_t indexSize = maxIndex <= std::numeric_limits<uint16_t >::max () ? sizeof (uint16_t ) : sizeof (uint32_t );
140
+ const auto outGeometry = core::move_and_static_cast<ICPUPolygonGeometry>(geo->clone (0u ));
141
+
142
+ if (indexing && indexing->knownTopology () == EPT_TRIANGLE_LIST)
143
+ return outGeometry;
144
+
145
+
146
+ auto * outGeo = outGeometry.get ();
147
+ const auto indexBufferUsages = [&]
148
+ {
149
+ if (originalView) return originalView.src .buffer ->getUsageFlags ();
150
+ return core::bitflag<IBuffer::E_USAGE_FLAGS>(IBuffer::EUF_INDEX_BUFFER_BIT);
151
+ }();
152
+ auto indexBuffer = ICPUBuffer::create ({ primCount * indexing->degree () * indexSize, indexBufferUsages });
153
+ auto indexBufferPtr = indexBuffer->getPointer ();
154
+ auto indexView = ICPUPolygonGeometry::SDataView{
155
+ .composed = {
156
+ .stride = indexSize,
157
+ },
158
+ .src = {
159
+ .offset = 0 ,
160
+ .size = indexBuffer->getSize (),
161
+ .buffer = std::move (indexBuffer)
162
+ }
163
+ };
164
+
165
+ switch (indexSize)
166
+ {
167
+ case 2 :
168
+ {
169
+ IPolygonGeometryBase::IIndexingCallback::SContext<uint16_t > context{
170
+ .indexBuffer = geo->getIndexView ().getPointer (),
171
+ .indexSize = originalIndexSize,
172
+ .beginPrimitive = 0 ,
173
+ .endPrimitive = primCount,
174
+ .out = indexBufferPtr,
175
+ };
176
+ indexing->operator ()(context);
177
+
178
+ indexView.composed .encodedDataRange .u16 .minVx [0 ] = 0 ;
179
+ indexView.composed .encodedDataRange .u16 .maxVx [0 ] = maxIndex;
180
+ indexView.composed .format = EF_R16_UINT;
181
+ indexView.composed .rangeFormat = IGeometryBase::EAABBFormat::U16;
182
+ break ;
183
+ }
184
+ case 4 :
185
+ {
186
+ IPolygonGeometryBase::IIndexingCallback::SContext<uint32_t > context{
187
+ .indexBuffer = geo->getIndexView ().getPointer (),
188
+ .indexSize = originalIndexSize,
189
+ .beginPrimitive = 0 ,
190
+ .endPrimitive = primCount,
191
+ .out = indexBufferPtr,
192
+ };
193
+ indexing->operator ()(context);
194
+
195
+ indexView.composed .encodedDataRange .u32 .minVx [0 ] = 0 ;
196
+ indexView.composed .encodedDataRange .u32 .maxVx [0 ] = maxIndex;
197
+ indexView.composed .format = EF_R32_UINT;
198
+ indexView.composed .rangeFormat = IGeometryBase::EAABBFormat::U32;
199
+ break ;
200
+ }
201
+ default :
202
+ {
203
+ assert (false );
204
+ return nullptr ;
205
+ }
206
+ }
207
+
208
+ outGeo->setIndexing (IPolygonGeometryBase::TriangleList ());
209
+ outGeo->setIndexView (std::move (indexView));
210
+ CGeometryManipulator::recomputeContentHash (outGeo->getIndexView ());
211
+
212
+ return outGeometry;
213
+ }
214
+
129
215
// ! Comparison methods
130
216
enum E_ERROR_METRIC
131
217
{
0 commit comments