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)
|
Blender python API quick-start
Syntax highlighting by Pygments.