From 4558a2a704bf75266f7262f8dd41bb1c9b094e1d Mon Sep 17 00:00:00 2001 From: vimene Date: Wed, 22 Nov 2023 20:32:48 +0100 Subject: code refactoring --- src/o3d/tri_vertex.cpp | 314 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 src/o3d/tri_vertex.cpp (limited to 'src/o3d/tri_vertex.cpp') diff --git a/src/o3d/tri_vertex.cpp b/src/o3d/tri_vertex.cpp new file mode 100644 index 0000000..7b6b379 --- /dev/null +++ b/src/o3d/tri_vertex.cpp @@ -0,0 +1,314 @@ +#include "o3d/tri_vertex.h" +#include +#include "math/math_vector.h" +#include "o3d/vertex_data.h" +#include "o3d/vertex.h" +#include "o3d/tri_vertex.h" + +TriangleVertex3::TriangleVertex3(Vertex3 vertex1, Vertex3 vertex2, Vertex3 vertex3) : vertex1{vertex1}, vertex2{vertex2}, vertex3{vertex3} { +} + +#define P1_OUT 1 +#define P2_OUT 2 +#define P3_OUT 4 +static void _crop_x(std::vector& tris, TriangleVertex3 t, int n, float x) { + switch (n) { + case 0: + tris.push_back(t); + break; + case P1_OUT: + case P2_OUT: + case P3_OUT: + case P2_OUT | P3_OUT: + case P1_OUT | P3_OUT: + case P1_OUT | P2_OUT: + { + Vertex3* q1; + Vertex3* q2; + Vertex3* q3; + switch (n) { + case P1_OUT: + case P2_OUT | P3_OUT: + q1 = &t.vertex1; + q2 = &t.vertex2; + q3 = &t.vertex3; + break; + case P2_OUT: + case P1_OUT | P3_OUT: + q1 = &t.vertex2; + q2 = &t.vertex1; + q3 = &t.vertex3; + break; + case P3_OUT: + case P1_OUT | P2_OUT: + q1 = &t.vertex3; + q2 = &t.vertex2; + q3 = &t.vertex1; + break; + } + MathVector3 dq2 = q1->point - q2->point; + float fac2 = (x - q2->point.x) / dq2.x; + Vertex3 r2{ + { + x, + q2->point.y + fac2 * dq2.y, + q2->point.z + fac2 * dq2.z + }, + VertexData::lerp(q2->data, q1->data, fac2) + }; + MathVector3 dq3 = q1->point - q3->point; + float fac3 = (x - q3->point.x) / dq3.x; + Vertex3 r3{ + { + x, + q3->point.y + fac3 * dq3.y, + q3->point.z + fac3 * dq3.z + }, + VertexData::lerp(q3->data, q1->data, fac3) + }; + switch (n) { + case P1_OUT: + tris.push_back({r3, *q2, *q3}); + tris.push_back({r3, r2, *q2}); + break; + case P2_OUT: + tris.push_back({r2, *q3, *q2}); + tris.push_back({r2, r3, *q3}); + break; + case P3_OUT: + tris.push_back({r2, *q3, *q2}); + tris.push_back({r2, r3, *q3}); + break; + case P2_OUT | P3_OUT: + tris.push_back({*q1, r2, r3}); + break; + case P1_OUT | P3_OUT: + tris.push_back({*q1, r3, r2}); + break; + case P1_OUT | P2_OUT: + tris.push_back({*q1, r3, r2}); + break; + } + } + break; + case P1_OUT | P2_OUT | P3_OUT: + break; + } +} + +static void _crop_y(std::vector& tris, TriangleVertex3 t, int n, float y) { + switch (n) { + case 0: + tris.push_back(t); + break; + case P1_OUT: + case P2_OUT: + case P3_OUT: + case P2_OUT | P3_OUT: + case P1_OUT | P3_OUT: + case P1_OUT | P2_OUT: + { + Vertex3* q1; + Vertex3* q2; + Vertex3* q3; + switch (n) { + case P1_OUT: + case P2_OUT | P3_OUT: + q1 = &t.vertex1; + q2 = &t.vertex2; + q3 = &t.vertex3; + break; + case P2_OUT: + case P1_OUT | P3_OUT: + q1 = &t.vertex2; + q2 = &t.vertex1; + q3 = &t.vertex3; + break; + case P3_OUT: + case P1_OUT | P2_OUT: + q1 = &t.vertex3; + q2 = &t.vertex2; + q3 = &t.vertex1; + break; + } + MathVector3 dq2 = q1->point - q2->point; + float fac2 = (y - q2->point.y) / dq2.y; + Vertex3 r2{ + { + q2->point.x + fac2 * dq2.x, + y, + q2->point.z + fac2 * dq2.z + }, + VertexData::lerp(q2->data, q1->data, fac2) + }; + MathVector3 dq3 = q1->point - q3->point; + float fac3 = (y - q3->point.y) / dq3.y; + Vertex3 r3{ + { + q3->point.x + fac3 * dq3.x, + y, + q3->point.z + fac3 * dq3.z + }, + VertexData::lerp(q3->data, q1->data, fac3) + }; + switch (n) { + case P1_OUT: + tris.push_back({r3, *q2, *q3}); + tris.push_back({r3, r2, *q2}); + break; + case P2_OUT: + tris.push_back({r2, *q3, *q2}); + tris.push_back({r2, r3, *q3}); + break; + case P3_OUT: + tris.push_back({r2, *q3, *q2}); + tris.push_back({r2, r3, *q3}); + break; + case P2_OUT | P3_OUT: + tris.push_back({*q1, r2, r3}); + break; + case P1_OUT | P3_OUT: + tris.push_back({*q1, r3, r2}); + break; + case P1_OUT | P2_OUT: + tris.push_back({*q1, r3, r2}); + break; + } + } + break; + case P1_OUT | P2_OUT | P3_OUT: + break; + } +} + +std::vector TriangleVertex3::crop_xy_out(float x1, float x2, float y1, float y2) const { + std::vector tris_final; + std::vector tris1; + _crop_x(tris1, *this, (vertex1.point.x < x1) | ((vertex2.point.x < x1) << 1) | ((vertex3.point.x < x1) << 2), x1); + for (auto t1 : tris1) { + std::vector tris2; + _crop_x(tris2, t1, (t1.vertex1.point.x > x2) | ((t1.vertex2.point.x > x2) << 1) | ((t1.vertex3.point.x > x2) << 2), x2); + for (auto t2 : tris2) { + std::vector tris3; + _crop_y(tris3, t2, (t2.vertex1.point.y < y1) | ((t2.vertex2.point.y < y1) << 1) | ((t2.vertex3.point.y < y1) << 2), y1); + for (auto t3 : tris3) + _crop_y(tris_final, t3, (t3.vertex1.point.y > y2) | ((t3.vertex2.point.y > y2) << 1) | ((t3.vertex3.point.y > y2) << 2), y2); + } + } + return tris_final; +} +#undef P1_OUT +#undef P2_OUT +#undef P3_OUT + +TriangleVertex4::TriangleVertex4(Vertex4 vertex1, Vertex4 vertex2, Vertex4 vertex3) : vertex1{vertex1}, vertex2{vertex2}, vertex3{vertex3} { +} + +TriangleVertex4::TriangleVertex4(TriangleVertex3 triangle) : vertex1{triangle.vertex1}, vertex2{triangle.vertex2}, vertex3{triangle.vertex3} { +} + +#define P1_OUT 1 +#define P2_OUT 2 +#define P3_OUT 4 +static void _crop_z(std::vector& tris, TriangleVertex4 t, int n, float z) { + switch (n) { + case 0: + tris.push_back(t); + break; + case P1_OUT: + case P2_OUT: + case P3_OUT: + case P2_OUT | P3_OUT: + case P1_OUT | P3_OUT: + case P1_OUT | P2_OUT: + { + Vertex4* q1; + Vertex4* q2; + Vertex4* q3; + switch (n) { + case P1_OUT: + case P2_OUT | P3_OUT: + q1 = &t.vertex1; + q2 = &t.vertex2; + q3 = &t.vertex3; + break; + case P2_OUT: + case P1_OUT | P3_OUT: + q1 = &t.vertex2; + q2 = &t.vertex1; + q3 = &t.vertex3; + break; + case P3_OUT: + case P1_OUT | P2_OUT: + q1 = &t.vertex3; + q2 = &t.vertex2; + q3 = &t.vertex1; + break; + } + MathVector4 dq2 = q1->point - q2->point; + float fac2 = (z - q2->point.z) / dq2.z; + Vertex4 r2{ + { + q2->point.x + fac2 * dq2.x, + q2->point.y + fac2 * dq2.y, + z, + q2->point.w + fac2 * dq2.w + }, + VertexData::lerp(q2->data, q1->data, fac2) + }; + MathVector4 dq3 = q1->point - q3->point; + float fac3 = (z - q3->point.z) / dq3.z; + Vertex4 r3{ + { + q3->point.x + fac3 * dq3.x, + q3->point.y + fac3 * dq3.y, + z, + q3->point.w + fac3 * dq3.w + }, + VertexData::lerp(q3->data, q1->data, fac3) + }; + switch (n) { + case P1_OUT: + tris.push_back({r3, *q2, *q3}); + tris.push_back({r3, r2, *q2}); + break; + case P2_OUT: + tris.push_back({r2, *q3, *q2}); + tris.push_back({r2, r3, *q3}); + break; + case P3_OUT: + tris.push_back({r2, *q3, *q2}); + tris.push_back({r2, r3, *q3}); + break; + case P2_OUT | P3_OUT: + tris.push_back({*q1, r2, r3}); + break; + case P1_OUT | P3_OUT: + tris.push_back({*q1, r3, r2}); + break; + case P1_OUT | P2_OUT: + tris.push_back({*q1, r3, r2}); + break; + } + } + break; + case P1_OUT | P2_OUT | P3_OUT: + break; + } +} + +std::vector TriangleVertex4::crop_z_out(float z1, float z2) const { + std::vector tris; + _crop_z(tris, *this, (vertex1.point.z < z1) | ((vertex2.point.z < z1) << 1) | ((vertex3.point.z < z1) << 2), z1); + std::vector tris2; + for (auto t : tris) + _crop_z(tris2, t, (t.vertex1.point.z > z2) | ((t.vertex2.point.z > z2) << 1) | ((t.vertex3.point.z > z2) << 2), z2); + return tris2; +} +#undef P1_OUT +#undef P2_OUT +#undef P3_OUT + +TriangleVertex3 TriangleVertex4::div_by_w() const { + return {vertex1.div_by_w(), vertex2.div_by_w(), vertex3.div_by_w()}; +} -- cgit v1.2.3