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

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xio_scene_gltf2/blender/com/gltf2_blender_math.py3
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py36
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py38
3 files changed, 47 insertions, 30 deletions
diff --git a/io_scene_gltf2/blender/com/gltf2_blender_math.py b/io_scene_gltf2/blender/com/gltf2_blender_math.py
index dd15ce2f..f3a20038 100755
--- a/io_scene_gltf2/blender/com/gltf2_blender_math.py
+++ b/io_scene_gltf2/blender/com/gltf2_blender_math.py
@@ -46,7 +46,7 @@ def list_to_mathutils(values: typing.List[float], data_path: str) -> typing.Unio
elif target == 'scale':
return Vector(values)
elif target == 'value':
- return values
+ return Vector(values)
return values
@@ -145,6 +145,7 @@ def transform_location(location: Vector, transform: Matrix = Matrix.Identity(4))
def transform_rotation(rotation: Quaternion, transform: Matrix = Matrix.Identity(4)) -> Quaternion:
"""Transform rotation."""
+ rotation.normalize()
m = rotation.to_matrix().to_4x4()
m = multiply(transform, m)
return m.to_quaternion()
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py
index 4ec68c88..4eb4df5c 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py
@@ -123,27 +123,31 @@ def gather_keyframes(channels: typing.Tuple[bpy.types.FCurve], export_settings)
if channels[0].keyframe_points[0].interpolation == "BEZIER":
# Construct the in tangent
if time == times[0]:
- # start in-tangent has zero length
- key.in_tangent = [0.0 for _ in channels]
+ # start in-tangent should become all zero
+ key.in_tangent = key.value
else:
- # otherwise construct an in tangent from the keyframes control points
-
+ # 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
key.in_tangent = [
- 3.0 * (c.keyframe_points[i].co[1] - c.keyframe_points[i].handle_left[1]
- ) / (time - times[i - 1])
+ c.keyframe_points[i].co[1] + ((c.keyframe_points[i].co[1] - c.keyframe_points[i].handle_left[1]
+ ) / (time - times[i - 1]))
for c in channels
]
# Construct the out tangent
if time == times[-1]:
- # end out-tangent has zero length
- key.out_tangent = [0.0 for _ in channels]
+ # end out-tangent should become all zero
+ key.out_tangent = key.value
else:
- # otherwise construct an out tangent from the keyframes control points
+ # 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
key.out_tangent = [
- 3.0 * (c.keyframe_points[i].handle_right[1] - c.keyframe_points[i].co[1]
- ) / (times[i + 1] - time)
+ c.keyframe_points[i].co[1] + ((c.keyframe_points[i].handle_right[1] - c.keyframe_points[i].co[1]
+ ) / (times[i + 1] - time))
for c in channels
]
+
keyframes.append(key)
return keyframes
@@ -197,11 +201,11 @@ def needs_baking(channels: typing.Tuple[bpy.types.FCurve],
"Baking animation because of differently located keyframes in one channel")
return True
- # Baking is required when the animation targets a quaternion with bezier interpolation
- if channels[0].data_path == "rotation_quaternion" and interpolation == "BEZIER":
- gltf2_io_debug.print_console("WARNING",
- "Baking animation because targeting a quaternion with bezier interpolation")
- return True
+ # # Baking is required when the animation targets a quaternion with bezier interpolation
+ # if channels[0].data_path == "rotation_quaternion" and interpolation == "BEZIER":
+ # gltf2_io_debug.print_console("WARNING",
+ # "Baking animation because targeting a quaternion with bezier interpolation")
+ # return True
return False
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py
index 981428c9..b4fda3c6 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py
@@ -16,6 +16,7 @@
import typing
import bpy
+import mathutils
from io_scene_gltf2.blender.com import gltf2_blender_math
from io_scene_gltf2.blender.com.gltf2_blender_data_path import get_target_property_name, get_target_object_path
from io_scene_gltf2.blender.exp import gltf2_blender_gather_animation_sampler_keyframes
@@ -104,7 +105,7 @@ def __gather_output(channels: typing.Tuple[bpy.types.FCurve],
target_datapath = channels[0].data_path
- transform = parent_inverse
+ transform = mathutils.Matrix.Identity(4)
is_yup = export_settings[gltf2_blender_export_keys.YUP]
@@ -113,17 +114,19 @@ def __gather_output(channels: typing.Tuple[bpy.types.FCurve],
if is_armature_animation:
bone = blender_object_if_armature.path_resolve(object_path)
if isinstance(bone, bpy.types.PoseBone):
- if bone.parent is not None:
- parent_transform = bone.parent.bone.matrix_local
- transform = gltf2_blender_math.multiply(transform, parent_transform.inverted())
- # if not is_yup:
- # transform = gltf2_blender_math.multiply(transform, gltf2_blender_math.to_zup())
+ 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)))
+
+ # extract bone transform
+ if bone.parent is None:
+ correction_matrix_local = gltf2_blender_math.multiply(axis_basis_change, bone.bone.matrix_local)
else:
- # only apply the y-up conversion to root bones, as child bones already are in the y-up space
- if is_yup:
- transform = gltf2_blender_math.multiply(transform, gltf2_blender_math.to_yup())
- local_transform = bone.bone.matrix_local
- transform = gltf2_blender_math.multiply(transform, local_transform)
+ correction_matrix_local = gltf2_blender_math.multiply(
+ bone.parent.bone.matrix_local.inverted(), bone.bone.matrix_local)
+
+ transform = gltf2_blender_math.multiply(correction_matrix_local, bone.matrix_basis)
values = []
for keyframe in keyframes:
@@ -132,16 +135,25 @@ def __gather_output(channels: typing.Tuple[bpy.types.FCurve],
if is_yup and not is_armature_animation:
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:
+ # we can directly transform the tangent as it currently is represented by a control point
in_tangent = gltf2_blender_math.transform(keyframe.in_tangent, target_datapath, transform)
if is_yup and blender_object_if_armature is None:
in_tangent = gltf2_blender_math.swizzle_yup(in_tangent, target_datapath)
- keyframe_value = gltf2_blender_math.mathutils_to_gltf(in_tangent) + keyframe_value
+ # the tangent in glTF is relative to the keyframe value
+ in_tangent = value - in_tangent if not isinstance(value, list) else [value[0] - in_tangent[0]]
+ keyframe_value = gltf2_blender_math.mathutils_to_gltf(in_tangent) + keyframe_value # append
+
if keyframe.out_tangent is not None:
+ # we can directly transform the tangent as it currently is represented by a control point
out_tangent = gltf2_blender_math.transform(keyframe.out_tangent, target_datapath, transform)
if is_yup and blender_object_if_armature is None:
out_tangent = gltf2_blender_math.swizzle_yup(out_tangent, target_datapath)
- keyframe_value = keyframe_value + gltf2_blender_math.mathutils_to_gltf(out_tangent)
+ # the tangent in glTF is relative to the keyframe value
+ out_tangent = value - out_tangent if not isinstance(value, list) else [value[0] - out_tangent[0]]
+ keyframe_value = keyframe_value + gltf2_blender_math.mathutils_to_gltf(out_tangent) # append
+
values += keyframe_value
component_type = gltf2_io_constants.ComponentType.Float