Skip to content

Commit c084e72

Browse files
committed
Improve code for animation export and add code doc
Signed-off-by: Squareys <Squareys@googlemail.com>
1 parent 89ca571 commit c084e72

1 file changed

Lines changed: 70 additions & 43 deletions

File tree

src/io_scene_ogex/OpenGexExporter.py

Lines changed: 70 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)