diff options
Diffstat (limited to 'io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py')
-rw-r--r-- | io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py | 72 |
1 files changed, 72 insertions, 0 deletions
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 643cbea0..cf4983e1 100644 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py @@ -3,10 +3,17 @@ import bpy import uuid +import numpy as np from . import gltf2_blender_export_keys from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extensions from mathutils import Quaternion, Matrix +from io_scene_gltf2.io.com import gltf2_io +from io_scene_gltf2.io.imp.gltf2_io_binary import BinaryData +from io_scene_gltf2.io.com import gltf2_io_constants +from .gltf2_blender_gather_primitive_attributes import array_to_accessor +from io_scene_gltf2.io.exp import gltf2_io_binary_data +from io_scene_gltf2.blender.exp import gltf2_blender_gather_accessors class VExportNode: @@ -237,6 +244,9 @@ class VExportTree: else: return [] + def get_all_node_of_type(self, node_type): + return [n.uuid for n in self.nodes.values() if n.blender_type == node_type] + def display(self, mode): if mode == "simple": for n in self.roots: @@ -375,6 +385,68 @@ class VExportTree: n.armature = candidates[0].uuid del n.armature_needed + def add_neutral_bones(self): + 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) + + 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 = [] |