def __gather_node(channels: typing.Tuple[bpy.types.FCurve],
                  blender_object: bpy.types.Object,
                  export_settings,
                  bake_bone: typing.Union[str, None],
                  driver_obj
                  ) -> gltf2_io.Node:

    if driver_obj is not None:
        return gltf2_blender_gather_nodes.gather_node(driver_obj,
            driver_obj.library.name if driver_obj.library else None,
            None, None, export_settings)

    if blender_object.type == "ARMATURE":
        # TODO: get joint from fcurve data_path and gather_joint

        if bake_bone is not None:
            blender_bone = blender_object.pose.bones[bake_bone]
        else:
            blender_bone = blender_object.path_resolve(channels[0].data_path.rsplit('.', 1)[0])

        if isinstance(blender_bone, bpy.types.PoseBone):
            if export_settings["gltf_def_bones"] is False:
                obj = blender_object.proxy if blender_object.proxy else blender_object
                return gltf2_blender_gather_joints.gather_joint(obj, blender_bone, export_settings)
            else:
                bones, _, _ = gltf2_blender_gather_skins.get_bone_tree(None, blender_object)
                if blender_bone.name in [b.name for b in bones]:
                    obj = blender_object.proxy if blender_object.proxy else blender_object
                    return gltf2_blender_gather_joints.gather_jointb(obj, blender_bone, export_settings)

    return gltf2_blender_gather_nodes.gather_node(blender_object,
        blender_object.library.name if blender_object.library else None,
        None, None, export_settings)
Exemple #2
0
def __get_channel_groups(blender_action: bpy.types.Action, blender_object: bpy.types.Object):
    targets = {}
    for fcurve in blender_action.fcurves:
        target_property = get_target_property_name(fcurve.data_path)
        object_path = get_target_object_path(fcurve.data_path)

        # find the object affected by this action
        if not object_path:
            target = blender_object
        else:
            try:
                target = blender_object.path_resolve(object_path)
            except ValueError:
                # 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)
                    target = blender_object.data.shape_keys
                else:
                    gltf2_io_debug.print_console("WARNING", "Can not export animations with target {}".format(object_path))
                    continue

        # group channels by target object and affected property of the target
        target_properties = targets.get(target, {})
        channels = target_properties.get(target_property, [])
        channels.append(fcurve)
        target_properties[target_property] = channels
        targets[target] = target_properties

    groups = []
    for p in targets.values():
        groups += list(p.values())

    return map(tuple, groups)
def __gather_node(channels: typing.Tuple[bpy.types.FCurve],
                  blender_object: bpy.types.Object,
                  export_settings
                  ) -> gltf2_io.Node:
    if blender_object.type == "ARMATURE":
        # TODO: get joint from fcurve data_path and gather_joint
        blender_bone = blender_object.path_resolve(channels[0].data_path.rsplit('.', 1)[0])
        return gltf2_blender_gather_joints.gather_joint(blender_bone, export_settings)

    return gltf2_blender_gather_nodes.gather_node(blender_object, export_settings)
def __gather_node(channels: typing.Tuple[bpy.types.FCurve],
                  blender_object: bpy.types.Object,
                  export_settings
                  ) -> gltf2_io.Node:
    if blender_object.type == "ARMATURE":
        # TODO: get joint from fcurve data_path and gather_joint
        blender_bone = blender_object.path_resolve(channels[0].data_path.rsplit('.', 1)[0])
        if isinstance(blender_bone, bpy.types.PoseBone):
            return gltf2_blender_gather_joints.gather_joint(blender_bone, export_settings)

    return gltf2_blender_gather_nodes.gather_node(blender_object, export_settings)
def __gather_node(channels: typing.Tuple[bpy.types.FCurve],
                  blender_object: bpy.types.Object,
                  export_settings,
                  bake_bone: typing.Union[str, None]
                  ) -> gltf2_io.Node:
    if blender_object.type == "ARMATURE":
        # TODO: get joint from fcurve data_path and gather_joint

        if bake_bone is not None:
            blender_bone = blender_object.pose.bones[bake_bone]
        else:
            blender_bone = blender_object.path_resolve(channels[0].data_path.rsplit('.', 1)[0])

        if isinstance(blender_bone, bpy.types.PoseBone):
            return gltf2_blender_gather_joints.gather_joint(blender_bone, export_settings)

    return gltf2_blender_gather_nodes.gather_node(blender_object, None, export_settings)
def __gather_output(channels: typing.Tuple[bpy.types.FCurve],
                    blender_object: bpy.types.Object,
                    export_settings) -> gltf2_io.Accessor:
    """Gather the data of the keyframes."""
    keyframes = gltf2_blender_gather_animation_sampler_keyframes.gather_keyframes(
        channels, export_settings)

    target_datapath = channels[0].data_path

    transform = Matrix.Identity(4)

    if blender_object.type == "ARMATURE":
        bone = blender_object.path_resolve(
            get_target_object_path(target_datapath))
        if isinstance(bone, bpy.types.PoseBone):
            transform = bone.bone.matrix_local
            if bone.parent is not None:
                parent_transform = bone.parent.bone.matrix_local
                transform = gltf2_blender_math.multiply(
                    parent_transform.inverted(), transform)
                # if not export_settings[gltf2_blender_export_keys.YUP]:
                #     transform = gltf2_blender_math.multiply(gltf2_blender_math.to_zup(), transform)
            else:
                # only apply the y-up conversion to root bones, as child bones already are in the y-up space
                if export_settings[gltf2_blender_export_keys.YUP]:
                    transform = gltf2_blender_math.multiply(
                        gltf2_blender_math.to_yup(), transform)

    values = []
    for keyframe in keyframes:
        # Transform the data and extract
        value = gltf2_blender_math.transform(keyframe.value, target_datapath,
                                             transform)
        if export_settings[gltf2_blender_export_keys.
                           YUP] and not blender_object.type == "ARMATURE":
            value = gltf2_blender_math.swizzle_yup(value, target_datapath)
        keyframe_value = gltf2_blender_math.mathutils_to_gltf(value)
        if keyframe.in_tangent is not None:
            in_tangent = gltf2_blender_math.transform(keyframe.in_tangent,
                                                      target_datapath,
                                                      transform)
            if export_settings[gltf2_blender_export_keys.
                               YUP] and not blender_object.type == "ARMATURE":
                in_tangent = gltf2_blender_math.swizzle_yup(
                    in_tangent, target_datapath)
            keyframe_value = gltf2_blender_math.mathutils_to_gltf(
                in_tangent) + keyframe_value
        if keyframe.out_tangent is not None:
            out_tangent = gltf2_blender_math.transform(keyframe.out_tangent,
                                                       target_datapath,
                                                       transform)
            if export_settings[gltf2_blender_export_keys.
                               YUP] and not blender_object.type == "ARMATURE":
                out_tangent = gltf2_blender_math.swizzle_yup(
                    out_tangent, target_datapath)
            keyframe_value = keyframe_value + gltf2_blender_math.mathutils_to_gltf(
                out_tangent)
        values += keyframe_value

    component_type = gltf2_io_constants.ComponentType.Float
    if get_target_property_name(target_datapath) == "value":
        # channels with 'weight' targets must have scalar accessors
        data_type = gltf2_io_constants.DataType.Scalar
    else:
        data_type = gltf2_io_constants.DataType.vec_type_from_num(
            len(keyframes[0].value))

    return gltf2_io.Accessor(
        buffer_view=gltf2_io_binary_data.BinaryData.from_list(
            values, component_type),
        byte_offset=None,
        component_type=component_type,
        count=len(values) //
        gltf2_io_constants.DataType.num_elements(data_type),
        extensions=None,
        extras=None,
        max=None,
        min=None,
        name=None,
        normalized=None,
        sparse=None,
        type=data_type)