diff options
author | Mika Salmela <mika.salmela@digia.com> | 2013-12-03 14:00:23 +0200 |
---|---|---|
committer | Mika Salmela <mika.salmela@digia.com> | 2013-12-03 14:06:59 +0200 |
commit | 344870fb79e647b87aa79b9433eef8237c901e10 (patch) | |
tree | f0ccaa5991d9f0304bc6f6f91ce3ffd45232384d /src/datavisualization/utils/surfaceobject.cpp | |
parent | 2af35db1a112c49991a80f48e3cd8d8814deb321 (diff) |
Better proxy API for surface
Part 2, item change. More is on the way.
Change-Id: Ic41f3a90b5a47502b741391ace990117ef2eaf80
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
Diffstat (limited to 'src/datavisualization/utils/surfaceobject.cpp')
-rw-r--r-- | src/datavisualization/utils/surfaceobject.cpp | 248 |
1 files changed, 176 insertions, 72 deletions
diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp index 81945900..ca23482a 100644 --- a/src/datavisualization/utils/surfaceobject.cpp +++ b/src/datavisualization/utils/surfaceobject.cpp @@ -120,8 +120,8 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR createBuffers(m_vertices, uvs, m_normals, 0, changeGeometry); } -void SurfaceObject::updateSmoothRows(const QSurfaceDataArray &dataArray, int startRow, - int endRow, GLfloat yRange, GLfloat yMin) +void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowIndex, + GLfloat yRange, GLfloat yMin) { GLfloat xMin = dataArray.at(0)->at(0).x(); GLfloat zMin = dataArray.at(0)->at(0).z(); @@ -130,64 +130,114 @@ void SurfaceObject::updateSmoothRows(const QSurfaceDataArray &dataArray, int sta GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f; // Update vertices - int totalIndex = startRow * m_columns; - for (int i = startRow; i < endRow; i++) { - const QSurfaceDataRow &p = *dataArray.at(i); - for (int j = 0; j < m_columns; j++) { - const QSurfaceDataItem &data = p.at(j); - float normalizedX = ((data.x() - xMin) / xNormalizer); - float normalizedY = ((data.y() - yMin) / yNormalizer); - float normalizedZ = ((data.z() - zMin) / zNormalizer); - m_vertices[totalIndex++] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f); - } + int p = rowIndex * m_columns; + const QSurfaceDataRow &dataRow = *dataArray.at(rowIndex); + for (int j = 0; j < m_columns; j++) { + const QSurfaceDataItem &data = dataRow.at(j); + float normalizedX = ((data.x() - xMin) / xNormalizer); + float normalizedY = ((data.y() - yMin) / yNormalizer); + float normalizedZ = ((data.z() - zMin) / zNormalizer); + m_vertices[p++] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f); } // Create normals int colLimit = m_columns - 1; - int rowColLimit = endRow * m_columns; - if (endRow == m_rows) - rowColLimit = (endRow - 1) * m_columns; - int totalLimit = endRow * m_columns - 1; - - totalIndex = startRow * m_columns; - if (startRow > 0) { - // Change the normals for the previous row also - totalIndex -= m_columns; - } - if (totalIndex < (m_rows - 1) * m_columns) { - for (int row = totalIndex; row < rowColLimit; row += m_columns) { - for (int j = 0; j < colLimit; j++) { - // One right and one up - m_normals[totalIndex++] = normal(m_vertices.at(row + j), - m_vertices.at(row + j + 1), - m_vertices.at(row + m_columns + j)); - } - int p = row + colLimit; - // One up and one left - m_normals[totalIndex++] = normal(m_vertices.at(p), - m_vertices.at(p + m_columns), - m_vertices.at(p - 1)); + int startRow = rowIndex; + if (startRow > 0) + startRow--; + int totalIndex = startRow * m_columns; + int rowLimit = (rowIndex + 1) * m_columns; + if (rowIndex == m_rows - 1) + rowLimit = rowIndex * m_columns; // The rowIndex is top most row, special handling + + for (int row = totalIndex; row < rowLimit; row += m_columns) { + for (int j = 0; j < colLimit; j++) { + // One right and one up + m_normals[totalIndex++] = normal(m_vertices.at(row + j), + m_vertices.at(row + j + 1), + m_vertices.at(row + m_columns + j)); } + int p = row + colLimit; + // One up and one left + m_normals[totalIndex++] = normal(m_vertices.at(p), + m_vertices.at(p + m_columns), + m_vertices.at(p - 1)); } - if (endRow == m_rows) { + if (rowIndex == m_rows - 1) { // Top most line, nothing above, must have different handling. // Take from one down and one right. Read till second-to-last - for (int j = rowColLimit; j < totalLimit; j++) { + rowLimit = (rowIndex + 1) * m_columns - 1; + for (int j = rowIndex * m_columns; j < rowLimit; j++) { m_normals[totalIndex++] = normal(m_vertices.at(j), m_vertices.at(j - m_columns), m_vertices.at(j + 1)); } // Top left corner. Take from one left and one down - m_normals[totalIndex++] = normal(m_vertices.at(totalLimit), - m_vertices.at(totalLimit - 1), - m_vertices.at(totalLimit - m_columns)); + m_normals[totalIndex++] = normal(m_vertices.at(rowLimit), + m_vertices.at(rowLimit - 1), + m_vertices.at(rowLimit - m_columns)); } +} - QVector<QVector2D> uvs; // Empty dummy - createBuffers(m_vertices, uvs, m_normals, 0, false); +void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row, + int column, GLfloat yRange, GLfloat yMin) +{ + GLfloat xMin = dataArray.at(0)->at(0).x(); + GLfloat zMin = dataArray.at(0)->at(0).z(); + GLfloat xNormalizer = (dataArray.at(0)->last().x() - xMin) / 2.0f; + GLfloat yNormalizer = yRange / 2.0f; + GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f; + + // Update a vertice + const QSurfaceDataItem &data = dataArray.at(row)->at(column); + float normalizedX = ((data.x() - xMin) / xNormalizer); + float normalizedY = ((data.y() - yMin) / yNormalizer); + float normalizedZ = ((data.z() - zMin) / zNormalizer); + m_vertices[row * m_columns + column] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f); + + // Create normals + int startRow = row; + if (startRow > 0) + startRow--; // Change the normal for previous row also + int startCol = column; + if (startCol > 0) + startCol--; + + for (int i = startRow; i <= row; i++) { + for (int j = startCol; j <= column; j++) { + int p = i * m_columns + j; + if (i < m_rows) { + if (j < m_columns) { + // One right and one up + m_normals[p] = normal(m_vertices.at(p), + m_vertices.at(p + 1), + m_vertices.at(p + m_columns)); + } else { + // Last item, nothing on the right. One up and one left + m_normals[p] = normal(m_vertices.at(p), + m_vertices.at(p + m_columns), + m_vertices.at(p - 1)); + } + } else { + // Top most line, nothing above, must have different handling. + if (j < m_columns) { + // Take from one down and one right. Read till second-to-last + m_normals[p] = normal(m_vertices.at(p), + m_vertices.at(j - m_columns), + m_vertices.at(j + 1)); + } else { + // Top left corner. Take from one left and one down + m_normals[p] = normal(m_vertices.at(p), + m_vertices.at(p - 1), + m_vertices.at(p - m_columns)); + } + } + } + } } + void SurfaceObject::createSmoothIndices(int x, int y, int endX, int endY) { if (endX >= m_columns) @@ -364,8 +414,8 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s delete[] indices; } -void SurfaceObject::updateCoarseRows(const QSurfaceDataArray &dataArray, int startRow, - int endRow, GLfloat yRange, GLfloat yMin) +void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex, + GLfloat yRange, GLfloat yMin) { GLfloat xMin = dataArray.at(0)->at(0).x(); GLfloat zMin = dataArray.at(0)->at(0).z(); @@ -375,47 +425,95 @@ void SurfaceObject::updateCoarseRows(const QSurfaceDataArray &dataArray, int sta int colLimit = m_columns - 1; int doubleColumns = m_columns * 2 - 2; - int totalIndex = startRow * doubleColumns; - for (int i = startRow; i < endRow; i++) { - const QSurfaceDataRow &row = *dataArray.at(i); - for (int j = 0; j < m_columns; j++) { - const QSurfaceDataItem &data = row.at(j); - float normalizedX = ((data.x() - xMin) / xNormalizer); - float normalizedY = ((data.y() - yMin) / yNormalizer); - float normalizedZ = ((data.z() - zMin) / zNormalizer); - m_vertices[totalIndex++] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f); - - if (j > 0 && j < colLimit) { - m_vertices[totalIndex] = m_vertices[totalIndex - 1]; - totalIndex++; - } + int p = rowIndex * doubleColumns; + const QSurfaceDataRow &dataRow = *dataArray.at(rowIndex); + for (int j = 0; j < m_columns; j++) { + const QSurfaceDataItem &data = dataRow.at(j); + float normalizedX = ((data.x() - xMin) / xNormalizer); + float normalizedY = ((data.y() - yMin) / yNormalizer); + float normalizedZ = ((data.z() - zMin) / zNormalizer); + m_vertices[p++] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f); + + if (j > 0 && j < colLimit) { + m_vertices[p] = m_vertices[p - 1]; + p++; } } // Create normals - if (startRow > 0) - startRow--; - totalIndex = startRow * doubleColumns; - int rowColLimit = startRow * doubleColumns; - for (int row = totalIndex, upperRow = totalIndex + doubleColumns; - row <= rowColLimit; + p = rowIndex * doubleColumns; + if (p > 0) + p -= doubleColumns; + int rowLimit = (rowIndex + 1) * doubleColumns; + for (int row = p, upperRow = p + doubleColumns; + row < rowLimit; row += doubleColumns, upperRow += doubleColumns) { for (int j = 0; j < doubleColumns; j += 2) { // Normal for the left triangle - m_normals[totalIndex++] = normal(m_vertices.at(row + j), - m_vertices.at(row + j + 1), - m_vertices.at(upperRow + j)); + m_normals[p++] = normal(m_vertices.at(row + j), + m_vertices.at(row + j + 1), + m_vertices.at(upperRow + j)); // Normal for the right triangle - m_normals[totalIndex++] = normal(m_vertices.at(row + j + 1), - m_vertices.at(upperRow + j + 1), - m_vertices.at(upperRow + j)); + m_normals[p++] = normal(m_vertices.at(row + j + 1), + m_vertices.at(upperRow + j + 1), + m_vertices.at(upperRow + j)); } } +} - QVector<QVector2D> uvs; // Empty dummy - createBuffers(m_vertices, uvs, m_normals, 0, false); +void SurfaceObject::updateCoarseItem(const QSurfaceDataArray &dataArray, int row, + int column, GLfloat yRange, GLfloat yMin) +{ + GLfloat xMin = dataArray.at(0)->at(0).x(); + GLfloat zMin = dataArray.at(0)->at(0).z(); + GLfloat xNormalizer = (dataArray.at(0)->last().x() - xMin) / 2.0f; + GLfloat yNormalizer = yRange / 2.0f; + GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f; + + int colLimit = m_columns - 1; + int doubleColumns = m_columns * 2 - 2; + + // Update a vertice + int p = row * doubleColumns + column * 2 - (column > 0); + const QSurfaceDataItem &data = dataArray.at(row)->at(column); + float normalizedX = ((data.x() - xMin) / xNormalizer); + float normalizedY = ((data.y() - yMin) / yNormalizer); + float normalizedZ = ((data.z() - zMin) / zNormalizer); + m_vertices[p] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f); + p++; + + if (column > 0 && column < colLimit) + m_vertices[p] = m_vertices[p - 1]; + + // Create normals + int startRow = row; + if (startRow > 0) + startRow--; // Change the normal for previous row also + int startCol = column; + if (startCol > 0) + startCol--; + if (row == m_rows - 1) + row--; + if (column == m_columns - 1) + column--; + + for (int i = startRow; i <= row; i++) { + for (int j = startCol; j <= column; j++) { + p = i * doubleColumns + j * 2; + // Normal for the left triangle + m_normals[p] = normal(m_vertices.at(p), + m_vertices.at(p + 1), + m_vertices.at(p + doubleColumns)); + p++; + + // Normal for the right triangle + m_normals[p] = normal(m_vertices.at(p), + m_vertices.at(p + doubleColumns), + m_vertices.at(p + doubleColumns - 1)); + } + } } void SurfaceObject::createCoarseIndices(int x, int y, int columns, int rows) @@ -511,6 +609,12 @@ void SurfaceObject::createCoarseGridlineIndices(int x, int y, int endX, int endY delete[] gridIndices; } +void SurfaceObject::uploadBuffers() +{ + QVector<QVector2D> uvs; // Empty dummy + createBuffers(m_vertices, uvs, m_normals, 0, false); +} + void SurfaceObject::createBuffers(const QVector<QVector3D> &vertices, const QVector<QVector2D> &uvs, const QVector<QVector3D> &normals, const GLint *indices, bool changeGeometry) |