From 21437090b80275f7967b7f5927ae0ead7f49d2e1 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 7 Dec 2024 12:59:40 +0100 Subject: [PATCH] Don't recalculate meshnode normals unnecessarily --- src/client/content_mapblock.cpp | 28 +++++++++++++++------------- src/client/mesh.cpp | 4 ++-- src/client/mesh.h | 2 +- src/nodedef.cpp | 7 +++++-- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/client/content_mapblock.cpp b/src/client/content_mapblock.cpp index 2d294953a..25d303156 100644 --- a/src/client/content_mapblock.cpp +++ b/src/client/content_mapblock.cpp @@ -1644,7 +1644,6 @@ void MapblockMeshGenerator::drawMeshNode() { u8 facedir = 0; scene::IMesh* mesh; - bool private_mesh; // as a grab/drop pair is not thread-safe int degrotate = 0; if (cur_node.f->param_type_2 == CPT2_FACEDIR || @@ -1664,32 +1663,37 @@ void MapblockMeshGenerator::drawMeshNode() if (cur_node.f->mesh_ptr) { // clone and rotate mesh - private_mesh = true; mesh = cloneMesh(cur_node.f->mesh_ptr); + bool modified = true; if (facedir) rotateMeshBy6dFacedir(mesh, facedir); else if (degrotate) rotateMeshXZby(mesh, 1.5f * degrotate); - recalculateBoundingBox(mesh); - meshmanip->recalculateNormals(mesh, true, false); + else + modified = false; + if (modified) { + recalculateBoundingBox(mesh); + // FIXME: we should rotate the normals too, instead of recalculating + meshmanip->recalculateNormals(mesh, true, false); + } } else { warningstream << "drawMeshNode(): missing mesh" << std::endl; return; } - int mesh_buffer_count = mesh->getMeshBufferCount(); - for (int j = 0; j < mesh_buffer_count; j++) { + for (u32 j = 0; j < mesh->getMeshBufferCount(); j++) { // Only up to 6 tiles are supported - const auto tile = mesh->getTextureSlot(j); + const u32 tile = mesh->getTextureSlot(j); useTile(MYMIN(tile, 5)); + scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices(); - int vertex_count = buf->getVertexCount(); + u32 vertex_count = buf->getVertexCount(); if (data->m_smooth_lighting) { // Mesh is always private here. So the lighting is applied to each // vertex right here. - for (int k = 0; k < vertex_count; k++) { + for (u32 k = 0; k < vertex_count; k++) { video::S3DVertex &vertex = vertices[k]; vertex.Color = blendLightColor(vertex.Pos, vertex.Normal); vertex.Pos += cur_node.origin; @@ -1697,15 +1701,13 @@ void MapblockMeshGenerator::drawMeshNode() collector->append(cur_node.tile, vertices, vertex_count, buf->getIndices(), buf->getIndexCount()); } else { - // Don't modify the mesh, it may not be private here. - // Instead, let the collector process colors, etc. + // Let the collector process colors, etc. collector->append(cur_node.tile, vertices, vertex_count, buf->getIndices(), buf->getIndexCount(), cur_node.origin, cur_node.color, cur_node.f->light_source); } } - if (private_mesh) - mesh->drop(); + mesh->drop(); } // also called when the drawtype is known but should have been pre-converted diff --git a/src/client/mesh.cpp b/src/client/mesh.cpp index 3f947ae50..012b9a45a 100644 --- a/src/client/mesh.cpp +++ b/src/client/mesh.cpp @@ -272,9 +272,9 @@ void rotateMeshYZby(scene::IMesh *mesh, f64 degrees) rotateMesh<&v3f::Y, &v3f::Z>(mesh, degrees); } -void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir) +void rotateMeshBy6dFacedir(scene::IMesh *mesh, u8 facedir) { - int axisdir = facedir >> 2; + u8 axisdir = facedir >> 2; facedir &= 0x03; switch (facedir) { case 1: rotateMeshXZby(mesh, -90); break; diff --git a/src/client/mesh.h b/src/client/mesh.h index 5fd0ebb0e..3345e24f7 100644 --- a/src/client/mesh.h +++ b/src/client/mesh.h @@ -68,7 +68,7 @@ void setMeshColorByNormal(scene::IMesh *mesh, const v3f &normal, Rotate the mesh by 6d facedir value. Method only for meshnodes, not suitable for entities. */ -void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir); +void rotateMeshBy6dFacedir(scene::IMesh *mesh, u8 facedir); /* Rotate the mesh around the axis and given angle in degrees. diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 2301b179f..81348cf23 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -943,14 +943,17 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc palette = tsrc->getPalette(palette_name); if (drawtype == NDT_MESH && !mesh.empty()) { - // Meshnode drawtype // Read the mesh and apply scale mesh_ptr = client->getMesh(mesh); if (mesh_ptr) { v3f scale = v3f(BS) * visual_scale; scaleMesh(mesh_ptr, scale); recalculateBoundingBox(mesh_ptr); - meshmanip->recalculateNormals(mesh_ptr, true, false); + if (!checkMeshNormals(mesh_ptr)) { + infostream << "ContentFeatures: recalculating normals for mesh " + << mesh << std::endl; + meshmanip->recalculateNormals(mesh_ptr, true, false); + } } } }