Revision control

++ // Copyright (C) 2019 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
++ // Qt-Security score:significant reason:default
++
++
++ #include "gridgeometry_p.h"
++ #include <QtQuick3DRuntimeRender/private/qssgrendergeometry_p.h>
++
++ /*!
++ \qmltype GridGeometry
++ \inqmlmodule QtQuick3D.Helpers
++ \inherits Geometry
++ \brief A custom geometry provider for rendering grids.
++
++ This helper implements grid geometry, which allows showing a grid in a scene.
++
++ For example, the following snippet would display a grid with 19 cells in
++ both directions in a scene that has one light. Without further
++ transformations, the grid is facing the camera by default.
++
++ \image gridgeometry.jpg
++ {19 by 19 cell grid facing camera with directional lighting}
++
++ \badcode
++ View3D {
++ anchors.fill: parent
++ camera: camera
++
++ PerspectiveCamera {
++ id: camera
++ position: Qt.vector3d(0, 0, 600)
++ }
++
++ DirectionalLight {
++ position: Qt.vector3d(-500, 500, -100)
++ color: Qt.rgba(0.4, 0.2, 0.6, 1.0)
++ ambientColor: Qt.rgba(0.1, 0.1, 0.1, 1.0)
++ }
++
++ Model {
++ scale: Qt.vector3d(100, 100, 100)
++ geometry: GridGeometry {
++ horizontalLines: 20
++ verticalLines: 20
++ }
++ materials: [ DefaultMaterial { } ]
++ }
++ }
++ \endcode
++
++ \sa {Qt Quick 3D - Custom Geometry Example}, Model
++ */
++
++ /*! \qmlproperty int GridGeometry::horizontalLines
++ Specifies the number of horizontal lines in a grid. The default value is 1000.
++ */
++ /*! \qmlproperty int GridGeometry::verticalLines
++ Specifies the number of vertical lines in a grid. The default value is 1000.
++ */
++ /*! \qmlproperty real GridGeometry::horizontalStep
++ Specifies the spacing between horizontal lines. The default value is 0.1.
++ */
++ /*! \qmlproperty real GridGeometry::verticalStep
++ Specifies the spacing between vertical lines. The default value is 0.1.
++ */
++
++ GridGeometry::GridGeometry()
++ : QQuick3DGeometry()
++ {
++ updateData();
++ }
++
++ GridGeometry::~GridGeometry()
++ {
++
++ }
++
++ int GridGeometry::horizontalLines() const
++ {
++ return m_horLines;
++ }
++
++ int GridGeometry::verticalLines() const
++ {
++ return m_vertLines;
++ }
++
++ float GridGeometry::horizontalStep() const
++ {
++ return m_horStep;
++ }
++
++ float GridGeometry::verticalStep() const
++ {
++ return m_vertStep;
++ }
++
++ void GridGeometry::setHorizontalLines(int count)
++ {
++ count = qMax(count, 1);
++ if (m_horLines == count)
++ return;
++ m_horLines = qMax(count, 1);
++ emit horizontalLinesChanged();
++ updateData();
++ update();
++ emit geometryChanged();
++ }
++
++ void GridGeometry::setVerticalLines(int count)
++ {
++ count = qMax(count, 1);
++ if (m_vertLines == count)
++ return;
++ m_vertLines = qMax(count, 1);
++ emit verticalLinesChanged();
++ updateData();
++ update();
++ emit geometryChanged();
++ }
++
++ void GridGeometry::setHorizontalStep(float step)
++ {
++ step = qMax(step, 0.0f);
++ if (qFuzzyCompare(m_horStep, step))
++ return;
++ m_horStep = step;
++ emit horizontalStepChanged();
++ updateData();
++ update();
++ emit geometryChanged();
++ }
++
++ void GridGeometry::setVerticalStep(float step)
++ {
++ step = qMax(step, 0.0f);
++ if (qFuzzyCompare(m_vertStep, step))
++ return;
++ m_vertStep = step;
++ emit verticalStepChanged();
++ updateData();
++ update();
++ emit geometryChanged();
++ }
++
++ static void fillVertexData(QByteArray &vertexData, int horLines, float horStep,
++ int vertLines, float vertStep)
++ {
++ const int size = (horLines + vertLines) * sizeof(float) * 8 * 2;
++ vertexData.resize(size);
++ float *dataPtr = reinterpret_cast<float *>(vertexData.data());
++
++ float y0 = -float(horLines - 1) * horStep * .5f;
++ float x0 = -float(vertLines - 1) * vertStep * .5f;
++ float y1 = -y0;
++ float x1 = -x0;
++
++ for (int i = 0; i < horLines; ++i) {
++ // start position
++ dataPtr[0] = x0;
++ dataPtr[1] = y0 + i * horStep;
++ dataPtr[2] = .0f;
++ dataPtr[3] = 1.f;
++
++ dataPtr[4] = 0;
++ dataPtr[5] = 0;
++ dataPtr[6] = 1.f;
++ dataPtr[7] = 0;
++
++ dataPtr += 8;
++
++ // end position
++ dataPtr[0] = x1;
++ dataPtr[1] = y0 + i * horStep;
++ dataPtr[2] = .0f;
++ dataPtr[3] = 1.f;
++
++ dataPtr[4] = 0;
++ dataPtr[5] = 0;
++ dataPtr[6] = 1.f;
++ dataPtr[7] = 0;
++
++ dataPtr += 8;
++ }
++
++ for (int i = 0; i < vertLines; ++i) {
++ // start position
++ dataPtr[0] = x0 + i * vertStep;
++ dataPtr[1] = y0;
++ dataPtr[2] = .0f;
++ dataPtr[3] = 1.f;
++
++ dataPtr[4] = 0;
++ dataPtr[5] = 0;
++ dataPtr[6] = 1.f;
++ dataPtr[7] = 0;
++
++ dataPtr += 8;
++
++ // end position
++ dataPtr[0] = x0 + i * vertStep;
++ dataPtr[1] = y1;
++ dataPtr[2] = .0f;
++ dataPtr[3] = 1.f;
++
++ dataPtr[4] = 0;
++ dataPtr[5] = 0;
++ dataPtr[6] = 1.f;
++ dataPtr[7] = 0;
++
++ dataPtr += 8;
++ }
++ }
++
++ void GridGeometry::updateData()
++ {
++ QByteArray vertexData;
++ fillVertexData(vertexData, m_horLines, m_horStep, m_vertLines, m_vertStep);
++ clear();
++ addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0,
++ QQuick3DGeometry::Attribute::ComponentType::F32Type);
++ addAttribute(QQuick3DGeometry::Attribute::NormalSemantic, 16,
++ QQuick3DGeometry::Attribute::ComponentType::F32Type);
++ setStride(32);
++ setVertexData(vertexData);
++ setPrimitiveType(QQuick3DGeometry::PrimitiveType::Lines);
++ setBounds(QVector3D(float(-m_vertLines / 2), float(-m_horLines / 2), 0.0f) * m_horStep,
++ QVector3D(float(m_vertLines / 2), float(m_horLines / 2), 0.0f) * m_vertStep);
++ }