rotation - Calculating the new position of a parented controller after rotating the parent in Maya using Python -
i'm creating code create motion path of controller based on it's keyframed positions in maya. i've run problem when trying use code create motion path of parented controller. if rotate , translate parent generated motion path not reflect actual path of motion. instead creates motion path if not affected parent. i've looked around , found information applying rotation using matrix transformations current position seems rotating way much. i've included function creating motion path, it's little long part isn't working within else statement when dealing upper torso controller.
updated code based on progress
# # function creates animation curve within scene follows path of motion # of selected controller. requires keyframe information in order genereate curve # , uses range of frames given user. # def createanimcurve( bodyfield, startfield, endfield, firstcolor ): # takes value of text field select controller obj = cmds.textfield(bodyfield, query=true, text=true) print obj # takes in string input of paramter values , turns them integer values startframe = cmds.intfield(startfield, query=true, value=true) print startframe endframe = cmds.intfield(endfield, query=true, value=true) print endframe color = cmds.colorindexslidergrp( firstcolor, query=true, value=true ) - 1 print color if obj == "": cmds.warning( "warning: need select body part diagram" ) return if cmds.objexists(obj[:-3]+'path'): # creates warning pop double checks if user wants remove curve delres = cmds.confirmdialog( title='delete path warning', message='recreation delete current path. sure?', button=['yes','no'], defaultbutton='yes', cancelbutton='no', dismissstring='no' ) # if yes curve deleted if delres == 'yes': #cmds.delete(obj[:-3]+'scalepath') #cmds.delete(obj[:-3]+'scalepath_loc') cmds.delete(obj[:-3]+'path') cmds.delete(obj[:-3]+'path_loc') else: return # sorts through list of keyframes of selected obj selected time line global keyframes keyframes = sorted(list(set(cmds.keyframe(obj, q=true, time=(startframe,endframe), timechange=true)))) # creates arrays required point positions points = [] centerpoints = [] centerrotates = [] combinedpoints = [] # special cases controllers named differently joints if obj == "l_foot_ctl" or obj == "r_foot_ctl": loc = obj[:-4] + "ankle_loc" elif obj == "m_uptorso_ctl": loc = "m_spinetip_loc" else: loc = obj[:-3] + "loc" # grabs original world space position calculate approraite motion points locpos = cmds.getattr(loc+".translate") centerlocpos = cmds.getattr("m_centermass_loc.translate") #for step in range( startframe, endframe+2, int(curvecvstep)): step in range(len(keyframes)): # moves throughout specified timeline find point results cmds.currenttime( keyframes[step] ) if obj != "m_uptorso_ctl": # queries position of controller draw curve # adds position of controller in world space draw relative control pos = cmds.xform( obj,q=true,ws=true,t=true ) pos[0] = pos[0] + locpos[0][0] pos[1] = pos[1] + locpos[0][1] pos[2] = pos[2] + locpos[0][2] # convert tuple (vector) string points.append(pos) print pos else: spinelength = cmds.getattr('spinecurveinfo.arclength') # queries position of controller draw curve # adds position of controller in world space draw relative control # adds in spine length y position take consideration offset of centermass controller pos = cmds.xform( obj,q=true,ws=true,t=true ) pos[0] = pos[0] + locpos[0][0] pos[1] = pos[1] + locpos[0][1] pos[2] = pos[2] + locpos[0][2] # convert tuple (vector) string print "printing out points" points.append(pos) print pos # queries position of center of mass controller centerpos = cmds.xform( "m_centermass_ctl",q=1,os=1,t=1 ) centerpos[0] = centerpos[0] #+ centerlocpos[0][0] centerpos[1] = centerpos[1] #+ centerlocpos[0][1] centerpos[2] = centerpos[2] #+ centerlocpos[0][2] # convert tuple (vector) string print "printing out center points" centerpoints.append(centerpos) print centerpos # combine 2 point positions find relative position combinedpos = [] combinedpos1 = pos[0] + centerpos[0] combinedpos.append(combinedpos1) combinedpos2 = pos[1] + centerpos[1] combinedpos.append(combinedpos2) combinedpos3 = pos[2] + centerpos[2] combinedpos.append(combinedpos3) print "printing out combined points" print combinedpos # queries rotation of center of mass controller #centerrot = cmds.xform( "m_centermass_ctl",q=1,ws=1,ro=1 ) #centerrotates.append(centerrot) #print "printing out rotations" #print centerrot # applies rotation of center of mass controller upper torso controller # rotation around z axis #tempx = combinedpos[0]*math.cos(math.radians(centerrot[2])) - combinedpos[1]*math.sin(math.radians(centerrot[2])) #tempy = combinedpos[0]*math.sin(math.radians(centerrot[2])) + combinedpos[1]*math.cos(math.radians(centerrot[2])) # rotation around y axis #tempx2 = tempx*math.cos(math.radians(centerrot[1])) + combinedpos[2]*math.sin(math.radians(centerrot[1])) #tempz = combinedpos[2]*math.cos(math.radians(centerrot[1])) - tempx*math.sin(math.radians(centerrot[1])) # rotation around x axis #tempy2 = tempy*math.cos(math.radians(centerrot[0])) - tempz*math.sin(math.radians(centerrot[0])) #tempz2 = tempy*math.sin(math.radians(centerrot[0])) + tempz*math.cos(math.radians(centerrot[0])) #combinedpos[0] = tempx2 #combinedpos[1] = tempy2 #combinedpos[2] = tempz2 #print "printing out rotated points" combinedpoints.append(combinedpos) print combinedpos # if obj upper torso controller need take consideration center of mass controller # creates motion curve required cvs if obj == "m_uptorso_ctl": cur = cmds.curve(d=2, ws=true, p=combinedpoints, n=obj[:-3]+'path') cmds.setattr(cur + '.overrideenabled', 1) cmds.setattr(cur + '.overridecolor', color) print cur cmds.move(points[0][0], points[0][1], points[0][2], cur+".scalepivot", cur+".rotatepivot", absolute=true) else: cur = cmds.curve(d=2, ws=true, p=points, n=obj[:-3]+'path') cmds.setattr(cur + '.overrideenabled', 1) cmds.setattr(cur + '.overridecolor', color) print cur cmds.move(points[0][0], points[0][1], points[0][2], cur+".scalepivot", cur+".rotatepivot", absolute=true) # command runs through each cv of curve , returns position within list. cvs = cmds.getattr( obj[:-3]+'path.cv[*]' ) print cvs global initcvs initcvs = cvs # create locator motion path controller follow locate = cmds.spacelocator( n=obj[:-3]+"path_loc" ) #for step in range( startframe, endframe+2, int(curvecvstep)): step in range(len(keyframes)): # moves throughout specified timeline find point results cmds.currenttime( keyframes[step] ) # moves locator match position of controller cmds.move( cvs[step][0], cvs[step][1], cvs[step][2], locate) # keyframes locator cmds.setkeyframe( locate ) # position obj @ location of locate. cmds.pointconstraint( locate, obj, n=obj[:-3]+"loc1_pnt" ) cmds.setattr( loc+'.visibility', 0) # keys weight of point constraint 0 before , after time frame (set 1 during time frame) #before startframe cmds.currenttime( startframe - 1 ) cmds.setattr(obj+'.blendpoint1', 0 ) cmds.setkeyframe(obj+'.blendpoint1' ) #after startframe cmds.currenttime( startframe ) cmds.setattr(obj+'.blendpoint1', 1 ) cmds.setkeyframe(obj+'.blendpoint1' ) #before endframe cmds.currenttime( endframe ) cmds.setattr(obj+'.blendpoint1', 1 ) cmds.setkeyframe(obj+'.blendpoint1' ) #after endframe cmds.currenttime( endframe + 1 ) cmds.setattr(obj+'.blendpoint1', 0 ) cmds.setkeyframe(obj+'.blendpoint1' ) cmds.select(obj)
here's resulting motion path looks
here's correct arc should following
here's new curve based on new code. seems following along path of motion it's compressed.
if you're trying world space position of something, can use:
position = cmds.xform(item, q=true, ws=true, t=true)
and use position data needed - should work regardless of how parents rotated... xform command can used set position of things in world space well:
cmds.xform(item, ws=true, t=position)
i'm not sure if answers question - it's little unclear you're trying achieve in code; can't quite follow reason locator , point constraint that's being turned on/off. trying create editable motion trail?
if so, have tried using maya's built in editable motion trail tool?
if you're trying make own reason, suppose follow '2 step' approach first create curve each cv @ world space position of control through designated start/end time. edit curve cv positions clean arc , run separate function queries world space position of each cv, applies them control , sets keyframe @ appropriate time. since you're doing in world space positions, shouldn't need worry parent positions/rotations (fortunately, should make code relatively simple).
Comments
Post a Comment