From 8466799187188e371080e0c4e46a9e3fe3a66d24 Mon Sep 17 00:00:00 2001 From: Julien Duroure <julien.duroure@gmail.com> Date: Tue, 4 Oct 2022 09:25:41 +0200 Subject: [PATCH] glTF exporter: Avoid adding multiple neutral bone on same armature --- io_scene_gltf2/__init__.py | 2 +- .../blender/exp/gltf2_blender_gather_tree.py | 120 +++++++++--------- 2 files changed, 64 insertions(+), 58 deletions(-) diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py index 534b63923..876456612 100755 --- a/io_scene_gltf2/__init__.py +++ b/io_scene_gltf2/__init__.py @@ -4,7 +4,7 @@ bl_info = { 'name': 'glTF 2.0 format', 'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin SchmithĂĽsen, Jim Eckerlein, and many external contributors', - "version": (3, 4, 27), + "version": (3, 4, 29), 'blender': (3, 3, 0), 'location': 'File > Import-Export', 'description': 'Import-Export as glTF 2.0', diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py index d341028c7..88b197317 100644 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py @@ -412,67 +412,73 @@ class VExportTree: del n.armature_needed def add_neutral_bones(self): + added_armatures = [] for n in [n for n in self.nodes.values() if n.armature is not None and n.blender_type == VExportNode.OBJECT and hasattr(self.nodes[n.armature], "need_neutral_bone")]: #all skin meshes objects where neutral bone is needed - # First add a new node - axis_basis_change = Matrix.Identity(4) - if self.export_settings[gltf2_blender_export_keys.YUP]: - axis_basis_change = Matrix(((1.0, 0.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0, -1.0, 0.0, 0.0), (0.0, 0.0, 0.0, 1.0))) - - trans, rot, sca = axis_basis_change.decompose() - translation, rotation, scale = (None, None, None) - if trans[0] != 0.0 or trans[1] != 0.0 or trans[2] != 0.0: - translation = [trans[0], trans[1], trans[2]] - if rot[0] != 1.0 or rot[1] != 0.0 or rot[2] != 0.0 or rot[3] != 0.0: - rotation = [rot[1], rot[2], rot[3], rot[0]] - if sca[0] != 1.0 or sca[1] != 1.0 or sca[2] != 1.0: - scale = [sca[0], sca[1], sca[2]] - neutral_bone = gltf2_io.Node( - camera=None, - children=None, - extensions=None, - extras=None, - matrix=None, - mesh=None, - name='neutral_bone', - rotation=rotation, - scale=scale, - skin=None, - translation=translation, - weights=None - ) - # Add it to child list of armature - self.nodes[n.armature].node.children.append(neutral_bone) - # Add it to joint list - n.node.skin.joints.append(neutral_bone) - - # Need to add an InverseBindMatrix - array = BinaryData.decode_accessor_internal(n.node.skin.inverse_bind_matrices) + if n.armature not in added_armatures: - axis_basis_change = Matrix.Identity(4) - if self.export_settings[gltf2_blender_export_keys.YUP]: - axis_basis_change = Matrix( - ((1.0, 0.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0, -1.0, 0.0, 0.0), (0.0, 0.0, 0.0, 1.0))) + added_armatures.append(n.armature) # Make sure to not insert 2 times the neural bone - inverse_bind_matrix = ( - axis_basis_change @ self.nodes[n.armature].matrix_world_armature).inverted_safe() - - matrix = [] - for column in range(0, 4): - for row in range(0, 4): - matrix.append(inverse_bind_matrix[row][column]) - - array = np.append(array, np.array([matrix]), axis=0) - binary_data = gltf2_io_binary_data.BinaryData.from_list(array.flatten(), gltf2_io_constants.ComponentType.Float) - n.node.skin.inverse_bind_matrices = gltf2_blender_gather_accessors.gather_accessor( - binary_data, - gltf2_io_constants.ComponentType.Float, - len(array.flatten()) // gltf2_io_constants.DataType.num_elements(gltf2_io_constants.DataType.Mat4), - None, - None, - gltf2_io_constants.DataType.Mat4, - self.export_settings - ) + # First add a new node + axis_basis_change = Matrix.Identity(4) + if self.export_settings[gltf2_blender_export_keys.YUP]: + axis_basis_change = Matrix(((1.0, 0.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0, -1.0, 0.0, 0.0), (0.0, 0.0, 0.0, 1.0))) + + trans, rot, sca = axis_basis_change.decompose() + translation, rotation, scale = (None, None, None) + if trans[0] != 0.0 or trans[1] != 0.0 or trans[2] != 0.0: + translation = [trans[0], trans[1], trans[2]] + if rot[0] != 1.0 or rot[1] != 0.0 or rot[2] != 0.0 or rot[3] != 0.0: + rotation = [rot[1], rot[2], rot[3], rot[0]] + if sca[0] != 1.0 or sca[1] != 1.0 or sca[2] != 1.0: + scale = [sca[0], sca[1], sca[2]] + neutral_bone = gltf2_io.Node( + camera=None, + children=None, + extensions=None, + extras=None, + matrix=None, + mesh=None, + name='neutral_bone', + rotation=rotation, + scale=scale, + skin=None, + translation=translation, + weights=None + ) + # Add it to child list of armature + self.nodes[n.armature].node.children.append(neutral_bone) + + # Add it to joint list + n.node.skin.joints.append(neutral_bone) + + # Need to add an InverseBindMatrix + array = BinaryData.decode_accessor_internal(n.node.skin.inverse_bind_matrices) + + axis_basis_change = Matrix.Identity(4) + if self.export_settings[gltf2_blender_export_keys.YUP]: + axis_basis_change = Matrix( + ((1.0, 0.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0, -1.0, 0.0, 0.0), (0.0, 0.0, 0.0, 1.0))) + + inverse_bind_matrix = ( + axis_basis_change @ self.nodes[n.armature].matrix_world_armature).inverted_safe() + + matrix = [] + for column in range(0, 4): + for row in range(0, 4): + matrix.append(inverse_bind_matrix[row][column]) + + array = np.append(array, np.array([matrix]), axis=0) + binary_data = gltf2_io_binary_data.BinaryData.from_list(array.flatten(), gltf2_io_constants.ComponentType.Float) + n.node.skin.inverse_bind_matrices = gltf2_blender_gather_accessors.gather_accessor( + binary_data, + gltf2_io_constants.ComponentType.Float, + len(array.flatten()) // gltf2_io_constants.DataType.num_elements(gltf2_io_constants.DataType.Mat4), + None, + None, + gltf2_io_constants.DataType.Mat4, + self.export_settings + ) def get_unused_skins(self): from .gltf2_blender_gather_skins import gather_skin skins = [] -- GitLab