# ---------
# Tested on Blender 2.75a and 2.76
# For a given object, makes an empty, which moves to indicate the velocity (displacement between frames) for each axis of the original object
# and another empty providing magnitude of the movement
# and another empty providing accumulative displacement for each axis,
# and yet another for acceleration.
# To run, select object, generate a motion path for the object (Editor>Motion Paths) across the total desired frame range, and Run Script.
# Bret Battey / BatHatMedia.com Dec 2015
# ---------
import bpy
from bpy.props import *
from mathutils import *
from math import *
import time
# ----- FUNCTION DEFINITIONS -----
# Time utils thanks to http://blenderscripting.blogspot.co.uk/search/label/time
def get_last_time():
if len(time_list) < 2:
return "ERROR: must have two time entries to calculate the difference"
return time_list[-1] - time_list[-2]
def mark_time():
time_list.append(time.time())
time_list = []
# ------------- SCRIPT START
object = bpy.context.object
path = object.motion_path
frame_start = path.frame_start
frame_end = path.frame_end
path_length = path.length
# velocity empty
bpy.ops.object.empty_add(type='PLAIN_AXES', radius=1, view_align=False, location=(0,0,0), layers=object.layers)
velempty = bpy.context.object
velempty.name = object.name + '_velocity'
# vector magnitude
bpy.ops.object.empty_add(type='PLAIN_AXES', radius=1, view_align=False, location=(0,0,0), layers=object.layers)
magempty = bpy.context.object
magempty.name = object.name + '_magnitude'
# accumulative distance traveled
bpy.ops.object.empty_add(type='PLAIN_AXES', radius=1, view_align=False, location=(0,0,0), layers=object.layers)
accumempty = bpy.context.object
accumempty.name = object.name + '_accum_distance'
# acceleration
bpy.ops.object.empty_add(type='PLAIN_AXES', radius=1, view_align=False, location=(0,0,0), layers=object.layers)
accelempty = bpy.context.object
accelempty.name = object.name + '_acceleration'
mark_time() # start measuring elapsed time
for i in range(0,path_length-2): # motion path index
nextPointCo = path.points[i+1].co # next time point
thisPointCo = path.points[i].co # this time point
dif = nextPointCo-thisPointCo # x,y,z distances
mag = sqrt(dif[0]*dif[0]+dif[1]*dif[1]+dif[2]*dif[2]) # vector magnitude via pythagorean theorem
velempty.location = dif # set vel empty's location to the velocity vector
magempty.location[2] = mag # set z position of mag empty's location to the magnitude
frame = frame_start+i # get absolute frame number
velempty.keyframe_insert(data_path='location',frame=frame,index=-1) # set keyframe for velocity. index -1 = set all three axes
magempty.keyframe_insert(data_path='location',frame=frame,index=2) # set keyframe for velocity. index -1 = set all three axes
if i == 0:
accumempty.keyframe_insert(data_path='location',frame=frame,index=-1) # set keyframe. index -1 = set all three axes
accumdif = accumempty.location # start accumulated distance with a convenient 0,0,0 vector
else:
accumdif[0] += abs(dif[0]) # add absolute value of velocity to the accumulative distance
accumdif[1] += abs(dif[1])
accumdif[2] += abs(dif[2])
accumempty.location = accumdif # move empty to this point
accumempty.keyframe_insert(data_path='location',frame=frame,index=-1) # set keyframe. index -1 = set all three axes
accelempty.location = dif-lastdif # acceleration = dif between this frame's velocity and the previous frame's
accelempty.keyframe_insert(data_path='location',frame=frame-1,index=-1) # set keyframe ONE FRAME BACK. index -1 = set all three axes
lastdif = dif
mark_time()
print('The keyframing took {: 5g} seconds'.format(get_last_time()))
Bret Battey blogging sundry ideas, favorable events, works in progress, and miscellaneous solutions in digital music and video-music research and creation. I see this as a subsidiary of my web site, BatHatMedia.com.
Tuesday, February 16, 2016
Blender Script for object-motion measurements
In Blender, given an object that has a motion path, will provide animated empties which indicate the object's velocity, acceleration, magnitude, and accumulated distance moved.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment