glTF importer: fcurve code refactor

This commit is contained in:
Julien Duroure 2019-09-26 16:58:13 +02:00
parent a0c33fe957
commit ba3c5b0b3b
5 changed files with 60 additions and 89 deletions

View File

@ -15,7 +15,7 @@
bl_info = {
'name': 'glTF 2.0 format',
'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
"version": (0, 9, 75),
"version": (0, 9, 76),
'blender': (2, 81, 6),
'location': 'File > Import-Export',
'description': 'Import-Export as glTF 2.0',

View File

@ -18,7 +18,7 @@ from mathutils import Matrix
from ..com.gltf2_blender_conversion import loc_gltf_to_blender, quaternion_gltf_to_blender, scale_to_matrix
from ...io.imp.gltf2_io_binary import BinaryData
from .gltf2_blender_animation_utils import simulate_stash
from .gltf2_blender_animation_utils import simulate_stash, make_fcurve
class BlenderBoneAnim():
@ -26,20 +26,6 @@ class BlenderBoneAnim():
def __new__(cls, *args, **kwargs):
raise RuntimeError("%s should not be instantiated" % cls)
@staticmethod
def set_interpolation(interpolation, kf):
"""Set interpolation."""
if interpolation == "LINEAR":
kf.interpolation = 'LINEAR'
elif interpolation == "STEP":
kf.interpolation = 'CONSTANT'
elif interpolation == "CUBICSPLINE":
kf.interpolation = 'BEZIER'
kf.handle_right_type = 'AUTO'
kf.handle_left_type = 'AUTO'
else:
kf.interpolation = 'LINEAR'
@staticmethod
def parse_translation_channel(gltf, node, obj, bone, channel, animation):
"""Manage Location animation."""
@ -193,22 +179,16 @@ class BlenderBoneAnim():
coords = [0] * (2 * len(keys))
coords[::2] = (key[0] * fps for key in keys)
if group_name not in action.groups:
action.groups.new(group_name)
group = action.groups[group_name]
for i in range(0, len(values[0])):
fcurve = action.fcurves.new(data_path=blender_path, index=i)
fcurve.group = group
fcurve.keyframe_points.add(len(keys))
coords[1::2] = (vals[i] for vals in values)
fcurve.keyframe_points.foreach_set('co', coords)
# Setting interpolation
for kf in fcurve.keyframe_points:
BlenderBoneAnim.set_interpolation(interpolation, kf)
fcurve.update() # force updating tangents (this may change when tangent will be managed)
make_fcurve(
action,
coords,
data_path=blender_path,
index=i,
group_name=group_name,
interpolation=interpolation,
)
@staticmethod
def anim(gltf, anim_idx, node_idx):

View File

@ -18,7 +18,7 @@ from mathutils import Vector
from ..com.gltf2_blender_conversion import loc_gltf_to_blender, quaternion_gltf_to_blender, scale_gltf_to_blender
from ..com.gltf2_blender_conversion import correction_rotation
from ...io.imp.gltf2_io_binary import BinaryData
from .gltf2_blender_animation_utils import simulate_stash
from .gltf2_blender_animation_utils import simulate_stash, make_fcurve
class BlenderNodeAnim():
@ -26,20 +26,6 @@ class BlenderNodeAnim():
def __new__(cls, *args, **kwargs):
raise RuntimeError("%s should not be instantiated" % cls)
@staticmethod
def set_interpolation(interpolation, kf):
"""Manage interpolation."""
if interpolation == "LINEAR":
kf.interpolation = 'LINEAR'
elif interpolation == "STEP":
kf.interpolation = 'CONSTANT'
elif interpolation == "CUBICSPLINE":
kf.interpolation = 'BEZIER'
kf.handle_right_type = 'AUTO'
kf.handle_left_type = 'AUTO'
else:
kf.interpolation = 'LINEAR'
@staticmethod
def anim(gltf, anim_idx, node_idx):
"""Manage animation."""
@ -117,20 +103,14 @@ class BlenderNodeAnim():
coords = [0] * (2 * len(keys))
coords[::2] = (key[0] * fps for key in keys)
if group_name not in action.groups:
action.groups.new(group_name)
group = action.groups[group_name]
for i in range(0, num_components):
fcurve = action.fcurves.new(data_path=blender_path, index=i)
fcurve.group = group
fcurve.keyframe_points.add(len(keys))
coords[1::2] = (vals[i] for vals in values)
fcurve.keyframe_points.foreach_set('co', coords)
# Setting interpolation
for kf in fcurve.keyframe_points:
BlenderNodeAnim.set_interpolation(animation.samplers[channel.sampler].interpolation, kf)
fcurve.update() # force updating tangents (this may change when tangent will be managed)
make_fcurve(
action,
coords,
data_path=blender_path,
index=i,
group_name=group_name,
interpolation=animation.samplers[channel.sampler].interpolation,
)

View File

@ -45,3 +45,35 @@ def restore_animation_on_object(obj, anim_name):
obj.animation_data.action = None
def make_fcurve(action, co, data_path, index=0, group_name=None, interpolation=None):
fcurve = action.fcurves.new(data_path=data_path, index=index)
if group_name:
if group_name not in action.groups:
action.groups.new(group_name)
group = action.groups[group_name]
fcurve.group = group
fcurve.keyframe_points.add(len(co) // 2)
fcurve.keyframe_points.foreach_set('co', co)
# Setting interpolation
if interpolation == 'CUBICSPLINE':
for kf in fcurve.keyframe_points:
kf.interpolation = 'BEZIER'
kf.handle_right_type = 'AUTO'
kf.handle_left_type = 'AUTO'
else:
if interpolation == 'LINEAR':
blender_interpolation = 'LINEAR'
elif interpolation == 'STEP':
blender_interpolation = 'CONSTANT'
else:
blender_interpolation = 'LINEAR'
for kf in fcurve.keyframe_points:
kf.interpolation = blender_interpolation
fcurve.update() # force updating tangents (this may change when tangent will be managed)
return fcurve

View File

@ -16,7 +16,7 @@ import json
import bpy
from ...io.imp.gltf2_io_binary import BinaryData
from .gltf2_blender_animation_utils import simulate_stash
from .gltf2_blender_animation_utils import simulate_stash, make_fcurve
class BlenderWeightAnim():
@ -24,20 +24,6 @@ class BlenderWeightAnim():
def __new__(cls, *args, **kwargs):
raise RuntimeError("%s should not be instantiated" % cls)
@staticmethod
def set_interpolation(interpolation, kf):
"""Manage interpolation."""
if interpolation == "LINEAR":
kf.interpolation = 'LINEAR'
elif interpolation == "STEP":
kf.interpolation = 'CONSTANT'
elif interpolation == "CUBICSPLINE":
kf.interpolation = 'BEZIER'
kf.handle_right_type = 'AUTO'
kf.handle_left_type = 'AUTO'
else:
kf.interpolation = 'LINEAR'
@staticmethod
def anim(gltf, anim_idx, node_idx):
"""Manage animation."""
@ -83,24 +69,17 @@ class BlenderWeightAnim():
coords = [0] * (2 * len(keys))
coords[::2] = (key[0] * fps for key in keys)
group_name = "ShapeKeys"
if group_name not in action.groups:
action.groups.new(group_name)
group = action.groups[group_name]
for sk in range(nb_targets):
if pymesh.shapekey_names[sk] is not None: # Do not animate shapekeys not created
coords[1::2] = (values[offset + stride * i + sk][0] for i in range(len(keys)))
kb_name = pymesh.shapekey_names[sk]
data_path = "key_blocks[" + json.dumps(kb_name) + "].value"
fcurve = action.fcurves.new(data_path=data_path)
fcurve.group = group
fcurve.keyframe_points.add(len(keys))
coords[1::2] = (values[offset + stride * i + sk][0] for i in range(len(keys)))
fcurve.keyframe_points.foreach_set('co', coords)
# Setting interpolation
for kf in fcurve.keyframe_points:
BlenderWeightAnim.set_interpolation(animation.samplers[channel.sampler].interpolation, kf)
fcurve.update() # force updating tangents (this may change when tangent will be managed)
make_fcurve(
action,
coords,
data_path=data_path,
group_name="ShapeKeys",
interpolation=animation.samplers[channel.sampler].interpolation,
)