18
18
#include < Qt3DRender/qbuffer.h>
19
19
#include < Qt3DRender/qbufferdatagenerator.h>
20
20
#include < limits>
21
+ #include < cmath>
21
22
22
23
// /@cond PRIVATE
23
24
@@ -51,6 +52,10 @@ static QByteArray createPlaneVertexData( int res, float skirtHeight, const QByte
51
52
const float du = 1.0 / ( resolution.width () - 1 );
52
53
const float dv = 1.0 / ( resolution.height () - 1 );
53
54
55
+ // the height of vertices with no-data value... the value should not really matter
56
+ // as we do not create valid triangles that would use such vertices
57
+ const float noDataHeight = 0 ;
58
+
54
59
// Iterate over z
55
60
for ( int j = -1 ; j <= resolution.height (); ++j )
56
61
{
@@ -71,6 +76,9 @@ static QByteArray createPlaneVertexData( int res, float skirtHeight, const QByte
71
76
else
72
77
height = zData[ jBound * resolution.width () + iBound ] - skirtHeight;
73
78
79
+ if ( std::isnan ( height ) )
80
+ height = noDataHeight;
81
+
74
82
// position
75
83
*fptr++ = x;
76
84
*fptr++ = height;
@@ -91,8 +99,23 @@ static QByteArray createPlaneVertexData( int res, float skirtHeight, const QByte
91
99
return bufferBytes;
92
100
}
93
101
102
+ inline int ijToHeightMapIndex ( int i, int j, int numVerticesX, int numVerticesZ )
103
+ {
104
+ i = qBound ( 1 , i, numVerticesX - 1 ) - 1 ;
105
+ j = qBound ( 1 , j, numVerticesZ - 1 ) - 1 ;
106
+ return j * ( numVerticesX - 2 ) + i;
107
+ }
108
+
109
+
110
+ static bool hasNoData ( int i, int j, const float *heightMap, int numVerticesX, int numVerticesZ )
111
+ {
112
+ return std::isnan ( heightMap[ ijToHeightMapIndex ( i, j, numVerticesX, numVerticesZ ) ] ) ||
113
+ std::isnan ( heightMap[ ijToHeightMapIndex ( i + 1 , j, numVerticesX, numVerticesZ ) ] ) ||
114
+ std::isnan ( heightMap[ ijToHeightMapIndex ( i, j + 1 , numVerticesX, numVerticesZ ) ] ) ||
115
+ std::isnan ( heightMap[ ijToHeightMapIndex ( i + 1 , j + 1 , numVerticesX, numVerticesZ ) ] );
116
+ }
94
117
95
- static QByteArray createPlaneIndexData ( int res )
118
+ static QByteArray createPlaneIndexData ( int res, const QByteArray &heightMap )
96
119
{
97
120
QSize resolution ( res, res );
98
121
int numVerticesX = resolution.width () + 2 ;
@@ -106,6 +129,8 @@ static QByteArray createPlaneIndexData( int res )
106
129
indexBytes.resize ( indices * sizeof ( quint32 ) );
107
130
quint32 *indexPtr = reinterpret_cast <quint32 *>( indexBytes.data () );
108
131
132
+ const float *heightMapFloat = reinterpret_cast <const float *>( heightMap.constData () );
133
+
109
134
// Iterate over z
110
135
for ( int j = 0 ; j < numVerticesZ - 1 ; ++j )
111
136
{
@@ -115,6 +140,20 @@ static QByteArray createPlaneIndexData( int res )
115
140
// Iterate over x
116
141
for ( int i = 0 ; i < numVerticesX - 1 ; ++i )
117
142
{
143
+ if ( hasNoData ( i, j, heightMapFloat, numVerticesX, numVerticesZ ) )
144
+ {
145
+ // at least one corner of the quad has no-data value
146
+ // so let's make two invalid triangles
147
+ *indexPtr++ = rowStartIndex + i;
148
+ *indexPtr++ = rowStartIndex + i;
149
+ *indexPtr++ = rowStartIndex + i;
150
+
151
+ *indexPtr++ = rowStartIndex + i;
152
+ *indexPtr++ = rowStartIndex + i;
153
+ *indexPtr++ = rowStartIndex + i;
154
+ continue ;
155
+ }
156
+
118
157
// Split quad into two triangles
119
158
*indexPtr++ = rowStartIndex + i;
120
159
*indexPtr++ = nextRowStartIndex + i;
@@ -169,13 +208,14 @@ class PlaneVertexBufferFunctor : public QBufferDataGenerator
169
208
class PlaneIndexBufferFunctor : public QBufferDataGenerator
170
209
{
171
210
public:
172
- explicit PlaneIndexBufferFunctor ( int resolution )
211
+ explicit PlaneIndexBufferFunctor ( int resolution, const QByteArray &heightMap )
173
212
: mResolution( resolution )
213
+ , mHeightMap( heightMap )
174
214
{}
175
215
176
216
QByteArray operator ()() final
177
217
{
178
- return createPlaneIndexData ( mResolution );
218
+ return createPlaneIndexData ( mResolution , mHeightMap );
179
219
}
180
220
181
221
bool operator ==( const QBufferDataGenerator &other ) const final
@@ -190,6 +230,7 @@ class PlaneIndexBufferFunctor : public QBufferDataGenerator
190
230
191
231
private:
192
232
int mResolution ;
233
+ QByteArray mHeightMap ;
193
234
};
194
235
195
236
@@ -254,7 +295,7 @@ void DemTerrainTileGeometry::init()
254
295
mIndexAttribute ->setCount ( faces * 3 );
255
296
256
297
mVertexBuffer ->setDataGenerator ( QSharedPointer<PlaneVertexBufferFunctor>::create ( mResolution , mSkirtHeight , mHeightMap ) );
257
- mIndexBuffer ->setDataGenerator ( QSharedPointer<PlaneIndexBufferFunctor>::create ( mResolution ) );
298
+ mIndexBuffer ->setDataGenerator ( QSharedPointer<PlaneIndexBufferFunctor>::create ( mResolution , mHeightMap ) );
258
299
259
300
addAttribute ( mPositionAttribute );
260
301
addAttribute ( mTexCoordAttribute );
0 commit comments