11
11
12
12
namespace nbl ::asset
13
13
{
14
+ //
15
+ class NBL_API2 IPolygonGeometryBase : public virtual core::IReferenceCounted
16
+ {
17
+ public:
18
+ //
19
+ class NBL_API2 IIndexingCallback
20
+ {
21
+ public:
22
+ // how many vertices per polygon
23
+ inline uint8_t degree () const
24
+ {
25
+ const auto retval = degree_impl ();
26
+ assert (retval>0 );
27
+ return retval;
28
+ }
29
+ //
30
+ inline uint8_t reuseCount () const
31
+ {
32
+ const auto retval = reuseCount_impl ();
33
+ assert (retval<degree ());
34
+ return retval;
35
+ }
36
+
37
+ struct SContext
38
+ {
39
+ template <typename Index> requires std::is_integral_v<Index>
40
+ inline Index indexSize () const {return Index (1 )<<indexSizeLog2;}
41
+
42
+ template <typename Index> requires std::is_integral_v<Index>
43
+ inline void setOutput (const Index value) const
44
+ {
45
+ switch (indexSizeLog2)
46
+ {
47
+ case 0 :
48
+ *reinterpret_cast <uint8_t *>(out) = value;
49
+ break ;
50
+ case 1 :
51
+ *reinterpret_cast <uint16_t *>(out) = value;
52
+ break ;
53
+ case 2 :
54
+ *reinterpret_cast <uint32_t *>(out) = value;
55
+ break ;
56
+ case 3 :
57
+ *reinterpret_cast <uint64_t *>(out) = value;
58
+ break ;
59
+ default :
60
+ assert (false );
61
+ break ;
62
+ }
63
+ }
64
+
65
+ const uint8_t * const indexBuffer;
66
+ // no point making them smaller cause of padding
67
+ const uint32_t inSizeLog2;
68
+ const uint32_t outSizeLog2;
69
+ uint8_t * out;
70
+ uint32_t newIndexID;
71
+ // if `reuseCount()==0` then should be ignored
72
+ uint32_t restartValue = ~0ull ;
73
+ };
74
+ inline void operator ()(SContext& ctx) const
75
+ {
76
+ const auto deg = degree ();
77
+ if (ctx.newIndexID <deg || primitiveRestart)
78
+ {
79
+ // straight up copy
80
+ }
81
+ operator_impl (ctx);
82
+ ctx.newIndexID += reuseCount ();
83
+ ctx.out += deg<<ctx.outSizeLog2 ;
84
+ }
85
+
86
+ // default is unknown
87
+ virtual inline E_PRIMITIVE_TOPOLOGY knownTopology () const {return static_cast <E_PRIMITIVE_TOPOLOGY>(~0 );}
88
+
89
+ protected:
90
+ virtual uint8_t degree_impl () const = 0;
91
+ virtual uint8_t reuseCount_impl () const = 0;
92
+ // needs to deal with being handed `!ctx.indexBuffer`
93
+ virtual void operator_impl (const SContext& ctx) const = 0;
94
+ };
95
+ //
96
+ static IIndexingCallback* PointList ();
97
+ static IIndexingCallback* LineList ();
98
+ static IIndexingCallback* TriangleList ();
99
+ static IIndexingCallback* QuadList ();
100
+ //
101
+ static IIndexingCallback* TriangleStrip ();
102
+ static IIndexingCallback* TriangleFan ();
103
+
104
+ //
105
+ inline const IIndexingCallback* getIndexingCallback () const {return m_indexing;}
106
+
107
+ protected:
108
+ virtual ~IPolygonGeometryBase () = default ;
109
+
110
+ //
111
+ const IIndexingCallback* m_indexing = nullptr ;
112
+ };
113
+
14
114
// Don't want to overengineer, support for variable vertex count (order) polgyon meshes is not encouraged or planned.
15
115
// If you want different polygon types in same model, bucket the polgyons into separate geometries and reunite in a single collection.
16
116
template <class BufferType >
17
- class NBL_API2 IPolygonGeometry : public IIndexableGeometry<BufferType>
117
+ class NBL_API2 IPolygonGeometry : public IIndexableGeometry<BufferType>, public IPolygonGeometryBase
18
118
{
19
119
using base_t = IIndexableGeometry<BufferType>;
20
120
21
121
protected:
22
122
using EPrimitiveType = base_t ::EPrimitiveType;
23
- using BLASTriangles = IBottomLevelAccelerationStructure::Triangles<std::remove_const<BufferType>>;
123
+ using SDataView = base_t ::SDataView;
124
+ using BLASTriangles = IBottomLevelAccelerationStructure::Triangles<std::remove_const_t <BufferType>>;
24
125
25
126
public:
26
127
//
27
128
virtual inline bool valid () const override
28
129
{
29
130
if (!base_t::valid ())
30
131
return false ;
132
+ if (!m_indexing)
133
+ return false ;
31
134
// things that make no sense
32
135
if (m_verticesPerSupplementary==0 || m_verticesPerSupplementary>m_verticesForFirst)
33
136
return false ;
34
137
// there needs to be at least one vertex to reference (it also needs to be formatted)
35
- if (m_positionView.getElementCount ()==0 )
138
+ const auto & positionBase = base_t ::m_positionView.composed ;
139
+ const auto vertexCount = positionBase.getElementCount ();
140
+ if (vertexCount==0 || !positionBase.isFormatted ())
36
141
return false ;
37
- const auto vertexCount = m_positionView.getElementCount ();
38
142
if (m_normalView && m_normalView.getElementCount ()<vertexCount)
39
143
return false ;
40
144
// the variable length vectors must be filled with valid views
@@ -52,18 +156,21 @@ class NBL_API2 IPolygonGeometry : public IIndexableGeometry<BufferType>
52
156
inline EPrimitiveType getPrimitiveType () const override final {return PrimitiveType;}
53
157
54
158
//
55
- inline const auto & getAABB () const override final {return m_positionView.encodedDataRange ;}
159
+ inline const IGeometryBase::SAABBStorage & getAABB () const override final {return base_t :: m_positionView.encodedDataRange ;}
56
160
57
161
//
58
- inline uint64_t getVertexReferenceCount () const {return getIndexView () ? getIndexCount ():m_positionView.getElementCount ();}
162
+ inline uint64_t getVertexReferenceCount () const {return base_t:: getIndexView () ? base_t:: getIndexCount (): base_t : :m_positionView.getElementCount ();}
59
163
60
164
//
61
165
inline uint64_t getPrimitiveCount () const override final
62
166
{
167
+ if (!m_indexing)
168
+ return 0 ;
63
169
const auto vertexReferenceCount = getVertexReferenceCount ();
64
- if (vertexReferenceCount<m_verticesForFirst)
170
+ const auto verticesForFirst = m_indexing->degree ();
171
+ if (vertexReferenceCount<verticesForFirst)
65
172
return 0 ;
66
- return (vertexReferenceCount-m_verticesForFirst)/m_verticesPerSupplementary ;
173
+ return (vertexReferenceCount-verticesForFirst)/(verticesForFirst-m_indexing-> reuseCount ()) ;
67
174
}
68
175
69
176
// For when the geometric normal of the patch isn't enough and you want interpolated custom normals
@@ -92,11 +199,6 @@ class NBL_API2 IPolygonGeometry : public IIndexableGeometry<BufferType>
92
199
// For User defined semantics
93
200
inline const core::vector<SDataView>& getAuxAttributeViews () const {return m_auxAttributeViews;}
94
201
95
- // Simple geometries like point, line, triangle and patch have `m_verticesForFirst==m_verticesPerSupplementary`
96
- // Note that this is also true for adjacency lists, but they're the reason `m_verticesForFirst` is not named `m_order` or `m_n`
97
- // While strips and fans have `m_verticesForFirst>m_verticesPerSupplementary`
98
- inline uint16_t getVerticesForFirst () const {return m_verticesForFirst;}
99
- inline uint16_t getVerticesPerSupplementary () const {return m_verticesPerSupplementary;}
100
202
101
203
// Does not set the `transform` or `geometryFlags` fields, because it doesn't care about it.
102
204
// Also won't set second set of vertex data, opacity mipmaps, etc.
@@ -108,9 +210,9 @@ class NBL_API2 IPolygonGeometry : public IIndexableGeometry<BufferType>
108
210
{
109
211
auto indexType = EIT_UNKNOWN;
110
212
// disallowed index format
111
- if (m_indexView)
213
+ if (base_t :: m_indexView)
112
214
{
113
- switch (m_indexView.format )
215
+ switch (base_t :: m_indexView.format )
114
216
{
115
217
case EF_R16_UINT:
116
218
indexType = EIT_16BIT;
@@ -124,11 +226,11 @@ class NBL_API2 IPolygonGeometry : public IIndexableGeometry<BufferType>
124
226
if (indexType==EIT_UNKNOWN)
125
227
return retval;
126
228
}
127
- retval.vertexData [0 ] = m_positionView;
128
- retval.indexData = m_indexView;
129
- retval.maxVertex = m_positionView.getElementCount ();
130
- retval.vertexStride = m_positionView.getStride ();
131
- retval.vertexFormat = m_positionView.format ;
229
+ retval.vertexData [0 ] = base_t :: m_positionView;
230
+ retval.indexData = base_t :: m_indexView;
231
+ retval.maxVertex = base_t :: m_positionView.getElementCount ();
232
+ retval.vertexStride = base_t :: m_positionView.getStride ();
233
+ retval.vertexFormat = base_t :: m_positionView.format ;
132
234
retval.indexType = indexType;
133
235
}
134
236
return retval;
@@ -137,6 +239,17 @@ class NBL_API2 IPolygonGeometry : public IIndexableGeometry<BufferType>
137
239
protected:
138
240
virtual ~IPolygonGeometry () = default ;
139
241
242
+ //
243
+ inline bool setIndexView (SDataView&& view)
244
+ {
245
+ if (!view || view.isFormattedScalarInteger ())
246
+ {
247
+ m_indexView = std::move (view);
248
+ return true ;
249
+ }
250
+ return false ;
251
+ }
252
+
140
253
//
141
254
core::vector<SJointWeight> m_jointWeightViews = {};
142
255
//
@@ -145,9 +258,6 @@ class NBL_API2 IPolygonGeometry : public IIndexableGeometry<BufferType>
145
258
SDataView m_normalView = {};
146
259
//
147
260
uint32_t m_jointCount = 0 ;
148
- //
149
- uint16_t m_verticesForFirst = 1 ;
150
- uint16_t m_verticesPerSupplementary = 0 ;
151
261
};
152
262
153
263
}
0 commit comments