[Bf-extensions-cvs] [919559f3] master: glTF exporter: Sampled animation now bake all bones, including constraints
Julien Duroure
noreply at git.blender.org
Sun May 26 23:57:32 CEST 2019
Commit: 919559f3deaffa77ad69bb173333f7c14c63028f
Author: Julien Duroure
Date: Sun May 26 23:46:18 2019 +0200
Branches: master
https://developer.blender.org/rBA919559f3deaffa77ad69bb173333f7c14c63028f
glTF exporter: Sampled animation now bake all bones, including constraints
Using "Always Sample Animation" can now export complex rigs, including constraints, like rigify for example
===================================================================
M io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py
M io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
M io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py
M io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py
===================================================================
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py
index 2e4ac1d7..5b2f28e8 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py
@@ -24,37 +24,47 @@ from io_scene_gltf2.blender.exp import gltf2_blender_gather_joints
@cached
def gather_animation_channel_target(channels: typing.Tuple[bpy.types.FCurve],
blender_object: bpy.types.Object,
+ bake_bone: typing.Union[str, None],
+ bake_channel: typing.Union[str, None],
export_settings
) -> gltf2_io.AnimationChannelTarget:
- return gltf2_io.AnimationChannelTarget(
- extensions=__gather_extensions(channels, blender_object, export_settings),
- extras=__gather_extras(channels, blender_object, export_settings),
- node=__gather_node(channels, blender_object, export_settings),
- path=__gather_path(channels, blender_object, export_settings)
- )
+ return gltf2_io.AnimationChannelTarget(
+ extensions=__gather_extensions(channels, blender_object, export_settings, bake_bone),
+ extras=__gather_extras(channels, blender_object, export_settings, bake_bone),
+ node=__gather_node(channels, blender_object, export_settings, bake_bone),
+ path=__gather_path(channels, blender_object, export_settings, bake_bone, bake_channel)
+ )
def __gather_extensions(channels: typing.Tuple[bpy.types.FCurve],
blender_object: bpy.types.Object,
- export_settings
+ export_settings,
+ bake_bone: typing.Union[str, None]
) -> typing.Any:
return None
def __gather_extras(channels: typing.Tuple[bpy.types.FCurve],
blender_object: bpy.types.Object,
- export_settings
+ export_settings,
+ bake_bone: typing.Union[str, None]
) -> typing.Any:
return None
def __gather_node(channels: typing.Tuple[bpy.types.FCurve],
blender_object: bpy.types.Object,
- export_settings
+ 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
- blender_bone = blender_object.path_resolve(channels[0].data_path.rsplit('.', 1)[0])
+
+ 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)
@@ -63,9 +73,14 @@ def __gather_node(channels: typing.Tuple[bpy.types.FCurve],
def __gather_path(channels: typing.Tuple[bpy.types.FCurve],
blender_object: bpy.types.Object,
- export_settings
+ export_settings,
+ bake_bone: typing.Union[str, None],
+ bake_channel: typing.Union[str, None]
) -> str:
- target = channels[0].data_path.split('.')[-1]
+ if bake_channel is None:
+ target = channels[0].data_path.split('.')[-1]
+ else:
+ target = bake_channel
path = {
"delta_location": "translation",
"delta_rotation_euler": "rotation",
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 1b76142c..aa81b073 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
@@ -31,26 +31,61 @@ def gather_animation_channels(blender_action: bpy.types.Action,
) -> typing.List[gltf2_io.AnimationChannel]:
channels = []
- for channel_group in __get_channel_groups(blender_action, blender_object):
- channel = __gather_animation_channel(channel_group, blender_object, export_settings)
- if channel is not None:
- channels.append(channel)
+ if blender_object.type == "ARMATURE" and export_settings['gltf_force_sampling'] is True:
+ # We have to store sampled animation data for every deformation bones
+
+ # First calculate range of animation for baking
+ bake_range_start = None
+ bake_range_end = None
+ groups = __get_channel_groups(blender_action, blender_object, export_settings)
+ for chans in groups:
+ ranges = [channel.range() for channel in chans]
+ if bake_range_start is None:
+ bake_range_start = min([channel.range()[0] for channel in chans])
+ else:
+ bake_range_start = min(bake_range_start, min([channel.range()[0] for channel in chans]))
+ if bake_range_end is None:
+ bake_range_end = max([channel.range()[1] for channel in chans])
+ else:
+ bake_range_end = max(bake_range_end, max([channel.range()[1] for channel in chans]))
+
+ # Then bake all bones
+ for bone in blender_object.data.bones:
+ for p in ["location", "rotation_quaternion", "scale"]:
+ channel = __gather_animation_channel(
+ (),
+ blender_object,
+ export_settings,
+ bone.name,
+ p,
+ bake_range_start,
+ bake_range_end)
+ 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)
+ if channel is not None:
+ channels.append(channel)
return channels
def __gather_animation_channel(channels: typing.Tuple[bpy.types.FCurve],
blender_object: bpy.types.Object,
- export_settings
+ export_settings,
+ bake_bone: typing.Union[str, None],
+ bake_channel: typing.Union[str, None],
+ bake_range_start,
+ bake_range_end
) -> typing.Union[gltf2_io.AnimationChannel, None]:
if not __filter_animation_channel(channels, blender_object, export_settings):
return None
return gltf2_io.AnimationChannel(
- extensions=__gather_extensions(channels, blender_object, export_settings),
- extras=__gather_extras(channels, blender_object, export_settings),
- sampler=__gather_sampler(channels, blender_object, export_settings),
- target=__gather_target(channels, blender_object, export_settings)
+ extensions=__gather_extensions(channels, blender_object, export_settings, bake_bone),
+ extras=__gather_extras(channels, blender_object, export_settings, bake_bone),
+ sampler=__gather_sampler(channels, blender_object, export_settings, bake_bone, bake_channel, bake_range_start, bake_range_end),
+ target=__gather_target(channels, blender_object, export_settings, bake_bone, bake_channel)
)
@@ -63,38 +98,50 @@ def __filter_animation_channel(channels: typing.Tuple[bpy.types.FCurve],
def __gather_extensions(channels: typing.Tuple[bpy.types.FCurve],
blender_object: bpy.types.Object,
- export_settings
+ export_settings,
+ bake_bone: typing.Union[str, None]
) -> typing.Any:
return None
def __gather_extras(channels: typing.Tuple[bpy.types.FCurve],
blender_object: bpy.types.Object,
- export_settings
+ export_settings,
+ bake_bone: typing.Union[str, None]
) -> typing.Any:
return None
def __gather_sampler(channels: typing.Tuple[bpy.types.FCurve],
blender_object: bpy.types.Object,
- export_settings
+ export_settings,
+ bake_bone: typing.Union[str, None],
+ bake_channel: typing.Union[str, None],
+ bake_range_start,
+ bake_range_end
) -> gltf2_io.AnimationSampler:
return gltf2_blender_gather_animation_samplers.gather_animation_sampler(
channels,
blender_object,
+ bake_bone,
+ bake_channel,
+ bake_range_start,
+ bake_range_end,
export_settings
)
def __gather_target(channels: typing.Tuple[bpy.types.FCurve],
blender_object: bpy.types.Object,
- export_settings
+ export_settings,
+ bake_bone: typing.Union[str, None],
+ bake_channel: typing.Union[str, None]
) -> gltf2_io.AnimationChannelTarget:
return gltf2_blender_gather_animation_channel_target.gather_animation_channel_target(
- channels, blender_object, export_settings)
+ channels, blender_object, bake_bone, bake_channel, export_settings)
-def __get_channel_groups(blender_action: bpy.types.Action, blender_object: bpy.types.Object):
+def __get_channel_groups(blender_action: bpy.types.Action, blender_object: bpy.types.Object, export_settings):
targets = {}
for fcurve in blender_action.fcurves:
target_property = get_target_property_name(fcurve.data_path)
diff --git a/io_scene_gl
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list