Here is an addon to do that (if my comprehension of the question is good).

To make it work, you need to associate the wanted objects (empties) in an object's group.
Then:
- Choose the group in the UI
- Set min and max values (the scramble part will take 3 random values in between and shift x, y, z with them)
- Choose a seed if you want to repeat it with the same random sequence
- Use the scramble button.
The scramble function is commented in the code below (other parts are simple UI):
bl_info = {
"name": "Scramble animation locations",
"author": "lemon",
"version": (1, 0),
"blender": (2, 78, 0),
"location": "",
"description": "",
"warning": "",
"wiki_url": "",
"category": "Animation"}
import bpy
from random import Random
def ScrambleObjectAnimation( object, scrambleMin, scrambleMax, rnd ):
#If there is an animation
if object.animation_data:
#Get random values to shift/scramble x y and z
dx = rnd.uniform( scrambleMin, scrambleMax )
dy = rnd.uniform( scrambleMin, scrambleMax )
dz = rnd.uniform( scrambleMin, scrambleMax )
delta = [dx, dy, dz]
#Loop on the animation curves that correspond to the location
for curve in [c for c in object.animation_data.action.fcurves if c.data_path.endswith( 'location' )]:
#Shift all control points of the curve
for key in curve.keyframe_points:
key.co[1] += delta[curve.array_index]
def ScrambleObjectsAnimation( objects, scrambleMin, scrambleMax, seed ):
rnd = Random()
if seed > 0:
rnd.seed( seed )
for object in objects:
ScrambleObjectAnimation( object, scrambleMin, scrambleMax, rnd )
def SettingsAreOK( context ):
return True
class ScrambleObjectAnimationOperator( bpy.types.Operator ):
bl_idname = "lemon.scrambleobjectanimationoperator"
bl_label = "Scramble objects animation"
bl_options = {'REGISTER','UNDO'}
@classmethod
def poll(self, context):
return context.mode == 'OBJECT' and SettingsAreOK( context )
def invoke(self, context, event):
scn = context.scene
settings = scn.scrambleObjectAnimation
#try:
objects = bpy.data.groups[settings.group_name].objects
scrambleMin = settings.scramble_min
scrambleMax = settings.scramble_max
seed = settings.seed
ScrambleObjectsAnimation( objects, scrambleMin, scrambleMax, seed )
#except:
#pass
return { 'FINISHED' }
class ScrambleObjectAnimationPanel( bpy.types.Panel ):
bl_idname = 'lemon.scrambleobjectanimationpanel'
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_label = "Scramble objects animation"
@classmethod
def poll(self, context):
return context.mode == 'OBJECT'
def draw(self, context):
layout = self.layout
scn = context.scene
settings = scn.scrambleObjectAnimation
layout.row().prop_search( settings, "group_name", bpy.data, "groups", text="Object group" )
layout.row().prop( settings, "scramble_min" )
layout.row().prop( settings, "scramble_max" )
layout.row().prop( settings, "seed" )
layout.row().operator( ScrambleObjectAnimationOperator.bl_idname, text="Scramble" )
class ScrambleObjectAnimationProps( bpy.types.PropertyGroup ):
group_name = bpy.props.StringProperty()
scramble_min = bpy.props.FloatProperty( name="Scramble min", default=-1.0, soft_min=-10, soft_max=0, step=2, precision=2 )
scramble_max = bpy.props.FloatProperty( name="Scramble max", default=1.0, soft_min=0, soft_max=10, step=2, precision=2 )
seed = bpy.props.IntProperty( name="Seed", default=0, min=0)
def register():
bpy.utils.register_module(__name__)
bpy.types.Scene.scrambleObjectAnimation = bpy.props.PointerProperty( type = ScrambleObjectAnimationProps )
def unregister():
del bpy.types.Scene.scrambleObjectAnimation
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()
