diff options
Diffstat (limited to 'model.cpp')
-rw-r--r-- | model.cpp | 118 |
1 files changed, 108 insertions, 10 deletions
@@ -45,9 +45,6 @@ Model::Model(const QString &filename) QVector<Point3d> pointData; QVector<Point3d> normalData; - QVector<int> pointIndices; - QVector<int> normalIndices; - QTextStream in(&file); while (!in.atEnd()) { QString input = in.readLine(); @@ -63,6 +60,7 @@ Model::Model(const QString &filename) Point3d p = readPoint(ts); p.y = -p.y; pointData << p; + normalData << Point3d(); min.x = qMin(min.x, p.x); min.y = qMin(min.y, p.y); @@ -91,13 +89,26 @@ Model::Model(const QString &filename) } for (int i = 0; i < 3; ++i) - pointIndices << p[i]; + m_pointIndices << p[i]; if (p.size() == 4) for (int i = 0; i < 3; ++i) - pointIndices << p[(i + 2) % 4]; + m_pointIndices << p[(i + 2) % 4]; + } + } + +#if 0 + for (int i = 0; i < m_pointIndices.size(); ++i) { + Point3d p1 = pointData.at(m_pointIndices.at(i)); + for (int j = 0; j < m_pointIndices.at(i); ++j) { + Point3d p2 = pointData.at(j); + if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) { + m_pointIndices[i] = j; + break; + } } } +#endif Point3d bounds = max - min; qreal scale = 1 / qMax(bounds.x, qMax(bounds.y, bounds.z)); @@ -114,22 +125,109 @@ Model::Model(const QString &filename) p.z *= scale; } - for (int i = 0; i < pointIndices.size(); ++i) - m_points << pointData.at(pointIndices.at(i)); + QVector<int> counts(normalData.size()); + + for (int i = 0; i < counts.size(); ++i) + counts[i] = 0; + + for (int i = 0; i < m_pointIndices.size(); i += 3) { + const Point3d a = pointData.at(m_pointIndices.at(i)); + const Point3d b = pointData.at(m_pointIndices.at(i+1)); + const Point3d c = pointData.at(m_pointIndices.at(i+2)); + + Point3d normal = cross(c - a, b - a).normalize(); + + for (int j = 0; j < 3; ++j) { + Point3d old = normalData.at(m_pointIndices.at(i + j)); + normalData[m_pointIndices.at(i + j)] = old + normal; + ++counts[m_pointIndices.at(i + j)]; + } + } + + for (int i = 0; i < normalData.size(); ++i) { + float r = 1. / counts.at(i); + normalData[i] = normalData.at(i) * r;//.normalize(); + } + +#if 0 + Point3d normal; + for (int i = 0; i < m_pointIndices.size(); ++i) { +#if 0 + if ((i % 3) == 0) { + Point3d a = pointData.at(m_pointIndices.at(i)); + Point3d b = pointData.at(m_pointIndices.at(i+1)); + Point3d c = pointData.at(m_pointIndices.at(i+2)); + + normal = cross(c - a, b - a).normalize(); + + //float len = normal.x * normal.x +normal.y * normal.y +normal.z * normal.z; + } +#endif + + m_points << pointData.at(m_pointIndices.at(i)); + m_normals << normalData.at(m_pointIndices.at(i)).normalize(); + +#if 0 + Point3d p = m_points.last(); + Point3d n = m_normals.last(); + + printf("Index: %d, point: %f %f %f, normal: %f %f %f\n", m_pointIndices.at(i), + p.x, p.y, p.z, + n.x, n.y, n.z); +#endif + } +#endif + + m_points = pointData; + m_normals = normalData; foreach(const Edge &edge, QVector<Edge>::fromList(edges.toList())) m_edges << pointData.at(edge.pointA) << pointData.at(edge.pointB); } -void Model::render(bool wireframe) const +void Model::render(bool wireframe, bool normals) const { glEnableClientState(GL_VERTEX_ARRAY); if (wireframe) { + glColor3f(0, 0, 0); glVertexPointer(3, GL_FLOAT, 0, m_edges.data()); glDrawArrays(GL_LINES, 0, m_edges.size()); } else { - glVertexPointer(3, GL_FLOAT, 0, m_points.data()); - glDrawArrays(GL_TRIANGLES, 0, m_points.size()); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_COLOR_MATERIAL); + + glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glEnableClientState(GL_NORMAL_ARRAY); + + glVertexPointer(3, GL_FLOAT, 0, (float *)m_points.data()); + glNormalPointer(GL_FLOAT, 0, (float *)m_normals.data()); + + glDrawElements(GL_TRIANGLES, m_pointIndices.size(), GL_UNSIGNED_INT, m_pointIndices.data()); + + glDisableClientState(GL_NORMAL_ARRAY); + + glDisable(GL_DEPTH_TEST); + + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_LIGHT0); + glDisable(GL_LIGHTING); } glDisableClientState(GL_VERTEX_ARRAY); + + if (normals) { + glColor3f(1, 0, 0); + glBegin(GL_LINES); + for (int i = 0; i < m_normals.size(); ++i) { + Point3d a = m_points.at(i); + Point3d b = m_points.at(i) + m_normals.at(i) * 0.02; + glVertex3f(a.x, a.y, a.z); + glVertex3f(b.x, b.y, b.z); + } + glEnd(); + } } + |