Skip to content

Commit b4bc767

Browse files
verteAzurmrdoob
authored andcommitted
Update animation.py (mrdoob#9272)
bones scaling support: remove hard coded values, add _scale & _handle_scale_channel functions + tested export and import
1 parent 3eb5223 commit b4bc767

File tree

1 file changed

+98
-5
lines changed
  • utils/exporters/blender/addons/io_three/exporter/api

1 file changed

+98
-5
lines changed

utils/exporters/blender/addons/io_three/exporter/api/animation.py

Lines changed: 98 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""
22
Module for handling the parsing of skeletal animation data.
3+
updated on 2/07/2016: bones scaling support (@uthor verteAzur verteAzur@multivers3d.fr)
34
"""
45

56
import math
@@ -91,18 +92,22 @@ def _parse_rest_action(action, armature, options):
9192
action, rotation_matrix)
9293
rot = _normalize_quaternion(rot)
9394

95+
sca, schange = _scale(bone, computed_frame,
96+
action, armature.matrix_world)
97+
9498
pos_x, pos_y, pos_z = pos.x, pos.z, -pos.y
9599
rot_x, rot_y, rot_z, rot_w = rot.x, rot.z, -rot.y, rot.w
100+
sca_x, sca_y, sca_z = sca.x, sca.z, sca.y
96101

97102
if frame == start_frame:
98103

99104
time = (frame * frame_step - start_frame) / fps
100-
# @TODO: missing scale values
105+
101106
keyframe = {
102107
constants.TIME: time,
103108
constants.POS: [pos_x, pos_y, pos_z],
104109
constants.ROT: [rot_x, rot_y, rot_z, rot_w],
105-
constants.SCL: [1, 1, 1]
110+
constants.SCL: [sca_x, sca_y, sca_z]
106111
}
107112
keys.append(keyframe)
108113

@@ -116,22 +121,23 @@ def _parse_rest_action(action, armature, options):
116121
constants.TIME: time,
117122
constants.POS: [pos_x, pos_y, pos_z],
118123
constants.ROT: [rot_x, rot_y, rot_z, rot_w],
119-
constants.SCL: [1, 1, 1]
124+
constants.SCL: [sca_x, sca_y, sca_z]
120125
}
121126
keys.append(keyframe)
122127

123128
# MIDDLE-FRAME: needs only one of the attributes,
124129
# can be an empty frame (optional frame)
125130

126-
elif pchange is True or rchange is True:
131+
elif pchange is True or rchange is True or schange is True:
127132

128133
time = (frame * frame_step - start_frame) / fps
129134

130135
if pchange is True and rchange is True:
131136
keyframe = {
132137
constants.TIME: time,
133138
constants.POS: [pos_x, pos_y, pos_z],
134-
constants.ROT: [rot_x, rot_y, rot_z, rot_w]
139+
constants.ROT: [rot_x, rot_y, rot_z, rot_w],
140+
constants.SCL: [sca_x, sca_y, sca_z]
135141
}
136142
elif pchange is True:
137143
keyframe = {
@@ -143,6 +149,11 @@ def _parse_rest_action(action, armature, options):
143149
constants.TIME: time,
144150
constants.ROT: [rot_x, rot_y, rot_z, rot_w]
145151
}
152+
elif schange is True:
153+
keyframe = {
154+
constants.TIME: time,
155+
constants.SCL: [sca_x, sca_y, sca_z]
156+
}
146157

147158
keys.append(keyframe)
148159

@@ -495,6 +506,60 @@ def _rotation(bone, frame, action, armature_matrix):
495506

496507
return rotation, change
497508

509+
def _scale(bone, frame, action, armature_matrix):
510+
"""
511+
512+
:param bone:
513+
:param frame:
514+
:param action:
515+
:param armature_matrix:
516+
517+
"""
518+
scale = mathutils.Vector((0.0, 0.0, 0.0))
519+
520+
change = False
521+
522+
ngroups = len(action.groups)
523+
524+
# animation grouped by bones
525+
526+
if ngroups > 0:
527+
528+
index = -1
529+
530+
for i in range(ngroups):
531+
if action.groups[i].name == bone.name:
532+
533+
print(action.groups[i].name)
534+
535+
index = i
536+
537+
if index > -1:
538+
for channel in action.groups[index].channels:
539+
540+
if "scale" in channel.data_path:
541+
has_changed = _handle_scale_channel(
542+
channel, frame, scale)
543+
change = change or has_changed
544+
545+
# animation in raw fcurves
546+
547+
else:
548+
549+
bone_label = '"%s"' % bone.name
550+
551+
for channel in action.fcurves:
552+
data_path = channel.data_path
553+
if bone_label in data_path and "scale" in data_path:
554+
has_changed = _handle_scale_channel(
555+
channel, frame, scale)
556+
change = change or has_changed
557+
558+
559+
#scale.xyz = armature_matrix * scale.xyz
560+
561+
return scale, change
562+
498563

499564
def _handle_rotation_channel(channel, frame, rotation):
500565
"""
@@ -559,6 +624,34 @@ def _handle_position_channel(channel, frame, position):
559624

560625
return change
561626

627+
def _handle_scale_channel(channel, frame, scale):
628+
"""
629+
630+
:param channel:
631+
:param frame:
632+
:param position:
633+
634+
"""
635+
change = False
636+
637+
if channel.array_index in [0, 1, 2]:
638+
for keyframe in channel.keyframe_points:
639+
if keyframe.co[0] == frame:
640+
change = True
641+
642+
value = channel.evaluate(frame)
643+
644+
if channel.array_index == 0:
645+
scale.x = value
646+
647+
if channel.array_index == 1:
648+
scale.y = value
649+
650+
if channel.array_index == 2:
651+
scale.z = value
652+
653+
return change
654+
562655

563656
def _quaternion_length(quat):
564657
"""Calculate the length of a quaternion

0 commit comments

Comments
 (0)