```import bpy from mathutils import * import math import random def random_axis_element(): rval = random.random()*2+1 if 0==random.randint(0,1): return rval else: return -rval def random_axis(): return [ random_axis_element(), random_axis_element(), random_axis_element()] def cyclic_wiggle_matrices(n): base = quaternion_sequence(n*2+1) rval = [] for i in range(n+1): s = i/n t = 1-s m1 = base[i] (loc,q1,scale) = m1.decompose() m2 = base[i+n] (loc,q2,scale) = m2.decompose() (axis1, angle1) = q1.to_axis_angle() (axis2, angle2) = q2.to_axis_angle() mf = Matrix.Rotation(angle1*s, 4, axis1) * Matrix.Rotation(angle2*t, 4, axis2) rval.append(mf) print(rval[0]) print(rval[-1]) print(rval[0].inverted()*rval[-1]) return rval def quaternion_sequence(n): """we're assuming the armature is for a layered "urchin" and the layers are in order from center to edge """ me = Matrix() print(me) axis = Vector(random_axis()) rval = [] for fr in range(n): speed = math.sin(fr*0.1) * 0.07 wiggle = Matrix.Rotation(speed, 4, axis) #print(wiggle) me = wiggle*me (loc,rot,scale) = me.decompose() rval .append( me.copy() ) # change the axis a little precession = Matrix.Rotation(0.2, 4, random_axis()) axis = precession * axis return rval def animate_wiggle(armature, frame_start, frame_end): """we're assuming the armature is for a layered "urchin" and the layers are in order from center to edge """ armature.animation_data_clear() m0 = armature.pose.bones[0].matrix_basis print(m0) for i in range(len(armature.pose.bones)): bone = armature.pose.bones[i] bone.matrix_basis.identity() axis = Vector(random_axis()) count = frame_end - frame_start + 1 matrix_sequence = cyclic_wiggle_matrices(count) for j in range(count): fr = j+frame_start wiggle = matrix_sequence[j] for i in range(len(armature.pose.bones)): bone = armature.pose.bones[i] # wiggle the bones in world space bone.matrix =wiggle f2 = fr +i if f2 > frame_end: f2 = f2 - count # keyframe, but each layer is offset in time armature.keyframe_insert(data_path="pose.bones[\"%s\"].rotation_quaternion"%bone.name, frame=f2) # armature = bpy.context.active_object animate_wiggle(armature, 1,15*30) ```

Syntax highlighting by Pygments.