mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-02 16:38:41 +00:00
Fix handling of skinned meshes for nodes
- Rigidly animated models (e.g. the gltf frog node) were not working correctly, since cloning the mesh ignored the transformation matrices. Note that scaling the mesh needs to occur *after* transforming the vertices. - Visual scale did not apply to skinned models, as resetting the animation overwrote scaled vertex data with static positions & normals. For backwards compatibility, we only apply a 10x scale to static (.obj) models.
This commit is contained in:
parent
57c1ab905c
commit
612db5b2ca
6 changed files with 72 additions and 65 deletions
|
@ -13,6 +13,7 @@
|
|||
#include "client/texturesource.h"
|
||||
#include "client/tile.h"
|
||||
#include <IMeshManipulator.h>
|
||||
#include <SMesh.h>
|
||||
#include <SkinnedMesh.h>
|
||||
#endif
|
||||
#include "log.h"
|
||||
|
@ -959,23 +960,28 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
|
|||
palette = tsrc->getPalette(palette_name);
|
||||
|
||||
if (drawtype == NDT_MESH && !mesh.empty()) {
|
||||
// Read the mesh and apply scale
|
||||
mesh_ptr = client->getMesh(mesh);
|
||||
if (mesh_ptr) {
|
||||
v3f scale = v3f(BS) * visual_scale;
|
||||
scaleMesh(mesh_ptr, scale);
|
||||
// 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<scene::SMesh *>(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));
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue