#ifndef POLYGON_H #define POLYGON_H #include "fastmath.hpp" struct polygon { vec3 points[3]; decimal delta[9]; bool small = false; decimal baryFactor; decimal bounding[4]; // min x, max x, min y, max y vec3 normals[3]; polygon(const vec3 &v1, const vec3 &v2, const vec3 &v3) : points{v1, v2, v3}, delta{} {} polygon() : points{}, delta{} {} void calcDelta() { for (int i = 0; i < 3; i++) { int n = (i + 1) % 3; delta[i * 3] = points[i].y() - points[n].y(); delta[i * 3 + 1] = points[n].x() - points[i].x(); delta[i * 3 + 2] = points[i].x() * points[n].y() - points[i].y() * points[n].x(); if (delta[i * 3].i == 0 && delta[i * 3 + 1].i == 0) small = true; } bounding[0] = points[0].x(); bounding[1] = points[0].x(); bounding[2] = points[0].y(); bounding[3] = points[0].y(); for (int i = 1; i < 3; i++) { if (bounding[0] > points[i].x()) bounding[0] = points[i].x(); if (bounding[1] < points[i].x()) bounding[1] = points[i].x(); if (bounding[2] > points[i].y()) bounding[2] = points[i].y(); if (bounding[3] < points[i].y()) bounding[3] = points[i].y(); } baryFactor = (points[1].x() - points[0].x()) * (points[2].y() - points[1].y()) - (points[1].y() - points[0].y()) * (points[2].x() - points[1].x()); if (baryFactor.isSmall()) { small = true; } else baryFactor = decimal(1.0) / baryFactor; // std::cout << baryFactor << std::endl; /*if ((bounding[1].i - bounding[0].i < 1 << HALF_SHIFT) && (bounding[3].i - bounding[2].i < 1 << HALF_SHIFT)) small = true;*/ } const bool contains(const vec3 &p) { // if (skip) // return false; for (int i = 0; i < 3; i++) { if (small) return true; vec3 d = p; if ((d.x() * delta[i * 3] + d.y() * delta[i * 3 + 1] + delta[i * 3 + 2]) > decimal(0.2)) return false; } return true; } friend std::ostream &operator<<(std::ostream &os, const polygon &p) { for (int i = 0; i < 3; i++) { os << p.points[i]; } return os; } vec3 calcNormal(vec3 barycentrics) { vec3 result = normals[0] * barycentrics[0] + normals[1] * barycentrics[1] + normals[2] * barycentrics[2]; return result.normalize(); } decimal calcDepth(vec3 barycentrics) { return points[0].z() * barycentrics[0] + points[1].z() * barycentrics[1] + points[2].z() * barycentrics[2]; } vec3 calcBarycentric(vec3 s) { if (small) return vec3(decimal(0.333), decimal(0.333), decimal(0.333)); vec3 result; result[0] = (points[1].x() - s.x()) * (points[2].y() - s.y()) - (points[2].x() - s.x()) * (points[1].y() - s.y()); result[1] = (points[2].x() - s.x()) * (points[0].y() - s.y()) - (points[0].x() - s.x()) * (points[2].y() - s.y()); result = result * baryFactor; result[2] = decimal(1.0) - result[1] - result[0]; return result; } }; #endif