From 8a28339ed33e82f75623a8b014aec7ba45837492 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Wed, 14 May 2025 23:21:33 +0200 Subject: [PATCH] Revert "Fix handling of skinned meshes for nodes" It literally breaks torches and doors in MTG. Regardless of whether this is an oversight or not let's not pull this in so close to release. This reverts commit 612db5b2ca8edd989af23dcc9347655b0222d2b4. --- src/client/content_mapblock.cpp | 2 +- src/client/mesh.cpp | 95 ++++++++++++++++----------------- src/client/mesh.h | 6 ++- src/client/wieldmesh.cpp | 4 +- src/nodedef.cpp | 28 ++++------ src/nodedef.h | 2 +- 6 files changed, 65 insertions(+), 72 deletions(-) diff --git a/src/client/content_mapblock.cpp b/src/client/content_mapblock.cpp index 3edba95e3..f5b528287 100644 --- a/src/client/content_mapblock.cpp +++ b/src/client/content_mapblock.cpp @@ -1676,7 +1676,7 @@ void MapblockMeshGenerator::drawMeshNode() if (cur_node.f->mesh_ptr) { // clone and rotate mesh - mesh = cloneStaticMesh(cur_node.f->mesh_ptr); + mesh = cloneMesh(cur_node.f->mesh_ptr); bool modified = true; if (facedir) rotateMeshBy6dFacedir(mesh, facedir); diff --git a/src/client/mesh.cpp b/src/client/mesh.cpp index 808dcdd18..a2c0ae327 100644 --- a/src/client/mesh.cpp +++ b/src/client/mesh.cpp @@ -3,8 +3,6 @@ // Copyright (C) 2010-2013 celeron55, Perttu Ahola #include "mesh.h" -#include "IMeshBuffer.h" -#include "SSkinMeshBuffer.h" #include "debug.h" #include "log.h" #include @@ -104,21 +102,6 @@ scene::IAnimatedMesh* createCubeMesh(v3f scale) return anim_mesh; } -template -inline static void transformMeshBuffer(scene::IMeshBuffer *buf, - const F &transform_vertex) -{ - const u32 stride = getVertexPitchFromType(buf->getVertexType()); - u32 vertex_count = buf->getVertexCount(); - u8 *vertices = (u8 *)buf->getVertices(); - for (u32 i = 0; i < vertex_count; i++) { - auto *vertex = (video::S3DVertex *)(vertices + i * stride); - transform_vertex(vertex); - } - buf->setDirty(scene::EBT_VERTEX); - buf->recalculateBoundingBox(); -} - void scaleMesh(scene::IMesh *mesh, v3f scale) { if (mesh == NULL) @@ -129,9 +112,14 @@ void scaleMesh(scene::IMesh *mesh, v3f scale) u32 mc = mesh->getMeshBufferCount(); for (u32 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); - transformMeshBuffer(buf, [scale](video::S3DVertex *vertex) { - vertex->Pos *= scale; - }); + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *)buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) + ((video::S3DVertex *)(vertices + i * stride))->Pos *= scale; + + buf->setDirty(scene::EBT_VERTEX); + buf->recalculateBoundingBox(); // calculate total bounding box if (j == 0) @@ -152,9 +140,14 @@ void translateMesh(scene::IMesh *mesh, v3f vec) u32 mc = mesh->getMeshBufferCount(); for (u32 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); - transformMeshBuffer(buf, [vec](video::S3DVertex *vertex) { - vertex->Pos += vec; - }); + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *)buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) + ((video::S3DVertex *)(vertices + i * stride))->Pos += vec; + + buf->setDirty(scene::EBT_VERTEX); + buf->recalculateBoundingBox(); // calculate total bounding box if (j == 0) @@ -337,40 +330,44 @@ bool checkMeshNormals(scene::IMesh *mesh) return true; } -template -static scene::IMeshBuffer *cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer) -{ - auto *v = static_cast(mesh_buffer->getVertices()); - u16 *indices = mesh_buffer->getIndices(); - auto *cloned_buffer = new SMeshBufferType(); - cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices, - mesh_buffer->getIndexCount()); - // Rigidly animated meshes may have transformation matrices that need to be applied - if (auto *sbuf = dynamic_cast(mesh_buffer)) { - transformMeshBuffer(cloned_buffer, [sbuf](video::S3DVertex *vertex) { - sbuf->Transformation.transformVect(vertex->Pos); - vertex->Normal = sbuf->Transformation.rotateAndScaleVect(vertex->Normal); - vertex->Normal.normalize(); - }); - } - return cloned_buffer; -} - scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer) { switch (mesh_buffer->getVertexType()) { - case video::EVT_STANDARD: - return cloneMeshBuffer(mesh_buffer); - case video::EVT_2TCOORDS: - return cloneMeshBuffer(mesh_buffer); - case video::EVT_TANGENTS: - return cloneMeshBuffer(mesh_buffer); + case video::EVT_STANDARD: { + video::S3DVertex *v = (video::S3DVertex *) mesh_buffer->getVertices(); + u16 *indices = mesh_buffer->getIndices(); + scene::SMeshBuffer *cloned_buffer = new scene::SMeshBuffer(); + cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices, + mesh_buffer->getIndexCount()); + return cloned_buffer; } + case video::EVT_2TCOORDS: { + video::S3DVertex2TCoords *v = + (video::S3DVertex2TCoords *) mesh_buffer->getVertices(); + u16 *indices = mesh_buffer->getIndices(); + scene::SMeshBufferLightMap *cloned_buffer = + new scene::SMeshBufferLightMap(); + cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices, + mesh_buffer->getIndexCount()); + return cloned_buffer; + } + case video::EVT_TANGENTS: { + video::S3DVertexTangents *v = + (video::S3DVertexTangents *) mesh_buffer->getVertices(); + u16 *indices = mesh_buffer->getIndices(); + scene::SMeshBufferTangents *cloned_buffer = + new scene::SMeshBufferTangents(); + cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices, + mesh_buffer->getIndexCount()); + return cloned_buffer; + } + } + // This should not happen. sanity_check(false); return NULL; } -scene::SMesh* cloneStaticMesh(scene::IMesh *src_mesh) +scene::SMesh* cloneMesh(scene::IMesh *src_mesh) { scene::SMesh* dst_mesh = new scene::SMesh(); for (u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) { diff --git a/src/client/mesh.h b/src/client/mesh.h index 53c54fc51..d8eb6080e 100644 --- a/src/client/mesh.h +++ b/src/client/mesh.h @@ -93,8 +93,10 @@ void rotateMeshYZby (scene::IMesh *mesh, f64 degrees); */ scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer); -/// Clone a mesh. For an animated mesh, this will clone the static pose. -scene::SMesh* cloneStaticMesh(scene::IMesh *src_mesh); +/* + Clone the mesh. +*/ +scene::SMesh* cloneMesh(scene::IMesh *src_mesh); /* Convert nodeboxes to mesh. Each tile goes into a different buffer. diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index bdd24a727..baa72f1d9 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -255,7 +255,7 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename, dim = core::dimension2d(dim.Width, frame_height); } scene::IMesh *original = g_extrusion_mesh_cache->create(dim); - scene::SMesh *mesh = cloneStaticMesh(original); + scene::SMesh *mesh = cloneMesh(original); original->drop(); //set texture mesh->getMeshBuffer(0)->getMaterial().setTexture(0, @@ -639,7 +639,7 @@ scene::SMesh *getExtrudedMesh(ITextureSource *tsrc, // get mesh core::dimension2d dim = texture->getSize(); scene::IMesh *original = g_extrusion_mesh_cache->create(dim); - scene::SMesh *mesh = cloneStaticMesh(original); + scene::SMesh *mesh = cloneMesh(original); original->drop(); //set texture diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 2339423e9..d4dc16a61 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -13,7 +13,6 @@ #include "client/texturesource.h" #include "client/tile.h" #include -#include #include #endif #include "log.h" @@ -960,28 +959,23 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc palette = tsrc->getPalette(palette_name); if (drawtype == NDT_MESH && !mesh.empty()) { - // Note: By freshly reading, we get an unencumbered mesh. - if (scene::IMesh *src_mesh = client->getMesh(mesh)) { - f32 mesh_scale = 1.0f; - if (auto *static_mesh = dynamic_cast(src_mesh)) { - mesh_ptr = static_mesh; - // Compatibility: Only apply BS scaling to static meshes (.obj). See #15811. - mesh_scale = 10.0f; - } else { - // We only want to consider static meshes from here on. - mesh_ptr = cloneStaticMesh(src_mesh); - src_mesh->drop(); - } - scaleMesh(mesh_ptr, v3f(mesh_scale * visual_scale)); + // 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); if (!checkMeshNormals(mesh_ptr)) { - // TODO this should be done consistently when the mesh is loaded infostream << "ContentFeatures: recalculating normals for mesh " << mesh << std::endl; meshmanip->recalculateNormals(mesh_ptr, true, false); + } else { + // Animation is not supported, but we need to reset it to + // default state if it is animated. + // Note: recalculateNormals() also does this hence the else-block + if (mesh_ptr->getMeshType() == scene::EAMT_SKINNED) + ((scene::SkinnedMesh*) mesh_ptr)->resetAnimation(); } - } else { - mesh_ptr = nullptr; } } } diff --git a/src/nodedef.h b/src/nodedef.h index 967e3fcd4..71a61896b 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -342,7 +342,7 @@ struct ContentFeatures enum NodeDrawType drawtype; std::string mesh; #if CHECK_CLIENT_BUILD() - scene::SMesh *mesh_ptr; // mesh in case of mesh node + scene::IMesh *mesh_ptr; // mesh in case of mesh node video::SColor minimap_color; #endif float visual_scale; // Misc. scale parameter