mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-27 17:28:41 +00:00
Refine node mesh scaling logic
We now do scale static meshes, as the bug that caused meshes not to be scaled was limited to skeletally animated meshes, hence we ought not to reproduce it for skinned meshes that do not take advantage of skeletal animations (e.g. current MTG doors). However, gltf models (e.g. Wuzzy's eyeballs) up until recently were always affected due to technical reasons (using skeletal animation for rigid animation). Thus, to preserve behavior, we: 1. Do not apply 10x scale to glTF models. 2. Apply 10x scale to obj models. 3. Apply 10x scale to static x or b3d models, but not to animated ones.
This commit is contained in:
parent
511c637c2a
commit
740223d30c
4 changed files with 33 additions and 12 deletions
|
@ -10172,9 +10172,12 @@ Used by `core.register_node`.
|
|||
mesh = "",
|
||||
-- File name of mesh when using "mesh" drawtype
|
||||
-- The center of the node is the model origin.
|
||||
-- For legacy reasons, models in OBJ format use a scale of 1 node = 1 unit;
|
||||
-- all other model file formats use a scale of 1 node = 10 units,
|
||||
-- consistent with the scale used for entities.
|
||||
-- For legacy reasons, this uses a different scale depending on the mesh:
|
||||
-- 1. For glTF models: 10 units = 1 node (consistent with the scale for entities).
|
||||
-- 2. For obj models: 1 unit = 1 node.
|
||||
-- 3. For b3d and x models: 1 unit = 1 node if static, otherwise 10 units = 1 node.
|
||||
-- Using static glTF or obj models is recommended.
|
||||
-- You can use the `visual_scale` multiplier to achieve the expected scale.
|
||||
|
||||
selection_box = {
|
||||
-- see [Node boxes] for possibilities
|
||||
|
|
|
@ -339,6 +339,10 @@ public:
|
|||
return AllJoints;
|
||||
}
|
||||
|
||||
//! Whether the mesh originated from a glTF file.
|
||||
//! This is important for legacy reasons.
|
||||
bool isGltf() const { return IsGltf; }
|
||||
|
||||
protected:
|
||||
void checkForAnimation();
|
||||
|
||||
|
@ -382,12 +386,14 @@ protected:
|
|||
bool PreparedForSkinning;
|
||||
bool AnimateNormals;
|
||||
bool HardwareSkinning;
|
||||
|
||||
bool IsGltf = false;
|
||||
};
|
||||
|
||||
// Interface for mesh loaders
|
||||
class SkinnedMeshBuilder : public SkinnedMesh {
|
||||
public:
|
||||
SkinnedMeshBuilder() : SkinnedMesh() {}
|
||||
SkinnedMeshBuilder(bool is_gltf = false) : SkinnedMesh() { IsGltf = is_gltf; }
|
||||
|
||||
//! loaders should call this after populating the mesh
|
||||
// returns *this, so do not try to drop the mesh builder instance
|
||||
|
|
|
@ -347,7 +347,7 @@ IAnimatedMesh* SelfType::createMesh(io::IReadFile* file)
|
|||
const char *filename = file->getFileName().c_str();
|
||||
try {
|
||||
tiniergltf::GlTF model = parseGLTF(file);
|
||||
irr_ptr<SkinnedMeshBuilder> mesh(new SkinnedMeshBuilder());
|
||||
irr_ptr<SkinnedMeshBuilder> mesh(new SkinnedMeshBuilder(true));
|
||||
MeshExtractor extractor(std::move(model), mesh.get());
|
||||
try {
|
||||
extractor.load();
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "nodedef.h"
|
||||
|
||||
#include "SAnimatedMesh.h"
|
||||
#include "itemdef.h"
|
||||
#if CHECK_CLIENT_BUILD()
|
||||
#include "client/mesh.h"
|
||||
|
@ -962,17 +963,28 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
|
|||
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<scene::SMesh *>(src_mesh)) {
|
||||
mesh_ptr = static_mesh;
|
||||
// Compatibility: Only apply BS scaling to static meshes (.obj). See #15811.
|
||||
mesh_scale = 10.0f;
|
||||
} else {
|
||||
bool apply_bs = false;
|
||||
// Unpack the possible matrjoshka of frame-animated meshes
|
||||
while (auto *src_meshes = dynamic_cast<scene::SAnimatedMesh *>(src_mesh)) {
|
||||
src_mesh = src_meshes->getMesh(0);
|
||||
src_mesh->grab();
|
||||
src_meshes->drop();
|
||||
}
|
||||
if (auto *skinned_mesh = dynamic_cast<scene::SkinnedMesh *>(src_mesh)) {
|
||||
// Compatibility: Animated meshes, as well as static gltf meshes, are not scaled by BS.
|
||||
// See https://github.com/luanti-org/luanti/pull/16112#issuecomment-2881860329
|
||||
apply_bs = skinned_mesh->isStatic() && !skinned_mesh->isGltf();
|
||||
// We only want to consider static meshes from here on.
|
||||
mesh_ptr = cloneStaticMesh(src_mesh);
|
||||
src_mesh->drop();
|
||||
} else {
|
||||
auto *static_mesh = dynamic_cast<scene::SMesh *>(src_mesh);
|
||||
assert(static_mesh);
|
||||
mesh_ptr = static_mesh;
|
||||
// Compatibility: Apply BS scaling to static meshes (.obj). See #15811.
|
||||
apply_bs = true;
|
||||
}
|
||||
scaleMesh(mesh_ptr, v3f(mesh_scale * visual_scale));
|
||||
scaleMesh(mesh_ptr, v3f((apply_bs ? BS : 1.0f) * visual_scale));
|
||||
recalculateBoundingBox(mesh_ptr);
|
||||
if (!checkMeshNormals(mesh_ptr)) {
|
||||
// TODO this should be done consistently when the mesh is loaded
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue