1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "gridgeometry_p.h"
5#include <QtQuick3DRuntimeRender/private/qssgrendergeometry_p.h>
6
7/*!
8 \qmltype GridGeometry
9 \inqmlmodule QtQuick3D.Helpers
10 \inherits Geometry
11 \brief A custom geometry provider for rendering grids.
12
13 This helper implements grid geometry, which allows showing a grid in a scene.
14
15 For example, the following snippet would display a grid with 19 cells in
16 both directions in a scene that has one light. Without further
17 transformations, the grid is facing the camera by default.
18
19 \image gridgeometry.jpg
20
21 \badcode
22 View3D {
23 anchors.fill: parent
24 camera: camera
25
26 PerspectiveCamera {
27 id: camera
28 position: Qt.vector3d(0, 0, 600)
29 }
30
31 DirectionalLight {
32 position: Qt.vector3d(-500, 500, -100)
33 color: Qt.rgba(0.4, 0.2, 0.6, 1.0)
34 ambientColor: Qt.rgba(0.1, 0.1, 0.1, 1.0)
35 }
36
37 Model {
38 scale: Qt.vector3d(100, 100, 100)
39 geometry: GridGeometry {
40 horizontalLines: 20
41 verticalLines: 20
42 }
43 materials: [ DefaultMaterial { } ]
44 }
45 }
46 \endcode
47
48 \sa {Qt Quick 3D - Custom Geometry Example}, Model
49*/
50
51/*! \qmlproperty int GridGeometry::horizontalLines
52 Specifies the number of horizontal lines in a grid. The default value is 1000.
53*/
54/*! \qmlproperty int GridGeometry::verticalLines
55 Specifies the number of vertical lines in a grid. The default value is 1000.
56*/
57/*! \qmlproperty real GridGeometry::horizontalStep
58 Specifies the spacing between horizontal lines. The default value is 0.1.
59*/
60/*! \qmlproperty real GridGeometry::verticalStep
61 Specifies the spacing between vertical lines. The default value is 0.1.
62*/
63
64GridGeometry::GridGeometry()
65 : QQuick3DGeometry()
66{
67 updateData();
68}
69
70GridGeometry::~GridGeometry()
71{
72
73}
74
75int GridGeometry::horizontalLines() const
76{
77 return m_horLines;
78}
79
80int GridGeometry::verticalLines() const
81{
82 return m_vertLines;
83}
84
85float GridGeometry::horizontalStep() const
86{
87 return m_horStep;
88}
89
90float GridGeometry::verticalStep() const
91{
92 return m_vertStep;
93}
94
95void GridGeometry::setHorizontalLines(int count)
96{
97 count = qMax(a: count, b: 1);
98 if (m_horLines == count)
99 return;
100 m_horLines = qMax(a: count, b: 1);
101 emit horizontalLinesChanged();
102 updateData();
103 update();
104}
105
106void GridGeometry::setVerticalLines(int count)
107{
108 count = qMax(a: count, b: 1);
109 if (m_vertLines == count)
110 return;
111 m_vertLines = qMax(a: count, b: 1);
112 emit verticalLinesChanged();
113 updateData();
114 update();
115}
116
117void GridGeometry::setHorizontalStep(float step)
118{
119 step = qMax(a: step, b: 0.0f);
120 if (qFuzzyCompare(p1: m_horStep, p2: step))
121 return;
122 m_horStep = step;
123 emit horizontalStepChanged();
124 updateData();
125 update();
126}
127
128void GridGeometry::setVerticalStep(float step)
129{
130 step = qMax(a: step, b: 0.0f);
131 if (qFuzzyCompare(p1: m_vertStep, p2: step))
132 return;
133 m_vertStep = step;
134 emit verticalStepChanged();
135 updateData();
136 update();
137}
138
139static void fillVertexData(QByteArray &vertexData, int horLines, float horStep,
140 int vertLines, float vertStep)
141{
142 const int size = (horLines + vertLines) * sizeof(float) * 8 * 2;
143 vertexData.resize(size);
144 float *dataPtr = reinterpret_cast<float *>(vertexData.data());
145
146 float y0 = -float(horLines - 1) * horStep * .5f;
147 float x0 = -float(vertLines - 1) * vertStep * .5f;
148 float y1 = -y0;
149 float x1 = -x0;
150
151 for (int i = 0; i < horLines; ++i) {
152 // start position
153 dataPtr[0] = x0;
154 dataPtr[1] = y0 + i * horStep;
155 dataPtr[2] = .0f;
156 dataPtr[3] = 1.f;
157
158 dataPtr[4] = 0;
159 dataPtr[5] = 0;
160 dataPtr[6] = 1.f;
161 dataPtr[7] = 0;
162
163 dataPtr += 8;
164
165 // end position
166 dataPtr[0] = x1;
167 dataPtr[1] = y0 + i * horStep;
168 dataPtr[2] = .0f;
169 dataPtr[3] = 1.f;
170
171 dataPtr[4] = 0;
172 dataPtr[5] = 0;
173 dataPtr[6] = 1.f;
174 dataPtr[7] = 0;
175
176 dataPtr += 8;
177 }
178
179 for (int i = 0; i < vertLines; ++i) {
180 // start position
181 dataPtr[0] = x0 + i * vertStep;
182 dataPtr[1] = y0;
183 dataPtr[2] = .0f;
184 dataPtr[3] = 1.f;
185
186 dataPtr[4] = 0;
187 dataPtr[5] = 0;
188 dataPtr[6] = 1.f;
189 dataPtr[7] = 0;
190
191 dataPtr += 8;
192
193 // end position
194 dataPtr[0] = x0 + i * vertStep;
195 dataPtr[1] = y1;
196 dataPtr[2] = .0f;
197 dataPtr[3] = 1.f;
198
199 dataPtr[4] = 0;
200 dataPtr[5] = 0;
201 dataPtr[6] = 1.f;
202 dataPtr[7] = 0;
203
204 dataPtr += 8;
205 }
206}
207
208void GridGeometry::updateData()
209{
210 QByteArray vertexData;
211 fillVertexData(vertexData, horLines: m_horLines, horStep: m_horStep, vertLines: m_vertLines, vertStep: m_vertStep);
212 clear();
213 addAttribute(semantic: QQuick3DGeometry::Attribute::PositionSemantic, offset: 0,
214 componentType: QQuick3DGeometry::Attribute::ComponentType::F32Type);
215 addAttribute(semantic: QQuick3DGeometry::Attribute::NormalSemantic, offset: 16,
216 componentType: QQuick3DGeometry::Attribute::ComponentType::F32Type);
217 setStride(32);
218 setVertexData(vertexData);
219 setPrimitiveType(QQuick3DGeometry::PrimitiveType::Lines);
220 setBounds(min: QVector3D(float(-m_vertLines / 2), float(-m_horLines / 2), 0.0f) * m_horStep,
221 max: QVector3D(float(m_vertLines / 2), float(m_horLines / 2), 0.0f) * m_vertStep);
222}
223

source code of qtquick3d/src/helpers/gridgeometry.cpp