[Bf-extensions-cvs] [fc320ea2] master: glTF exporter: fix shapekeys animation export

Julien Duroure noreply at git.blender.org
Fri Aug 23 07:30:43 CEST 2019


Commit: fc320ea236c7f264a1438e7af338581a37bb74b1
Author: Julien Duroure
Date:   Fri Aug 23 07:29:41 2019 +0200
Branches: master
https://developer.blender.org/rBAfc320ea236c7f264a1438e7af338581a37bb74b1

glTF exporter: fix shapekeys animation export

Animation channels must be sorted in exactly same order than shapekeys

===================================================================

M	io_scene_gltf2/__init__.py
M	io_scene_gltf2/blender/exp/gltf2_blender_extract.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py

===================================================================

diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index b38eaf82..a020e0eb 100755
--- a/io_scene_gltf2/__init__.py
+++ b/io_scene_gltf2/__init__.py
@@ -15,7 +15,7 @@
 bl_info = {
     'name': 'glTF 2.0 format',
     'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
-    "version": (0, 9, 48),
+    "version": (0, 9, 49),
     'blender': (2, 80, 0),
     'location': 'File > Import-Export',
     'description': 'Import-Export as glTF 2.0',
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
index 7adda5a4..a4705e91 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
@@ -499,14 +499,14 @@ def extract_primitives(glTF, blender_mesh, blender_vertex_groups, modifiers, exp
     blender_shape_keys = []
 
     if blender_mesh.shape_keys is not None:
-        morph_max = len(blender_mesh.shape_keys.key_blocks) - 1
-
         for blender_shape_key in blender_mesh.shape_keys.key_blocks:
             if blender_shape_key != blender_shape_key.relative_key:
-                blender_shape_keys.append(ShapeKey(
-                    blender_shape_key,
-                    blender_shape_key.normals_vertex_get(),  # calculate vertex normals for this shape key
-                    blender_shape_key.normals_polygon_get()))  # calculate polygon normals for this shape key
+                if blender_shape_key.mute is False:
+                    morph_max += 1
+                    blender_shape_keys.append(ShapeKey(
+                        blender_shape_key,
+                        blender_shape_key.normals_vertex_get(),  # calculate vertex normals for this shape key
+                        blender_shape_key.normals_polygon_get()))  # calculate polygon normals for this shape key
 
     #
     # Convert polygon to primitive indices and eliminate invalid ones. Assign to material.
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
index 412f275b..45a75717 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
@@ -64,12 +64,35 @@ def gather_animation_channels(blender_action: bpy.types.Action,
                 channels.append(channel)
     else:
         for channel_group in __get_channel_groups(blender_action, blender_object, export_settings):
-            channel = __gather_animation_channel(channel_group, blender_object, export_settings, None, None, None, None, blender_action.name)
+            channel_group_sorted = __get_channel_group_sorted(channel_group, blender_object)
+            channel = __gather_animation_channel(channel_group_sorted, blender_object, export_settings, None, None, None, None, blender_action.name)
             if channel is not None:
                 channels.append(channel)
 
     return channels
 
+def __get_channel_group_sorted(channels: typing.Tuple[bpy.types.FCurve], blender_object: bpy.types.Object):
+    # if this is shapekey animation, we need to sort in same order than shapekeys
+    # else, no need to sort
+    if blender_object.type == "MESH":
+        first_channel = channels[0]
+        object_path = get_target_object_path(first_channel.data_path)
+        if object_path:
+            # This is shapekeys, we need to sort channels
+            shapekeys_idx = {}
+            cpt_sk = 0
+            for sk in blender_object.data.shape_keys.key_blocks:
+                if sk == sk.relative_key:
+                    continue
+                if sk.mute is True:
+                    continue
+                shapekeys_idx[sk.name] = cpt_sk
+                cpt_sk += 1
+
+            return tuple(sorted(channels, key=lambda x: shapekeys_idx[blender_object.data.shape_keys.path_resolve(get_target_object_path(x.data_path)).name]))
+
+    # if not shapekeys, stay in same order, because order doesn't matter
+    return channels
 
 def __gather_animation_channel(channels: typing.Tuple[bpy.types.FCurve],
                                blender_object: bpy.types.Object,
@@ -164,12 +187,17 @@ def __get_channel_groups(blender_action: bpy.types.Action, blender_object: bpy.t
         else:
             try:
                 target = gltf2_blender_get.get_object_from_datapath(blender_object, object_path)
+                if blender_object.type == "MESH":
+                    shape_key = blender_object.data.shape_keys.path_resolve(object_path)
+                    if shape_key.mute is True:
+                        continue
             except ValueError as e:
                 # if the object is a mesh and the action target path can not be resolved, we know that this is a morph
                 # animation.
                 if blender_object.type == "MESH":
-                    # if you need the specific shape key for some reason, this is it:
-                    # shape_key = blender_object.data.shape_keys.path_resolve(object_path)
+                    shape_key = blender_object.data.shape_keys.path_resolve(object_path)
+                    if shape_key.mute is True:
+                        continue
                     target = blender_object.data.shape_keys
                 else:
                     gltf2_io_debug.print_console("WARNING", "Animation target {} not found".format(object_path))
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py
index e321ea07..d0d2d4a5 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py
@@ -83,7 +83,8 @@ def __gather_extras(blender_mesh: bpy.types.Mesh,
             target_names = []
             for blender_shape_key in blender_mesh.shape_keys.key_blocks:
                 if blender_shape_key != blender_shape_key.relative_key:
-                    target_names.append(blender_shape_key.name)
+                    if blender_shape_key.mute is False:
+                        target_names.append(blender_shape_key.name)
             extras['targetNames'] = target_names
 
     if extras:
@@ -130,7 +131,8 @@ def __gather_weights(blender_mesh: bpy.types.Mesh,
 
     for blender_shape_key in blender_mesh.shape_keys.key_blocks:
         if blender_shape_key != blender_shape_key.relative_key:
-            weights.append(blender_shape_key.value)
+            if blender_shape_key.mute is False:
+                weights.append(blender_shape_key.value)
 
     return weights
 
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
index 2c4ee91f..82673e5e 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
@@ -143,87 +143,91 @@ def __gather_targets(blender_primitive, blender_mesh, modifiers, export_settings
         if blender_mesh.shape_keys is not None:
             morph_index = 0
             for blender_shape_key in blender_mesh.shape_keys.key_blocks:
-                if blender_shape_key != blender_shape_key.relative_key:
-
-                    target_position_id = 'MORPH_POSITION_' + str(morph_index)
-                    target_normal_id = 'MORPH_NORMAL_' + str(morph_index)
-                    target_tangent_id = 'MORPH_TANGENT_' + str(morph_index)
-
-                    if blender_primitive["attributes"].get(target_position_id):
-                        target = {}
-                        internal_target_position = blender_primitive["attributes"][target_position_id]
+                if blender_shape_key == blender_shape_key.relative_key:
+                    continue
+
+                if blender_shape_key.mute is True:
+                    continue
+
+                target_position_id = 'MORPH_POSITION_' + str(morph_index)
+                target_normal_id = 'MORPH_NORMAL_' + str(morph_index)
+                target_tangent_id = 'MORPH_TANGENT_' + str(morph_index)
+
+                if blender_primitive["attributes"].get(target_position_id):
+                    target = {}
+                    internal_target_position = blender_primitive["attributes"][target_position_id]
+                    binary_data = gltf2_io_binary_data.BinaryData.from_list(
+                        internal_target_position,
+                        gltf2_io_constants.ComponentType.Float
+                    )
+                    target["POSITION"] = gltf2_io.Accessor(
+                        buffer_view=binary_data,
+                        byte_offset=None,
+                        component_type=gltf2_io_constants.ComponentType.Float,
+                        count=len(internal_target_position) // gltf2_io_constants.DataType.num_elements(
+                            gltf2_io_constants.DataType.Vec3),
+                        extensions=None,
+                        extras=None,
+                        max=gltf2_blender_utils.max_components(
+                            internal_target_position, gltf2_io_constants.DataType.Vec3),
+                        min=gltf2_blender_utils.min_components(
+                            internal_target_position, gltf2_io_constants.DataType.Vec3),
+                        name=None,
+                        normalized=None,
+                        sparse=None,
+                        type=gltf2_io_constants.DataType.Vec3
+                    )
+
+                    if export_settings[NORMALS] \
+                            and export_settings[MORPH_NORMAL] \
+                            and blender_primitive["attributes"].get(target_normal_id):
+
+                        internal_target_normal = blender_primitive["attributes"][target_normal_id]
                         binary_data = gltf2_io_binary_data.BinaryData.from_list(
-                            internal_target_position,
-                            gltf2_io_constants.ComponentType.Float
+                            internal_target_normal,
+                            gltf2

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list