forked from qt-creator/qt-creator
QmlDesigner: Implement grid zooming
Grid zooms in and out according to camera zoom so that grid spacing is neither too condense nor too sparse. Also changed the grid color to be a bit darker and few other small tweaks. PS: if the view camera is panned, the grid will not work correctly. This is due to issues with the camera zoom calculations and is not part of this commit. Task-number: QDS-1566 Change-Id: Ib08d5387b028b8d870df9ecf88a5766eae5a509e Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -79,9 +79,11 @@ Window {
|
||||
{"usePerspective": usePerspective,
|
||||
"showSceneLight": showEditLight,
|
||||
"importScene": activeScene,
|
||||
"cameraZoomFactor": cameraControl._zoomFactor,
|
||||
"z": 1});
|
||||
editView.usePerspective = Qt.binding(function() {return usePerspective;});
|
||||
editView.showSceneLight = Qt.binding(function() {return showEditLight;});
|
||||
editView.cameraZoomFactor = Qt.binding(function() {return cameraControl._zoomFactor;});
|
||||
|
||||
selectionBoxes.length = 0;
|
||||
}
|
||||
|
@@ -32,11 +32,13 @@ Node {
|
||||
|
||||
property alias lines: gridGeometry.lines
|
||||
property alias step: gridGeometry.step
|
||||
property alias subdivAlpha: subGridMaterial.opacity
|
||||
|
||||
rotation.x: 90
|
||||
|
||||
// Note: Only one instance of HelperGrid is supported, as the geometry names are fixed
|
||||
Model {
|
||||
|
||||
Model { // Main grid lines
|
||||
geometry: GridGeometry {
|
||||
id: gridGeometry
|
||||
name: "3D Edit View Helper Grid"
|
||||
@@ -45,13 +47,32 @@ Node {
|
||||
materials: [
|
||||
DefaultMaterial {
|
||||
id: mainGridMaterial
|
||||
emissiveColor: "#cccccc"
|
||||
emissiveColor: "#aaaaaa"
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullingMode: Material.DisableCulling
|
||||
}
|
||||
]
|
||||
}
|
||||
Model {
|
||||
|
||||
Model { // Subdivision lines
|
||||
geometry: GridGeometry {
|
||||
lines: gridGeometry.lines
|
||||
step: gridGeometry.step
|
||||
isSubdivision: true
|
||||
name: "3D Edit View Helper Grid subdivisions"
|
||||
}
|
||||
|
||||
materials: [
|
||||
DefaultMaterial {
|
||||
id: subGridMaterial
|
||||
emissiveColor: mainGridMaterial.emissiveColor
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullingMode: Material.DisableCulling
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Model { // Z Axis
|
||||
geometry: GridGeometry {
|
||||
lines: gridGeometry.lines
|
||||
step: gridGeometry.step
|
||||
@@ -67,7 +88,7 @@ Node {
|
||||
}
|
||||
]
|
||||
}
|
||||
Model {
|
||||
Model { // X Axis
|
||||
rotation.z: 90
|
||||
geometry: GridGeometry {
|
||||
lines: gridGeometry.lines
|
||||
|
@@ -35,16 +35,29 @@ View3D {
|
||||
property alias sceneHelpers: sceneHelpers
|
||||
property alias perpectiveCamera: scenePerspectiveCamera
|
||||
property alias orthoCamera: sceneOrthoCamera
|
||||
property double cameraZoomFactor: .55;
|
||||
|
||||
// Empirical cameraZoomFactor values at which the grid zoom level is doubled. The values are
|
||||
// approximately uniformally distributed over the non-linear range of cameraZoomFactor.
|
||||
readonly property var grid_thresholds: [0.1, 0.265, 0.55, 1.10, 2.35, 4.9, 10.0, 20.5, 42.0, 85.0, 999999.0]
|
||||
property var thresIdx: 1
|
||||
property var thresPerc: 1.0 // percentage of cameraZoomFactor to the current grid zoom threshold (0.0 - 1.0)
|
||||
|
||||
camera: usePerspective ? scenePerspectiveCamera : sceneOrthoCamera
|
||||
|
||||
onCameraZoomFactorChanged: {
|
||||
thresIdx = Math.max(1, grid_thresholds.findIndex(v => v > cameraZoomFactor));
|
||||
thresPerc = (grid_thresholds[thresIdx] - cameraZoomFactor) / (grid_thresholds[thresIdx] - grid_thresholds[thresIdx - 1]);
|
||||
}
|
||||
|
||||
Node {
|
||||
id: sceneHelpers
|
||||
|
||||
HelperGrid {
|
||||
id: helperGrid
|
||||
lines: 50
|
||||
step: 50
|
||||
lines: 20 + Math.round((1 - thresPerc) * 20);
|
||||
step: 100 * grid_thresholds[0] * Math.pow(2, thresIdx - 1);
|
||||
subdivAlpha: thresPerc;
|
||||
}
|
||||
|
||||
PointLight {
|
||||
|
@@ -114,16 +114,18 @@ QSSGRenderGraphObject *GridGeometry::updateSpatialNode(QSSGRenderGraphObject *no
|
||||
|
||||
void GridGeometry::fillVertexData(QByteArray &vertexData)
|
||||
{
|
||||
const int size = m_isCenterLine
|
||||
? int(sizeof(float)) * 3 * 2
|
||||
: 4 * m_lines * int(sizeof(float)) * 3 * 2;
|
||||
const int numSubdivs = 1; // number of subdivision lines (i.e. lines between main grid lines)
|
||||
const int vtxSize = int(sizeof(float)) * 3 * 2;
|
||||
const int size = m_isCenterLine ? vtxSize
|
||||
: m_isSubdivision ? 4 * m_lines * vtxSize * numSubdivs
|
||||
: 4 * m_lines * vtxSize;
|
||||
vertexData.resize(size);
|
||||
float *dataPtr = reinterpret_cast<float *>(vertexData.data());
|
||||
|
||||
float y0 = -float(m_lines) * m_step;
|
||||
float x0 = -float(m_lines) * m_step;
|
||||
float y1 = -y0;
|
||||
float y0 = x0;
|
||||
float x1 = -x0;
|
||||
float y1 = x1;
|
||||
|
||||
if (m_isCenterLine) {
|
||||
// start position
|
||||
@@ -135,25 +137,46 @@ void GridGeometry::fillVertexData(QByteArray &vertexData)
|
||||
dataPtr[4] = y1;
|
||||
dataPtr[5] = 0.f;
|
||||
} else {
|
||||
auto generateLines = [this, &dataPtr](float x0, float y0, float x1, float y1, bool vertical) {
|
||||
for (int i = 0; i < m_lines; ++i) {
|
||||
// start position
|
||||
dataPtr[0] = vertical ? x0 + i * m_step : x0;
|
||||
dataPtr[1] = vertical ? y0 : y0 + i * m_step;
|
||||
dataPtr[2] = .0f;
|
||||
// end position
|
||||
dataPtr[3] = vertical ? x0 + i * m_step : x1;
|
||||
dataPtr[4] = vertical ? y1 : y0 + i * m_step;
|
||||
dataPtr[5] = .0f;
|
||||
dataPtr += 6;
|
||||
}
|
||||
};
|
||||
|
||||
// Lines are created so that bounding box can later be calculated from first and last vertex
|
||||
generateLines(x0, y0, x1, y1, true);
|
||||
generateLines(x0, y0, x1, y1, false);
|
||||
generateLines(x0, m_step, x1, y1, false);
|
||||
generateLines(m_step, y0, x1, y1, true);
|
||||
if (m_isSubdivision) {
|
||||
const float subdivStep = m_step / float(numSubdivs + 1);
|
||||
const int subdivMainLines = m_lines * 2;
|
||||
auto generateSubLines = [&](float x0, float y0, float x1, float y1, bool vertical) {
|
||||
for (int i = 0; i < subdivMainLines; ++i) {
|
||||
for (int j = 1; j <= numSubdivs; ++j) {
|
||||
// start position
|
||||
dataPtr[0] = vertical ? x0 + i * m_step + j * subdivStep : x0;
|
||||
dataPtr[1] = vertical ? y0 : y0 + i * m_step + j * subdivStep;
|
||||
dataPtr[2] = .0f;
|
||||
// end position
|
||||
dataPtr[3] = vertical ? x0 + i * m_step + j * subdivStep : x1;
|
||||
dataPtr[4] = vertical ? y1 : y0 + i * m_step + j * subdivStep;
|
||||
dataPtr[5] = .0f;
|
||||
dataPtr += 6;
|
||||
}
|
||||
}
|
||||
};
|
||||
generateSubLines(x0, y0, x1, y1, true);
|
||||
generateSubLines(x0, y0, x1, y1, false);
|
||||
} else {
|
||||
auto generateLines = [this, &dataPtr](float x0, float y0, float x1, float y1, bool vertical) {
|
||||
for (int i = 0; i < m_lines; ++i) {
|
||||
// start position
|
||||
dataPtr[0] = vertical ? x0 + i * m_step : x0;
|
||||
dataPtr[1] = vertical ? y0 : y0 + i * m_step;
|
||||
dataPtr[2] = .0f;
|
||||
// end position
|
||||
dataPtr[3] = vertical ? x0 + i * m_step : x1;
|
||||
dataPtr[4] = vertical ? y1 : y0 + i * m_step;
|
||||
dataPtr[5] = .0f;
|
||||
dataPtr += 6;
|
||||
}
|
||||
};
|
||||
generateLines(x0, y0, x1, y1, true);
|
||||
generateLines(x0, y0, x1, y1, false);
|
||||
generateLines(x0, m_step, x1, y1, false);
|
||||
generateLines(m_step, y0, x1, y1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -35,9 +35,11 @@ namespace Internal {
|
||||
class GridGeometry : public QQuick3DGeometry
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(int lines READ lines WRITE setLines NOTIFY linesChanged)
|
||||
Q_PROPERTY(float step READ step WRITE setStep NOTIFY stepChanged)
|
||||
Q_PROPERTY(bool isCenterLine READ isCenterLine WRITE setIsCenterLine NOTIFY isCenterLineChanged)
|
||||
Q_PROPERTY(bool isSubdivision MEMBER m_isSubdivision)
|
||||
|
||||
public:
|
||||
GridGeometry();
|
||||
@@ -63,9 +65,10 @@ protected:
|
||||
private:
|
||||
void fillVertexData(QByteArray &vertexData);
|
||||
|
||||
int m_lines = 1000;
|
||||
int m_lines = 20; // number of lines on 1 side of an axis (so total number of grid lines in 1 direction = 2 * m_lines + 1)
|
||||
float m_step = .1f;
|
||||
bool m_isCenterLine = false;
|
||||
bool m_isSubdivision = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user