aboutsummaryrefslogtreecommitdiff
path: root/src/o3d
diff options
context:
space:
mode:
Diffstat (limited to 'src/o3d')
-rw-r--r--src/o3d/mesh.cpp10
-rw-r--r--src/o3d/mesh.hpp4
-rw-r--r--src/o3d/polygon.hpp69
3 files changed, 56 insertions, 27 deletions
diff --git a/src/o3d/mesh.cpp b/src/o3d/mesh.cpp
index fc5ff78..c3314b4 100644
--- a/src/o3d/mesh.cpp
+++ b/src/o3d/mesh.cpp
@@ -21,7 +21,7 @@ struct VertexIndicesHasher {
}
};
-Mesh Mesh::plane(float width, float height) {
+Mesh Mesh::plane(float width, float height) noexcept {
const float w2 = width / 2,
h2 = height / 2;
return {
@@ -50,18 +50,18 @@ Mesh Mesh::plane(float width, float height) {
};
}
-std::tuple<std::vector<engine::vk::Vertex>, std::vector<uint16_t>> Mesh::linearize_indices() const & {
+std::tuple<std::vector<engine::vk::Vertex>, std::vector<uint16_t>> Mesh::linearize_indices() const & noexcept {
std::unordered_map<std::array<size_t, 3>, size_t, VertexIndicesHasher<3>> unique_vertices;
std::vector<engine::vk::Vertex> linearized_vertices;
std::vector<uint16_t> linearized_indices;
- for (const auto& triangle_indices : this->indices) {
+ for (const auto& triangle_indices : indices) {
for (const auto& vertex_indices : triangle_indices) {
auto it = unique_vertices.find(vertex_indices);
if (it == unique_vertices.end()) {
- linearized_vertices.emplace_back(this->vertices[vertex_indices[0]], this->normals[vertex_indices[1]], this->uvs[vertex_indices[2]]);
+ linearized_vertices.emplace_back(vertices[vertex_indices[0]], normals[vertex_indices[1]], uvs[vertex_indices[2]]);
size_t idx = linearized_vertices.size() - 1;
- unique_vertices.emplace(vertex_indices, idx);
+ unique_vertices[vertex_indices] = idx;
linearized_indices.emplace_back(idx);
} else {
linearized_indices.emplace_back((*it).second);
diff --git a/src/o3d/mesh.hpp b/src/o3d/mesh.hpp
index d1d3f1c..cac0f62 100644
--- a/src/o3d/mesh.hpp
+++ b/src/o3d/mesh.hpp
@@ -13,7 +13,7 @@
namespace engine::o3d {
struct Mesh {
- static Mesh plane(float width, float height);
+ static Mesh plane(float width, float height) noexcept;
std::vector<engine::math::Vector3> vertices;
std::vector<engine::math::Vector3> normals;
@@ -22,7 +22,7 @@ struct Mesh {
// TODO: find a better way to do this. This workaround is due to the fact that vulkan only
// accepts a single index, not an index for each attributes
- std::tuple<std::vector<engine::vk::Vertex>, std::vector<uint16_t>> linearize_indices() const &;
+ std::tuple<std::vector<engine::vk::Vertex>, std::vector<uint16_t>> linearize_indices() const & noexcept;
};
}
diff --git a/src/o3d/polygon.hpp b/src/o3d/polygon.hpp
index 5ede910..47ecafe 100644
--- a/src/o3d/polygon.hpp
+++ b/src/o3d/polygon.hpp
@@ -17,11 +17,39 @@ concept PolygonVectorTypeConcept = engine::math::VectorTypeConcept<T> && (std::i
template<PolygonVectorTypeConcept VectorType, std::size_t max_points_count> struct Polygon;
+class ToPolygon {
+ public:
+ constexpr ToPolygon() {}
+};
+
template<engine::math::VectorTypeConcept VectorType>
-constexpr Polygon<VectorType, 3> from_triangle_derived(const engine::o3d::TriangleDerived<VectorType>& triangle_derived);
+constexpr Polygon<VectorType, 3> operator|(const engine::o3d::TriangleDerived<VectorType>& triangle_derived, ToPolygon);
template<PolygonVectorTypeConcept VectorType, std::size_t max_points_count, engine::math::vector_coords::VectorCoord coord_id, bool keep_geq>
-constexpr Polygon<VectorType, max_points_count + 1> clip_aligned(float boundary, const Polygon<VectorType, max_points_count>& polygon);
+class ClipAligned {
+ public:
+ constexpr ClipAligned(float boundary) : m_boundary { boundary } {}
+
+ constexpr float boundary() const & {
+ return m_boundary;
+ }
+ private:
+ float m_boundary;
+};
+
+template<PolygonVectorTypeConcept VectorType, std::size_t max_points_count, engine::math::vector_coords::VectorCoord coord_id, bool keep_geq>
+constexpr Polygon<VectorType, max_points_count + 1> operator|(const Polygon<VectorType, max_points_count>& polygon,
+ ClipAligned<VectorType, max_points_count, coord_id, keep_geq> clip_aligned);
+
+class DivByW {
+ public:
+ constexpr DivByW() {}
+};
+
+class SignedAreaXY {
+ public:
+ constexpr SignedAreaXY() {}
+};
template<PolygonVectorTypeConcept VectorType, std::size_t max_points_count>
struct Polygon {
@@ -33,19 +61,19 @@ struct Polygon {
: points_count { points_count }, points { points } {}
constexpr Polygon<VectorType, max_points_count + 2> clip_z(float z1, float z2) const & {
- return
- clip_aligned<VectorType, max_points_count + 1, engine::math::vector_coords::VectorCoord::z, false>(z2,
- clip_aligned<VectorType, max_points_count + 0, engine::math::vector_coords::VectorCoord::z, true >(z1,
- *this));
+ return *this
+ | ClipAligned<VectorType, max_points_count + 0, engine::math::vector_coords::VectorCoord::z, true >(z1)
+ | ClipAligned<VectorType, max_points_count + 1, engine::math::vector_coords::VectorCoord::z, false>(z2)
+ ;
}
constexpr Polygon<VectorType, max_points_count + 4> clip_xy(float x1, float y1, float x2, float y2) const & {
- return
- clip_aligned<VectorType, max_points_count + 3, engine::math::vector_coords::VectorCoord::y, false>(y2,
- clip_aligned<VectorType, max_points_count + 2, engine::math::vector_coords::VectorCoord::x, false>(x2,
- clip_aligned<VectorType, max_points_count + 1, engine::math::vector_coords::VectorCoord::y, true >(y1,
- clip_aligned<VectorType, max_points_count + 0, engine::math::vector_coords::VectorCoord::x, true >(x1,
- *this))));
+ return *this
+ | ClipAligned<VectorType, max_points_count + 0, engine::math::vector_coords::VectorCoord::x, true >(x1)
+ | ClipAligned<VectorType, max_points_count + 1, engine::math::vector_coords::VectorCoord::y, true >(y1)
+ | ClipAligned<VectorType, max_points_count + 2, engine::math::vector_coords::VectorCoord::x, false>(x2)
+ | ClipAligned<VectorType, max_points_count + 3, engine::math::vector_coords::VectorCoord::y, false>(y2)
+ ;
}
constexpr Polygon<VectorType, max_points_count> map_xy(
@@ -89,12 +117,13 @@ struct Polygon {
};
template<engine::math::VectorTypeConcept VectorType>
-constexpr Polygon<VectorType, 3> from_triangle_derived(const engine::o3d::TriangleDerived<VectorType>& triangle_derived) {
+constexpr Polygon<VectorType, 3> operator|(const engine::o3d::TriangleDerived<VectorType>& triangle_derived, ToPolygon) {
return { 3, { triangle_derived.derived_vertex1, triangle_derived.derived_vertex2, triangle_derived.derived_vertex3 } };
}
template<PolygonVectorTypeConcept VectorType, std::size_t max_points_count, engine::math::vector_coords::VectorCoord coord_id, bool keep_geq>
-constexpr Polygon<VectorType, max_points_count + 1> clip_aligned(float boundary, const Polygon<VectorType, max_points_count>& polygon)
+constexpr Polygon<VectorType, max_points_count + 1> operator|(const Polygon<VectorType, max_points_count>& polygon,
+ ClipAligned<VectorType, max_points_count, coord_id, keep_geq> clip_aligned)
{
using transposition = engine::math::vector_coords::transpose<engine::math::vector_coords::VectorCoord::x, coord_id>;
constexpr auto y_coord_id = transposition::template id<engine::math::vector_coords::VectorCoord::y>();
@@ -107,10 +136,10 @@ constexpr Polygon<VectorType, max_points_count + 1> clip_aligned(float boundary,
for (size_t i = 0; i < polygon.points_count; i++) {
const auto& prev = polygon.points[(i + polygon.points_count - 1) % polygon.points_count];
const auto& cur = polygon.points[i];
- if (is_in(prev, boundary) != is_in(cur, boundary)) {
- float fac = (boundary - prev.vertex.template v<coord_id>()) / (cur.vertex.template v<coord_id>() - prev.vertex.template v<coord_id>());
+ if (is_in(prev, clip_aligned.boundary()) != is_in(cur, clip_aligned.boundary())) {
+ float fac = (clip_aligned.boundary() - prev.vertex.template v<coord_id>()) / (cur.vertex.template v<coord_id>() - prev.vertex.template v<coord_id>());
auto& new_point = new_polygon.points[new_polygon.points_count++];
- new_point.vertex.template v<coord_id>() = boundary;
+ new_point.vertex.template v<coord_id>() = clip_aligned.boundary();
new_point.vertex.template v<y_coord_id>() = engine::math::utils::lerp(prev.vertex.template v<y_coord_id>(), cur.vertex.template v<y_coord_id>(), fac);
if constexpr (std::is_same_v<VectorType, engine::math::Vector3>) {
// called new_w because it represents w, but because we only need x, y and w, we use
@@ -127,14 +156,14 @@ constexpr Polygon<VectorType, max_points_count + 1> clip_aligned(float boundary,
new_point.b1 = engine::math::utils::lerp(prev.b1, cur.b1, fac);
}
}
- if (is_in(cur, boundary))
+ if (is_in(cur, clip_aligned.boundary()))
new_polygon.points[new_polygon.points_count++] = cur;
}
return new_polygon;
}
template<std::size_t max_points_count>
-constexpr Polygon<engine::math::Vector3, max_points_count> div_by_w(const Polygon<engine::math::Vector4, max_points_count>& polygon) {
+constexpr Polygon<engine::math::Vector3, max_points_count> operator|(const Polygon<engine::math::Vector4, max_points_count>& polygon, DivByW) {
Polygon<engine::math::Vector3, max_points_count> new_polygon;
new_polygon.points_count = polygon.points_count;
for (std::size_t i = 0; i < polygon.points_count; i++)
@@ -143,7 +172,7 @@ constexpr Polygon<engine::math::Vector3, max_points_count> div_by_w(const Polygo
}
template<std::size_t max_points_count>
-constexpr float signed_area_xy(const Polygon<engine::math::Vector3, max_points_count>& polygon) {
+constexpr float operator|(const Polygon<engine::math::Vector3, max_points_count>& polygon, SignedAreaXY) {
float res = 0.f;
if (polygon.points_count > 0) {
for (std::size_t i = 0; i < polygon.points_count - 1; i++)