summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/utils
diff options
context:
space:
mode:
authorMika Salmela <mika.salmela@digia.com>2014-10-03 16:47:44 +0300
committerTomi Korpipää <tomi.korpipaa@digia.com>2014-10-06 11:34:27 +0300
commit90ac955006749ecf6ea021bc7cf736a6c21095af (patch)
tree690bf1af7e0bce7287ab2b240b857a66dbd33742 /src/datavisualization/utils
parent2788e9f7412fa650f41b25fad1f4b02efb0e5e89 (diff)
Fix surface normals on ascending/descending
Normals and triangles are generated according to data direction. Task-number: QTRD-3160 Change-Id: Ia4286467682628930da3d82b204fd1ec078a396a Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com> Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization/utils')
-rw-r--r--src/datavisualization/utils/surfaceobject.cpp555
-rw-r--r--src/datavisualization/utils/surfaceobject_p.h24
2 files changed, 379 insertions, 200 deletions
diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp
index f8dae6f4..c91075e5 100644
--- a/src/datavisualization/utils/surfaceobject.cpp
+++ b/src/datavisualization/utils/surfaceobject.cpp
@@ -32,7 +32,9 @@ SurfaceObject::SurfaceObject(Surface3DRenderer *renderer)
m_axisCacheY(renderer->m_axisCacheY),
m_axisCacheZ(renderer->m_axisCacheZ),
m_renderer(renderer),
- m_returnTextureBuffer(false)
+ m_returnTextureBuffer(false),
+ m_dataDimension(0),
+ m_oldDataDimension(-1)
{
m_indicesType = GL_UNSIGNED_INT;
initializeOpenGLFunctions();
@@ -63,6 +65,12 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR
m_surfaceType = SurfaceSmooth;
+ checkDirections(dataArray);
+ bool indicesDirty = false;
+ if (m_dataDimension != m_oldDataDimension)
+ indicesDirty = true;
+ m_oldDataDimension = m_dataDimension;
+
// Create/populate vertix table
if (changeGeometry)
m_vertices.resize(totalSize);
@@ -96,46 +104,198 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR
// Create normals
int rowLimit = m_rows - 1;
int colLimit = m_columns - 1;
- int rowColLimit = rowLimit * m_columns;
- int totalLimit = totalSize - 1;
if (changeGeometry)
m_normals.resize(totalSize);
totalIndex = 0;
- const bool flipNormal = checkFlipNormal(dataArray);
- for (int row = 0; row < rowColLimit; row += m_columns) {
- for (int j = 0; j < colLimit; j++) {
- m_normals[totalIndex++] = normal(m_vertices.at(row + j),
- m_vertices.at(row + j + 1),
- m_vertices.at(row + m_columns + j),
- flipNormal);
- }
- int p = row + colLimit;
- m_normals[totalIndex++] = normal(m_vertices.at(p),
- m_vertices.at(p + m_columns),
- m_vertices.at(p - 1),
- flipNormal);
- }
- for (int j = rowColLimit; j < totalLimit; j++) {
- m_normals[totalIndex++] = normal(m_vertices.at(j),
- m_vertices.at(j - m_columns),
- m_vertices.at(j + 1),
- flipNormal);
+
+ if ((m_dataDimension == BothAscending) || (m_dataDimension == XDescending)) {
+ for (int row = 0; row < rowLimit; row ++)
+ createSmoothNormalBodyLine(totalIndex, row * m_columns);
+ createSmoothNormalUpperLine(totalIndex);
+ } else { // BothDescending || ZDescending
+ createSmoothNormalUpperLine(totalIndex);
+ for (int row = 1; row < m_rows; row++)
+ createSmoothNormalBodyLine(totalIndex, row * m_columns);
}
- m_normals[totalIndex++] = normal(m_vertices.at(totalLimit),
- m_vertices.at(totalLimit - 1),
- m_vertices.at(totalLimit - m_columns),
- flipNormal);
// Create indices table
- if (changeGeometry)
+ if (changeGeometry || indicesDirty)
createSmoothIndices(0, 0, colLimit, rowLimit);
// Create line element indices
if (changeGeometry)
createSmoothGridlineIndices(0, 0, colLimit, rowLimit);
- createBuffers(m_vertices, uvs, m_normals, 0, changeGeometry);
+ createBuffers(m_vertices, uvs, m_normals, 0);
+}
+
+void SurfaceObject::createSmoothNormalBodyLine(int &totalIndex, int column)
+{
+ int colLimit = m_columns - 1;
+
+ if (m_dataDimension == BothAscending) {
+ int end = colLimit + column;
+ for (int j = column; j < end; j++) {
+ m_normals[totalIndex++] = normal(m_vertices.at(j),
+ m_vertices.at(j + 1),
+ m_vertices.at(j + m_columns));
+ }
+ m_normals[totalIndex++] = normal(m_vertices.at(end),
+ m_vertices.at(end + m_columns),
+ m_vertices.at(end - 1));
+ } else if (m_dataDimension == XDescending) {
+ m_normals[totalIndex++] = normal(m_vertices.at(column),
+ m_vertices.at(column + m_columns),
+ m_vertices.at(column + 1));
+ int end = column + m_columns;
+ for (int j = column + 1; j < end; j++) {
+ m_normals[totalIndex++] = normal(m_vertices.at(j),
+ m_vertices.at(j - 1),
+ m_vertices.at(j + m_columns));
+ }
+ } else if (m_dataDimension == ZDescending) {
+ int end = colLimit + column;
+ for (int j = column; j < end; j++) {
+ m_normals[totalIndex++] = normal(m_vertices.at(j),
+ m_vertices.at(j + 1),
+ m_vertices.at(j - m_columns));
+ }
+ m_normals[totalIndex++] = normal(m_vertices.at(end),
+ m_vertices.at(end - m_columns),
+ m_vertices.at(end - 1));
+ } else { // BothDescending
+ m_normals[totalIndex++] = normal(m_vertices.at(column),
+ m_vertices.at(column - m_columns),
+ m_vertices.at(column + 1));
+ int end = column + m_columns;
+ for (int j = column + 1; j < end; j++) {
+ m_normals[totalIndex++] = normal(m_vertices.at(j),
+ m_vertices.at(j - 1),
+ m_vertices.at(j - m_columns));
+ }
+ }
+}
+
+void SurfaceObject::createSmoothNormalUpperLine(int &totalIndex)
+{
+ if ((m_dataDimension == BothAscending) ) {
+ int lineEnd = m_rows * m_columns - 1;
+ for (int j = (m_rows - 1) * m_columns; j < lineEnd; j++) {
+ m_normals[totalIndex++] = normal(m_vertices.at(j),
+ m_vertices.at(j - m_columns),
+ m_vertices.at(j + 1));
+ }
+ m_normals[totalIndex++] = normal(m_vertices.at(lineEnd),
+ m_vertices.at(lineEnd - 1),
+ m_vertices.at(lineEnd - m_columns));
+ } else if (m_dataDimension == XDescending) {
+ int lineStart = (m_rows - 1) * m_columns;
+ int lineEnd = m_rows * m_columns;
+ m_normals[totalIndex++] = normal(m_vertices.at(lineStart),
+ m_vertices.at(lineStart + 1),
+ m_vertices.at(lineStart - m_columns));
+ for (int j = lineStart + 1; j < lineEnd; j++) {
+ m_normals[totalIndex++] = normal(m_vertices.at(j),
+ m_vertices.at(j - m_columns),
+ m_vertices.at(j - 1));
+ }
+ } else if (m_dataDimension == ZDescending) {
+ int colLimit = m_columns - 1;
+ for (int j = 0; j < colLimit; j++) {
+ m_normals[totalIndex++] = normal(m_vertices.at(j),
+ m_vertices.at(j + m_columns),
+ m_vertices.at(j + 1));
+ }
+ m_normals[totalIndex++] = normal(m_vertices.at(colLimit),
+ m_vertices.at(colLimit - 1),
+ m_vertices.at(colLimit + m_columns));
+ } else { // BothDescending
+ m_normals[totalIndex++] = normal(m_vertices.at(0),
+ m_vertices.at(1),
+ m_vertices.at(m_columns));
+ for (int j = 1; j < m_columns; j++) {
+ m_normals[totalIndex++] = normal(m_vertices.at(j),
+ m_vertices.at(j + m_columns),
+ m_vertices.at(j - 1));
+ }
+ }
+}
+
+QVector3D SurfaceObject::createSmoothNormalBodyLineItem(int x, int y)
+{
+ int p = y * m_columns + x;
+ if (m_dataDimension == BothAscending) {
+ if (x < m_columns - 1) {
+ return normal(m_vertices.at(p), m_vertices.at(p + 1),
+ m_vertices.at(p + m_columns));
+ } else {
+ return normal(m_vertices.at(p), m_vertices.at(p + m_columns),
+ m_vertices.at(p - 1));
+ }
+ } else if (m_dataDimension == XDescending) {
+ if (x == 0) {
+ return normal(m_vertices.at(p), m_vertices.at(p + m_columns),
+ m_vertices.at(p + 1));
+ } else {
+ return normal(m_vertices.at(p), m_vertices.at(p - 1),
+ m_vertices.at(p + m_columns));
+ }
+ } else if (m_dataDimension == ZDescending) {
+ if (x < m_columns - 1) {
+ return normal(m_vertices.at(p), m_vertices.at(p + 1),
+ m_vertices.at(p - m_columns));
+ } else {
+ return normal(m_vertices.at(p), m_vertices.at(p - m_columns),
+ m_vertices.at(p - 1));
+ }
+ } else { // BothDescending
+ if (x == 0) {
+ return normal(m_vertices.at(p), m_vertices.at(p - m_columns),
+ m_vertices.at(p + 1));
+ } else {
+ return normal(m_vertices.at(p), m_vertices.at(p - 1),
+ m_vertices.at(p - m_columns));
+ }
+ }
+}
+
+QVector3D SurfaceObject::createSmoothNormalUpperLineItem(int x, int y)
+{
+ int p = y * m_columns + x;
+ if ((m_dataDimension == BothAscending) ) {
+ if (x < m_columns - 1) {
+ return normal(m_vertices.at(p), m_vertices.at(p - m_columns),
+ m_vertices.at(p + 1));
+ } else {
+ return normal(m_vertices.at(p), m_vertices.at(p - 1),
+ m_vertices.at(p - m_columns));
+ }
+ } else if (m_dataDimension == XDescending) {
+ if (x == 0) {
+ return normal(m_vertices.at(p), m_vertices.at(p + 1),
+ m_vertices.at(p - m_columns));
+ } else {
+ return normal(m_vertices.at(p), m_vertices.at(p - m_columns),
+ m_vertices.at(p - 1));
+ }
+ } else if (m_dataDimension == ZDescending) {
+ if (x < m_columns - 1) {
+ return normal(m_vertices.at(p), m_vertices.at(p + m_columns),
+ m_vertices.at(p + 1));
+ } else {
+ return normal(m_vertices.at(p), m_vertices.at(p - 1),
+ m_vertices.at(p + m_columns));
+ }
+ } else { // BothDescending
+ if (x == 0) {
+ return normal(m_vertices.at(0), m_vertices.at(1),
+ m_vertices.at(m_columns));
+ } else {
+ return normal(m_vertices.at(p), m_vertices.at(p + m_columns),
+ m_vertices.at(p - 1));
+ }
+ }
}
void SurfaceObject::smoothUVs(const QSurfaceDataArray &dataArray,
@@ -179,48 +339,27 @@ void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowI
getNormalizedVertex(dataRow.at(j), m_vertices[p++], polar, false);
// Create normals
- int colLimit = m_columns - 1;
+ bool upwards = (m_dataDimension == BothAscending) || (m_dataDimension == XDescending);
int startRow = rowIndex;
- if (startRow > 0)
+ if ((startRow > 0) && upwards)
startRow--;
+ int endRow = rowIndex;
+ if (!upwards && (rowIndex < m_rows - 1))
+ endRow++;
+ if ((endRow == m_rows - 1) && upwards)
+ endRow--;
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
- const bool flipNormal = checkFlipNormal(dataArray);
- 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),
- flipNormal);
- }
- 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),
- flipNormal);
+ if ((startRow == 0) && !upwards) {
+ createSmoothNormalUpperLine(totalIndex);
+ startRow++;
}
- 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
- 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),
- flipNormal);
- }
- // Top left corner. Take from one left and one down
- m_normals[totalIndex++] = normal(m_vertices.at(rowLimit),
- m_vertices.at(rowLimit - 1),
- m_vertices.at(rowLimit - m_columns),
- flipNormal);
- }
+ for (int row = startRow; row <= endRow; row++)
+ createSmoothNormalBodyLine(totalIndex, row * m_columns);
+
+ if ((rowIndex == m_rows - 1) && upwards)
+ createSmoothNormalUpperLine(totalIndex);
}
void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row, int column,
@@ -231,50 +370,33 @@ void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row
m_vertices[row * m_columns + column], polar, false);
// Create normals
+ bool upwards = (m_dataDimension == BothAscending) || (m_dataDimension == XDescending);
+ bool rightwards = (m_dataDimension == BothAscending) || (m_dataDimension == ZDescending);
int startRow = row;
- if (startRow > 0)
- startRow--; // Change the normal for previous row also
+ if ((startRow > 0) && upwards)
+ startRow--;
+ int endRow = row;
+ if (!upwards && (row < m_rows - 1))
+ endRow++;
+ if ((endRow == m_rows - 1) && upwards)
+ endRow--;
int startCol = column;
- if (startCol > 0)
+ if ((startCol > 0) && rightwards)
startCol--;
- int rightCol = m_columns - 1;
- int topRow = m_rows - 1;
+ int endCol = column;
+ if ((endCol < m_columns - 1) && !rightwards)
+ endCol++;
- const bool flipNormal = checkFlipNormal(dataArray);
- for (int i = startRow; i <= row; i++) {
- for (int j = startCol; j <= column; j++) {
+ for (int i = startRow; i <= endRow; i++) {
+ for (int j = startCol; j <= endCol; j++) {
int p = i * m_columns + j;
- if (i < topRow) {
- if (j < rightCol) {
- // One right and one up
- m_normals[p] = normal(m_vertices.at(p),
- m_vertices.at(p + 1),
- m_vertices.at(p + m_columns),
- flipNormal);
- } 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),
- flipNormal);
- }
- } else {
- // Top most line, nothing above, must have different handling.
- if (j < rightCol) {
- // Take from one down and one right. Read till second-to-last
- m_normals[p] = normal(m_vertices.at(p),
- m_vertices.at(p - m_columns),
- m_vertices.at(p + 1),
- flipNormal);
- } 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),
- flipNormal);
- }
- }
- }
+ if ((i == 0) && !upwards)
+ m_normals[p] = createSmoothNormalUpperLineItem(j, i);
+ else if ((i == m_rows - 1) && upwards)
+ m_normals[p] = createSmoothNormalUpperLineItem(j, i);
+ else
+ m_normals[p] = createSmoothNormalBodyLineItem(j, i);
+ }
}
}
@@ -296,15 +418,38 @@ void SurfaceObject::createSmoothIndices(int x, int y, int endX, int endY)
int rowEnd = endY * m_columns;
for (int row = y * m_columns; row < rowEnd; row += m_columns) {
for (int j = x; j < endX; j++) {
- // Left triangle
- indices[p++] = row + j + 1;
- indices[p++] = row + m_columns + j;
- indices[p++] = row + j;
-
- // Right triangle
- indices[p++] = row + m_columns + j + 1;
- indices[p++] = row + m_columns + j;
- indices[p++] = row + j + 1;
+ if ((m_dataDimension == BothAscending) || (m_dataDimension == BothDescending)) {
+ // Left triangle
+ indices[p++] = row + j + 1;
+ indices[p++] = row + m_columns + j;
+ indices[p++] = row + j;
+
+ // Right triangle
+ indices[p++] = row + m_columns + j + 1;
+ indices[p++] = row + m_columns + j;
+ indices[p++] = row + j + 1;
+ } else if (m_dataDimension == XDescending) {
+ // Right triangle
+ indices[p++] = row + m_columns + j;
+ indices[p++] = row + m_columns + j + 1;
+ indices[p++] = row + j;
+
+ // Left triangle
+ indices[p++] = row + j;
+ indices[p++] = row + m_columns + j + 1;
+ indices[p++] = row + j + 1;
+ } else {
+ // Left triangle
+ indices[p++] = row + m_columns + j;
+ indices[p++] = row + m_columns + j + 1;
+ indices[p++] = row + j;
+
+ // Right triangle
+ indices[p++] = row + j;
+ indices[p++] = row + m_columns + j + 1;
+ indices[p++] = row + j + 1;
+
+ }
}
}
@@ -364,6 +509,12 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s
GLfloat uvX = 1.0f / GLfloat(m_columns - 1);
GLfloat uvY = 1.0f / GLfloat(m_rows - 1);
+ checkDirections(dataArray);
+ bool indicesDirty = false;
+ if (m_dataDimension != m_oldDataDimension)
+ indicesDirty = true;
+ m_oldDataDimension = m_dataDimension;
+
m_surfaceType = SurfaceFlat;
// Create vertix table
@@ -411,42 +562,23 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s
// Create normals & indices table
GLint *indices = 0;
- int p = 0;
- if (changeGeometry) {
+ if (changeGeometry || indicesDirty) {
int normalCount = 2 * colLimit * rowLimit;
m_indexCount = 3 * normalCount;
indices = new GLint[m_indexCount];
m_normals.resize(normalCount);
}
+ int p = 0;
totalIndex = 0;
- const bool flipNormal = checkFlipNormal(dataArray);
for (int row = 0, upperRow = doubleColumns;
row < rowColLimit;
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),
- flipNormal);
-
- // 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),
- flipNormal);
-
- if (changeGeometry) {
- // Left triangle
- indices[p++] = row + j + 1;
- indices[p++] = upperRow + j;
- indices[p++] = row + j;
+ createNormals(totalIndex, row, upperRow, j);
- // Right triangle
- indices[p++] = upperRow + j + 1;
- indices[p++] = upperRow + j;
- indices[p++] = row + j + 1;
+ if (changeGeometry || indicesDirty) {
+ createCoarseIndices(indices, p, row, upperRow, j);
}
}
}
@@ -455,7 +587,7 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s
if (changeGeometry)
createCoarseGridlineIndices(0, 0, colLimit, rowLimit);
- createBuffers(m_vertices, uvs, m_normals, indices, changeGeometry);
+ createBuffers(m_vertices, uvs, m_normals, indices);
delete[] indices;
}
@@ -519,23 +651,11 @@ void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowI
int rowLimit = (rowIndex + 1) * doubleColumns;
if (rowIndex == m_rows - 1)
rowLimit = rowIndex * doubleColumns; //Topmost row, no normals
- const bool flipNormal = checkFlipNormal(dataArray);
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[p++] = normal(m_vertices.at(row + j),
- m_vertices.at(row + j + 1),
- m_vertices.at(upperRow + j),
- flipNormal);
-
- // Normal for the right triangle
- m_normals[p++] = normal(m_vertices.at(row + j + 1),
- m_vertices.at(upperRow + j + 1),
- m_vertices.at(upperRow + j),
- flipNormal);
- }
+ for (int j = 0; j < doubleColumns; j += 2)
+ createNormals(p, row, upperRow, j);
}
}
@@ -564,27 +684,15 @@ void SurfaceObject::updateCoarseItem(const QSurfaceDataArray &dataArray, int row
if (column == m_columns - 1)
column--;
- const bool flipNormal = checkFlipNormal(dataArray);
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),
- flipNormal);
- 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),
- flipNormal);
+ createNormals(p, i * doubleColumns, (i + 1) * doubleColumns, j * 2);
}
}
}
-void SurfaceObject::createCoarseIndices(int x, int y, int columns, int rows)
+void SurfaceObject::createCoarseSubSection(int x, int y, int columns, int rows)
{
if (columns > m_columns)
columns = m_columns;
@@ -606,17 +714,8 @@ void SurfaceObject::createCoarseIndices(int x, int y, int columns, int rows)
for (int row = y * doubleColumns, upperRow = (y + 1) * doubleColumns;
row < rowColLimit;
row += doubleColumns, upperRow += doubleColumns) {
- for (int j = 2 * x; j < doubleColumnsLimit; j += 2) {
- // Left triangle
- indices[p++] = row + j + 1;
- indices[p++] = upperRow + j;
- indices[p++] = row + j;
-
- // Right triangle
- indices[p++] = upperRow + j + 1;
- indices[p++] = upperRow + j;
- indices[p++] = row + j + 1;
- }
+ for (int j = 2 * x; j < doubleColumnsLimit; j += 2)
+ createCoarseIndices(indices, p, row, upperRow, j);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer);
@@ -680,12 +779,11 @@ void SurfaceObject::createCoarseGridlineIndices(int x, int y, int endX, int endY
void SurfaceObject::uploadBuffers()
{
QVector<QVector2D> uvs; // Empty dummy
- createBuffers(m_vertices, uvs, m_normals, 0, false);
+ createBuffers(m_vertices, uvs, m_normals, 0);
}
void SurfaceObject::createBuffers(const QVector<QVector3D> &vertices, const QVector<QVector2D> &uvs,
- const QVector<QVector3D> &normals, const GLint *indices,
- bool changeGeometry)
+ const QVector<QVector3D> &normals, const GLint *indices)
{
// Move to buffers
glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer);
@@ -696,30 +794,37 @@ void SurfaceObject::createBuffers(const QVector<QVector3D> &vertices, const QVec
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(QVector3D),
&normals.at(0), GL_DYNAMIC_DRAW);
- if (changeGeometry) {
+ if (uvs.size()) {
glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer);
glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(QVector2D),
&uvs.at(0), GL_STATIC_DRAW);
+ }
- if (indices) {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indexCount * sizeof(GLint),
- indices, GL_STATIC_DRAW);
- }
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ if (indices) {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indexCount * sizeof(GLint),
+ indices, GL_STATIC_DRAW);
}
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
m_meshDataLoaded = true;
}
-bool SurfaceObject::checkFlipNormal(const QSurfaceDataArray &array)
+void SurfaceObject::checkDirections(const QSurfaceDataArray &array)
{
- const bool ascendingX = array.at(0)->at(0).x() < array.at(0)->at(array.at(0)->size() - 1).x();
- const bool ascendingZ = array.at(0)->at(0).z() < array.at(array.size() - 1)->at(0).z();
- return ascendingX != ascendingZ;
+ m_dataDimension = BothAscending;
+
+ if (array.at(0)->at(0).x() > array.at(0)->at(array.at(0)->size() - 1).x())
+ m_dataDimension |= XDescending;
+ if (m_axisCacheX.reversed())
+ m_dataDimension ^= XDescending;
+
+ if (array.at(0)->at(0).z() > array.at(array.size() - 1)->at(0).z())
+ m_dataDimension |= ZDescending;
+ if (m_axisCacheZ.reversed())
+ m_dataDimension ^= ZDescending;
}
void SurfaceObject::getNormalizedVertex(const QSurfaceDataItem &data, QVector3D &vertex,
@@ -792,14 +897,74 @@ void SurfaceObject::clear()
m_normals.clear();
}
-QVector3D SurfaceObject::normal(const QVector3D &a, const QVector3D &b, const QVector3D &c,
- bool flipNormal)
+void SurfaceObject::createCoarseIndices(GLint *indices, int &p, int row, int upperRow, int j)
+{
+ if ((m_dataDimension == BothAscending) || (m_dataDimension == BothDescending)) {
+ // Left triangle
+ indices[p++] = row + j + 1;
+ indices[p++] = upperRow + j;
+ indices[p++] = row + j;
+
+ // Right triangle
+ indices[p++] = upperRow + j + 1;
+ indices[p++] = upperRow + j;
+ indices[p++] = row + j + 1;
+ } else if (m_dataDimension == XDescending) {
+ indices[p++] = upperRow + j;
+ indices[p++] = upperRow + j + 1;
+ indices[p++] = row + j;
+
+ indices[p++] = row + j;
+ indices[p++] = upperRow + j + 1;
+ indices[p++] = row + j + 1;
+ } else {
+ // Left triangle
+ indices[p++] = upperRow + j;
+ indices[p++] = upperRow + j + 1;
+ indices[p++] = row + j;
+
+ // Right triangle
+ indices[p++] = row + j;
+ indices[p++] = upperRow + j + 1;
+ indices[p++] = row + j + 1;
+ }
+}
+
+void SurfaceObject::createNormals(int &p, int row, int upperRow, int j)
+{
+ if ((m_dataDimension == BothAscending) || (m_dataDimension == BothDescending)) {
+ m_normals[p++] = 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 + 1),
+ m_vertices.at(upperRow + j + 1),
+ m_vertices.at(upperRow + j));
+ } else if (m_dataDimension == XDescending) {
+ m_normals[p++] = normal(m_vertices.at(row + j),
+ m_vertices.at(upperRow + j),
+ m_vertices.at(upperRow + j + 1));
+
+ m_normals[p++] = normal(m_vertices.at(row + j + 1),
+ m_vertices.at(row + j),
+ m_vertices.at(upperRow + j + 1));
+ } else {
+ m_normals[p++] = normal(m_vertices.at(row + j),
+ m_vertices.at(upperRow + j),
+ m_vertices.at(upperRow + j + 1));
+
+ m_normals[p++] = normal(m_vertices.at(row + j + 1),
+ m_vertices.at(row + j),
+ m_vertices.at(upperRow + j + 1));
+ }
+}
+
+QVector3D SurfaceObject::normal(const QVector3D &a, const QVector3D &b, const QVector3D &c)
{
QVector3D v1 = b - a;
QVector3D v2 = c - a;
QVector3D normal = QVector3D::crossProduct(v1, v2);
- if (flipNormal)
- normal *= -1;
+
return normal;
}
diff --git a/src/datavisualization/utils/surfaceobject_p.h b/src/datavisualization/utils/surfaceobject_p.h
index f373eb5d..39d10445 100644
--- a/src/datavisualization/utils/surfaceobject_p.h
+++ b/src/datavisualization/utils/surfaceobject_p.h
@@ -49,6 +49,13 @@ public:
Undefined
};
+ enum DataDimensions {
+ BothAscending = 0,
+ XDescending = 1,
+ ZDescending = 2,
+ BothDescending = XDescending | ZDescending
+ };
+
public:
SurfaceObject(Surface3DRenderer *renderer);
virtual ~SurfaceObject();
@@ -64,7 +71,7 @@ public:
void updateSmoothItem(const QSurfaceDataArray &dataArray, int row, int column, bool polar);
void updateCoarseItem(const QSurfaceDataArray &dataArray, int row, int column, bool polar);
void createSmoothIndices(int x, int y, int endX, int endY);
- void createCoarseIndices(int x, int y, int columns, int rows);
+ void createCoarseSubSection(int x, int y, int columns, int rows);
void createSmoothGridlineIndices(int x, int y, int endX, int endY);
void createCoarseGridlineIndices(int x, int y, int endX, int endY);
void uploadBuffers();
@@ -78,11 +85,16 @@ public:
inline void activateSurfaceTexture(bool value) { m_returnTextureBuffer = value; }
private:
- QVector3D normal(const QVector3D &a, const QVector3D &b, const QVector3D &c, bool flipNormal);
+ void createCoarseIndices(GLint *indices, int &p, int row, int upperRow, int j);
+ void createNormals(int &p, int row, int upperRow, int j);
+ void createSmoothNormalBodyLine(int &totalIndex, int column);
+ void createSmoothNormalUpperLine(int &totalIndex);
+ QVector3D createSmoothNormalBodyLineItem(int x, int y);
+ QVector3D createSmoothNormalUpperLineItem(int x, int y);
+ QVector3D normal(const QVector3D &a, const QVector3D &b, const QVector3D &c);
void createBuffers(const QVector<QVector3D> &vertices, const QVector<QVector2D> &uvs,
- const QVector<QVector3D> &normals, const GLint *indices,
- bool changeGeometry);
- bool checkFlipNormal(const QSurfaceDataArray &array);
+ const QVector<QVector3D> &normals, const GLint *indices);
+ void checkDirections(const QSurfaceDataArray &array);
inline void getNormalizedVertex(const QSurfaceDataItem &data, QVector3D &vertex, bool polar,
bool flipXZ);
@@ -103,6 +115,8 @@ private:
float m_maxY;
GLuint m_uvTextureBuffer;
bool m_returnTextureBuffer;
+ int m_dataDimension;
+ int m_oldDataDimension;
};
QT_END_NAMESPACE_DATAVISUALIZATION