22 #include <unordered_map>
29 std::size_t operator()(
const std::array<std::size_t, 2>& v)
const noexcept
31 std::size_t
hash = std::hash<std::size_t>()(
v[0]);
32 return hash ^ (std::hash<std::size_t>()(
v[1]) + 0x9e3779b9 + (
hash << 6) + (
hash >> 2));
38 for (
const auto& vertex: vertices)
41 std::unordered_map<std::array<std::size_t, 2>,
geom::mesh::edge*, edge_hasher> edge_map;
43 std::vector<geom::mesh::edge*> loop(3);
45 for (
const auto& triangle: triangles)
49 mesh_vertices[triangle[0]],
50 mesh_vertices[triangle[1]],
51 mesh_vertices[triangle[2]]
54 for (
int j = 0; j < 3; ++j)
59 if (
auto it = edge_map.find({start->index, end->index}); it != edge_map.end())
66 edge_map[{start->index, end->index}] = loop[j];
67 edge_map[{end->index, start->index}] = loop[j]->
symmetric;
80 for (std::size_t i = 0; i < faces.size(); ++i)
105 std::vector<float3> tangent_buffer(vertices.size(),
float3{0.0f, 0.0f, 0.0f});
106 std::vector<float3> bitangent_buffer(vertices.size(),
float3{0.0f, 0.0f, 0.0f});
109 for (std::size_t i = 0; i < faces.size(); ++i)
115 const float3& a = vertices[ia]->position;
116 const float3& b = vertices[ib]->position;
117 const float3& c = vertices[ic]->position;
118 const float2& uva = texcoords[ia];
119 const float2& uvb = texcoords[ib];
120 const float2& uvc = texcoords[ic];
127 float f = 1.0f / (uvba.
x() * uvca.
y() - uvca.
x() * uvba.
y());
129 float3 bitangent = (ba * -uvca.
x() + ca * uvba.
x()) * f;
134 bitangent_buffer[ia] += bitangent;
135 bitangent_buffer[ib] += bitangent;
136 bitangent_buffer[ic] += bitangent;
140 for (std::size_t i = 0; i < vertices.size(); ++i)
142 const float3& n = normals[i];
143 const float3& t = tangent_buffer[i];
144 const float3& b = bitangent_buffer[i];
159 for (
int i = 0; i < 3; ++i)
161 bounds.
min[i] = std::numeric_limits<float>::infinity();
162 bounds.
max[i] = -std::numeric_limits<float>::infinity();
167 const auto&
position = vertex->position;
183 loop.push_back(edge);
184 sum_positions += edge->vertex->position;
187 if (loop.size() <= 2)
206 for (std::size_t i = 1; i < loop.size(); ++i)
211 if (i == loop.size() - 1)
void remove_face(mesh::face *face)
Removes a face from the mesh.
mesh::face * add_face(const loop &loop)
Adds a face to the mesh.
const std::vector< mesh::face * > & get_faces() const
Returns the mesh faces.
mesh::vertex * add_vertex(const float3 &position)
Adds a vertex to the mesh.
std::vector< edge * > loop
List of edges which form a face.
mesh::edge * add_edge(mesh::vertex *a, mesh::vertex *b)
Adds two half edges to the mesh.
const std::vector< mesh::vertex * > & get_vertices() const
Returns the mesh vertices.
void calculate_face_normals(float3 *normals, const mesh &mesh)
Calculates normals for each face.
void create_triangle_mesh(mesh &mesh, const std::vector< float3 > &vertices, const std::vector< std::array< std::uint_fast32_t, 3 >> &triangles)
Creates a triangle mesh from a list of vertices and indices.
box< float > calculate_bounds(const mesh &mesh)
Calculates the AABB bounds of a mesh.
mesh::vertex * poke_face(mesh &mesh, std::size_t index)
Triangulates a face by adding a new vertex in the center, then creating triangles between the edges o...
void calculate_vertex_tangents(float4 *tangents, const float2 *texcoords, const float3 *normals, const mesh &mesh)
Calculates smooth tangents per-vertex.
float3 calculate_face_normal(const mesh::face &face)
quaternion< T > normalize(const quaternion< T > &q)
Normalizes a quaternion.
constexpr vector< T, 3 > cross(const vector< T, 3 > &x, const vector< T, 3 > &y) noexcept
Calculate the cross product of two vectors.
constexpr T dot(const quaternion< T > &a, const quaternion< T > &b) noexcept
Calculates the dot product of two quaternions.
@ index
General purpose index (uint)
@ position
Vertex position (vec3)
@ tangent
Vertex tangent (vec4)
Half-edge mesh edge, containing its index and pointers to its starting vertex, parent face,...
mesh::edge * next
Pointer to the next edge in the parent face.
mesh::vertex * vertex
Pointer to the vertex at which the edge starts.
mesh::edge * symmetric
Pointer to the symmetric edge.
mesh::edge * previous
Pointer to the previous edge in the parent face.
Half-edge mesh face, containing its index and a pointer to its first edge.
mesh::edge * edge
Pointer to the first edge in this face.
Half-edge mesh vertex, containing its index, a pointer to its parent edge, and its position vector.
float3 position
Vertex position.
std::size_t index
Index of this vertex.
n-dimensional axis-aligned rectangle.
vector_type min
Minimum extent of the hyperrectangle.
vector_type max
Maximum extent of the hyperrectangle.
void extend(const vector_type &point) noexcept
Extends the hyperrectangle to include a point.
constexpr element_type & x() noexcept
Returns a reference to the first element.
constexpr element_type & y() noexcept
Returns a reference to the second element.