20#include <Qt3DCore/QAttribute>
21#include <Qt3DCore/QBuffer>
23#include "moc_qgsbillboardgeometry.cpp"
25using namespace Qt::StringLiterals;
29 , mVertexBuffer( new
Qt3DCore::QBuffer( this ) )
31 static constexpr float quadVertices[] = { -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f };
32 Qt3DCore::QBuffer *quadVertexBuffer =
new Qt3DCore::QBuffer(
this );
33 quadVertexBuffer->setData( QByteArray(
reinterpret_cast<const char *
>( quadVertices ),
sizeof( quadVertices ) ) );
35 Qt3DCore::QAttribute *quadVertexAttribute =
new Qt3DCore::QAttribute(
this );
36 quadVertexAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
37 quadVertexAttribute->setBuffer( quadVertexBuffer );
38 quadVertexAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
39 quadVertexAttribute->setVertexSize( 2 );
40 quadVertexAttribute->setByteOffset( 0 );
41 quadVertexAttribute->setByteStride( 2 *
sizeof(
float ) );
42 quadVertexAttribute->setCount( 4 );
43 quadVertexAttribute->setName( u
"vertexPosition"_s );
44 addAttribute( quadVertexAttribute );
46 setMode( Mode::PositionOnly );
49void QgsBillboardGeometry::setMode( Mode mode )
54 case Mode::PositionOnly:
55 stride = 3 *
sizeof( float );
57 case Mode::PositionAndTextureData:
58 stride = ( 3 + 2 + 2 ) *
sizeof(
float );
60 case Mode::PositionAndTextureDataWithPixelOffsets:
61 stride = ( 3 + 2 + 2 ) *
sizeof(
float ) + 2 *
sizeof( int );
65 if ( mPositionAttribute && mPositionAttribute->byteStride() == stride )
70 else if ( mPositionAttribute )
72 removeAttribute( mPositionAttribute );
73 delete mPositionAttribute;
74 mPositionAttribute =
nullptr;
77 mPositionAttribute =
new Qt3DCore::QAttribute(
this );
78 mPositionAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
79 mPositionAttribute->setBuffer( mVertexBuffer );
80 mPositionAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
81 mPositionAttribute->setVertexSize( 3 );
82 mPositionAttribute->setByteOffset( 0 );
83 mPositionAttribute->setByteStride( stride );
84 mPositionAttribute->setDivisor( 1 );
85 mPositionAttribute->setName(
"instancePosition" );
86 addAttribute( mPositionAttribute );
90 case Mode::PositionOnly:
92 if ( mAtlasOffsetAttribute )
94 removeAttribute( mAtlasOffsetAttribute );
95 delete mAtlasOffsetAttribute;
96 mAtlasOffsetAttribute =
nullptr;
98 if ( mAtlasSizeAttribute )
100 removeAttribute( mAtlasSizeAttribute );
101 delete mAtlasSizeAttribute;
102 mAtlasSizeAttribute =
nullptr;
104 if ( mAtlasPixelOffsetAttribute )
106 removeAttribute( mAtlasPixelOffsetAttribute );
107 delete mAtlasPixelOffsetAttribute;
108 mAtlasPixelOffsetAttribute =
nullptr;
113 case Mode::PositionAndTextureData:
115 if ( mAtlasPixelOffsetAttribute )
117 removeAttribute( mAtlasPixelOffsetAttribute );
118 delete mAtlasPixelOffsetAttribute;
119 mAtlasPixelOffsetAttribute =
nullptr;
122 mAtlasOffsetAttribute =
new Qt3DCore::QAttribute(
this );
123 mAtlasOffsetAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
124 mAtlasOffsetAttribute->setBuffer( mVertexBuffer );
125 mAtlasOffsetAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
126 mAtlasOffsetAttribute->setVertexSize( 2 );
127 mAtlasOffsetAttribute->setByteOffset( 3 *
sizeof(
float ) );
128 mAtlasOffsetAttribute->setByteStride( stride );
129 mAtlasOffsetAttribute->setDivisor( 1 );
130 mAtlasOffsetAttribute->setName( u
"atlasOffset"_s );
131 addAttribute( mAtlasOffsetAttribute );
133 mAtlasSizeAttribute =
new Qt3DCore::QAttribute(
this );
134 mAtlasSizeAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
135 mAtlasSizeAttribute->setBuffer( mVertexBuffer );
136 mAtlasSizeAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
137 mAtlasSizeAttribute->setVertexSize( 2 );
138 mAtlasSizeAttribute->setByteOffset( ( 3 + 2 ) *
sizeof(
float ) );
139 mAtlasSizeAttribute->setByteStride( stride );
140 mAtlasSizeAttribute->setDivisor( 1 );
141 mAtlasSizeAttribute->setName( u
"atlasSize"_s );
142 addAttribute( mAtlasSizeAttribute );
146 case Mode::PositionAndTextureDataWithPixelOffsets:
148 mAtlasOffsetAttribute =
new Qt3DCore::QAttribute(
this );
149 mAtlasOffsetAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
150 mAtlasOffsetAttribute->setBuffer( mVertexBuffer );
151 mAtlasOffsetAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
152 mAtlasOffsetAttribute->setVertexSize( 2 );
153 mAtlasOffsetAttribute->setByteOffset( 3 *
sizeof(
float ) );
154 mAtlasOffsetAttribute->setByteStride( stride );
155 mAtlasOffsetAttribute->setDivisor( 1 );
156 mAtlasOffsetAttribute->setName( u
"atlasOffset"_s );
157 addAttribute( mAtlasOffsetAttribute );
159 mAtlasSizeAttribute =
new Qt3DCore::QAttribute(
this );
160 mAtlasSizeAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
161 mAtlasSizeAttribute->setBuffer( mVertexBuffer );
162 mAtlasSizeAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
163 mAtlasSizeAttribute->setVertexSize( 2 );
164 mAtlasSizeAttribute->setByteOffset( ( 3 + 2 ) *
sizeof(
float ) );
165 mAtlasSizeAttribute->setByteStride( stride );
166 mAtlasSizeAttribute->setDivisor( 1 );
167 mAtlasSizeAttribute->setName( u
"atlasSize"_s );
168 addAttribute( mAtlasSizeAttribute );
170 mAtlasPixelOffsetAttribute =
new Qt3DCore::QAttribute(
this );
171 mAtlasPixelOffsetAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
172 mAtlasPixelOffsetAttribute->setBuffer( mVertexBuffer );
173 mAtlasPixelOffsetAttribute->setVertexBaseType( Qt3DCore::QAttribute::Int );
174 mAtlasPixelOffsetAttribute->setVertexSize( 2 );
175 mAtlasPixelOffsetAttribute->setByteOffset( ( 3 + 2 + 2 ) *
sizeof(
float ) );
176 mAtlasPixelOffsetAttribute->setByteStride( stride );
177 mAtlasPixelOffsetAttribute->setDivisor( 1 );
178 mAtlasPixelOffsetAttribute->setName( u
"pixelOffset"_s );
179 addAttribute( mAtlasPixelOffsetAttribute );
187 setMode( Mode::PositionOnly );
189 QByteArray vertexBufferData;
190 vertexBufferData.resize( vertices.size() * 3 *
sizeof(
float ) );
191 float *rawVertexArray =
reinterpret_cast<float *
>( vertexBufferData.data() );
193 for (
const auto &v : vertices )
195 rawVertexArray[idx++] = v.x();
196 rawVertexArray[idx++] = v.y();
197 rawVertexArray[idx++] = v.z();
200 mVertexCount = vertices.count();
201 mVertexBuffer->setData( vertexBufferData );
207#pragma pack( push, 1 )
208struct BillboardVertex
211 float textureAtlasOffset[2];
212 float textureAtlasSize[2];
215struct BillboardVertexWithPixelOffset : BillboardVertex
221template<
typename VertexType> QByteArray createVertexBuffer(
const QVector<QgsBillboardGeometry::BillboardAtlasData> &billboards )
224 buffer.resize( billboards.size() *
sizeof( VertexType ) );
225 auto *vertexData =
reinterpret_cast<VertexType *
>( buffer.data() );
230 VertexType &vertex = vertexData[idx++];
232 vertex.position[0] = billboard.position.x();
233 vertex.position[1] = billboard.position.y();
234 vertex.position[2] = billboard.position.z();
236 vertex.textureAtlasOffset[0] = billboard.textureAtlasOffset.x();
237 vertex.textureAtlasOffset[1] = billboard.textureAtlasOffset.y();
239 vertex.textureAtlasSize[0] = billboard.textureAtlasSize.x();
240 vertex.textureAtlasSize[1] = billboard.textureAtlasSize.y();
242 if constexpr ( std::is_same_v<VertexType, BillboardVertexWithPixelOffset> )
244 vertex.pixelOffset[0] = billboard.pixelOffset.x();
245 vertex.pixelOffset[1] = billboard.pixelOffset.y();
254 if ( includePixelOffsets )
255 setMode( Mode::PositionAndTextureDataWithPixelOffsets );
257 setMode( Mode::PositionAndTextureData );
260 QByteArray vertexBufferData;
261 if ( includePixelOffsets )
263 vertexBufferData = createVertexBuffer<BillboardVertexWithPixelOffset>( billboards );
267 vertexBufferData = createVertexBuffer<BillboardVertex>( billboards );
270 mVertexCount = billboards.count();
271 mVertexBuffer->setData( vertexBufferData );
void countChanged(int count)
Signal when the number of points changed.
void setBillboardData(const QVector< QgsBillboardGeometry::BillboardAtlasData > &billboards, bool includePixelOffsets=false)
Set the position and texture data for the billboard.
void setPositions(const QVector< QVector3D > &vertices)
Sets the vertex positions for the billboards.
QgsBillboardGeometry(Qt3DCore::QNode *parent=nullptr)
Constructor of QgsBillboardGeometry.
Contains the billboard positions and texture information.