dust3d/src/triangletangentresolve.cpp

40 lines
1.5 KiB
C++
Raw Normal View History

#include <QDebug>
#include "triangletangentresolve.h"
2020-11-17 14:31:51 +00:00
void triangleTangentResolve(const Object &object, std::vector<QVector3D> &tangents)
{
2020-11-17 14:31:51 +00:00
tangents.resize(object.triangles.size());
2020-11-17 14:31:51 +00:00
if (nullptr == object.triangleVertexUvs())
return;
2020-11-17 14:31:51 +00:00
const std::vector<std::vector<QVector2D>> &triangleVertexUvs = *object.triangleVertexUvs();
2020-11-17 14:31:51 +00:00
for (decltype(object.triangles.size()) i = 0; i < object.triangles.size(); i++) {
tangents[i] = {0, 0, 0};
const auto &uv = triangleVertexUvs[i];
QVector2D uv1 = {uv[0][0], uv[0][1]};
QVector2D uv2 = {uv[1][0], uv[1][1]};
QVector2D uv3 = {uv[2][0], uv[2][1]};
2020-11-17 14:31:51 +00:00
const auto &triangle = object.triangles[i];
const QVector3D &pos1 = object.vertices[triangle[0]];
const QVector3D &pos2 = object.vertices[triangle[1]];
const QVector3D &pos3 = object.vertices[triangle[2]];
QVector3D edge1 = pos2 - pos1;
QVector3D edge2 = pos3 - pos1;
QVector2D deltaUv1 = uv2 - uv1;
QVector2D deltaUv2 = uv3 - uv1;
auto bottom = deltaUv1.x() * deltaUv2.y() - deltaUv2.x() * deltaUv1.y();
if (qFuzzyIsNull(bottom)) {
bottom = 0.000001;
}
float f = 1.0 / bottom;
QVector3D tangent = {
f * (deltaUv2.y() * edge1.x() - deltaUv1.y() * edge2.x()),
f * (deltaUv2.y() * edge1.y() - deltaUv1.y() * edge2.y()),
f * (deltaUv2.y() * edge1.z() - deltaUv1.y() * edge2.z())
};
tangents[i] = tangent.normalized();
}
}