@@ -128,27 +128,28 @@ class NBL_API2 CPolygonGeometryManipulator
128128 const_cast <IGeometryBase::SAABBStorage&>(geo->getAABBStorage ()) = computeAABB (geo);
129129 }
130130
131- static inline core::smart_refctd_ptr<ICPUPolygonGeometry> createTriangleListIndexing (const ICPUPolygonGeometry* geo)
131+ static inline core::smart_refctd_ptr<ICPUPolygonGeometry> createTriangleListIndexing (const ICPUPolygonGeometry* geo, const bool reverse= false , const bool recomputeHash= true )
132132 {
133133 const auto * indexing = geo->getIndexingCallback ();
134- if (!indexing) return nullptr ;
135- if (indexing-> degree () != 3 ) return nullptr ;
134+ if (!indexing || indexing-> degree ()!= 3 ) // TODO: why just triangle?
135+ return nullptr ;
136136
137137 const auto originalView = geo->getIndexView ();
138- const auto originalIndexSize = originalView ? originalView.composed .stride : 0 ;
138+ const auto originalIndexSize = originalView ? originalView.composed .stride : 0 ;
139139 const auto primCount = geo->getPrimitiveCount ();
140140 const auto maxIndex = geo->getPositionView ().getElementCount () - 1 ;
141141 const uint8_t indexSize = maxIndex <= std::numeric_limits<uint16_t >::max () ? sizeof (uint16_t ) : sizeof (uint32_t );
142142 const auto outGeometry = core::move_and_static_cast<ICPUPolygonGeometry>(geo->clone (0u ));
143143
144- if (indexing && indexing ->knownTopology () == EPT_TRIANGLE_LIST)
144+ if (indexing->knownTopology ()== EPT_TRIANGLE_LIST && !reverse)
145145 return outGeometry;
146146
147147
148148 auto * outGeo = outGeometry.get ();
149149 const auto indexBufferUsages = [&]
150150 {
151- if (originalView) return originalView.src .buffer ->getUsageFlags ();
151+ if (originalView)
152+ return originalView.src .buffer ->getUsageFlags ();
152153 return core::bitflag<IBuffer::E_USAGE_FLAGS>(IBuffer::EUF_INDEX_BUFFER_BIT);
153154 }();
154155 auto indexBuffer = ICPUBuffer::create ({ primCount * indexing->degree () * indexSize, indexBufferUsages });
@@ -173,7 +174,8 @@ class NBL_API2 CPolygonGeometryManipulator
173174 .indexSize = originalIndexSize,
174175 .beginPrimitive = 0 ,
175176 .endPrimitive = primCount,
176- .out = indexBufferPtr,
177+ .reversePrims = reverse,
178+ .out = indexBufferPtr
177179 };
178180 indexing->operator ()(context);
179181
@@ -190,7 +192,8 @@ class NBL_API2 CPolygonGeometryManipulator
190192 .indexSize = originalIndexSize,
191193 .beginPrimitive = 0 ,
192194 .endPrimitive = primCount,
193- .out = indexBufferPtr,
195+ .reversePrims = reverse,
196+ .out = indexBufferPtr
194197 };
195198 indexing->operator ()(context);
196199
@@ -209,11 +212,35 @@ class NBL_API2 CPolygonGeometryManipulator
209212
210213 outGeo->setIndexing (IPolygonGeometryBase::TriangleList ());
211214 outGeo->setIndexView (std::move (indexView));
212- CGeometryManipulator::recomputeContentHash (outGeo->getIndexView ());
215+
216+ if (recomputeHash)
217+ CGeometryManipulator::recomputeContentHash (outGeo->getIndexView ());
213218
214219 return outGeometry;
215220 }
216221
222+ template <typename FetchVertexFn>
223+ requires (std::same_as<std::invoke_result_t <FetchVertexFn, size_t >, hlsl::float32_t3>)
224+ static inline hlsl::shapes::OBB<3 , hlsl::float32_t > calculateOBB (size_t vertexCount, FetchVertexFn&& fetchFn, float epsilon = 1 .525e-5f )
225+ {
226+ return COBBGenerator::compute (vertexCount, std::forward<FetchVertexFn>(fetchFn), epsilon);
227+ }
228+
229+ static core::smart_refctd_ptr<ICPUPolygonGeometry> createUnweldedList (const ICPUPolygonGeometry* inGeo, const bool reverse=false , const bool recomputeHash=true );
230+
231+ using SSNGVertexData = CSmoothNormalGenerator::VertexData;
232+ using SSNGVxCmpFunction = CSmoothNormalGenerator::VxCmpFunction;
233+ // NOTE: Requires unwelded mesh on input, TODO make it resillient against that (only unweld normals temporarily, maybe even avoid position unweld)
234+ static core::smart_refctd_ptr<ICPUPolygonGeometry> createSmoothVertexNormal (const ICPUPolygonGeometry* inbuffer, const bool enableWelding=false , float epsilon=1 .525e-5f ,
235+ SSNGVxCmpFunction vxcmp=[](const SSNGVertexData& v0, const SSNGVertexData& v1, const ICPUPolygonGeometry* buffer)
236+ {
237+ constexpr float cosOf45Deg = 0 .70710678118f ;
238+ return hlsl::dot (v0.weightedNormal ,v1.weightedNormal )*hlsl::rsqrt (hlsl::dot (v0.weightedNormal ,v0.weightedNormal )*hlsl::dot (v1.weightedNormal ,v1.weightedNormal )) > cosOf45Deg;
239+ },
240+ const bool recomputeHash = true
241+ );
242+
243+
217244 // ! Comparison methods
218245 enum E_ERROR_METRIC
219246 {
@@ -232,26 +259,6 @@ class NBL_API2 CPolygonGeometryManipulator
232259 EEM_QUATERNION,
233260 EEM_COUNT
234261 };
235-
236- template <typename FetchVertexFn>
237- requires (std::same_as<std::invoke_result_t <FetchVertexFn, size_t >, hlsl::float32_t3>)
238- static inline hlsl::shapes::OBB<3 , hlsl::float32_t > calculateOBB (size_t vertexCount, FetchVertexFn&& fetchFn, float epsilon = 1 .525e-5f )
239- {
240- return COBBGenerator::compute (vertexCount, std::forward<FetchVertexFn>(fetchFn), epsilon);
241- }
242-
243- static core::smart_refctd_ptr<ICPUPolygonGeometry> createUnweldedList (const ICPUPolygonGeometry* inGeo);
244-
245- using SSNGVertexData = CSmoothNormalGenerator::VertexData;
246- using SSNGVxCmpFunction = CSmoothNormalGenerator::VxCmpFunction;
247-
248- static core::smart_refctd_ptr<ICPUPolygonGeometry> createSmoothVertexNormal (const ICPUPolygonGeometry* inbuffer, bool enableWelding = false , float epsilon = 1 .525e-5f ,
249- SSNGVxCmpFunction vxcmp = [](const SSNGVertexData& v0, const SSNGVertexData& v1, const ICPUPolygonGeometry* buffer)
250- {
251- constexpr float cosOf45Deg = 0 .70710678118f ;
252- return dot (normalize (v0.weightedNormal ),normalize (v1.weightedNormal )) > cosOf45Deg;
253- });
254-
255262#if 0 // TODO: REDO
256263 //! Struct used to pass chosen comparison method and epsilon to functions performing error metrics.
257264 /**
@@ -385,24 +392,6 @@ class NBL_API2 CPolygonGeometryManipulator
385392 */
386393 static core::smart_refctd_ptr<ICPUBuffer> idxBufferFromLineStripsToLines(const void* _input, uint32_t& _idxCount, E_INDEX_TYPE _inIndexType, E_INDEX_TYPE _outIndexType);
387394
388- //! Creates index buffer from input converting it to indices for triangle list primitives. Input is assumed to be indices for triangle strip.
389- /**
390- @param _input Input index buffer's data.
391- @param _idxCount Index count.
392- @param _inIndexType Type of input index buffer data (32bit or 16bit).
393- @param _outIndexType Type of output index buffer data (32bit or 16bit).
394- */
395- static core::smart_refctd_ptr<ICPUBuffer> idxBufferFromTriangleStripsToTriangles(const void* _input, uint32_t& _idxCount, E_INDEX_TYPE _inIndexType, E_INDEX_TYPE _outIndexType);
396-
397- //! Creates index buffer from input converting it to indices for triangle list primitives. Input is assumed to be indices for triangle fan.
398- /**
399- @param _input Input index buffer's data.
400- @param _idxCount Index count.
401- @param _inIndexType Type of input index buffer data (32bit or 16bit).
402- @param _outIndexType Type of output index buffer data (32bit or 16bit).
403- */
404- static core::smart_refctd_ptr<ICPUBuffer> idxBufferFromTrianglesFanToTriangles(const void* _input, uint32_t& _idxCount, E_INDEX_TYPE _inIndexType, E_INDEX_TYPE _outIndexType);
405-
406395 //!
407396 static inline std::array<uint32_t,3u> getTriangleIndices(const ICPUMeshBuffer* mb, uint32_t triangleIx)
408397 {
@@ -606,40 +595,6 @@ class NBL_API2 CPolygonGeometryManipulator
606595 return aabb;
607596 }
608597
609- //! Recalculates the cached bounding box of the meshbuffer
610- static inline void recalculateBoundingBox(ICPUMeshBuffer* meshbuffer)
611- {
612- meshbuffer->setBoundingBox(calculateBoundingBox(meshbuffer,meshbuffer->getJointAABBs()));
613- }
614-
615- //! Flips the direction of surfaces.
616- /** Changes backfacing triangles to frontfacing
617- triangles and vice versa.
618- \param mesh Mesh on which the operation is performed. */
619- static void flipSurfaces(ICPUMeshBuffer* inbuffer);
620-
621- //! Creates a copy of a mesh with all vertices unwelded
622- /** \param mesh Input mesh
623- \return Mesh consisting only of unique faces. All vertices
624- which were previously shared are now duplicated. */
625- static core::smart_refctd_ptr<ICPUMeshBuffer> createMeshBufferUniquePrimitives(ICPUMeshBuffer* inbuffer, bool _makeIndexBuf = false);
626-
627- //
628- static core::smart_refctd_ptr<ICPUMeshBuffer> calculateSmoothNormals(ICPUMeshBuffer* inbuffer, bool makeNewMesh = false, float epsilon = 1.525e-5f,
629- uint32_t normalAttrID = 3u,
630- VxCmpFunction vxcmp = [](const IMeshManipulator::SSNGVertexData& v0, const IMeshManipulator::SSNGVertexData& v1, ICPUMeshBuffer* buffer)
631- {
632- static constexpr float cosOf45Deg = 0.70710678118f;
633- return dot(v0.parentTriangleFaceNormal,v1.parentTriangleFaceNormal)[0] > cosOf45Deg;
634- });
635-
636-
637- //! Creates a copy of a mesh with vertices welded
638- /** \param mesh Input mesh
639- \param errMetrics Array of size EVAI_COUNT. Describes error metric for each vertex attribute (used if attribute is of floating point or normalized type).
640- \param tolerance The threshold for vertex comparisons.
641- \return Mesh without redundant vertices. */
642- static core::smart_refctd_ptr<ICPUMeshBuffer> createMeshBufferWelded(ICPUMeshBuffer *inbuffer, const SErrorMetric* errMetrics, const bool& optimIndexType = true, const bool& makeNewMesh = false);
643598
644599 //! Throws meshbuffer into full optimizing pipeline consisting of: vertices welding, z-buffer optimization, vertex cache optimization (Forsyth's algorithm), fetch optimization and attributes requantization. A new meshbuffer is created unless given meshbuffer doesn't own (getMeshDataAndFormat()==NULL) a data format descriptor.
645600 /**@return A new meshbuffer or NULL if an error occured. */
@@ -864,45 +819,6 @@ class CMeshManipulator : public IMeshManipulator
864819 return output;
865820 }
866821
867- template<typename InType, typename OutType>
868- static inline core::smart_refctd_ptr<ICPUBuffer> triangleStripsToTriangles(const void* _input, uint32_t& _idxCount)
869- {
870- const auto outputSize = _idxCount = (_idxCount - 2) * 3;
871-
872- auto output = ICPUBuffer::create({ sizeof(OutType)*outputSize });
873- const auto* iptr = reinterpret_cast<const InType*>(_input);
874- auto* optr = reinterpret_cast<OutType*>(output->getPointer());
875- for (uint32_t i = 0, j = 0; i < outputSize; j += 2)
876- {
877- optr[i++] = iptr[j + 0];
878- optr[i++] = iptr[j + 1];
879- optr[i++] = iptr[j + 2];
880- if (i == outputSize)
881- break;
882- optr[i++] = iptr[j + 2];
883- optr[i++] = iptr[j + 1];
884- optr[i++] = iptr[j + 3];
885- }
886- return output;
887- }
888-
889- template<typename InType, typename OutType>
890- static inline core::smart_refctd_ptr<ICPUBuffer> trianglesFanToTriangles(const void* _input, uint32_t& _idxCount)
891- {
892- const auto outputSize = _idxCount = (_idxCount - 2) * 3;
893-
894- auto output = ICPUBuffer::create({ sizeof(OutType)*outputSize });
895- const auto* iptr = reinterpret_cast<const InType*>(_input);
896- auto* optr = reinterpret_cast<OutType*>(output->getPointer());
897- for (uint32_t i = 0, j = 1; i < outputSize;)
898- {
899- optr[i++] = iptr[0];
900- optr[i++] = iptr[j++];
901- optr[i++] = iptr[j];
902- }
903- return output;
904- }
905-
906822 private:
907823 CQuantNormalCache quantNormalCache;
908824 CQuantQuaternionCache quantQuaternionCache;
0 commit comments