godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.5k stars 20.26k forks source link

EditorSceneImporterMesh does not support default blend shape weights. #49005

Open lyuma opened 3 years ago

lyuma commented 3 years ago

Godot version: 4.0.dev 45d3b965bb55f3111478306070034ed18e8fa5e4

OS/device including version: Windows 10.0.19041.985

Issue description: glTF 2.0 permits meshes to assign "weights" to set blend shapes at a default value.

However, EditorSceneImporterMesh does not have an API to assign weights. This problem affects at least glTF. It could also affect COLLADA or FBX if those store the default blend weights.

The code in GLTFDocument::_generate_mesh_instance does the following to assign the blend shape weights onto the mesh:

    Ref<EditorSceneImporterMesh> import_mesh = mesh->get_mesh();
    if (import_mesh.is_null()) {
        return mi;
    }
    mi->set_mesh(import_mesh);
    for (int i = 0; i < mesh->get_blend_weights().size(); i++) {
        mi->set("blend_shapes/" + mesh->get_mesh()->get_blend_shape_name(i), mesh->get_blend_weights()[i]);
    }

I have verified with a debugger that this code all works. However, mi is an EditorSceneImporterMesh, which does not define properties for blend_shapes/... so that set() call is ignored.

The sample glTF model uses the following JSON:

  "meshes": [
    {
      "weights": [
        0.5
      ],
      "name": "mesh",
      "primitives": [
        {
          "attributes": {
            "NORMAL": 1,
            "POSITION": 2,
            "TEXCOORD_0": 3
          },
          "indices": 0,
          "material": 0,
          "targets": [
            {
              "POSITION": 4
            }
          ],
          "mode": 4
        },
        {
          "attributes": {
            "POSITION": 7,
            "NORMAL": 6,
            "TEXCOORD_0": 8
          },
          "indices": 5,
          "material": 1,
          "targets": [
            {
              "POSITION": 9
            }
          ],
          "mode": 4
        }
      ]
    }
  ],

Steps to reproduce:

  1. Open the attached process.
  2. Check the MorphPrimitivesTest model.
  3. Compare it against the screenshot. It is supposed to be bumpy (weight = 0.5).
  4. However, in master branch, the plane will be completely flat (weight = 0.0)

Minimal reproduction project: gltf_khronos_morph_primitives.zip

KoBeWi commented 2 years ago

Still valid in 2ec379e Why is this labelled as regression though?

lyuma commented 2 years ago

It's a regression because the initial blend weights set by imported glTF files, such as the 0.5 in the example, are being ignored, while it used to work with the old ArrayMesh api.

Without fixing ImporterMeshInstance3D, there isn't an obvious way to store the default blend weights during the import process, up until the final ArrayMesh is generated. ImporterMeshInstance3D is the place that makes sense.