18 #include <Qt3DRender/QAttribute>
19 #include <Qt3DRender/QBuffer>
20 #include <Qt3DRender/QBufferDataGenerator>
30 mWithNormals( _withNormals ),
31 mInvertNormals( _invertNormals ),
32 mAddBackFaces( _addBackFaces ),
33 mAddTextureCoords( _addTextureCoords )
35 mVertexBuffer =
new Qt3DRender::QBuffer(
this );
37 const QgsTessellator tmpTess( 0, 0, mWithNormals,
false,
false,
false, mAddTextureCoords );
38 const int stride = tmpTess.
stride();
40 mPositionAttribute =
new Qt3DRender::QAttribute(
this );
41 mPositionAttribute->setName( Qt3DRender::QAttribute::defaultPositionAttributeName() );
42 mPositionAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
43 mPositionAttribute->setVertexSize( 3 );
44 mPositionAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
45 mPositionAttribute->setBuffer( mVertexBuffer );
46 mPositionAttribute->setByteStride( stride );
47 mPositionAttribute->setByteOffset( 0 );
48 addAttribute( mPositionAttribute );
52 mNormalAttribute =
new Qt3DRender::QAttribute(
this );
53 mNormalAttribute->setName( Qt3DRender::QAttribute::defaultNormalAttributeName() );
54 mNormalAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
55 mNormalAttribute->setVertexSize( 3 );
56 mNormalAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
57 mNormalAttribute->setBuffer( mVertexBuffer );
58 mNormalAttribute->setByteStride( stride );
59 mNormalAttribute->setByteOffset( 3 *
sizeof(
float ) );
60 addAttribute( mNormalAttribute );
62 if ( mAddTextureCoords )
64 mTextureCoordsAttribute =
new Qt3DRender::QAttribute(
this );
65 mTextureCoordsAttribute->setName( Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName() );
66 mTextureCoordsAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
67 mTextureCoordsAttribute->setVertexSize( 2 );
68 mTextureCoordsAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
69 mTextureCoordsAttribute->setBuffer( mVertexBuffer );
70 mTextureCoordsAttribute->setByteStride( stride );
71 mTextureCoordsAttribute->setByteOffset( mWithNormals ? 6 *
sizeof(
float ) : 3 *
sizeof(
float ) );
72 addAttribute( mTextureCoordsAttribute );
78 Q_ASSERT( polygons.count() == featureIds.count() );
79 mTriangleIndexStartingIndices.reserve( polygons.count() );
80 mTriangleIndexFids.reserve( polygons.count() );
82 QgsTessellator tessellator( origin.
x(), origin.
y(), mWithNormals, mInvertNormals, mAddBackFaces,
false, mAddTextureCoords );
83 for (
int i = 0; i < polygons.count(); ++i )
86 const uint startingTriangleIndex =
static_cast<uint
>( tessellator.
dataVerticesCount() / 3 );
87 mTriangleIndexStartingIndices.append( startingTriangleIndex );
88 mTriangleIndexFids.append( featureIds[i] );
91 const float extr = extrusionHeightPerPolygon.
isEmpty() ? extrusionHeight : extrusionHeightPerPolygon.at( i );
95 qDeleteAll( polygons );
97 const QByteArray data( (
const char * )tessellator.
data().constData(), tessellator.
data().count() *
sizeof(
float ) );
98 const int nVerts = data.count() / tessellator.
stride();
100 mVertexBuffer->setData( data );
101 mPositionAttribute->setCount( nVerts );
102 if ( mNormalAttribute )
103 mNormalAttribute->setCount( nVerts );
104 if ( mAddTextureCoords )
105 mTextureCoordsAttribute->setCount( nVerts );
110 mTriangleIndexStartingIndices = triangleIndexStartingIndices;
111 mTriangleIndexFids = triangleIndexFids;
113 mVertexBuffer->setData( vertexBufferData );
114 mPositionAttribute->setCount( vertexCount );
115 if ( mNormalAttribute )
116 mNormalAttribute->setCount( vertexCount );
117 if ( mTextureCoordsAttribute )
118 mTextureCoordsAttribute->setCount( vertexCount );
123 static int binary_search( uint v,
const uint *data,
int count )
126 int idx1 = count - 1;
128 if ( v < data[0] || v >= data[count - 1] )
131 while ( idx0 != idx1 )
133 const int idxPivot = ( idx0 + idx1 ) / 2;
134 const uint pivot = data[idxPivot];
137 if ( data[idxPivot + 1] > v )
151 const int i = binary_search( triangleIndex, mTriangleIndexStartingIndices.constData(), mTriangleIndexStartingIndices.count() );
152 return i != -1 ? mTriangleIndexFids[i] :
FID_NULL;