aboutsummaryrefslogtreecommitdiff
path: root/src/o3d
diff options
context:
space:
mode:
authorvimene <vincent.menegaux@gmail.com>2023-11-22 20:32:48 +0100
committervimene <vincent.menegaux@gmail.com>2023-11-22 20:32:48 +0100
commit4558a2a704bf75266f7262f8dd41bb1c9b094e1d (patch)
tree3042dedc701d0458d5ede0a85d554ec174c61a6f /src/o3d
parent6322e8d7e6e4ddb1c0a0b3a00a1b516d1a84df49 (diff)
downloadengine-4558a2a704bf75266f7262f8dd41bb1c9b094e1d.tar.gz
code refactoring
Diffstat (limited to 'src/o3d')
-rw-r--r--src/o3d/obj3d.cpp46
-rw-r--r--src/o3d/obj3d.h42
-rw-r--r--src/o3d/tri_vertex.cpp314
-rw-r--r--src/o3d/tri_vertex.h29
-rw-r--r--src/o3d/vertex.cpp16
-rw-r--r--src/o3d/vertex.h25
-rw-r--r--src/o3d/vertex_data.cpp12
-rw-r--r--src/o3d/vertex_data.h12
8 files changed, 496 insertions, 0 deletions
diff --git a/src/o3d/obj3d.cpp b/src/o3d/obj3d.cpp
new file mode 100644
index 0000000..46f4db6
--- /dev/null
+++ b/src/o3d/obj3d.cpp
@@ -0,0 +1,46 @@
+#include "o3d/obj3d.h"
+#include <vector>
+#include <array>
+#include "o3d/vertex.h"
+#include "o3d/tri_vertex.h"
+
+Object3D::TriangleVertex3Iterator::TriangleVertex3Iterator(const Object3D* obj, int face_ind) : obj{obj}, face_ind{face_ind} {
+}
+
+Object3D::TriangleVertex3Iterator& Object3D::TriangleVertex3Iterator::operator++() {
+ face_ind++;
+ return *this;
+}
+
+Object3D::TriangleVertex3Iterator Object3D::TriangleVertex3Iterator::operator++(int) {
+ TriangleVertex3Iterator retval = *this;
+ ++(*this);
+ return retval;
+}
+
+bool Object3D::TriangleVertex3Iterator::operator==(TriangleVertex3Iterator other) const {
+ return obj == other.obj && face_ind == other.face_ind;
+}
+
+bool Object3D::TriangleVertex3Iterator::operator!=(TriangleVertex3Iterator other) const {
+ return !(*this == other);
+}
+
+Object3D::TriangleVertex3Iterator::reference Object3D::TriangleVertex3Iterator::operator*() const {
+ return {
+ obj->pts[obj->faces[face_ind][0]],
+ obj->pts[obj->faces[face_ind][1]],
+ obj->pts[obj->faces[face_ind][2]]
+ };
+}
+
+Object3D::Object3D(std::vector<Vertex3> pts, std::vector<std::array<int, 3>> faces) : pts{pts}, faces{faces} {
+}
+
+Object3D::TriangleVertex3Iterator Object3D::begin() {
+ return Object3D::TriangleVertex3Iterator{this};
+}
+
+Object3D::TriangleVertex3Iterator Object3D::end() {
+ return Object3D::TriangleVertex3Iterator{this, static_cast<int>(faces.size())};
+}
diff --git a/src/o3d/obj3d.h b/src/o3d/obj3d.h
new file mode 100644
index 0000000..559ed63
--- /dev/null
+++ b/src/o3d/obj3d.h
@@ -0,0 +1,42 @@
+#ifndef O3D_OBJ3D_H
+#define O3D_OBJ3D_H
+
+#include <vector>
+#include <array>
+#include <iterator>
+#include "o3d/vertex.h"
+#include "o3d/tri_vertex.h"
+
+class Object3D {
+ public:
+ class TriangleVertex3Iterator {
+ public:
+ using iterator_category = std::input_iterator_tag;
+ using value_type = TriangleVertex3;
+ using difference_type = TriangleVertex3;
+ using pointer = const TriangleVertex3*;
+ using reference = TriangleVertex3;
+
+ explicit TriangleVertex3Iterator(const Object3D* obj, int face_ind = 0);
+ TriangleVertex3Iterator& operator++();
+ TriangleVertex3Iterator operator++(int);
+ bool operator==(TriangleVertex3Iterator other) const;
+ bool operator!=(TriangleVertex3Iterator other) const;
+ reference operator*() const;
+
+ private:
+ const Object3D* obj;
+ int face_ind;
+
+ };
+
+ Object3D(std::vector<Vertex3> pts, std::vector<std::array<int, 3>> faces);
+ TriangleVertex3Iterator begin();
+ TriangleVertex3Iterator end();
+
+ private:
+ std::vector<Vertex3> pts;
+ std::vector<std::array<int, 3>> faces;
+};
+
+#endif // O3D_OBJ3D_H
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 <vector>
+#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<TriangleVertex3>& 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<TriangleVertex3>& 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> TriangleVertex3::crop_xy_out(float x1, float x2, float y1, float y2) const {
+ std::vector<TriangleVertex3> tris_final;
+ std::vector<TriangleVertex3> 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<TriangleVertex3> 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<TriangleVertex3> 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<TriangleVertex4>& 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> TriangleVertex4::crop_z_out(float z1, float z2) const {
+ std::vector<TriangleVertex4> tris;
+ _crop_z(tris, *this, (vertex1.point.z < z1) | ((vertex2.point.z < z1) << 1) | ((vertex3.point.z < z1) << 2), z1);
+ std::vector<TriangleVertex4> 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()};
+}
diff --git a/src/o3d/tri_vertex.h b/src/o3d/tri_vertex.h
new file mode 100644
index 0000000..91e20f5
--- /dev/null
+++ b/src/o3d/tri_vertex.h
@@ -0,0 +1,29 @@
+#ifndef O3D_TRI_VERTEX_H
+#define O3D_TRI_VERTEX_H
+
+#include "o3d/vertex.h"
+#include <vector>
+
+class TriangleVertex3 {
+ public:
+ Vertex3 vertex1;
+ Vertex3 vertex2;
+ Vertex3 vertex3;
+
+ TriangleVertex3(Vertex3 vertex1, Vertex3 vertex2, Vertex3 vertex3);
+ std::vector<TriangleVertex3> crop_xy_out(float x1, float x2, float y1, float y2) const;
+};
+
+class TriangleVertex4 {
+ public:
+ Vertex4 vertex1;
+ Vertex4 vertex2;
+ Vertex4 vertex3;
+
+ TriangleVertex4(Vertex4 vertex1, Vertex4 vertex2, Vertex4 vertex3);
+ TriangleVertex4(TriangleVertex3 triangle);
+ std::vector<TriangleVertex4> crop_z_out(float z1, float z2) const;
+ TriangleVertex3 div_by_w() const;
+};
+
+#endif // O3D_TRI_VERTEX_H
diff --git a/src/o3d/vertex.cpp b/src/o3d/vertex.cpp
new file mode 100644
index 0000000..c3bddef
--- /dev/null
+++ b/src/o3d/vertex.cpp
@@ -0,0 +1,16 @@
+#include "o3d/vertex.h"
+#include "math/math_vector.h"
+#include "o3d/vertex_data.h"
+
+Vertex3::Vertex3(MathVector3 point, VertexData data) : point{point}, data{data} {
+}
+
+Vertex4::Vertex4(MathVector4 point, VertexData data) : point{point}, data{data} {
+}
+
+Vertex4::Vertex4(Vertex3 vertex) : point{vertex.point}, data{vertex.data} {
+}
+
+Vertex3 Vertex4::div_by_w() const {
+ return {point.div_by_w(), data};
+}
diff --git a/src/o3d/vertex.h b/src/o3d/vertex.h
new file mode 100644
index 0000000..27ca56a
--- /dev/null
+++ b/src/o3d/vertex.h
@@ -0,0 +1,25 @@
+#ifndef O3D_VERTEX_H
+#define O3D_VERTEX_H
+
+#include "math/math_vector.h"
+#include "o3d/vertex_data.h"
+
+class Vertex3 {
+ public:
+ MathVector3 point;
+ VertexData data;
+
+ Vertex3(MathVector3 point, VertexData data);
+};
+
+class Vertex4 {
+ public:
+ MathVector4 point;
+ VertexData data;
+
+ Vertex4(MathVector4 point, VertexData data);
+ Vertex4(Vertex3 vertex);
+ Vertex3 div_by_w() const;
+};
+
+#endif // O3D_VERTEX_H
diff --git a/src/o3d/vertex_data.cpp b/src/o3d/vertex_data.cpp
new file mode 100644
index 0000000..8d6f77b
--- /dev/null
+++ b/src/o3d/vertex_data.cpp
@@ -0,0 +1,12 @@
+#include "o3d/vertex_data.h"
+
+VertexData VertexData::lerp(VertexData& vd1, VertexData& vd2, float s) {
+ return {};
+}
+
+VertexData VertexData::bilerp(VertexData& vd1, VertexData& vd2, VertexData& vd3, float s, float t) {
+ return {};
+}
+
+VertexData::VertexData() {
+}
diff --git a/src/o3d/vertex_data.h b/src/o3d/vertex_data.h
new file mode 100644
index 0000000..0000dda
--- /dev/null
+++ b/src/o3d/vertex_data.h
@@ -0,0 +1,12 @@
+#ifndef O3D_VERTEX_DATA_H
+#define O3D_VERTEX_DATA_H
+
+class VertexData {
+ public:
+ static VertexData lerp(VertexData& vd1, VertexData& vd2, float s);
+ static VertexData bilerp(VertexData& vd1, VertexData& vd2, VertexData& vd3, float s, float t);
+
+ VertexData();
+};
+
+#endif // O3D_VERTEX_DATA_H