86 size_t total_vertices_count = 0;
87 size_t total_indices_count = 0;
89 result.primitives.reserve(primitives.size());
91 for (
const auto &it : primitives)
93 result.primitives.emplace_back(total_indices_count, it.indices.size());
95 total_vertices_count += it.vertices.size();
96 total_indices_count += it.indices.size();
100 result.vertices.reserve(total_vertices_count);
101 result.indices.reserve(total_indices_count);
103 size_t vertices_count = 0;
104 for (
const auto &it : primitives)
106 const auto& vertices = it.vertices;
107 const auto& indices = it.indices;
110 result.vertices.insert(result.vertices.end(), vertices.cbegin(), vertices.cend());
113 std::ranges::transform(
115 std::back_inserter(result.indices),
116 [vertices_count](
const IndexType& i) { return vertices_count + i; }
120 vertices_count += vertices.size();
131 assert(primitive < primitives.size());
133 const auto& primitive_data = primitives.at(primitive);
135 std::span<index_type> primitive_indices = {indices.begin() + primitive_data.offset, primitive_data.size};
138 bool is_first_vertex =
true;
140 for (
auto &it : primitive_indices)
142 const vertex_type& vertex = vertices.at(it);
146 result = {vertex.position, vertex.position};
147 is_first_vertex =
false;
165 assert(primitive < primitives.size());
167 const auto& primitive_data = primitives.at(primitive);
169 std::span<index_type> primitive_indices = {indices.begin() + primitive_data.offset, primitive_data.size};
172 bool is_first_vertex =
true;
174 for (
auto &it : primitive_indices)
176 const vertex_type& vertex = vertices.at(it);
178 if (predicate(vertex))
182 result = {vertex.position, vertex.position};
183 is_first_vertex =
false;
276 if (triangles.size() == 0)
280 glm::vec3 e1, e2, no;
282 std::vector<size_t> count_normals;
283 count_normals.resize(vertices.size());
285 for (
size_t i=0; i<vertices.size(); i++)
287 vertices[i].normal = glm::vec3(0.0);
290 for (
size_t i=0; i<triangles.size(); i++)
292 const glm::uvec3& face = triangles[i];
294 VertexType& va = vertices[face[0]];
295 VertexType& vb = vertices[face[1]];
296 VertexType& vc = vertices[face[2]];
298 e1 = vb.position - va.position;
299 e2 = vc.position - va.position;
301 no = glm::cross(e1, e2);
307 count_normals[face[0]]++;
308 count_normals[face[1]]++;
309 count_normals[face[2]]++;
312 for (
size_t i=0; i<vertices.size(); i++)
314 if (count_normals[i] > 0)
316 vertices[i].normal = glm::normalize(vertices[i].normal / (
float)count_normals[i]);
342 SMikkTSpaceInterface callbacks
344 .m_getNumFaces = [] (
const SMikkTSpaceContext * pContext) ->
int
348 const std::vector<glm::uvec3>& triangles = data->
triangles;
350 return triangles.size();
353 .m_getNumVerticesOfFace = [] (
const SMikkTSpaceContext*,
const int32_t) -> int32_t
359 .m_getPosition = [] (
const SMikkTSpaceContext * pContext,
float fvPosOut[],
const int32_t iFace,
const int32_t iVert)
364 const std::vector<glm::uvec3>& triangles = data->
triangles;
366 const std::vector<VertexType>& vertices = mesh->vertices;
368 const VertexType& vertex = vertices[triangles[iFace][iVert]];
369 const glm::vec3& position = vertex.position;
371 fvPosOut[0] = position.x;
372 fvPosOut[1] = position.y;
373 fvPosOut[2] = position.z;
376 .m_getNormal = [] (
const SMikkTSpaceContext * pContext,
float fvNormOut[],
const int32_t iFace,
const int32_t iVert)
381 const std::vector<glm::uvec3>& triangles = data->
triangles;
383 const std::vector<VertexType>& vertices = mesh->vertices;
385 const VertexType& vertex = vertices[triangles[iFace][iVert]];
386 const glm::vec3& normal = vertex.normal;
388 fvNormOut[0] = normal.x;
389 fvNormOut[1] = normal.y;
390 fvNormOut[2] = normal.z;
393 .m_getTexCoord = [] (
const SMikkTSpaceContext * pContext,
float fvTexcOut[],
const int32_t iFace,
const int32_t iVert)
398 const std::vector<glm::uvec3>& triangles = data->
triangles;
400 const std::vector<VertexType>& vertices = mesh->vertices;
402 const VertexType& vertex = vertices[triangles[iFace][iVert]];
403 const glm::vec2& tex_coords = vertex.tex_coords_0;
405 fvTexcOut[0] = tex_coords.x;
406 fvTexcOut[1] = tex_coords.y;
409 .m_setTSpaceBasic = [] (
const SMikkTSpaceContext * pContext,
const float fvTangent[],
const float fSign,
const int32_t iFace,
const int32_t iVert)
414 const std::vector<glm::uvec3>& triangles = data->
triangles;
416 std::vector<VertexType>& vertices = mesh->vertices;
418 VertexType& vertex = vertices[triangles[iFace][iVert]];
420 vertex.tangent = glm::vec3(fvTangent[0], fvTangent[1], fvTangent[2]);
421 vertex.bitangent = fSign * glm::cross(vertex.tangent, vertex.normal);
424 .m_setTSpace = [] (
const SMikkTSpaceContext *,
const float[],
const float[],
const float ,
const float,
const tbool,
const int32_t,
const int32_t)
436 SMikkTSpaceContext context = {
437 .m_pInterface = &callbacks,
438 .m_pUserData = &user_data
441 genTangSpaceDefault(&context);