diff --git a/fastmath.hpp b/fastmath.hpp index e904eaa..c4f26d1 100644 --- a/fastmath.hpp +++ b/fastmath.hpp @@ -208,24 +208,24 @@ struct vec2 : public vec<2, vec2> { }; struct vec3 : public vec<3, vec3> { - vec3() : vec<3, vec3>() {} + constexpr vec3() : vec<3, vec3>() {} - vec3(float x, float y, float z) + constexpr vec3(float x, float y, float z) : vec<3, vec3>(decimal(x), decimal(y), decimal(z)) {} - vec3(double x, double y, double z) + constexpr vec3(double x, double y, double z) : vec<3, vec3>(decimal(x), decimal(y), decimal(z)) {} - vec3(int32_t x, int32_t y, int32_t z) + constexpr vec3(int32_t x, int32_t y, int32_t z) : vec<3, vec3>(decimal(x), decimal(y), decimal(z)) {} - vec3(decimal x, decimal y, decimal z) : vec<3, vec3>(x, y, z) {} + constexpr vec3(decimal x, decimal y, decimal z) : vec<3, vec3>(x, y, z) {} - decimal &x() { return v[0]; } - decimal &y() { return v[1]; } - decimal &z() { return v[2]; } + inline decimal &x() { return v[0]; } + inline decimal &y() { return v[1]; } + inline decimal &z() { return v[2]; } - vec3 cross(vec3 &v) { + inline vec3 cross(vec3 &v) { return vec3((y() * v.z()) - (z() * v.y()), (z() * v.x()) - (x() * v.z()), (x() * v.y()) - (y() * v.x())); diff --git a/polygon.hpp b/polygon.hpp index b56d984..c246133 100644 --- a/polygon.hpp +++ b/polygon.hpp @@ -13,6 +13,8 @@ struct polygon { decimal bounding[4]; // min x, max x, min y, max y vec3 normals[3]; vec3 colors[3]; + vec3 barycentrics; + vec3 boundingBarycentrics; polygon(const vec3 &v1, const vec3 &v2, const vec3 &v3) : points{v1, v2, v3}, delta{} {} @@ -61,13 +63,13 @@ struct polygon { vec3 avgNormal() { vec3 result; - for (int i = 0; i < 3;i++) { + for (int i = 0; i < 3; i++) { result += normals[i]; } return result * decimal(0.3333); } - const bool contains(const vec3 &p) { + const bool depContains(const vec3 &p) { // if (skip) // return false; for (int i = 0; i < 3; i++) { @@ -80,6 +82,14 @@ struct polygon { } return true; } + const bool contains(const vec3 &p) { + if (small) + return true; + else + return (barycentrics[0] >= decimal(-0.01)) && + (barycentrics[1] >= decimal(-0.01)) && + (barycentrics[2] >= decimal(-0.01)); + } friend std::ostream &operator<<(std::ostream &os, const polygon &p) { for (int i = 0; i < 3; i++) { os << p.points[i]; @@ -87,40 +97,37 @@ struct polygon { return os; } - vec3 calcNormal(vec3 barycentrics) { - vec3 result = normals[0] * barycentrics[0] + - normals[1] * barycentrics[1] + - normals[2] * barycentrics[2]; - if (result.isSmall()) - return normals[0]; - else - return result.normalize(); + vec3 calcNormal() { + return normals[0] * boundingBarycentrics[0] + + normals[1] * boundingBarycentrics[1] + + normals[2] * boundingBarycentrics[2]; } - vec3 calcColor(vec3 barycentrics) { - return colors[0] * barycentrics[0] + colors[1] * barycentrics[1] + - colors[2] * barycentrics[2]; + vec3 calcColor() { + return colors[0] * boundingBarycentrics[0] + + colors[1] * boundingBarycentrics[1] + + colors[2] * boundingBarycentrics[2]; } - decimal calcDepth(vec3 barycentrics) { - return points[0].z() * barycentrics[0] + - points[1].z() * barycentrics[1] + - points[2].z() * barycentrics[2]; + decimal calcDepth() { + return points[0].z() * boundingBarycentrics[0] + + points[1].z() * boundingBarycentrics[1] + + points[2].z() * boundingBarycentrics[2]; } - vec3 calcBarycentric(vec3 s) { + void 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]; + + barycentrics[0] = (points[1].x() - s.x()) * (points[2].y() - s.y()) - + (points[2].x() - s.x()) * (points[1].y() - s.y()); + barycentrics[1] = (points[2].x() - s.x()) * (points[0].y() - s.y()) - + (points[0].x() - s.x()) * (points[2].y() - s.y()); + barycentrics = barycentrics * baryFactor; + barycentrics[2] = decimal(1.0) - barycentrics[1] - barycentrics[0]; // return result; - return vec3::max(vec3::min(result, vec3(1.0, 1.0, 1.0)), - vec3(0.0, 0.0, 0.0)); + boundingBarycentrics = vec3::max( + vec3::min(barycentrics, vec3(1.0, 1.0, 1.0)), vec3(0.0, 0.0, 0.0)); } }; diff --git a/renderer.hpp b/renderer.hpp index 20fa0da..32bf0b1 100644 --- a/renderer.hpp +++ b/renderer.hpp @@ -84,15 +84,18 @@ class Renderer { vec3 pos = vec3(testP.bounding[0], testP.bounding[2], 0.0); for (int x = startX; x < endX; x++) { for (int y = startY; y < endY; y++) { + + testP.calcBarycentric(pos); + if (testP.contains(pos)) { if (testP.small) continue; - vec3 factors = testP.calcBarycentric(pos); - decimal depth = testP.calcDepth(factors); + + decimal depth = testP.calcDepth(); if (depth < target->getDepth(x, y)) { // std::cout << factors << std::endl; - vec3 normal = testP.calcNormal(factors); - vec3 color = testP.calcColor(factors); + vec3 normal = testP.calcNormal(); + vec3 color = testP.calcColor(); decimal lightFac = std::max(normal * (-sunDir), decimal(0.0)) + decimal(0.5); @@ -106,7 +109,8 @@ class Renderer { // target->set(x, y, // (normal + vec3(1.0, 1.0, 1.0)) * // decimal(120.0)); - // target->set(x, y, factors * decimal(200.0)); + // target->set(x, y, + // testP.barycentrics * decimal(200.0)); // if (!factors.isSmall()) // target->set(x, y, vec3(0., 255.0, 0.)); }