Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Duroure <julien.duroure@gmail.com>2019-08-23 08:29:41 +0300
committerJulien Duroure <julien.duroure@gmail.com>2019-08-23 08:29:41 +0300
commitfc320ea236c7f264a1438e7af338581a37bb74b1 (patch)
tree2619ec51d39be2d0bff04cc017dbe8556e8a04dc
parent3c3c2243dbbd8a35d1472db445a7dbc6c561ab38 (diff)
glTF exporter: fix shapekeys animation export
Animation channels must be sorted in exactly same order than shapekeys
-rwxr-xr-xio_scene_gltf2/__init__.py2
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_extract.py12
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py34
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py6
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py138
5 files changed, 113 insertions, 79 deletions
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_io_constants.ComponentType.Float,
)
- target["POSITION"] = gltf2_io.Accessor(
+ target['NORMAL'] = 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(
+ count=len(internal_target_normal) // 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),
+ max=None,
+ min=None,
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_normal,
- gltf2_io_constants.ComponentType.Float,
- )
- target['NORMAL'] = gltf2_io.Accessor(
- buffer_view=binary_data,
- byte_offset=None,
- component_type=gltf2_io_constants.ComponentType.Float,
- count=len(internal_target_normal) // gltf2_io_constants.DataType.num_elements(
- gltf2_io_constants.DataType.Vec3),
- extensions=None,
- extras=None,
- max=None,
- min=None,
- name=None,
- normalized=None,
- sparse=None,
- type=gltf2_io_constants.DataType.Vec3
- )
-
- if export_settings[TANGENTS] \
- and export_settings[MORPH_TANGENT] \
- and blender_primitive["attributes"].get(target_tangent_id):
- internal_target_tangent = blender_primitive["attributes"][target_tangent_id]
- binary_data = gltf2_io_binary_data.BinaryData.from_list(
- internal_target_tangent,
- gltf2_io_constants.ComponentType.Float,
- )
- target['TANGENT'] = gltf2_io.Accessor(
- buffer_view=binary_data,
- byte_offset=None,
- component_type=gltf2_io_constants.ComponentType.Float,
- count=len(internal_target_tangent) // gltf2_io_constants.DataType.num_elements(
- gltf2_io_constants.DataType.Vec3),
- extensions=None,
- extras=None,
- max=None,
- min=None,
- name=None,
- normalized=None,
- sparse=None,
- type=gltf2_io_constants.DataType.Vec3
- )
- targets.append(target)
- morph_index += 1
+ if export_settings[TANGENTS] \
+ and export_settings[MORPH_TANGENT] \
+ and blender_primitive["attributes"].get(target_tangent_id):
+ internal_target_tangent = blender_primitive["attributes"][target_tangent_id]
+ binary_data = gltf2_io_binary_data.BinaryData.from_list(
+ internal_target_tangent,
+ gltf2_io_constants.ComponentType.Float,
+ )
+ target['TANGENT'] = gltf2_io.Accessor(
+ buffer_view=binary_data,
+ byte_offset=None,
+ component_type=gltf2_io_constants.ComponentType.Float,
+ count=len(internal_target_tangent) // gltf2_io_constants.DataType.num_elements(
+ gltf2_io_constants.DataType.Vec3),
+ extensions=None,
+ extras=None,
+ max=None,
+ min=None,
+ name=None,
+ normalized=None,
+ sparse=None,
+ type=gltf2_io_constants.DataType.Vec3
+ )
+ targets.append(target)
+ morph_index += 1
return targets
return None