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();
}