]> git.tdb.fi Git - libs/gl.git/blobdiff - blender/io_mspgl/animation.py
Add exporter for animations
[libs/gl.git] / blender / io_mspgl / animation.py
diff --git a/blender/io_mspgl/animation.py b/blender/io_mspgl/animation.py
new file mode 100644 (file)
index 0000000..5ad937d
--- /dev/null
@@ -0,0 +1,88 @@
+import mathutils
+
+class Curve:
+       def __init__(self, curve):
+               self._curve = curve
+               self.knots = []
+
+               for i in range(len(self.keyframe_points)-1):
+                       kf1 = self.keyframe_points[i]
+                       kf2 = self.keyframe_points[i+1]
+                       dx = (kf2.co[0]-kf1.co[0])/3
+                       slope1 = (kf1.handle_right[1]-kf1.co[1])/(kf1.handle_right[0]-kf1.co[0])
+                       slope2 = (kf2.co[1]-kf2.handle_left[1])/(kf2.co[0]-kf2.handle_left[0])
+
+                       if i==0:
+                               self.knots.append(mathutils.Vector(kf1.co))
+                       self.knots.append(kf1.co+mathutils.Vector((dx, slope1*dx)))
+                       self.knots.append(kf2.co-mathutils.Vector((dx, slope2*dx)))
+                       self.knots.append(mathutils.Vector(kf2.co))
+
+       def __getattr__(self, attr):
+               return getattr(self._curve, attr)
+
+
+class Keyframe:
+       def __init__(self, time):
+               self.time = time
+               self.control = False
+               self.curves = []
+
+
+class Animation:
+       def __init__(self, action):
+               self._action = action
+               self.curves = [Curve(c) for c in action.fcurves]
+               self.fps = 1
+
+               for c in self.curves:
+                       for i in range(0, len(c.knots)-1, 3):
+                               p0 = c.knots[i]
+                               p1 = c.knots[i+1]
+                               p2 = c.knots[i+2]
+                               p3 = c.knots[i+3]
+                               for j in range(50):
+                                       t = (p0[0]*(50-j)+p3[0]*j)/50
+                                       x = (t-p0[0])/(p3[0]-p0[0])
+                                       v1 = c._curve.evaluate(t)
+                                       v2 = p0[1]*(1-x)**3+3*p1[1]*x*(1-x)**2+3*p2[1]*x**2*(1-x)+p3[1]*x**3
+
+               keyframes_by_time = {}
+               controls_by_time = {}
+               self.keyframes = []
+               for c in self.curves:
+                       for i, k in enumerate(c.knots):
+                               x = k[0]
+                               control = i%3!=0
+                               kf_map = controls_by_time if control else keyframes_by_time
+                               if x in kf_map:
+                                       kf = kf_map[x]
+                               else:
+                                       kf = Keyframe(x)
+                                       kf.control = control
+                                       self.keyframes.append(kf)
+                                       kf_map[x] = kf
+                               kf.curves.append((c, i))
+
+               self.keyframes.sort(key=lambda k: k.time)
+
+       def __getattr__(self, attr):
+               return getattr(self._curve, attr)
+
+       def change_fps(self, fps):
+               scale = self.fps/fps
+               self.fps = fps
+
+               for c in self.curves:
+                       for k in c.knots:
+                               k[0] *= scale
+
+               for k in self.keyframes:
+                       k.time *= scale
+
+
+def create_animation_from_action(context, action):
+       anim = Animation(action)
+       render = context.scene.render
+       anim.change_fps(render.fps/render.fps_base)
+       return anim