CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
SubdivideMesh.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
10#include "Edge.hpp"
11#include "MeshVertex.hpp"
12#include "Triangle.hpp"
13#include "Utility.hpp"
14
17
19
20 template<typename Mesh, int Iterations> class SubdivideMesh {
21 static_assert(Iterations > 0, "Iterations must be greater than zero!");
22
23 private:
26
27 public:
28 SubdivideMesh(Mesh mesh) : mSubdivideMesh{SubdivideMesh<Mesh, Iterations - 1>{std::move(mesh)}} {}
29
30 using Triangles = typename Impl::Triangles;
31 [[nodiscard]] Triangles triangles() const noexcept { return mSubdivideMesh.triangles(); }
32
33 using Vertices = typename Impl::Vertices;
34 [[nodiscard]] Vertices vertices() const noexcept { return mSubdivideMesh.vertices(); }
35 };
36
37 template<typename Mesh> class SubdivideMesh<Mesh, 0> {
38 private:
39 using Impl = Mesh;
41
42 public:
43 SubdivideMesh(Mesh mesh) : mMesh{std::move(mesh)} {}
44
45 using Triangles = typename Impl::Triangles;
46 [[nodiscard]] Triangles triangles() const noexcept { return mMesh.triangles(); }
47
48 using Vertices = typename Impl::Vertices;
49 [[nodiscard]] Vertices vertices() const noexcept { return mMesh.vertices(); }
50 };
51
53 template<typename Mesh> class SubdivideMesh<Mesh, 1> {
54 public:
55 class Triangles {
56 public:
57 [[nodiscard]] bool done() const noexcept { return mTriangles.done(); }
58
59 [[nodiscard]] Triangle generate() const {
60 if(i_ == 0)
61 triangle_ = mTriangles.generate();
62
63 if(i_ == 3) {
64 return Triangle{{vertexFromEdge(triangle_.vertices[0], triangle_.vertices[1]), vertexFromEdge(triangle_.vertices[1], triangle_.vertices[2]),
65 vertexFromEdge(triangle_.vertices[2], triangle_.vertices[0])}};
66 }
67
68 const int j = (i_ + 1) % 3;
69 const int k = (i_ + 2) % 3;
70 return Triangle{{triangle_.vertices[i_], vertexFromEdge(triangle_.vertices[i_], triangle_.vertices[j]),
71 vertexFromEdge(triangle_.vertices[k], triangle_.vertices[i_])}};
72 }
73
74 void next() {
75 ++i_;
76 if(i_ == 4) {
77 i_ = 0;
78 mTriangles.next();
79 }
80 }
81
82 private:
84
85 int i_;
86
88
90
91 Triangles(const SubdivideMesh& mesh) : mMesh{&mesh}, i_{0}, mTriangles{mesh.mMesh.triangles()}, triangle_{} {}
92
93 int vertexFromEdge(int a, int b) const {
94 if(a > b)
95 std::swap(a, b);
96 return static_cast<int>(mMesh->mVertexCache.size()) + mMesh->edgeMap_.at({a, b});
97 }
98
99 friend class SubdivideMesh;
100 };
101
102 class Vertices {
103 public:
104 [[nodiscard]] bool done() const noexcept { return vertexIndex_ == mMesh->mVertexCache.size() && edgeIndex_ == mMesh->edgeCache_.size(); }
105
106 [[nodiscard]] MeshVertex generate() const {
107 if(vertexIndex_ < mMesh->mVertexCache.size())
108 return mMesh->mVertexCache[vertexIndex_];
109
110 const MeshVertex& v1 = mMesh->mVertexCache[mMesh->edgeCache_[edgeIndex_].vertices[0]];
111 const MeshVertex& v2 = mMesh->mVertexCache[mMesh->edgeCache_[edgeIndex_].vertices[1]];
112
113 MeshVertex vertex;
114 vertex.position = mix(v1.position, v2.position, 0.5);
115 vertex.texCoord = mix(v1.texCoord, v2.texCoord, 0.5);
116 vertex.normal = normalize(mix(v1.normal, v2.normal, 0.5));
117 return vertex;
118 }
119
120 void next() {
121 if(vertexIndex_ < mMesh->mVertexCache.size())
122 ++vertexIndex_;
123 else
124 ++edgeIndex_;
125 }
126
127 private:
129
132
133 Vertices(const SubdivideMesh& mesh) : mMesh{&mesh}, edgeIndex_{0}, vertexIndex_{0} {}
134
135 friend class SubdivideMesh;
136 };
137
138 SubdivideMesh(Mesh mesh) : mMesh{std::move(mesh)} {
139 for(const MeshVertex& vertex : mMesh.vertices()) {
140 mVertexCache.push_back(vertex);
141 }
142
143 for(const Triangle& triangle : mMesh.triangles()) {
144 for(int i = 0; i < 3; ++i) {
145 const int j = (i + 1) % 3;
146
147 Edge e{{triangle.vertices[i], triangle.vertices[j]}};
148 if(e.vertices[0] > e.vertices[1])
149 std::swap(e.vertices[0], e.vertices[1]);
150
151 if(edgeMap_.find(e.vertices) == edgeMap_.end()) {
152 edgeMap_[e.vertices] = static_cast<int>(edgeCache_.size());
153 edgeCache_.push_back(e);
154 }
155 }
156 }
157 }
158
159 [[nodiscard]] Triangles triangles() const noexcept { return *this; }
160
161 [[nodiscard]] Vertices vertices() const noexcept { return *this; }
162
163 private:
165
167
169
171 };
172
173} // namespace CeresEngine::MeshGenerator
Definition Edge.hpp:14
Definition MeshVertex.hpp:14
Vector3 normal
Unit vector perpendicular to the surface.
Definition MeshVertex.hpp:19
Vector2 texCoord
UV texture coordinates.
Definition MeshVertex.hpp:22
Vector3 position
Definition MeshVertex.hpp:16
Vertices vertices() const noexcept
Definition SubdivideMesh.hpp:49
typename Impl::Vertices Vertices
Definition SubdivideMesh.hpp:48
Impl mMesh
Definition SubdivideMesh.hpp:40
typename Impl::Triangles Triangles
Definition SubdivideMesh.hpp:45
Triangles triangles() const noexcept
Definition SubdivideMesh.hpp:46
SubdivideMesh(Mesh mesh)
Definition SubdivideMesh.hpp:43
const SubdivideMesh * mMesh
Definition SubdivideMesh.hpp:83
TriangleGeneratorType< Mesh >::Type mTriangles
Definition SubdivideMesh.hpp:87
int vertexFromEdge(int a, int b) const
Definition SubdivideMesh.hpp:93
Triangles(const SubdivideMesh &mesh)
Definition SubdivideMesh.hpp:91
Triangle generate() const
Definition SubdivideMesh.hpp:59
bool done() const noexcept
Definition SubdivideMesh.hpp:57
const SubdivideMesh * mMesh
Definition SubdivideMesh.hpp:128
Vertices(const SubdivideMesh &mesh)
Definition SubdivideMesh.hpp:133
MeshVertex generate() const
Definition SubdivideMesh.hpp:106
bool done() const noexcept
Definition SubdivideMesh.hpp:104
SubdivideMesh(Mesh mesh)
Definition SubdivideMesh.hpp:138
Triangles triangles() const noexcept
Definition SubdivideMesh.hpp:159
Mesh mMesh
Definition SubdivideMesh.hpp:164
Map< Vector2i, int > edgeMap_
Definition SubdivideMesh.hpp:168
Vector< Edge > edgeCache_
Definition SubdivideMesh.hpp:166
Vertices vertices() const noexcept
Definition SubdivideMesh.hpp:161
Vector< MeshVertex > mVertexCache
Definition SubdivideMesh.hpp:170
Definition SubdivideMesh.hpp:20
SubdivideMesh(Mesh mesh)
Definition SubdivideMesh.hpp:28
Vertices vertices() const noexcept
Definition SubdivideMesh.hpp:34
typename Impl::Triangles Triangles
Definition SubdivideMesh.hpp:30
Impl mSubdivideMesh
Definition SubdivideMesh.hpp:25
typename Impl::Vertices Vertices
Definition SubdivideMesh.hpp:33
Triangles triangles() const noexcept
Definition SubdivideMesh.hpp:31
decltype(std::declval< const Primitive * >() ->triangles()) Type
Definition Utility.hpp:32
Definition Triangle.hpp:14
Vector3i vertices
Zero based indices of the triangle vertices in counterclockwise order.
Definition Triangle.hpp:17
A base class for all mesh implementations.
Definition Mesh.hpp:112
Definition AnyGenerator.hpp:12
std::vector< T, ScopedAllocatorAdaptor< StdAllocator< T, RawAllocator > > > Vector
Vector is a sequence container that encapsulates dynamic size arrays.
Definition Vector.hpp:17
auto move(Vector3 position)
Moves a entity to the given position.
Definition Helpers.hpp:22
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
std::map< Key, T, Compare, ScopedAllocatorAdaptor< StdAllocator< Pair< const Key, T >, RawAllocator > > > Map
Map is a sorted associative container that contains key-value pairs with unique keys.
Definition Map.hpp:24
Definition Span.hpp:668