@@ -201,7 +201,12 @@ def animation_present(fcurve, kind):
201201
202202 @staticmethod
203203 def matrices_differ (m1 , m2 ):
204-
204+ """
205+ Compare matrices using the export epsilon.
206+ :param m1: Matrix A
207+ :param m2: Matrix B
208+ :return: True if at least one component of A differs significantly form the analog component in B
209+ """
205210 for i in range (4 ):
206211 for j in range (4 ):
207212 if math .fabs (m1 [i ][j ] - m2 [i ][j ]) > k_export_epsilon :
@@ -224,108 +229,130 @@ def export_bone_animation(armature, name):
224229
225230 return curve_array
226231
227- def export_key_times (self , fcurve ):
232+ def export_key_times (self , function_curve ):
228233 """
229- :param fcurve:
234+ Export points of a time curve. Each value on the curve will be offset to the begin frame.
235+ :param function_curve: the curve
230236 :return: a Key DdlStructure
231237 """
232238 return Key (data = [(p .co [0 ] - self .container .beginFrame ) * self .container .frameTime
233- for p in fcurve .keyframe_points ])
239+ for p in function_curve .keyframe_points ])
234240
235- def export_key_time_control_points (self , fcurve ):
241+ def export_key_time_control_points (self , function_curve ):
236242 """
237- :param fcurve:
238- :return: a list of Key DdlStructures
243+ Export handles (/control points) of a time bezier curve. Each handle on the curve will be offset to the begin frame.
244+ :param function_curve: the curve
245+ :return: two Key DdlStructures in a list
239246 """
240247 return [
241248 Key (kind = B"-control" ,
242249 data = [(point .handle_left [0 ] - self .container .beginFrame ) * self .container .frameTime
243- for point in fcurve .keyframe_points ]),
250+ for point in function_curve .keyframe_points ]),
244251 Key (kind = B"+control" ,
245252 data = [(point .handle_right [0 ] - self .container .beginFrame ) * self .container .frameTime
246- for point in fcurve .keyframe_points ])
253+ for point in function_curve .keyframe_points ])
247254 ]
248255
249- def export_key_values (self , fcurve ):
256+ @staticmethod
257+ def export_key_values (function_curve ):
250258 """
251- :param fcurve:
259+ Export points of a value curve.
260+ :param function_curve: the curve
252261 :return: a Key DdlStructure
253262 """
254- return Key (data = [p .co [1 ] for p in fcurve .keyframe_points ])
263+ return Key (data = [p .co [1 ] for p in function_curve .keyframe_points ])
255264
256- def export_key_value_control_points (self , fcurve ):
265+ @staticmethod
266+ def export_key_value_control_points (function_curve ):
257267 """
258- :param fcurve:
259- :return: a list of Key DdlStructures
268+ Export handles (/control points) of a value bezier curve.
269+ :param function_curve: the curve
270+ :return: two Key DdlStructures in a list
260271 """
261272 return [
262- Key (kind = B"-control" , data = [p .handle_left [1 ] for p in fcurve .keyframe_points ]),
263- Key (kind = B"+control" , data = [p .handle_right [1 ] for p in fcurve .keyframe_points ])
273+ Key (kind = B"-control" , data = [p .handle_left [1 ] for p in function_curve .keyframe_points ]),
274+ Key (kind = B"+control" , data = [p .handle_right [1 ] for p in function_curve .keyframe_points ])
264275 ]
265276
266- def export_animation_track (self , fcurve , kind , target ):
267- # TODO doc
277+ def export_animation_track (self , function_curve , kind , target ):
268278 """
269- :param fcurve:
270- :param kind:
271- :param target:
272- :return: a Track DdlStructure
279+ Export a function curve as a Track DDL structure.
280+ :param function_curve: the curve
281+ :param kind: Animation type (linear or bezier)
282+ :param target: the structure that is being animated
283+ :return: the Track DdlStructure
273284 """
274285 # This function exports a single animation track. The curve types for the
275286 # Time and Value structures are given by the kind parameter.
276287 track_struct = Track (target = target )
277288
278289 if kind != k_animation_bezier :
279- # TODO simplify to one iteration over fcurve
280290 track_struct .children .extend ([
281- Time (children = self .export_key_times (fcurve )),
282- Value (children = self .export_key_values (fcurve ))
291+ Time (children = self .export_key_times (function_curve )),
292+ Value (children = self .export_key_values (function_curve ))
283293 ])
284294 else :
285295 track_struct .children .extend ([
286- Time (curve = B"bezier" , children = [self .export_key_times (fcurve )] + self .export_key_time_control_points (fcurve )),
287- Value (curve = B"bezier" , children = [self .export_key_values (fcurve )] + self .export_key_value_control_points (fcurve ))
296+ Time (curve = B"bezier" ,
297+ children = [self .export_key_times (function_curve )] + self .export_key_time_control_points (function_curve )),
298+ Value (curve = B"bezier" ,
299+ children = [self .export_key_values (function_curve )] + self .export_key_value_control_points (function_curve ))
288300 ])
289301
290302 return track_struct
291303
292304 def export_node_sampled_animation (self , nw , node , scene ):
293- # This function exports animation as full 4x4 matrices for each frame.
294-
295- current_frame = scene .frame_current
296- current_subframe = scene .frame_subframe
305+ """
306+ Export animation as full 4x4 matrices for each frame.
307+ :param nw: Node wrapper
308+ :param node: the node to export the animated transforms for
309+ :param scene: the current scene
310+ :return: the created Animation DdlStructure
311+ """
312+ # Save frame settings to later restore
313+ previous_frame = scene .frame_current
314+ previous_subframe = scene .frame_subframe
297315
316+ # if transform for frames is the same, there is no need for animation.
298317 has_animation = False
299- m1 = node .matrix_local .copy ()
300-
318+ first_frame_transform = node .matrix_local .copy ()
301319 for i in range (self .container .beginFrame , self .container .endFrame ):
320+ # matrix_local adapts to the current frame.
302321 scene .frame_set (i )
303- m2 = node .matrix_local
304- if OpenGexExporter .matrices_differ (m1 , m2 ):
322+ cur_frame_transform = node .matrix_local
323+
324+ if OpenGexExporter .matrices_differ (first_frame_transform , cur_frame_transform ):
305325 has_animation = True
306326 break
307327
328+ # if there is an animation, assemble the Animation DdlStructure
308329 animation_struct = None
309330 if has_animation :
331+ # helper to get local transformation matrix at a certain frame index
310332 def get_matrix_local_at_frame (i ):
311333 scene .frame_set (i )
312- return node .matrix_local
334+ blender_matrix = self .handle_offset (node .matrix_local , nw .offset )
335+ return itertools .chain (* zip (* blender_matrix )) # create list of all elements
336+
337+ begin_frame = self .container .beginFrame
338+ end_frame = self .container .endFrame
339+ frame_time = self .container .frameTime
313340
314341 animation_struct = DdlStructure (B"Animation" , children = [
315342 Track (target = B"%transform" , children = [
316343 Time (children = [
317- Key (data = [((i - self .container .beginFrame ) * self .container .frameTime )
318- for i in range (self .container .beginFrame , self .container .endFrame + 1 )])
344+ Key (data = [((i - begin_frame ) * frame_time ) for i in range (begin_frame , end_frame + 1 )])
319345 ]),
320346 Value (children = [
321- Key (vector_size = 16 , data = [itertools .chain (* zip (* self .handle_offset (get_matrix_local_at_frame (i ),
322- nw .offset )))
323- for i in range (self .container .beginFrame , self .container .endFrame + 1 )])
347+ Key (data = [get_matrix_local_at_frame (i ) for i in range (begin_frame , end_frame + 1 )],
348+ vector_size = 16 )
324349 ])
325350 ])
326351 ])
327352
328- scene .frame_set (current_frame , current_subframe )
353+ # restore "current frame" settings
354+ scene .frame_set (previous_frame , previous_subframe )
355+
329356 return animation_struct
330357
331358 def export_bone_sampled_animation (self , pose_bone , scene ):
0 commit comments