accelerated-raytracer/src/Triangle.cpp

62 lines
1.9 KiB
C++

#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<float> 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<float>(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