#include "Triangle.h" namespace raytry { Triangle::Triangle(QVector3D a, QVector3D b, QVector3D c) : a{a}, b{b}, c{c} { an = bn = cn = QVector3D::crossProduct(b - a, c - a).normalized(); } Triangle::Triangle(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &an, const QVector3D &bn, const QVector3D &cn, const RenderMaterial &mat) : a(a), b(b), c(c), an(an), bn(bn), cn(cn), mat(mat) {} std::optional Triangle::intersects(const Ray &ray) const { // Möller, Trumbore const QVector3D &v0v1 = b - a; const QVector3D &v0v2 = c - a; const auto pvec = QVector3D::crossProduct(ray.directionVec, v0v2); const float det = QVector3D::dotProduct(v0v1, pvec); if (qFuzzyIsNull(det)) { return std::nullopt; } const float invDet = 1 / det; const auto tvec = ray.originVec - a; const float u = QVector3D::dotProduct(tvec, pvec) * invDet; if (u < 0 || u > 1) { return std::nullopt; } const auto qvec = QVector3D::crossProduct(tvec, v0v1); const float v = QVector3D::dotProduct(ray.directionVec, qvec) * invDet; if (v < 0 || u + v > 1) { return std::nullopt; } const auto& t = QVector3D::dotProduct(v0v2, qvec) * invDet; if (t < nearCrop) { return std::nullopt; } return std::make_optional(t); } const QVector3D &Triangle::aVec() const { return a; } const QVector3D &Triangle::bVec() const { return b; } const QVector3D &Triangle::cVec() const { return c; } RenderMaterial Triangle::material() const { return mat; } void Triangle::setMaterial(RenderMaterial material) { mat = material; } QVector3D Triangle::calculateNormal(QVector3D hitpoint) const { // FIXME return an; } }// namespace raytry