@@ -32,9 +32,14 @@ class CVertexWelder {
3232 {
3333 private:
3434
35- static inline bool isIntegralElementEqual (const ICPUPolygonGeometry::SDataView& view, uint32_t index1, uint32_t index2)
35+ struct SDataViewContext
36+ {
37+ uint32_t channelCount : 3 ;
38+ uint32_t byteSize: 29 ;
39+ };
40+
41+ static inline bool isIntegralElementEqual (const ICPUPolygonGeometry::SDataView& view, uint32_t index1, uint32_t index2, uint32_t byteSize)
3642 {
37- const auto byteSize = getTexelOrBlockBytesize (view.composed .format );
3843 const auto * basePtr = reinterpret_cast <const std::byte*>(view.getPointer ());
3944 const auto stride = view.composed .stride ;
4045 return (memcmp (basePtr + (index1 * stride), basePtr + (index2 * stride), byteSize) == 0 );
@@ -53,48 +58,50 @@ class CVertexWelder {
5358 return true ;
5459 }
5560
56- static inline bool isAttributeValEqual (const ICPUPolygonGeometry::SDataView& view, uint32_t index1, uint32_t index2, float epsilon)
61+ static inline bool isAttributeValEqual (const ICPUPolygonGeometry::SDataView& view, const SDataViewContext& context, uint32_t index1, uint32_t index2, float epsilon)
5762 {
63+ if (context.byteSize == 0 ) return true ;
64+
5865 assert (view);
5966 assert (view.composed .isFormatted ());
6067 assert (IGeometryBase::getMatchingAABBFormat (view.composed .format ) == view.composed .rangeFormat );
61- const auto channelCount = getFormatChannelCount (view.composed .format );
6268 switch (view.composed .rangeFormat )
6369 {
6470 case IGeometryBase::EAABBFormat::U64:
6571 case IGeometryBase::EAABBFormat::U32:
6672 case IGeometryBase::EAABBFormat::S64:
6773 case IGeometryBase::EAABBFormat::S32:
6874 {
69- return isIntegralElementEqual (view, index1, index2);
75+ return isIntegralElementEqual (view, index1, index2, context. byteSize );
7076 }
7177 default :
7278 {
73- return isRealElementEqual (view, index1, index2, channelCount, epsilon);
79+ return isRealElementEqual (view, index1, index2, context. channelCount , epsilon);
7480 }
7581 }
7682 return true ;
7783 }
7884
79- static inline bool isAttributeDirEqual (const ICPUPolygonGeometry::SDataView& view, uint32_t index1, uint32_t index2, float epsilon)
85+ static inline bool isAttributeDirEqual (const ICPUPolygonGeometry::SDataView& view, const SDataViewContext& context, uint32_t index1, uint32_t index2, float epsilon)
8086 {
87+ if (context.byteSize == 0 ) return true ;
88+
8189 assert (view);
8290 assert (view.composed .isFormatted ());
8391 assert (IGeometryBase::getMatchingAABBFormat (view.composed .format ) == view.composed .rangeFormat );
84- const auto channelCount = getFormatChannelCount (view.composed .format );
8592 switch (view.composed .rangeFormat )
8693 {
8794 case IGeometryBase::EAABBFormat::U64:
8895 case IGeometryBase::EAABBFormat::U32:
8996 case IGeometryBase::EAABBFormat::S64:
9097 case IGeometryBase::EAABBFormat::S32:
9198 {
92- return isIntegralElementEqual (view, index1, index2);
99+ return isIntegralElementEqual (view, index1, index2, context. byteSize );
93100 }
94101 default :
95102 {
96- if (channelCount != 3 )
97- return isRealElementEqual (view, index1, index2, channelCount, epsilon);
103+ if (context. channelCount != 3 )
104+ return isRealElementEqual (view, index1, index2, context. channelCount , epsilon);
98105
99106 hlsl::float64_t4 val1, val2;
100107 view.decodeElement <hlsl::float64_t4>(index1, val1);
@@ -106,28 +113,97 @@ class CVertexWelder {
106113
107114 float m_epsilon;
108115
116+ SDataViewContext m_positionViewContext;
117+ SDataViewContext m_normalViewContext;
118+
119+ struct SJointViewContext
120+ {
121+ SDataViewContext indices;
122+ SDataViewContext weights;
123+ };
124+ core::vector<SJointViewContext> m_jointViewContexts;
125+
126+ core::vector<SDataViewContext> m_auxAttributeViewContexts;
127+
109128 public:
110129
111130 inline DefaultWeldPredicate (float epsilon) : m_epsilon(epsilon) {}
112131
113132 inline bool init (const ICPUPolygonGeometry* polygon) override
114133 {
115- return polygon->valid ();
134+ auto isViewFormatValid = [](const ICPUPolygonGeometry::SDataView& view)
135+ {
136+ return view.composed .isFormatted () && IGeometryBase::getMatchingAABBFormat (view.composed .format ) == view.composed .rangeFormat ;
137+ };
138+ auto getViewContext = [](const ICPUPolygonGeometry::SDataView& view) -> SDataViewContext
139+ {
140+ if (!view)
141+ {
142+ return {
143+ .channelCount = 0 ,
144+ .byteSize = 0
145+ };
146+ }
147+ return {
148+ .channelCount = getFormatChannelCount (view.composed .format ),
149+ .byteSize = getTexelOrBlockBytesize (view.composed .format )
150+ };
151+ };
152+
153+ if (!polygon->valid ()) return false ;
154+
155+ const auto & positionView = polygon->getPositionView ();
156+ if (IGeometryBase::getMatchingAABBFormat (positionView.composed .format ) == positionView.composed .rangeFormat ) return false ;
157+ m_positionViewContext = {
158+ .channelCount = getFormatChannelCount (positionView.composed .format ),
159+ .byteSize = getTexelOrBlockBytesize (positionView.composed .format ),
160+ };
161+
162+ const auto & normalView = polygon->getNormalView ();
163+ if (normalView && !isViewFormatValid (normalView)) return false ;
164+ m_normalViewContext = getViewContext (normalView);
165+
166+ m_jointViewContexts.reserve (polygon->getJointWeightViews ().size ());
167+ for (const auto & jointWeightView : polygon->getJointWeightViews ())
168+ {
169+ if (jointWeightView.indices && !isViewFormatValid (jointWeightView.indices )) return false ;
170+ if (jointWeightView.weights && !isViewFormatValid (jointWeightView.weights )) return false ;
171+ m_jointViewContexts.push_back ({
172+ .indices = getViewContext (jointWeightView.indices ),
173+ .weights = getViewContext (jointWeightView.weights ),
174+ });
175+ }
176+
177+ m_auxAttributeViewContexts.reserve (polygon->getAuxAttributeViews ().size ());
178+ for (const auto & auxAttributeView : polygon->getAuxAttributeViews ())
179+ {
180+ if (auxAttributeView && !isViewFormatValid (auxAttributeView)) return false ;
181+ m_auxAttributeViewContexts.push_back (getViewContext (auxAttributeView));
182+ }
183+
116184 }
117185
118186 inline bool operator ()(const ICPUPolygonGeometry* polygon, uint32_t index1, uint32_t index2) const override
119187 {
120- if (!isAttributeValEqual (polygon->getPositionView (), index1, index2, m_epsilon))
188+ if (!isAttributeValEqual (polygon->getPositionView (), m_positionViewContext, index1, index2, m_epsilon))
121189 return false ;
122- if (!isAttributeDirEqual (polygon->getNormalView (), index1, index2, m_epsilon))
190+
191+ const auto & normalView = polygon->getNormalView ();
192+ if (!isAttributeDirEqual (normalView, m_normalViewContext, index1, index2, m_epsilon))
123193 return false ;
124- for (const auto & jointWeightView : polygon->getJointWeightViews ())
194+
195+ for (uint64_t joint_i = 0 ; joint_i < polygon->getJointWeightViews ().size (); joint_i++)
125196 {
126- if (!isAttributeValEqual (jointWeightView.indices , index1, index2, m_epsilon)) return false ;
127- if (!isAttributeValEqual (jointWeightView.weights , index1, index2, m_epsilon)) return false ;
197+ const auto & jointWeightView = polygon->getJointWeightViews ()[joint_i];
198+ if (!isAttributeValEqual (jointWeightView.indices , m_jointViewContexts[joint_i].indices , index1, index2, m_epsilon)) return false ;
199+ if (!isAttributeValEqual (jointWeightView.weights , m_jointViewContexts[joint_i].weights , index1, index2, m_epsilon)) return false ;
200+ }
201+
202+ const auto & auxAttrViews = polygon->getAuxAttributeViews ();
203+ for (uint64_t aux_i = 0 ; aux_i < auxAttrViews.size (); aux_i++)
204+ {
205+ if (!isAttributeValEqual (auxAttrViews[aux_i], m_auxAttributeViewContexts[aux_i], index1, index2, m_epsilon)) return false ;
128206 }
129- for (const auto & auxAttributeView : polygon->getAuxAttributeViews ())
130- if (!isAttributeValEqual (auxAttributeView, index1, index2, m_epsilon)) return false ;
131207
132208 return true ;
133209 }
0 commit comments