1 # SPDX-FileCopyrightText: 2018-2021 The glTF-Blender-IO authors
3 # SPDX-License-Identifier: Apache-2.0
7 from ...io
.imp
.gltf2_io_user_extensions
import import_user_extensions
8 from ...io
.imp
.gltf2_io_binary
import BinaryData
9 from .gltf2_blender_animation_utils
import make_fcurve
12 class BlenderWeightAnim():
13 """Blender ShapeKey Animation."""
14 def __new__(cls
, *args
, **kwargs
):
15 raise RuntimeError("%s should not be instantiated" % cls
)
18 def anim(gltf
, anim_idx
, vnode_id
):
19 """Manage animation."""
20 vnode
= gltf
.vnodes
[vnode_id
]
22 node_idx
= vnode
.mesh_node_idx
24 import_user_extensions('gather_import_animation_weight_before_hook', gltf
, vnode
, gltf
.data
.animations
[anim_idx
])
29 node
= gltf
.data
.nodes
[node_idx
]
30 obj
= vnode
.blender_object
31 fps
= (bpy
.context
.scene
.render
.fps
* bpy
.context
.scene
.render
.fps_base
)
33 animation
= gltf
.data
.animations
[anim_idx
]
35 if anim_idx
not in node
.animations
.keys():
38 for channel_idx
in node
.animations
[anim_idx
]:
39 channel
= animation
.channels
[channel_idx
]
40 if channel
.target
.path
== "weights":
42 if channel
.target
.path
== "pointer":
43 pointer_tab
= channel
.target
.extensions
["KHR_animation_pointer"]["pointer"].split("/")
44 if len(pointer_tab
) >= 4 and pointer_tab
[1] in ["nodes", "meshes"] and pointer_tab
[3] == "weights":
49 name
= animation
.track_name
+ "_" + obj
.name
50 action
= bpy
.data
.actions
.new(name
)
51 action
.id_root
= "KEY"
52 gltf
.needs_stash
.append((obj
.data
.shape_keys
, action
))
54 keys
= BinaryData
.get_data_from_accessor(gltf
, animation
.samplers
[channel
.sampler
].input)
55 values
= BinaryData
.get_data_from_accessor(gltf
, animation
.samplers
[channel
.sampler
].output
)
57 # retrieve number of targets
58 pymesh
= gltf
.data
.meshes
[gltf
.data
.nodes
[node_idx
].mesh
]
59 nb_targets
= len(pymesh
.shapekey_names
)
61 if animation
.samplers
[channel
.sampler
].interpolation
== "CUBICSPLINE":
63 stride
= 3 * nb_targets
68 coords
= [0] * (2 * len(keys
))
69 coords
[::2] = (key
[0] * fps
for key
in keys
)
71 for sk
in range(nb_targets
):
72 if pymesh
.shapekey_names
[sk
] is not None: # Do not animate shapekeys not created
73 coords
[1::2] = (values
[offset
+ stride
* i
+ sk
][0] for i
in range(len(keys
)))
74 kb_name
= pymesh
.shapekey_names
[sk
]
75 data_path
= 'key_blocks["%s"].value' % bpy
.utils
.escape_identifier(kb_name
)
81 group_name
="ShapeKeys",
82 interpolation
=animation
.samplers
[channel
.sampler
].interpolation
,
85 # Expand weight range if needed
86 kb
= obj
.data
.shape_keys
.key_blocks
[kb_name
]
87 min_weight
= min(coords
[1:2])
88 max_weight
= max(coords
[1:2])
89 if min_weight
< kb
.slider_min
: kb
.slider_min
= min_weight
90 if max_weight
> kb
.slider_max
: kb
.slider_max
= max_weight
92 import_user_extensions('gather_import_animation_weight_after_hook', gltf
, vnode
, animation
)