glTF exporter: Fixed bezier control points to cubic spline tangents conversion
Fix when animation are not baked
This commit is contained in:
parent
4082824096
commit
08d13c024f
|
@ -4,7 +4,7 @@
|
|||
bl_info = {
|
||||
'name': 'glTF 2.0 format',
|
||||
'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
|
||||
"version": (3, 3, 15),
|
||||
"version": (3, 3, 16),
|
||||
'blender': (3, 3, 0),
|
||||
'location': 'File > Import-Export',
|
||||
'description': 'Import-Export as glTF 2.0',
|
||||
|
|
|
@ -398,11 +398,17 @@ def gather_keyframes(blender_obj_uuid: str,
|
|||
key.set_first_tangent()
|
||||
else:
|
||||
# otherwise construct an in tangent coordinate from the keyframes control points. We intermediately
|
||||
# use a point at t-1 to define the tangent. This allows the tangent control point to be transformed
|
||||
# normally
|
||||
# use a point at t+1 to define the tangent. This allows the tangent control point to be transformed
|
||||
# normally, but only works for locally linear transformation. The more non-linear a transform, the
|
||||
# more imprecise this method is.
|
||||
# We could use any other (v1, t1) for which (v1 - v0) / (t1 - t0) equals the tangent. By using t+1
|
||||
# for both in and out tangents, we guarantee that (even if there are errors or numerical imprecisions)
|
||||
# symmetrical control points translate to symmetrical tangents.
|
||||
# Note: I am not sure that linearity is never broken with quaternions and their normalization.
|
||||
# Especially at sign swap it might occure that the value gets negated but the control point not.
|
||||
# I have however not once encountered an issue with this.
|
||||
key.in_tangent = [
|
||||
c.keyframe_points[i].co[1] + ((c.keyframe_points[i].co[1] - c.keyframe_points[i].handle_left[1]
|
||||
) / (frame - frames[i - 1]))
|
||||
c.keyframe_points[i].co[1] + (c.keyframe_points[i].handle_left[1] - c.keyframe_points[i].co[1]) / (c.keyframe_points[i].handle_left[0] - c.keyframe_points[i].co[0])
|
||||
for c in channels if c is not None
|
||||
]
|
||||
# Construct the out tangent
|
||||
|
@ -410,12 +416,10 @@ def gather_keyframes(blender_obj_uuid: str,
|
|||
# end out-tangent should become all zero
|
||||
key.set_last_tangent()
|
||||
else:
|
||||
# otherwise construct an in tangent coordinate from the keyframes control points. We intermediately
|
||||
# use a point at t+1 to define the tangent. This allows the tangent control point to be transformed
|
||||
# normally
|
||||
# otherwise construct an in tangent coordinate from the keyframes control points.
|
||||
# This happens the same way how in tangents are handled above.
|
||||
key.out_tangent = [
|
||||
c.keyframe_points[i].co[1] + ((c.keyframe_points[i].handle_right[1] - c.keyframe_points[i].co[1]
|
||||
) / (frames[i + 1] - frame))
|
||||
c.keyframe_points[i].co[1] + (c.keyframe_points[i].handle_right[1] - c.keyframe_points[i].co[1]) / (c.keyframe_points[i].handle_right[0] - c.keyframe_points[i].co[0])
|
||||
for c in channels if c is not None
|
||||
]
|
||||
|
||||
|
|
|
@ -414,6 +414,7 @@ def __gather_output(channels: typing.Tuple[bpy.types.FCurve],
|
|||
transform = parent_inverse
|
||||
|
||||
values = []
|
||||
fps = bpy.context.scene.render.fps
|
||||
for keyframe in keyframes:
|
||||
# Transform the data and build gltf control points
|
||||
value = gltf2_blender_math.transform(keyframe.value, target_datapath, transform, need_rotation_correction)
|
||||
|
@ -426,11 +427,11 @@ def __gather_output(channels: typing.Tuple[bpy.types.FCurve],
|
|||
in_tangent = gltf2_blender_math.transform(keyframe.in_tangent, target_datapath, transform, need_rotation_correction)
|
||||
if is_yup and blender_object_if_armature is None:
|
||||
in_tangent = gltf2_blender_math.swizzle_yup(in_tangent, target_datapath)
|
||||
# the tangent in glTF is relative to the keyframe value
|
||||
# the tangent in glTF is relative to the keyframe value and uses seconds
|
||||
if not isinstance(value, list):
|
||||
in_tangent = value - in_tangent
|
||||
in_tangent = fps * (in_tangent - value)
|
||||
else:
|
||||
in_tangent = [value[i] - in_tangent[i] for i in range(len(value))]
|
||||
in_tangent = [fps * (in_tangent[i] - value[i]) for i in range(len(value))]
|
||||
keyframe_value = gltf2_blender_math.mathutils_to_gltf(in_tangent) + keyframe_value # append
|
||||
|
||||
if keyframe.out_tangent is not None:
|
||||
|
@ -438,11 +439,11 @@ def __gather_output(channels: typing.Tuple[bpy.types.FCurve],
|
|||
out_tangent = gltf2_blender_math.transform(keyframe.out_tangent, target_datapath, transform, need_rotation_correction)
|
||||
if is_yup and blender_object_if_armature is None:
|
||||
out_tangent = gltf2_blender_math.swizzle_yup(out_tangent, target_datapath)
|
||||
# the tangent in glTF is relative to the keyframe value
|
||||
# the tangent in glTF is relative to the keyframe value and uses seconds
|
||||
if not isinstance(value, list):
|
||||
out_tangent = value - out_tangent
|
||||
out_tangent = fps * (out_tangent - value)
|
||||
else:
|
||||
out_tangent = [value[i] - out_tangent[i] for i in range(len(value))]
|
||||
out_tangent = [fps * (out_tangent[i] - value[i]) for i in range(len(value))]
|
||||
keyframe_value = keyframe_value + gltf2_blender_math.mathutils_to_gltf(out_tangent) # append
|
||||
|
||||
values += keyframe_value
|
||||
|
|
Loading…
Reference in New Issue