@@ -126,6 +126,92 @@ class NBL_API2 CPolygonGeometryManipulator
126126 const_cast <IGeometryBase::SAABBStorage&>(geo->getAABBStorage ()) = computeAABB (geo);
127127 }
128128
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+
129215 // ! Comparison methods
130216 enum E_ERROR_METRIC
131217 {
0 commit comments