[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2690] contrib/py/scripts/addons/ animation_motion_trail.py: Moving from upload to contrib.
Bart Crouch
bartius.crouch at gmail.com
Thu Dec 1 09:50:08 CET 2011
Revision: 2690
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2690
Author: crouch
Date: 2011-12-01 08:49:59 +0000 (Thu, 01 Dec 2011)
Log Message:
-----------
Moving from upload to contrib.
Added Paths:
-----------
contrib/py/scripts/addons/animation_motion_trail.py
Added: contrib/py/scripts/addons/animation_motion_trail.py
===================================================================
--- contrib/py/scripts/addons/animation_motion_trail.py (rev 0)
+++ contrib/py/scripts/addons/animation_motion_trail.py 2011-12-01 08:49:59 UTC (rev 2690)
@@ -0,0 +1,1736 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+
+bl_info = {
+ 'name': "Motion Trail",
+ 'author': "Bart Crouch",
+ 'version': (3, 1, 0),
+ 'blender': (2, 6, 0),
+ 'api': 42181,
+ 'location': "View3D > Toolbar > Motion Trail tab",
+ 'warning': "",
+ 'description': "Display and edit motion trails in the 3d-view",
+ 'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.5/"\
+ "Py/Scripts/Animation/Motion_Trail",
+ 'tracker_url': "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=26374",
+ 'category': 'Animation'}
+
+
+import bgl
+import blf
+import bpy
+from bpy_extras import view3d_utils
+import math
+import mathutils
+
+
+# fake fcurve class, used if no fcurve is found for a path
+class fake_fcurve():
+ def __init__(self, object, index, rotation=False, scale=False):
+ # location
+ if not rotation and not scale:
+ self.loc = object.location[index]
+ # scale
+ elif scale:
+ self.loc = object.scale[index]
+ # rotation
+ elif rotation == 'QUATERNION':
+ self.loc = object.rotation_quaternion[index]
+ elif rotation == 'AXIS_ANGLE':
+ self.loc = object.rotation_axis_angle[index]
+ else:
+ self.loc = object.rotation_euler[index]
+ self.keyframe_points = []
+
+ def evaluate(self, frame):
+ return(self.loc)
+
+ def range(self):
+ return([])
+
+
+# get location curves of the given object
+def get_curves(object, child=False):
+ if object.animation_data and object.animation_data.action:
+ action = object.animation_data.action
+ if child:
+ # posebone
+ curves = [fc for fc in action.fcurves if len(fc.data_path)>=14 \
+ and fc.data_path[-9:]=='.location' and \
+ child.name in fc.data_path.split("\"")]
+ else:
+ # normal object
+ curves = [fc for fc in action.fcurves if \
+ fc.data_path == 'location']
+ elif object.animation_data and object.animation_data.use_nla:
+ curves = []
+ strips = []
+ for track in object.animation_data.nla_tracks:
+ not_handled = [s for s in track.strips]
+ while not_handled:
+ current_strip = not_handled.pop(-1)
+ if current_strip.action:
+ strips.append(current_strip)
+ if current_strip.strips:
+ # meta strip
+ not_handled += [s for s in current_strip.strips]
+
+ for strip in strips:
+ if child:
+ # posebone
+ curves = [fc for fc in strip.action.fcurves if \
+ len(fc.data_path)>=14 and fc.data_path[-9:]=='.location' \
+ and child.name in fc.data_path.split("\"")]
+ else:
+ # normal object
+ curves = [fc for fc in strip.action.fcurves if \
+ fc.data_path == 'location']
+ if curves:
+ # use first strip with location fcurves
+ break
+ else:
+ # should not happen?
+ curves = []
+
+ # ensure we have three curves per object
+ fcx = None
+ fcy = None
+ fcz = None
+ for fc in curves:
+ if fc.array_index == 0:
+ fcx = fc
+ elif fc.array_index == 1:
+ fcy = fc
+ elif fc.array_index == 2:
+ fcz = fc
+ if fcx == None:
+ fcx = fake_fcurve(object, 0)
+ if fcy == None:
+ fcy = fake_fcurve(object, 1)
+ if fcz == None:
+ fcz = fake_fcurve(object, 2)
+
+ return([fcx, fcy, fcz])
+
+
+# turn screen coordinates (x,y) into world coordinates vector
+def screen_to_world(context, x, y):
+ depth_vector = view3d_utils.region_2d_to_vector_3d(\
+ context.region, context.region_data, [x,y])
+ vector = view3d_utils.region_2d_to_location_3d(\
+ context.region, context.region_data, [x,y], depth_vector)
+
+ return(vector)
+
+
+# turn 3d world coordinates vector into screen coordinate integers (x,y)
+def world_to_screen(context, vector):
+ prj = context.region_data.perspective_matrix * \
+ mathutils.Vector((vector[0], vector[1], vector[2], 1.0))
+ width_half = context.region.width / 2.0
+ height_half = context.region.height / 2.0
+
+ x = int(width_half + width_half * (prj.x / prj.w))
+ y = int(height_half + height_half * (prj.y / prj.w))
+
+ # correction for corner cases in perspective mode
+ if prj.w < 0:
+ if x < 0:
+ x = context.region.width * 2
+ else:
+ x = context.region.width * -2
+ if y < 0:
+ y = context.region.height * 2
+ else:
+ y = context.region.height * -2
+
+ return(x, y)
+
+
+# calculate location of display_ob in worldspace
+def get_location(frame, display_ob, offset_ob, curves):
+ if offset_ob:
+ bpy.context.scene.frame_set(frame)
+ display_mat = getattr(display_ob, "matrix", False)
+ if not display_mat:
+ # posebones have "matrix", objects have "matrix_world"
+ display_mat = display_ob.matrix_world
+ if offset_ob:
+ loc = display_mat.to_translation() + \
+ offset_ob.matrix_world.to_translation()
+ else:
+ loc = display_mat.to_translation()
+ else:
+ fcx, fcy, fcz = curves
+ locx = fcx.evaluate(frame)
+ locy = fcy.evaluate(frame)
+ locz = fcz.evaluate(frame)
+ loc = mathutils.Vector([locx, locy, locz])
+
+ return(loc)
+
+
+# get position of keyframes and handles at the start of dragging
+def get_original_animation_data(context, keyframes):
+ keyframes_ori = {}
+ handles_ori = {}
+
+ if context.active_object and context.active_object.mode == 'POSE':
+ armature_ob = context.active_object
+ objects = [[armature_ob, pb, armature_ob] for pb in \
+ context.selected_pose_bones]
+ else:
+ objects = [[ob, False, False] for ob in context.selected_objects]
+
+ for action_ob, child, offset_ob in objects:
+ if not action_ob.animation_data:
+ continue
+ curves = get_curves(action_ob, child)
+ if len(curves) == 0:
+ continue
+ fcx, fcy, fcz = curves
+ if child:
+ display_ob = child
+ else:
+ display_ob = action_ob
+
+ # get keyframe positions
+ frame_old = context.scene.frame_current
+ keyframes_ori[display_ob.name] = {}
+ for frame in keyframes[display_ob.name]:
+ loc = get_location(frame, display_ob, offset_ob, curves)
+ keyframes_ori[display_ob.name][frame] = [frame, loc]
+
+ # get handle positions
+ handles_ori[display_ob.name] = {}
+ for frame in keyframes[display_ob.name]:
+ handles_ori[display_ob.name][frame] = {}
+ left_x = [frame, fcx.evaluate(frame)]
+ right_x = [frame, fcx.evaluate(frame)]
+ for kf in fcx.keyframe_points:
+ if kf.co[0] == frame:
+ left_x = kf.handle_left[:]
+ right_x = kf.handle_right[:]
+ break
+ left_y = [frame, fcy.evaluate(frame)]
+ right_y = [frame, fcy.evaluate(frame)]
+ for kf in fcy.keyframe_points:
+ if kf.co[0] == frame:
+ left_y = kf.handle_left[:]
+ right_y = kf.handle_right[:]
+ break
+ left_z = [frame, fcz.evaluate(frame)]
+ right_z = [frame, fcz.evaluate(frame)]
+ for kf in fcz.keyframe_points:
+ if kf.co[0] == frame:
+ left_z = kf.handle_left[:]
+ right_z = kf.handle_right[:]
+ break
+ handles_ori[display_ob.name][frame]["left"] = [left_x, left_y,
+ left_z]
+ handles_ori[display_ob.name][frame]["right"] = [right_x, right_y,
+ right_z]
+
+ if context.scene.frame_current != frame_old:
+ context.scene.frame_set(frame_old)
+
+ return(keyframes_ori, handles_ori)
+
+
+# callback function that calculates positions of all things that need be drawn
+def calc_callback(self, context):
+ if context.active_object and context.active_object.mode == 'POSE':
+ armature_ob = context.active_object
+ objects = [[armature_ob, pb, armature_ob] for pb in \
+ context.selected_pose_bones]
+ else:
+ objects = [[ob, False, False] for ob in context.selected_objects]
+ if objects == self.displayed:
+ selection_change = False
+ else:
+ selection_change = True
+
+ if self.lock and not selection_change and \
+ context.region_data.perspective_matrix == self.perspective and not \
+ context.window_manager.motion_trail.force_update:
+ return
+
+ # dictionaries with key: objectname
+ self.paths = {} # value: list of lists with x, y, colour
+ self.keyframes = {} # value: dict with frame as key and [x,y] as value
+ self.handles = {} # value: dict of dicts
+ self.timebeads = {} # value: dict with frame as key and [x,y] as value
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list