summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2014-05-30 12:01:42 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2014-06-03 12:40:56 +0300
commit51c5836ccb6d9f71b4f6301e1e9834aa8b95f975 (patch)
tree1a2f401e192ce39a43afa1b9024d9558e7b8ae58 /src
parent69926b074405f5117e6a1f124804f21416ef3fb8 (diff)
Flip surface normals if either rows or columns are descending
If both are descending or ascending, do not flip. Flip is needed to make specular highlight work correctly. Task-number: QTRD-3156 Change-Id: Ida256ee4ff96553c6f1cd5bf94e71d2e95ce7cf4 Reviewed-by: Titta Heikkala <titta.heikkala@digia.com> Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/datavisualization/utils/surfaceobject.cpp75
-rw-r--r--src/datavisualization/utils/surfaceobject_p.h3
2 files changed, 57 insertions, 21 deletions
diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp
index 088bb150..d999ba90 100644
--- a/src/datavisualization/utils/surfaceobject.cpp
+++ b/src/datavisualization/utils/surfaceobject.cpp
@@ -101,25 +101,30 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR
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));
+ 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));
+ 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));
+ m_vertices.at(j + 1),
+ flipNormal);
}
m_normals[totalIndex++] = normal(m_vertices.at(totalLimit),
m_vertices.at(totalLimit - 1),
- m_vertices.at(totalLimit - m_columns));
+ m_vertices.at(totalLimit - m_columns),
+ flipNormal);
// Create indices table
if (changeGeometry)
@@ -156,18 +161,21 @@ void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowI
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));
+ 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));
+ m_vertices.at(p - 1),
+ flipNormal);
}
if (rowIndex == m_rows - 1) {
// Top most line, nothing above, must have different handling.
@@ -176,13 +184,15 @@ void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowI
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));
+ 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));
+ m_vertices.at(rowLimit - m_columns),
+ flipNormal);
}
}
@@ -205,6 +215,7 @@ void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row
int rightCol = m_columns - 1;
int topRow = m_rows - 1;
+ const bool flipNormal = checkFlipNormal(dataArray);
for (int i = startRow; i <= row; i++) {
for (int j = startCol; j <= column; j++) {
int p = i * m_columns + j;
@@ -213,12 +224,14 @@ void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row
// One right and one up
m_normals[p] = normal(m_vertices.at(p),
m_vertices.at(p + 1),
- m_vertices.at(p + m_columns));
+ 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));
+ m_vertices.at(p - 1),
+ flipNormal);
}
} else {
// Top most line, nothing above, must have different handling.
@@ -226,12 +239,14 @@ void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row
// 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));
+ 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));
+ m_vertices.at(p - m_columns),
+ flipNormal);
}
}
}
@@ -383,6 +398,7 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s
}
totalIndex = 0;
+ const bool flipNormal = checkFlipNormal(dataArray);
for (int row = 0, upperRow = doubleColumns;
row < rowColLimit;
row += doubleColumns, upperRow += doubleColumns) {
@@ -390,12 +406,14 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s
// 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_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));
+ m_vertices.at(upperRow + j),
+ flipNormal);
if (changeGeometry) {
// Left triangle
@@ -448,6 +466,7 @@ 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) {
@@ -455,12 +474,14 @@ void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowI
// 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));
+ 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));
+ m_vertices.at(upperRow + j),
+ flipNormal);
}
}
}
@@ -494,19 +515,22 @@ 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));
+ 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));
+ m_vertices.at(p + doubleColumns - 1),
+ flipNormal);
}
}
}
@@ -642,6 +666,13 @@ void SurfaceObject::createBuffers(const QVector<QVector3D> &vertices, const QVec
m_meshDataLoaded = true;
}
+bool SurfaceObject::checkFlipNormal(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;
+}
+
GLuint SurfaceObject::gridElementBuf()
{
if (!m_meshDataLoaded)
@@ -676,11 +707,15 @@ void SurfaceObject::clear()
m_normals.clear();
}
-QVector3D SurfaceObject::normal(const QVector3D &a, const QVector3D &b, const QVector3D &c)
+QVector3D SurfaceObject::normal(const QVector3D &a, const QVector3D &b, const QVector3D &c,
+ bool flipNormal)
{
QVector3D v1 = b - a;
QVector3D v2 = c - a;
- return QVector3D::crossProduct(v1, v2);
+ QVector3D normal = QVector3D::crossProduct(v1, v2);
+ if (flipNormal)
+ normal *= -1;
+ return normal;
}
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/utils/surfaceobject_p.h b/src/datavisualization/utils/surfaceobject_p.h
index c8f7de95..9c18dcb2 100644
--- a/src/datavisualization/utils/surfaceobject_p.h
+++ b/src/datavisualization/utils/surfaceobject_p.h
@@ -72,10 +72,11 @@ public:
void clear();
private:
- QVector3D normal(const QVector3D &a, const QVector3D &b, const QVector3D &c);
+ QVector3D normal(const QVector3D &a, const QVector3D &b, const QVector3D &c, bool flipNormal);
void createBuffers(const QVector<QVector3D> &vertices, const QVector<QVector2D> &uvs,
const QVector<QVector3D> &normals, const GLint *indices,
bool changeGeometry);
+ bool checkFlipNormal(const QSurfaceDataArray &array);
private:
SurfaceType m_surfaceType;