i dunno, i will look into it. i had not baked a camera before.
Well, after a couple all nighters and reading all the good links you guys gave me, including the magic invert() from poselib16, here is a script that bakes a constrained armature:
# prior to running script, make a duplicate of a reference (constrained) armature and remove constraints from the clone.
# simplistic example where ref and clone have to be identical with respect to bone names and order
# select the unconstrained armature clone, then shift-select the reference armature object.
# the actual motion of the reference armature's bones will be keyed in the clone's pose ipo
import Blender
import bpy
import BPyMessages
#Vector= Blender.Mathutils.Vector
#Euler= Blender.Mathutils.Euler
Matrix= Blender.Mathutils.Matrix #invert() function at least
#RotationMatrix = Blender.Mathutils.RotationMatrix
#TranslationMatrix= Blender.Mathutils.TranslationMatrix
# Make a dict for fast access without rebuilding a list all the time.
xformConstants = [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT]
CURFRAME='curframe'
scn = bpy.data.scenes.active
def bakeBone(frame,pbone,ref_pose): #frame to bake for, bone to bake, reference bones, armature pose for children to find their parents
print ('Baking bone %s' % pbone)
# ref bone must be properly positioned for the frame before entry
rbones = ref_pose.bones.values()
#magic happens here. Thank you Faulty
for rbone in rbones: # find reference bone
if rbone.name == pbone.name: break
if pbone.parent == None:
par_mat = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1])
else:
print (' bone %s parent is %s' % (pbone,pbone.parent.name))
parent_pbone = ref_pose.bones[rbone.parent.name] #get their parent's role model (uncle)
par_mat = parent_pbone.poseMatrix
par_mat.invert()
pbone.localMatrix = rbone.poseMatrix * par_mat
print ('Baked %s frame %i matrix %s' % (pbone.name,frame,pbone.localMatrix[0]))
pbone.insertKey(arm_ob, frame, xformConstants, True )
return
def bakeBones(ref_ob,arm_ob): #copy pose from ref_ob to arm_ob
context=scn.getRenderingContext()
staframe = context.startFrame()
endframe = context.endFrame()
curframe = Blender.Get(CURFRAME)
frame = staframe
ref_mat = ref_ob.matrixWorld
ref_data = ref_ob.getData()
ref_arm = Blender.Armature.Get(ref_data.name) #the armature used by the passed object
arm_pose = arm_ob.getPose()
ref_pose = ref_ob.getPose()
pbones = arm_pose.bones.values()
rbones = ref_pose.bones.values()
act = Blender.Armature.NLA.NewAction()
act.setActive(arm_ob)
act.setName(arm_ob.getName())
# Pose the reference object before starting, or you get a wierd glitch where the bones may not be copied correctly (od data in buffer somewhere)
Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
for frame in range(staframe,endframe+1):
print ('=================')
print ('Baking frame %i' % frame)
Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
Blender.Redraw()
for pbone in pbones:
bakeBone(frame,pbone,ref_pose) #bake this bone based on its role model (cousin and possibly uncle)
# eye-candy - smoothly rewind the animation, showing now how the clone match moves
for frame in range (endframe,staframe,-1): #rewind
Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
Blender.Redraw()
# user comprehension feature - change channel ipo name to match the bone names they drive
print ('Renaming each ipo to match the bone they pose')
idx=0
arm_channels = act.getAllChannelIpos()
for pbone in pbones:
print pbone.name, arm_channels[pbone.name]
ipo=arm_channels[pbone.name]
ipo.name = pbone.name
return
ref_ob = Blender.Object.GetSelected()[0]
arm_ob = Blender.Object.GetSelected()[1]
bakeBones(ref_ob,arm_ob)
print 'done'