MCPcopy Create free account
hub / github.com/PlotJuggler/PlotJuggler / appendNode

Function appendNode

pj_scene3D/widgets/src/mesh_loader.cpp:217–300  ·  view source on GitHub ↗

Walk the node graph, accumulating each mesh's transformed vertices/indices. `node_transform` is the cumulative parent transform (column-major glm).

Source from the content-addressed store, hash-verified

215// Walk the node graph, accumulating each mesh's transformed vertices/indices.
216// `node_transform` is the cumulative parent transform (column-major glm).
217void appendNode(
218 const aiScene* scene, const aiNode* node, const glm::mat4& parent_transform, const glm::mat3& extra_rotation,
219 const std::vector<std::shared_ptr<const Material>>& materials, MeshData& out) {
220 // assimp row-major aiMatrix4x4 -> glm column-major.
221 const aiMatrix4x4& m = node->mTransformation;
222 glm::mat4 local(
223 m.a1, m.b1, m.c1, m.d1, // col 0
224 m.a2, m.b2, m.c2, m.d2, // col 1
225 m.a3, m.b3, m.c3, m.d3, // col 2
226 m.a4, m.b4, m.c4, m.d4); // col 3
227 const glm::mat4 node_transform = parent_transform * local;
228 const glm::mat3 normal_matrix = glm::mat3(glm::transpose(glm::inverse(node_transform)));
229 const glm::mat3 linear = glm::mat3(node_transform);
230
231 for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
232 const aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
233 static const std::shared_ptr<const Material> k_fallback = std::make_shared<const Material>();
234 const std::shared_ptr<const Material>& material =
235 mesh->mMaterialIndex < materials.size() ? materials[mesh->mMaterialIndex] : k_fallback;
236 const auto base_index = static_cast<std::uint32_t>(out.vertices.size());
237
238 out.vertices.reserve(out.vertices.size() + mesh->mNumVertices);
239 for (unsigned int v = 0; v < mesh->mNumVertices; ++v) {
240 Vertex vert;
241 const aiVector3D& p = mesh->mVertices[v];
242 glm::vec3 pos = glm::vec3(node_transform * glm::vec4(p.x, p.y, p.z, 1.0f));
243 glm::vec3 nrm(0.0f, 0.0f, 1.0f);
244 if (mesh->HasNormals()) {
245 const aiVector3D& n = mesh->mNormals[v];
246 nrm = glm::normalize(normal_matrix * glm::vec3(n.x, n.y, n.z));
247 }
248 vert.position = extra_rotation * pos;
249 vert.normal = glm::normalize(extra_rotation * nrm);
250 // Vertex color carries ONLY genuine per-vertex colors (glTF COLOR_0); the
251 // material base color lives in SubMesh::material and is applied by the
252 // shader. A white default leaves untextured/non-vertex-colored meshes to be
253 // driven purely by the material factor (no double-application).
254 vert.color =
255 mesh->HasVertexColors(0)
256 ? glm::vec4(mesh->mColors[0][v].r, mesh->mColors[0][v].g, mesh->mColors[0][v].b, mesh->mColors[0][v].a)
257 : glm::vec4(1.0f);
258 if (mesh->HasTextureCoords(0)) {
259 const aiVector3D& uv = mesh->mTextureCoords[0][v];
260 vert.uv = glm::vec2(uv.x, uv.y);
261 }
262 // Tangent basis for normal mapping (aiProcess_CalcTangentSpace). Transform
263 // into world like the geometry, re-orthogonalize against the final normal
264 // (Gram-Schmidt), and store the bitangent handedness in .w.
265 if (mesh->HasTangentsAndBitangents()) {
266 const aiVector3D& t = mesh->mTangents[v];
267 const aiVector3D& b = mesh->mBitangents[v];
268 glm::vec3 tan = extra_rotation * (linear * glm::vec3(t.x, t.y, t.z));
269 glm::vec3 bit = extra_rotation * (linear * glm::vec3(b.x, b.y, b.z));
270 tan = tan - vert.normal * glm::dot(vert.normal, tan);
271 if (glm::dot(tan, tan) > 1e-12f) {
272 tan = glm::normalize(tan);
273 const float sign = glm::dot(glm::cross(vert.normal, tan), bit) < 0.0f ? -1.0f : 1.0f;
274 vert.tangent = glm::vec4(tan, sign);

Callers 1

buildMeshDataFunction · 0.85

Calls 2

reserveMethod · 0.80
sizeMethod · 0.45

Tested by

no test coverage detected