diff --git a/ACKNOWLEDGEMENTS.html b/ACKNOWLEDGEMENTS.html index af5f628a..e5a4f806 100644 --- a/ACKNOWLEDGEMENTS.html +++ b/ACKNOWLEDGEMENTS.html @@ -1065,3 +1065,8 @@ https://www.reddit.com/r/gamedev/comments/5iuf3h/i_am_writting_a_3d_monster_mode OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +

Martijn Buijs

+
+    http://www.bytehazard.com/articles/wnormals100.ms
+
\ No newline at end of file diff --git a/src/meshresultcontext.cpp b/src/meshresultcontext.cpp index 01e3fb49..20dbfa9b 100644 --- a/src/meshresultcontext.cpp +++ b/src/meshresultcontext.cpp @@ -420,11 +420,30 @@ void MeshResultContext::calculateResultTriangleUvs(std::vector void MeshResultContext::interpolateVertexNormals(std::vector &resultNormals) { resultNormals.resize(vertices.size()); + + auto angleBetweenVectors = [](const QVector3D &first, const QVector3D &second) { + return std::acos(QVector3D::dotProduct(first.normalized(), second.normalized())); + }; + + auto areaOfTriangle = [](const QVector3D &a, const QVector3D &b, const QVector3D &c) { + auto ab = b - a; + auto ac = c - a; + return 0.5 * QVector3D::crossProduct(ab, ac).length(); + }; + for (size_t triangleIndex = 0; triangleIndex < triangles.size(); triangleIndex++) { const auto &sourceTriangle = triangles[triangleIndex]; + const auto &v1 = vertices[sourceTriangle.indicies[0]].position; + const auto &v2 = vertices[sourceTriangle.indicies[1]].position; + const auto &v3 = vertices[sourceTriangle.indicies[2]].position; + float area = areaOfTriangle(v1, v2, v3); + float angles[] = {angleBetweenVectors(v2-v1, v3-v1), + angleBetweenVectors(v1-v2, v3-v2), + angleBetweenVectors(v1-v3, v2-v3)}; for (int i = 0; i < 3; i++) - resultNormals[sourceTriangle.indicies[i]] += sourceTriangle.normal; + resultNormals[sourceTriangle.indicies[i]] += sourceTriangle.normal * area * angles[i]; } + for (auto &item: resultNormals) item.normalize(); }