20#include <Qt3DCore/QAttribute>
21#include <Qt3DCore/QBuffer>
23#include "moc_qgsbillboardgeometry.cpp"
25using namespace Qt::StringLiterals;
29 , mVertexBuffer( new
Qt3DCore::QBuffer( this ) )
31 setMode( Mode::PositionOnly );
34void QgsBillboardGeometry::setMode( Mode mode )
39 case Mode::PositionOnly:
40 stride = 3 *
sizeof( float );
42 case Mode::PositionAndTextureData:
43 stride = ( 3 + 2 + 2 ) *
sizeof(
float );
45 case Mode::PositionAndTextureDataWithPixelOffsets:
46 stride = ( 3 + 2 + 2 ) *
sizeof(
float ) + 2 *
sizeof( int );
50 if ( mPositionAttribute && mPositionAttribute->byteStride() == stride )
55 else if ( mPositionAttribute )
57 removeAttribute( mPositionAttribute );
58 delete mPositionAttribute;
59 mPositionAttribute =
nullptr;
62 mPositionAttribute =
new Qt3DCore::QAttribute(
this );
63 mPositionAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
64 mPositionAttribute->setBuffer( mVertexBuffer );
65 mPositionAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
66 mPositionAttribute->setVertexSize( 3 );
67 mPositionAttribute->setByteOffset( 0 );
68 mPositionAttribute->setByteStride( stride );
69 mPositionAttribute->setName( Qt3DCore::QAttribute::defaultPositionAttributeName() );
70 addAttribute( mPositionAttribute );
74 case Mode::PositionOnly:
76 if ( mAtlasOffsetAttribute )
78 removeAttribute( mAtlasOffsetAttribute );
79 delete mAtlasOffsetAttribute;
80 mAtlasOffsetAttribute =
nullptr;
82 if ( mAtlasSizeAttribute )
84 removeAttribute( mAtlasSizeAttribute );
85 delete mAtlasSizeAttribute;
86 mAtlasSizeAttribute =
nullptr;
88 if ( mAtlasPixelOffsetAttribute )
90 removeAttribute( mAtlasPixelOffsetAttribute );
91 delete mAtlasPixelOffsetAttribute;
92 mAtlasPixelOffsetAttribute =
nullptr;
97 case Mode::PositionAndTextureData:
99 if ( mAtlasPixelOffsetAttribute )
101 removeAttribute( mAtlasPixelOffsetAttribute );
102 delete mAtlasPixelOffsetAttribute;
103 mAtlasPixelOffsetAttribute =
nullptr;
106 mAtlasOffsetAttribute =
new Qt3DCore::QAttribute(
this );
107 mAtlasOffsetAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
108 mAtlasOffsetAttribute->setBuffer( mVertexBuffer );
109 mAtlasOffsetAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
110 mAtlasOffsetAttribute->setVertexSize( 2 );
111 mAtlasOffsetAttribute->setByteOffset( 3 *
sizeof(
float ) );
112 mAtlasOffsetAttribute->setByteStride( stride );
113 mAtlasOffsetAttribute->setName( u
"atlasOffset"_s );
114 addAttribute( mAtlasOffsetAttribute );
116 mAtlasSizeAttribute =
new Qt3DCore::QAttribute(
this );
117 mAtlasSizeAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
118 mAtlasSizeAttribute->setBuffer( mVertexBuffer );
119 mAtlasSizeAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
120 mAtlasSizeAttribute->setVertexSize( 2 );
121 mAtlasSizeAttribute->setByteOffset( ( 3 + 2 ) *
sizeof(
float ) );
122 mAtlasSizeAttribute->setByteStride( stride );
123 mAtlasSizeAttribute->setName( u
"atlasSize"_s );
124 addAttribute( mAtlasSizeAttribute );
128 case Mode::PositionAndTextureDataWithPixelOffsets:
130 mAtlasOffsetAttribute =
new Qt3DCore::QAttribute(
this );
131 mAtlasOffsetAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
132 mAtlasOffsetAttribute->setBuffer( mVertexBuffer );
133 mAtlasOffsetAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
134 mAtlasOffsetAttribute->setVertexSize( 2 );
135 mAtlasOffsetAttribute->setByteOffset( 3 *
sizeof(
float ) );
136 mAtlasOffsetAttribute->setByteStride( stride );
137 mAtlasOffsetAttribute->setName( u
"atlasOffset"_s );
138 addAttribute( mAtlasOffsetAttribute );
140 mAtlasSizeAttribute =
new Qt3DCore::QAttribute(
this );
141 mAtlasSizeAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
142 mAtlasSizeAttribute->setBuffer( mVertexBuffer );
143 mAtlasSizeAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
144 mAtlasSizeAttribute->setVertexSize( 2 );
145 mAtlasSizeAttribute->setByteOffset( ( 3 + 2 ) *
sizeof(
float ) );
146 mAtlasSizeAttribute->setByteStride( stride );
147 mAtlasSizeAttribute->setName( u
"atlasSize"_s );
148 addAttribute( mAtlasSizeAttribute );
150 mAtlasPixelOffsetAttribute =
new Qt3DCore::QAttribute(
this );
151 mAtlasPixelOffsetAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
152 mAtlasPixelOffsetAttribute->setBuffer( mVertexBuffer );
153 mAtlasPixelOffsetAttribute->setVertexBaseType( Qt3DCore::QAttribute::Int );
154 mAtlasPixelOffsetAttribute->setVertexSize( 2 );
155 mAtlasPixelOffsetAttribute->setByteOffset( ( 3 + 2 + 2 ) *
sizeof(
float ) );
156 mAtlasPixelOffsetAttribute->setByteStride( stride );
157 mAtlasPixelOffsetAttribute->setName( u
"pixelOffset"_s );
158 addAttribute( mAtlasPixelOffsetAttribute );
166 setMode( Mode::PositionOnly );
168 QByteArray vertexBufferData;
169 vertexBufferData.resize( vertices.size() * 3 *
sizeof(
float ) );
170 float *rawVertexArray =
reinterpret_cast<float *
>( vertexBufferData.data() );
172 for (
const auto &v : vertices )
174 rawVertexArray[idx++] = v.x();
175 rawVertexArray[idx++] = v.y();
176 rawVertexArray[idx++] = v.z();
179 mVertexCount = vertices.count();
180 mVertexBuffer->setData( vertexBufferData );
186#pragma pack( push, 1 )
187struct BillboardVertex
190 float textureAtlasOffset[2];
191 float textureAtlasSize[2];
194struct BillboardVertexWithPixelOffset : BillboardVertex
200template<
typename VertexType>
201QByteArray createVertexBuffer(
const QVector<QgsBillboardGeometry::BillboardAtlasData> &billboards )
204 buffer.resize( billboards.size() *
sizeof( VertexType ) );
205 auto *vertexData =
reinterpret_cast<VertexType *
>( buffer.data() );
210 VertexType &vertex = vertexData[idx++];
212 vertex.position[0] = billboard.position.x();
213 vertex.position[1] = billboard.position.y();
214 vertex.position[2] = billboard.position.z();
216 vertex.textureAtlasOffset[0] = billboard.textureAtlasOffset.x();
217 vertex.textureAtlasOffset[1] = billboard.textureAtlasOffset.y();
219 vertex.textureAtlasSize[0] = billboard.textureAtlasSize.x();
220 vertex.textureAtlasSize[1] = billboard.textureAtlasSize.y();
222 if constexpr ( std::is_same_v<VertexType, BillboardVertexWithPixelOffset> )
224 vertex.pixelOffset[0] = billboard.pixelOffset.x();
225 vertex.pixelOffset[1] = billboard.pixelOffset.y();
234 if ( includePixelOffsets )
235 setMode( Mode::PositionAndTextureDataWithPixelOffsets );
237 setMode( Mode::PositionAndTextureData );
240 QByteArray vertexBufferData;
241 if ( includePixelOffsets )
243 vertexBufferData = createVertexBuffer<BillboardVertexWithPixelOffset>( billboards );
247 vertexBufferData = createVertexBuffer<BillboardVertex>( billboards );
250 mVertexCount = billboards.count();
251 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.