From 569abc900f42d8e7b70520e2c9ef8a5547878266 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 16 Jun 2019 11:52:27 +0300 Subject: [PATCH] Add looping detection to animation exporter Since Blender's actions do not have a looping property, detect looping by comparing the first and last keyframes of each curve. --- blender/io_mspgl/__init__.py | 2 ++ blender/io_mspgl/animation.py | 23 ++++++++++++++++++++++- blender/io_mspgl/export_animation.py | 5 ++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/blender/io_mspgl/__init__.py b/blender/io_mspgl/__init__.py index f0cb6579..3ce60c4c 100644 --- a/blender/io_mspgl/__init__.py +++ b/blender/io_mspgl/__init__.py @@ -98,6 +98,7 @@ class ExportMspGLAnimation(bpy.types.Operator, ExportMspGLBase): export_all = bpy.props.BoolProperty(name="Export all animations", description="Export all animations present on the selected objects' NLA tracks") collection = bpy.props.BoolProperty(name="As a collection", description="Export the animations as a single collection file", default=True) + looping_threshold = bpy.props.FloatProperty(name="Looping threshold", description="Tolerance for curve beginning and end values for looping", min=0.0, soft_max=1.0, precision=4, default=0.001) def check(self, context): result = False @@ -122,6 +123,7 @@ class ExportMspGLAnimation(bpy.types.Operator, ExportMspGLBase): col.prop(self, "export_all") if self.export_all: col.prop(self, "collection") + col.prop(self, "looping_threshold") class ExportMspGLScene(bpy.types.Operator, ExportMspGLBase): bl_idname = "export_scene.mspgl_scene" diff --git a/blender/io_mspgl/animation.py b/blender/io_mspgl/animation.py index ffce11f5..59f34b4d 100644 --- a/blender/io_mspgl/animation.py +++ b/blender/io_mspgl/animation.py @@ -1,3 +1,4 @@ +import math import mathutils class Curve: @@ -34,6 +35,7 @@ class Animation: self._action = action self.curves = [Curve(c) for c in action.fcurves] self.fps = 1 + self.looping = False for c in self.curves: for i in range(0, len(c.knots)-1, 3): @@ -77,6 +79,24 @@ class Animation: def __getattr__(self, attr): return getattr(self._curve, attr) + def check_looping(self, threshold): + self.looping = True + for c in self.curves: + first_y = c.knots[0][1] + last_y = c.knots[-1][1] + d = abs(last_y-first_y) + + if c.data_path=="rotation_euler": + while d>math.pi/2: + d -= math.pi + while d<-math.pi/2: + d += math.pi + + print("Difference for {} {} is {}".format(c.data_path, c.array_index, d)) + if d>threshold: + self.looping = False + break + def change_fps(self, fps): scale = self.fps/fps self.fps = fps @@ -89,8 +109,9 @@ class Animation: k.time *= scale -def create_animation_from_action(context, action): +def create_animation_from_action(context, action, *, looping_threshold=0.001): anim = Animation(action) render = context.scene.render + anim.check_looping(looping_threshold) anim.change_fps(render.fps/render.fps_base) return anim diff --git a/blender/io_mspgl/export_animation.py b/blender/io_mspgl/export_animation.py index e2c7733d..0d72edb4 100644 --- a/blender/io_mspgl/export_animation.py +++ b/blender/io_mspgl/export_animation.py @@ -5,6 +5,7 @@ class AnimationExporter: def __init__(self): self.export_all = False self.collection = True + self.looping_threshold = 0.001 def export_to_file(self, context, out_fn): if self.export_all: @@ -55,7 +56,7 @@ class AnimationExporter: def export_animation(self, context, action): from .animation import create_animation_from_action - anim = create_animation_from_action(context, action) + anim = create_animation_from_action(context, action, looping_threshold=self.looping_threshold) from .datafile import Resource, Statement resource = Resource(action.name+".anim") @@ -100,5 +101,7 @@ class AnimationExporter: resource.statements.append(st) + resource.statements.append(Statement("looping", anim.looping)) + return resource -- 2.43.0