1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

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 612db5b2ca.
This commit is contained in:
sfan5 2025-05-14 23:21:33 +02:00
parent e039f4c8af
commit 8a28339ed3
6 changed files with 65 additions and 72 deletions

View file

@ -1676,7 +1676,7 @@ void MapblockMeshGenerator::drawMeshNode()
if (cur_node.f->mesh_ptr) { if (cur_node.f->mesh_ptr) {
// clone and rotate mesh // clone and rotate mesh
mesh = cloneStaticMesh(cur_node.f->mesh_ptr); mesh = cloneMesh(cur_node.f->mesh_ptr);
bool modified = true; bool modified = true;
if (facedir) if (facedir)
rotateMeshBy6dFacedir(mesh, facedir); rotateMeshBy6dFacedir(mesh, facedir);

View file

@ -3,8 +3,6 @@
// Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> // Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
#include "mesh.h" #include "mesh.h"
#include "IMeshBuffer.h"
#include "SSkinMeshBuffer.h"
#include "debug.h" #include "debug.h"
#include "log.h" #include "log.h"
#include <cmath> #include <cmath>
@ -104,21 +102,6 @@ scene::IAnimatedMesh* createCubeMesh(v3f scale)
return anim_mesh; return anim_mesh;
} }
template<typename F>
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) void scaleMesh(scene::IMesh *mesh, v3f scale)
{ {
if (mesh == NULL) if (mesh == NULL)
@ -129,9 +112,14 @@ void scaleMesh(scene::IMesh *mesh, v3f scale)
u32 mc = mesh->getMeshBufferCount(); u32 mc = mesh->getMeshBufferCount();
for (u32 j = 0; j < mc; j++) { for (u32 j = 0; j < mc; j++) {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
transformMeshBuffer(buf, [scale](video::S3DVertex *vertex) { const u32 stride = getVertexPitchFromType(buf->getVertexType());
vertex->Pos *= scale; 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 // calculate total bounding box
if (j == 0) if (j == 0)
@ -152,9 +140,14 @@ void translateMesh(scene::IMesh *mesh, v3f vec)
u32 mc = mesh->getMeshBufferCount(); u32 mc = mesh->getMeshBufferCount();
for (u32 j = 0; j < mc; j++) { for (u32 j = 0; j < mc; j++) {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
transformMeshBuffer(buf, [vec](video::S3DVertex *vertex) { const u32 stride = getVertexPitchFromType(buf->getVertexType());
vertex->Pos += vec; 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 // calculate total bounding box
if (j == 0) if (j == 0)
@ -337,40 +330,44 @@ bool checkMeshNormals(scene::IMesh *mesh)
return true; return true;
} }
template<class VertexType, class SMeshBufferType>
static scene::IMeshBuffer *cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer)
{
auto *v = static_cast<VertexType *>(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<scene::SSkinMeshBuffer *>(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) scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer)
{ {
switch (mesh_buffer->getVertexType()) { switch (mesh_buffer->getVertexType()) {
case video::EVT_STANDARD: case video::EVT_STANDARD: {
return cloneMeshBuffer<video::S3DVertex, scene::SMeshBuffer>(mesh_buffer); video::S3DVertex *v = (video::S3DVertex *) mesh_buffer->getVertices();
case video::EVT_2TCOORDS: u16 *indices = mesh_buffer->getIndices();
return cloneMeshBuffer<video::S3DVertex2TCoords, scene::SMeshBufferLightMap>(mesh_buffer); scene::SMeshBuffer *cloned_buffer = new scene::SMeshBuffer();
case video::EVT_TANGENTS: cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices,
return cloneMeshBuffer<video::S3DVertexTangents, scene::SMeshBufferTangents>(mesh_buffer); 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); sanity_check(false);
return NULL; return NULL;
} }
scene::SMesh* cloneStaticMesh(scene::IMesh *src_mesh) scene::SMesh* cloneMesh(scene::IMesh *src_mesh)
{ {
scene::SMesh* dst_mesh = new scene::SMesh(); scene::SMesh* dst_mesh = new scene::SMesh();
for (u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) { for (u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) {

View file

@ -93,8 +93,10 @@ void rotateMeshYZby (scene::IMesh *mesh, f64 degrees);
*/ */
scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer); 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. Convert nodeboxes to mesh. Each tile goes into a different buffer.

View file

@ -255,7 +255,7 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename,
dim = core::dimension2d<u32>(dim.Width, frame_height); dim = core::dimension2d<u32>(dim.Width, frame_height);
} }
scene::IMesh *original = g_extrusion_mesh_cache->create(dim); scene::IMesh *original = g_extrusion_mesh_cache->create(dim);
scene::SMesh *mesh = cloneStaticMesh(original); scene::SMesh *mesh = cloneMesh(original);
original->drop(); original->drop();
//set texture //set texture
mesh->getMeshBuffer(0)->getMaterial().setTexture(0, mesh->getMeshBuffer(0)->getMaterial().setTexture(0,
@ -639,7 +639,7 @@ scene::SMesh *getExtrudedMesh(ITextureSource *tsrc,
// get mesh // get mesh
core::dimension2d<u32> dim = texture->getSize(); core::dimension2d<u32> dim = texture->getSize();
scene::IMesh *original = g_extrusion_mesh_cache->create(dim); scene::IMesh *original = g_extrusion_mesh_cache->create(dim);
scene::SMesh *mesh = cloneStaticMesh(original); scene::SMesh *mesh = cloneMesh(original);
original->drop(); original->drop();
//set texture //set texture

View file

@ -13,7 +13,6 @@
#include "client/texturesource.h" #include "client/texturesource.h"
#include "client/tile.h" #include "client/tile.h"
#include <IMeshManipulator.h> #include <IMeshManipulator.h>
#include <SMesh.h>
#include <SkinnedMesh.h> #include <SkinnedMesh.h>
#endif #endif
#include "log.h" #include "log.h"
@ -960,28 +959,23 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
palette = tsrc->getPalette(palette_name); palette = tsrc->getPalette(palette_name);
if (drawtype == NDT_MESH && !mesh.empty()) { if (drawtype == NDT_MESH && !mesh.empty()) {
// Note: By freshly reading, we get an unencumbered mesh. // Read the mesh and apply scale
if (scene::IMesh *src_mesh = client->getMesh(mesh)) { mesh_ptr = client->getMesh(mesh);
f32 mesh_scale = 1.0f; if (mesh_ptr) {
if (auto *static_mesh = dynamic_cast<scene::SMesh *>(src_mesh)) { v3f scale = v3f(BS) * visual_scale;
mesh_ptr = static_mesh; scaleMesh(mesh_ptr, scale);
// 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));
recalculateBoundingBox(mesh_ptr); recalculateBoundingBox(mesh_ptr);
if (!checkMeshNormals(mesh_ptr)) { if (!checkMeshNormals(mesh_ptr)) {
// TODO this should be done consistently when the mesh is loaded
infostream << "ContentFeatures: recalculating normals for mesh " infostream << "ContentFeatures: recalculating normals for mesh "
<< mesh << std::endl; << mesh << std::endl;
meshmanip->recalculateNormals(mesh_ptr, true, false); 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;
} }
} }
} }

View file

@ -342,7 +342,7 @@ struct ContentFeatures
enum NodeDrawType drawtype; enum NodeDrawType drawtype;
std::string mesh; std::string mesh;
#if CHECK_CLIENT_BUILD() #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; video::SColor minimap_color;
#endif #endif
float visual_scale; // Misc. scale parameter float visual_scale; // Misc. scale parameter