Added calculation to determine change in root translation when retargeting - needs cleanup/optimization

This commit is contained in:
2011-06-17 11:47:45 +00:00
parent d240733ae2
commit c9360a4c1e

View File

@@ -15,27 +15,35 @@ scene = bpy.context.scene
# dictionary of mapping # dictionary of mapping
# this is currently manuall input'ed, but will # this is currently manuall input'ed, but will
# be created from a more comfortable UI in the future # be created from a more comfortable UI in the future
bonemap = { "LeftFoot": ("DEF_Foot.L","DEF_Toes.L"), bonemap = { "Head": "Head",
"LeftUpLeg": "DEF_Thigh.L", "Neck": "Head",
"Hips": "DEF_Hip", "Spine1": "Chest",
"LowerBack": "DEF_Spine", "Spine2": "Chest",
"Spine": "DEF_Torso", "Spine3": "Chest",
"Neck": "DEF_Neck", "Spine": "Torso",
"Neck1": "DEF_Neck", "Hips": "root",
"Head": "DEF_Head", "LeftUpLeg": "Thigh.L",
"LeftShoulder": "DEF_Shoulder.L", "LeftUpLegRoll": "Thigh.L",
"LeftArm": "DEF_Forearm.L", "LeftLeg": "Shin.L",
"LeftForeArm": "DEF_Arm.L", "LeftLegRoll": "Shin.L",
"LeftHand": "DEF_Hand.L", "LeftFoot": "Foot.L",
"RightShoulder": "DEF_Shoulder.R", "RightUpLeg": "Thigh.R",
"RightArm": "DEF_Forearm.R", "RightUpLegRoll": "Thigh.R",
"RightForeArm": "DEF_Arm.R", "RightLeg": "Shin.R",
"RightHand": "DEF_Hand.R", "RightLegRoll": "Shin.R",
"RightFoot": ("DEF_Foot.R","DEF_Toes.R"), "RightFoot": "Foot.R",
"RightUpLeg": "DEF_Thigh.R", "LeftShoulder": "Shoulder.L",
"RightLeg": "DEF_Shin.R", "LeftArm": "HiArm.L",
"LeftLeg": "DEF_Shin.L"} "LeftArmRoll": "HiArm.L",
"LeftForeArm": "LoArm.L",
"LeftForeArmRoll": "LoArm.L",
"RightShoulder": "Shoulder.R",
"RightArm": "HiArm.R",
"RightArmRoll": "HiArm.R",
"RightForeArm": "LoArm.R",
"RightForeArmRoll": "LoArm.R" }
root = "root"
# creation of a reverse map # creation of a reverse map
# multiple keys get mapped to list values # multiple keys get mapped to list values
bonemapr = {} bonemapr = {}
@@ -76,7 +84,10 @@ def createIntermediate():
empty.name = perf_bone.name+"Org" empty.name = perf_bone.name+"Org"
empty = bpy.data.objects[perf_bone.name+"Org"] empty = bpy.data.objects[perf_bone.name+"Org"]
offset = perf_bone.vector offset = perf_bone.vector
scaling = perf_bone.length / inter_bone.length if inter_bone.length == 0 or perf_bone.length == 0:
scaling = 1
else:
scaling = perf_bone.length / inter_bone.length
offset/=scaling offset/=scaling
empty.location = inter_bone.head + offset empty.location = inter_bone.head + offset
empty.keyframe_insert("location") empty.keyframe_insert("location")
@@ -147,7 +158,7 @@ def createIntermediate():
for t in range(1,150): for t in range(1,150):
scene.frame_set(t) scene.frame_set(t)
inter_bone = inter_bones["DEF_Hip"] inter_bone = inter_bones[root]
retargetPerfToInter(inter_bone) retargetPerfToInter(inter_bone)
return inter_obj,inter_arm return inter_obj,inter_arm
@@ -191,8 +202,73 @@ def retargetEnduser():
for t in range(1,150): for t in range(1,150):
scene.frame_set(t) scene.frame_set(t)
end_bone = end_bones["DEF_Hip"] end_bone = end_bones[root]
bakeTransform(end_bone) bakeTransform(end_bone)
#recieves the performer feet bones as a variable
# by "feet" I mean those bones that have plants
# (they don't move, despite root moving) somewhere in the animation.
def copyTranslation(perfFeet):
endFeet = [bonemap[perfBone] for perfBone in perfFeet]
perfRoot = bonemapr[root][0]
locDictKeys = perfFeet+endFeet+[perfRoot]
perf_bones = performer_obj.pose.bones
end_bones = enduser_obj.pose.bones
def tailLoc(bone):
return bone.center+(bone.vector/2)
#Step 1 - we create a dict that contains these keys:
#(Performer) Hips, Feet
#(End user) Feet
# where the values are their world position on each (1,120) frame
locDict = {}
for key in locDictKeys:
locDict[key] = []
for t in range(scene.frame_start,scene.frame_end):
scene.frame_set(t)
for bone in perfFeet:
locDict[bone].append(tailLoc(perf_bones[bone]))
locDict[perfRoot].append(tailLoc(perf_bones[perfRoot]))
for bone in endFeet:
locDict[bone].append(tailLoc(end_bones[bone]))
# now we take our locDict and analyze it.
# we need to derive all chains
locDeriv = {}
for key in locDictKeys:
locDeriv[key] = []
for key in locDict.keys():
graph = locDict[key]
for t in range(len(graph)-1):
x = graph[t]
xh = graph[t+1]
locDeriv[key].append(xh-x)
# now find the plant frames, where perfFeet don't move much
linearAvg = []
for key in perfFeet:
for i in range(len(locDeriv[key])-1):
v = locDeriv[key][i]
hipV = locDeriv[perfRoot][i]
endV = locDeriv[bonemap[key]][i]
if (v.length<0.1):
#this is a plant frame.
#lets see what the original hip delta is, and the corresponding
#end bone's delta
if endV.length!=0:
linearAvg.append(hipV.length/endV.length)
if linearAvg:
avg = sum(linearAvg)/len(linearAvg)
print("retargeted root motion should be "+ str(1/avg)+ " of original")
inter_obj, inter_arm = createIntermediate() inter_obj, inter_arm = createIntermediate()
retargetEnduser() retargetEnduser()
copyTranslation(["RightFoot","LeftFoot"])