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

gltf2_blender_gather_skins.py « exp « blender « io_scene_gltf2 - git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 136d654d0084b0cc2d9d35b017b0c579370fd741 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# SPDX-License-Identifier: Apache-2.0
# Copyright 2018-2021 The glTF-Blender-IO authors.

import mathutils
from . import gltf2_blender_export_keys
from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached
from io_scene_gltf2.io.com import gltf2_io
from io_scene_gltf2.io.exp import gltf2_io_binary_data
from io_scene_gltf2.io.com import gltf2_io_constants
from io_scene_gltf2.blender.exp import gltf2_blender_gather_accessors
from io_scene_gltf2.blender.exp import gltf2_blender_gather_joints
from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extensions
from io_scene_gltf2.blender.exp import gltf2_blender_gather_tree
from io_scene_gltf2.blender.exp.gltf2_blender_gather_tree import VExportNode


@cached
def gather_skin(armature_uuid, export_settings):
    """
    Gather armatures, bones etc into a glTF2 skin object.

    :param blender_object: the object which may contain a skin
    :param export_settings:
    :return: a glTF2 skin object
    """

    blender_armature_object = export_settings['vtree'].nodes[armature_uuid].blender_object

    if not __filter_skin(blender_armature_object, export_settings):
        return None

    skin = gltf2_io.Skin(
        extensions=__gather_extensions(blender_armature_object, export_settings),
        extras=__gather_extras(blender_armature_object, export_settings),
        inverse_bind_matrices=__gather_inverse_bind_matrices(armature_uuid, export_settings),
        joints=__gather_joints(armature_uuid, export_settings),
        name=__gather_name(blender_armature_object, export_settings),
        skeleton=__gather_skeleton(blender_armature_object, export_settings)
    )

    # If armature is not exported, joints will be empty.
    # Do not construct skin in that case
    if len(skin.joints) == 0:
        return None

    export_user_extensions('gather_skin_hook', export_settings, skin, blender_armature_object)

    return skin


def __filter_skin(blender_armature_object, export_settings):
    if not export_settings[gltf2_blender_export_keys.SKINS]:
        return False
    if blender_armature_object.type != 'ARMATURE' or len(blender_armature_object.pose.bones) == 0:
        return False

    return True


def __gather_extensions(blender_armature_object, export_settings):
    return None


def __gather_extras(blender_armature_object, export_settings):
    return None

def __gather_inverse_bind_matrices(armature_uuid, export_settings):

    blender_armature_object = export_settings['vtree'].nodes[armature_uuid].blender_object

    axis_basis_change = mathutils.Matrix.Identity(4)
    if export_settings[gltf2_blender_export_keys.YUP]:
        axis_basis_change = mathutils.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)))

    bones_uuid = export_settings['vtree'].get_all_bones(armature_uuid)
    def __collect_matrices(bone):
        inverse_bind_matrix = (
            axis_basis_change @
            (
                blender_armature_object.matrix_world @
                bone.bone.matrix_local
            )
        ).inverted_safe()
        matrices.append(inverse_bind_matrix)

    matrices = []
    for b in bones_uuid:
        __collect_matrices(blender_armature_object.pose.bones[export_settings['vtree'].nodes[b].blender_bone.name])

    # flatten the matrices
    inverse_matrices = []
    for matrix in matrices:
        for column in range(0, 4):
            for row in range(0, 4):
                inverse_matrices.append(matrix[row][column])

    binary_data = gltf2_io_binary_data.BinaryData.from_list(inverse_matrices, gltf2_io_constants.ComponentType.Float)
    return gltf2_blender_gather_accessors.gather_accessor(
        binary_data,
        gltf2_io_constants.ComponentType.Float,
        len(inverse_matrices) // gltf2_io_constants.DataType.num_elements(gltf2_io_constants.DataType.Mat4),
        None,
        None,
        gltf2_io_constants.DataType.Mat4,
        export_settings
    )


def __gather_joints(armature_uuid, export_settings):

    blender_armature_object = export_settings['vtree'].nodes[armature_uuid].blender_object

    all_armature_children = export_settings['vtree'].nodes[armature_uuid].children
    root_bones_uuid = [c for c in all_armature_children if export_settings['vtree'].nodes[c].blender_type == VExportNode.BONE]

    # Create bone nodes
    for root_bone_uuid in root_bones_uuid:
        gltf2_blender_gather_joints.gather_joint_vnode(root_bone_uuid, export_settings)

    bones_uuid = export_settings['vtree'].get_all_bones(armature_uuid)
    joints = [export_settings['vtree'].nodes[b].node for b in bones_uuid]
    return joints


def __gather_name(blender_armature_object, export_settings):
    return blender_armature_object.name


def __gather_skeleton(blender_armature_object, export_settings):
    # In the future support the result of https://github.com/KhronosGroup/glTF/pull/1195
    return None