1 # SPDX-License-Identifier: Apache-2.0
2 # Copyright 2018-2021 The glTF-Blender-IO authors.
6 from ...io
.imp
.gltf2_io_binary
import BinaryData
7 from .gltf2_blender_animation_utils
import make_fcurve
8 from io_scene_gltf2
.io
.imp
.gltf2_io_user_extensions
import import_user_extensions
11 class BlenderWeightAnim():
12 """Blender ShapeKey Animation."""
13 def __new__(cls
, *args
, **kwargs
):
14 raise RuntimeError("%s should not be instantiated" % cls
)
17 def anim(gltf
, anim_idx
, vnode_id
):
18 """Manage animation."""
19 vnode
= gltf
.vnodes
[vnode_id
]
21 node_idx
= vnode
.mesh_node_idx
23 import_user_extensions('gather_import_animation_weight_before_hook', gltf
, vnode
, gltf
.data
.animations
[anim_idx
])
28 node
= gltf
.data
.nodes
[node_idx
]
29 obj
= vnode
.blender_object
30 fps
= bpy
.context
.scene
.render
.fps
32 animation
= gltf
.data
.animations
[anim_idx
]
34 if anim_idx
not in node
.animations
.keys():
37 for channel_idx
in node
.animations
[anim_idx
]:
38 channel
= animation
.channels
[channel_idx
]
39 if channel
.target
.path
== "weights":
44 name
= animation
.track_name
+ "_" + obj
.name
45 action
= bpy
.data
.actions
.new(name
)
46 action
.id_root
= "KEY"
47 gltf
.needs_stash
.append((obj
.data
.shape_keys
, action
))
49 keys
= BinaryData
.get_data_from_accessor(gltf
, animation
.samplers
[channel
.sampler
].input)
50 values
= BinaryData
.get_data_from_accessor(gltf
, animation
.samplers
[channel
.sampler
].output
)
52 # retrieve number of targets
53 pymesh
= gltf
.data
.meshes
[gltf
.data
.nodes
[node_idx
].mesh
]
54 nb_targets
= len(pymesh
.shapekey_names
)
56 if animation
.samplers
[channel
.sampler
].interpolation
== "CUBICSPLINE":
58 stride
= 3 * nb_targets
63 coords
= [0] * (2 * len(keys
))
64 coords
[::2] = (key
[0] * fps
for key
in keys
)
66 for sk
in range(nb_targets
):
67 if pymesh
.shapekey_names
[sk
] is not None: # Do not animate shapekeys not created
68 coords
[1::2] = (values
[offset
+ stride
* i
+ sk
][0] for i
in range(len(keys
)))
69 kb_name
= pymesh
.shapekey_names
[sk
]
70 data_path
= 'key_blocks["%s"].value' % bpy
.utils
.escape_identifier(kb_name
)
76 group_name
="ShapeKeys",
77 interpolation
=animation
.samplers
[channel
.sampler
].interpolation
,
80 # Expand weight range if needed
81 kb
= obj
.data
.shape_keys
.key_blocks
[kb_name
]
82 min_weight
= min(coords
[1:2])
83 max_weight
= max(coords
[1:2])
84 if min_weight
< kb
.slider_min
: kb
.slider_min
= min_weight
85 if max_weight
> kb
.slider_max
: kb
.slider_max
= max_weight
87 import_user_extensions('gather_import_animation_weight_after_hook', gltf
, vnode
, animation
)