1
1
"""
2
2
Module for handling the parsing of skeletal animation data.
3
+ updated on 2/07/2016: bones scaling support (@uthor verteAzur verteAzur@multivers3d.fr)
3
4
"""
4
5
5
6
import math
@@ -91,18 +92,22 @@ def _parse_rest_action(action, armature, options):
91
92
action , rotation_matrix )
92
93
rot = _normalize_quaternion (rot )
93
94
95
+ sca , schange = _scale (bone , computed_frame ,
96
+ action , armature .matrix_world )
97
+
94
98
pos_x , pos_y , pos_z = pos .x , pos .z , - pos .y
95
99
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
96
101
97
102
if frame == start_frame :
98
103
99
104
time = (frame * frame_step - start_frame ) / fps
100
- # @TODO: missing scale values
105
+
101
106
keyframe = {
102
107
constants .TIME : time ,
103
108
constants .POS : [pos_x , pos_y , pos_z ],
104
109
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 ]
106
111
}
107
112
keys .append (keyframe )
108
113
@@ -116,22 +121,23 @@ def _parse_rest_action(action, armature, options):
116
121
constants .TIME : time ,
117
122
constants .POS : [pos_x , pos_y , pos_z ],
118
123
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 ]
120
125
}
121
126
keys .append (keyframe )
122
127
123
128
# MIDDLE-FRAME: needs only one of the attributes,
124
129
# can be an empty frame (optional frame)
125
130
126
- elif pchange is True or rchange is True :
131
+ elif pchange is True or rchange is True or schange is True :
127
132
128
133
time = (frame * frame_step - start_frame ) / fps
129
134
130
135
if pchange is True and rchange is True :
131
136
keyframe = {
132
137
constants .TIME : time ,
133
138
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 ]
135
141
}
136
142
elif pchange is True :
137
143
keyframe = {
@@ -143,6 +149,11 @@ def _parse_rest_action(action, armature, options):
143
149
constants .TIME : time ,
144
150
constants .ROT : [rot_x , rot_y , rot_z , rot_w ]
145
151
}
152
+ elif schange is True :
153
+ keyframe = {
154
+ constants .TIME : time ,
155
+ constants .SCL : [sca_x , sca_y , sca_z ]
156
+ }
146
157
147
158
keys .append (keyframe )
148
159
@@ -495,6 +506,60 @@ def _rotation(bone, frame, action, armature_matrix):
495
506
496
507
return rotation , change
497
508
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
+
498
563
499
564
def _handle_rotation_channel (channel , frame , rotation ):
500
565
"""
@@ -559,6 +624,34 @@ def _handle_position_channel(channel, frame, position):
559
624
560
625
return change
561
626
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
+
562
655
563
656
def _quaternion_length (quat ):
564
657
"""Calculate the length of a quaternion
0 commit comments