Updated
This commit is contained in:
770
Scripts/Animation/aTools/animTools/animBar/subUIs/tangents.py
Normal file
770
Scripts/Animation/aTools/animTools/animBar/subUIs/tangents.py
Normal file
@ -0,0 +1,770 @@
|
||||
'''
|
||||
========================================================================================================================
|
||||
Author: Alan Camilo
|
||||
www.alancamilo.com
|
||||
Modified: Michael Klimenko
|
||||
|
||||
Requirements: aTools Package
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
To install aTools, please follow the instructions in the file how_to_install.txt
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
To unistall aTools, go to menu (the last button on the right), Uninstall
|
||||
|
||||
========================================================================================================================
|
||||
'''
|
||||
|
||||
from maya import cmds
|
||||
from maya import mel
|
||||
import math
|
||||
from aTools.generalTools.aToolsGlobals import aToolsGlobals as G
|
||||
from aTools.commonMods import uiMod
|
||||
from aTools.commonMods import animMod
|
||||
from aTools.commonMods import utilMod
|
||||
|
||||
class Tangents_Gui(uiMod.BaseSubUI):
|
||||
|
||||
def createLayout(self):
|
||||
|
||||
tangents = Tangents()
|
||||
buttons = ["flow", "bounce", "auto", "spline", "linear", "flat", "step"]
|
||||
|
||||
cmds.rowLayout(numberOfColumns=8, parent=self.parentLayout)
|
||||
|
||||
for loopButton in buttons:
|
||||
cmds.iconTextButton(style='iconAndTextVertical', image= uiMod.getImagePath("tangents_%s"%loopButton), highlightImage= uiMod.getImagePath("tangents_%s copy"%loopButton), w=self.wb, h=self.hb, command=lambda loopButton=loopButton, *args: tangents.setTangent(loopButton), annotation="%s tangent\\nRight click for options"%str.title(loopButton))
|
||||
tangents.popupMenu(loopButton)
|
||||
|
||||
# end createLayout
|
||||
|
||||
class Tangents(object):
|
||||
|
||||
def __init__(self):
|
||||
if G.aToolsBar.tangents: return
|
||||
G.aToolsBar.tangents = self
|
||||
|
||||
def popupMenu(self, button, *args):
|
||||
menu = cmds.popupMenu()
|
||||
cmds.popupMenu(menu, edit=True, postMenuCommand=lambda *args:self.populateMenu(menu, button), postMenuCommandOnce=True)
|
||||
|
||||
|
||||
def populateMenu(self, menu, button, *args):
|
||||
|
||||
print(("menu, button, *args", menu, button, args))
|
||||
|
||||
|
||||
if button != "step":
|
||||
cmds.menuItem(label='In Tangent', command=lambda *args: self.setTangent(button, 'in'), parent=menu)
|
||||
cmds.menuItem(label='Out Tangent', command=lambda *args: self.setTangent(button, 'out'), parent=menu)
|
||||
cmds.menuItem(divider=True, parent=menu)
|
||||
cmds.menuItem(label='First Frame', command=lambda *args: self.setTangent(button, 'out', 'first'), parent=menu)
|
||||
cmds.menuItem(label='Last Frame', command=lambda *args: self.setTangent(button, 'in', 'last'), parent=menu)
|
||||
cmds.menuItem(label='Both Ends', command=lambda *args: self.setTangent(button, 'inOut', 'both'), parent=menu)
|
||||
|
||||
cmds.menuItem(divider=True, parent=menu)
|
||||
cmds.menuItem(label='All Keys', command=lambda *args: self.setTangent(button, 'inOut', 'all'), parent=menu)
|
||||
|
||||
|
||||
|
||||
|
||||
def flowAround(self, frames = 2, excludeCurrKey = False):
|
||||
|
||||
getCurves = animMod.getAnimCurves()
|
||||
animCurves = getCurves[0]
|
||||
getFrom = getCurves[1]
|
||||
|
||||
if animCurves:
|
||||
#if getFrom == "graphEditor":
|
||||
keysSel = animMod.getTarget("keysSel", animCurves, getFrom)
|
||||
tangentType = "flow"
|
||||
time = None
|
||||
|
||||
#animMod.expandKeySelection(frames)
|
||||
|
||||
index = animMod.getTarget("keysIndexSel", animCurves, getFrom)
|
||||
indexTimes = animMod.getTarget("keyIndexTimes", animCurves, getFrom)
|
||||
|
||||
#expand selection
|
||||
for n, loopCurve in enumerate(index):
|
||||
for x in range(frames):
|
||||
if loopCurve[0] >= 1:
|
||||
loopCurve.insert(0, loopCurve[0]-1)
|
||||
if loopCurve[-1] < indexTimes[n][-1]:
|
||||
loopCurve.append(loopCurve[-1]+1)
|
||||
|
||||
#if excludeCurrKey:
|
||||
|
||||
|
||||
|
||||
self.applyTangent(animCurves, tangentType, getFrom, time, index)
|
||||
|
||||
#select back keys
|
||||
if keysSel:
|
||||
cmds.selectKey(clear=True)
|
||||
for n, aCurve in enumerate(animCurves):
|
||||
for key in keysSel[n]:
|
||||
cmds.selectKey(aCurve, addTo=True, time=(key, key))
|
||||
|
||||
def applyTangent(self, animCurves, tangentType, getFrom, time, index, tangentInOut="inOut"):
|
||||
|
||||
|
||||
|
||||
if self.isDefaultTangent(tangentType): #default maya tangents
|
||||
if tangentType == "step":
|
||||
cmds.keyTangent(animCurves, edit=True, time=time, outTangentType=tangentType)
|
||||
|
||||
else:
|
||||
if tangentInOut =="inOut" or tangentInOut == "in":
|
||||
#print "applied in", time, tangentType
|
||||
cmds.keyTangent(animCurves, edit=True, time=time, inTangentType=tangentType)
|
||||
if tangentInOut =="inOut" or tangentInOut == "out":
|
||||
#print "applied out", time, tangentType
|
||||
cmds.keyTangent(animCurves, edit=True, time=time, outTangentType=tangentType)
|
||||
|
||||
else: #custom tangents
|
||||
|
||||
|
||||
|
||||
keyTimes = animMod.getTarget("keyTimes", animCurves)
|
||||
keyIndexTimes = animMod.getTarget("keyIndexTimes", animCurves)
|
||||
keysIndexSel = index
|
||||
keyValues = animMod.getTarget("keyValues", animCurves)
|
||||
|
||||
|
||||
cycleArray = []
|
||||
tangentArray = []
|
||||
|
||||
for n, aCurve in enumerate(animCurves):
|
||||
cycleArray.append([])
|
||||
tangentArray.append([])
|
||||
|
||||
if keysIndexSel != None and keyTimes[n] != None and keysIndexSel[n] != None and len(keyTimes[n]) >=2:
|
||||
|
||||
if keyValues[n][0] == keyValues[n][-1] and keysIndexSel[n] == keyIndexTimes[n]: #it's a cycle
|
||||
cycleArray[n] = True
|
||||
else:
|
||||
cycleArray[n] = False
|
||||
|
||||
#define tangent array
|
||||
for i in keysIndexSel[n]:
|
||||
tangentArray[n].append(cmds.keyTangent(aCurve, query=True, index=(i, i), inTangentType=True, outTangentType=True, inAngle=True, outAngle=True))
|
||||
|
||||
|
||||
passes = [self.averageTangent, self.flowTangent]
|
||||
#passes = [averageTangent]
|
||||
#self.fixTangentOvershoot, self.fixTangentOpposite
|
||||
self.applyPass(passes, animCurves, keyTimes, keyValues, keysIndexSel, tangentType)
|
||||
|
||||
|
||||
|
||||
|
||||
# put back saved in out sides
|
||||
for n, aCurve in enumerate(animCurves):
|
||||
|
||||
if keysIndexSel != None and keyTimes[n] != None and keysIndexSel[n] != None and len(keyTimes[n]) >=2:
|
||||
|
||||
for nn, i in enumerate(keysIndexSel[n]):
|
||||
|
||||
tangent = tangentArray[n][nn]
|
||||
|
||||
if tangentInOut == "in":
|
||||
cmds.keyTangent(aCurve, edit=True, index=(i, i), lock=False)
|
||||
cmds.keyTangent(aCurve, edit=True, index=(i, i), outTangentType=tangent[3], outAngle=tangent[1])
|
||||
cmds.keyTangent(aCurve, edit=True, index=(i, i), lock=True)
|
||||
|
||||
elif tangentInOut == "out":
|
||||
cmds.keyTangent(aCurve, edit=True, index=(i, i), lock=False)
|
||||
cmds.keyTangent(aCurve, edit=True, index=(i, i), inTangentType=tangent[2], inAngle=tangent[0])
|
||||
cmds.keyTangent(aCurve, edit=True, index=(i, i), lock=True)
|
||||
|
||||
|
||||
|
||||
if tangentType == "flow":
|
||||
# bounce ends
|
||||
|
||||
for n, aCurve in enumerate(animCurves):
|
||||
first = None
|
||||
last = None
|
||||
|
||||
if 0 in keysIndexSel[n]: first = True
|
||||
if len(keyTimes[n])-1 in keysIndexSel[n]: last = True
|
||||
|
||||
if first and last:
|
||||
self.bounceEnds([aCurve], "bounce", getFrom, tangentInOut, [keyTimes[n]], [keyIndexTimes[n]], "both")
|
||||
elif first:
|
||||
self.bounceEnds([aCurve], "bounce", getFrom, tangentInOut, [keyTimes[n]], [keyIndexTimes[n]], "first")
|
||||
elif last:
|
||||
self.bounceEnds([aCurve], "bounce", getFrom, tangentInOut, [keyTimes[n]], [keyIndexTimes[n]], "last")
|
||||
|
||||
#print "fl", first, last
|
||||
|
||||
# cycle?
|
||||
for n, aCurve in enumerate(animCurves):
|
||||
if cycleArray[n]:
|
||||
angle = cmds.keyTangent(aCurve, query=True, index=(0, 0), outAngle=True)[0]
|
||||
cmds.keyTangent(aCurve, time=(keyTimes[n][-1], keyTimes[n][-1]), inAngle=angle, outAngle=angle)
|
||||
|
||||
|
||||
|
||||
|
||||
def applyPass(self, passes, animCurves, keyTimes, keyValues, keysIndexSel, tangentType):
|
||||
|
||||
|
||||
|
||||
newKeysIndexSel = utilMod.dupList(keysIndexSel)
|
||||
|
||||
for loopFunction in passes:
|
||||
|
||||
#utilMod.timer("s")
|
||||
|
||||
for n, aCurve in enumerate(animCurves):
|
||||
|
||||
if keysIndexSel != None and keyTimes[n] != None and keysIndexSel[n] != None and len(keyTimes[n]) >=2:
|
||||
|
||||
#utilMod.timer()
|
||||
|
||||
#unlock weights
|
||||
weighted = cmds.keyTangent(aCurve, query=True, weightedTangents=True)[0]
|
||||
locked = cmds.keyTangent(aCurve, query=True, lock=True)
|
||||
|
||||
#utilMod.timer()
|
||||
|
||||
if weighted: cmds.keyTangent(aCurve, edit=True, weightedTangents=False) #weight to balance in and out tangents
|
||||
cmds.keyTangent(aCurve, edit=True, weightedTangents=True)
|
||||
|
||||
#utilMod.timer()
|
||||
|
||||
if loopFunction == self.fixTangentOpposite:
|
||||
#remove last index
|
||||
if len(keysIndexSel[n]) > 0: keysIndexSel[n].pop()
|
||||
if len(newKeysIndexSel[n]) > 0: newKeysIndexSel[n].pop()
|
||||
#reorder index according with size of segment
|
||||
keysIndexSel[n] = self.tangentOppositeReorder(keysIndexSel[n], keyValues[n])
|
||||
|
||||
#utilMod.timer()
|
||||
|
||||
# apply the damn function
|
||||
for loopIndex in keysIndexSel[n]:
|
||||
|
||||
curTangType = self.tangType(keyValues[n], keyTimes[n], loopIndex)
|
||||
|
||||
applied = loopFunction(aCurve, keyValues[n], loopIndex, tangentType, curTangType, keysIndexSel[n], keyTimes[n])
|
||||
|
||||
if loopFunction == self.fixTangentOvershoot and applied:
|
||||
#remove the applied index to avoid changind that tangent again
|
||||
if newKeysIndexSel[n]: newKeysIndexSel[n].remove(loopIndex)
|
||||
|
||||
#utilMod.timer()
|
||||
|
||||
# put back
|
||||
for i, loopLocked in enumerate(locked):
|
||||
cmds.undoInfo(stateWithoutFlush=False)
|
||||
if loopLocked: cmds.keyTangent(aCurve, edit=True, index=(i,i), lock=loopLocked)
|
||||
cmds.undoInfo(stateWithoutFlush=True)
|
||||
|
||||
#utilMod.timer()
|
||||
|
||||
if weighted: cmds.keyTangent(aCurve, edit=True, weightedTangents=False) #weight to balance in and out tangents
|
||||
cmds.keyTangent(aCurve, edit=True, weightedTangents=weighted)
|
||||
|
||||
#utilMod.timer("e", loopFunction)
|
||||
|
||||
|
||||
def tangentOppositeReorder(self, indexes, values):
|
||||
#put bigger segments first
|
||||
|
||||
difList = []
|
||||
for n, loopVal in enumerate(values[2:-3]):
|
||||
dif = values[n+1+2] - values[n+2]
|
||||
difList.append(abs(dif))
|
||||
|
||||
indexList = []
|
||||
tmpDifList = utilMod.dupList(difList)
|
||||
for n, loopDif in enumerate(tmpDifList):
|
||||
maxDif = max(tmpDifList)
|
||||
index = difList.index(maxDif)
|
||||
tmpDifList[index] = -1
|
||||
indexList.append(index)
|
||||
|
||||
newIndexes = []
|
||||
for loopIndex in indexList:
|
||||
if loopIndex in indexes:
|
||||
newIndexes.append(loopIndex)
|
||||
|
||||
"""
|
||||
print "indexList",indexList
|
||||
print "values",values
|
||||
print "difList",difList
|
||||
print "indexes",indexes
|
||||
print "newIndexes",newIndexes
|
||||
"""
|
||||
|
||||
return newIndexes
|
||||
|
||||
def setTangent(self, tangentType, tangentInOut="inOut", targetKeys="selected", *args):
|
||||
|
||||
#utilMod.timer(mode="s", function="MAIN FUNCTION")
|
||||
|
||||
cmds.waitCursor(state=True)
|
||||
|
||||
"""
|
||||
cmds.undoInfo(openChunk=True)
|
||||
cmds.undoInfo(closeChunk=True)
|
||||
cmds.undoInfo(openChunk=True)
|
||||
cmds.undoInfo(closeChunk=True)
|
||||
cmds.undoInfo(openChunk=True)
|
||||
cmds.undoInfo(closeChunk=True)
|
||||
cmds.undoInfo(openChunk=True)
|
||||
"""
|
||||
|
||||
#tangentType = flow, bounce, auto, etc
|
||||
#targetKeys = all, selected
|
||||
#tangentInOut = inOut, in, out
|
||||
|
||||
#set default tangent type
|
||||
if tangentType == "flow":
|
||||
cmds.keyTangent(edit=True, g=True, inTangentType="auto", outTangentType="auto")
|
||||
elif tangentType == "step":
|
||||
cmds.keyTangent(edit=True, g=True, outTangentType=tangentType)
|
||||
elif tangentType != "bounce":
|
||||
cmds.keyTangent(edit=True, g=True, inTangentType=tangentType, outTangentType=tangentType)
|
||||
|
||||
|
||||
# get target curves
|
||||
getCurves = animMod.getAnimCurves()
|
||||
animCurves = getCurves[0]
|
||||
getFrom = getCurves[1]
|
||||
|
||||
#if there is no curves, exit
|
||||
if animCurves:
|
||||
status = "aTools - Tangents..."
|
||||
utilMod.startProgressBar(status)
|
||||
totalSteps = len(animCurves)
|
||||
firstStep = 0
|
||||
thisStep = 0
|
||||
estimatedTime = None
|
||||
startChrono = None
|
||||
|
||||
index = None
|
||||
time = None
|
||||
|
||||
if targetKeys == "all": # apply for all keys
|
||||
time = (-50000, 500000)
|
||||
|
||||
if not self.isDefaultTangent(tangentType):
|
||||
index = animMod.getTarget("keyIndexTimes", animCurves, getFrom)
|
||||
|
||||
self.applyTangent(animCurves, tangentType, getFrom, time, index)
|
||||
|
||||
elif targetKeys == "selected": #apply on a range
|
||||
if getFrom == "timeline":
|
||||
time = animMod.getTimelineRange(); time = (time[0], time[1])#flow and bounce
|
||||
if not self.isDefaultTangent(tangentType): index = animMod.getTarget("keysIndexSel", animCurves, getFrom)
|
||||
self.applyTangent(animCurves, tangentType, getFrom, time, index, tangentInOut)
|
||||
|
||||
else:
|
||||
if self.isDefaultTangent(tangentType): # if the tangent types are default maya types
|
||||
#apply individually on each key
|
||||
keysSel = animMod.getTarget("keysSel", animCurves, getFrom)
|
||||
|
||||
for thisStep, aCurve in enumerate(animCurves):
|
||||
if cmds.progressBar(G.progBar, query=True, isCancelled=True ):
|
||||
utilMod.setProgressBar(endProgress=True)
|
||||
break
|
||||
startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status)
|
||||
|
||||
for loopKey in keysSel[thisStep] :
|
||||
time = (loopKey, loopKey)
|
||||
self.applyTangent(aCurve, tangentType, getFrom, time, index, tangentInOut)
|
||||
|
||||
estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps)
|
||||
|
||||
else: #flow and bounce
|
||||
index = animMod.getTarget("keysIndexSel", animCurves, getFrom)
|
||||
self.applyTangent(animCurves, tangentType, getFrom, time, index, tangentInOut)
|
||||
else:# first and last frame
|
||||
keyTimes = animMod.getTarget("keyTimes", animCurves, getFrom)
|
||||
keyIndexTimes = animMod.getTarget("keyIndexTimes", animCurves, getFrom)
|
||||
|
||||
self.bounceEnds(animCurves, tangentType, getFrom, tangentInOut, keyTimes, keyIndexTimes, targetKeys)
|
||||
|
||||
|
||||
utilMod.setProgressBar(endProgress=True)
|
||||
#cmds.undoInfo(closeChunk=True)
|
||||
|
||||
cmds.waitCursor(state=False)
|
||||
|
||||
#utilMod.timer(mode="e", function="MAIN FUNCTION")
|
||||
|
||||
def bounceEnds(self, animCurves, tangentType, getFrom, tangentInOut, keyTimes, keyIndexTimes, targetKeys):
|
||||
for n, aCurve in enumerate(animCurves):
|
||||
if targetKeys == "first" or targetKeys == "both":
|
||||
|
||||
firstTime = keyTimes[n][0]
|
||||
firstIndex = keyIndexTimes[n][0]
|
||||
time = (firstTime,firstTime)
|
||||
index = [firstIndex]
|
||||
|
||||
self.applyTangent([aCurve], tangentType, getFrom, [time], [index], tangentInOut)
|
||||
|
||||
if targetKeys == "last" or targetKeys == "both":
|
||||
lastTime = keyTimes[n][-1]
|
||||
lastIndex = keyIndexTimes[n][-1]
|
||||
time = (lastTime,lastTime)
|
||||
index = [lastIndex]
|
||||
|
||||
self.applyTangent([aCurve], tangentType, getFrom, [time], [index], tangentInOut)
|
||||
|
||||
|
||||
def isDefaultTangent(self, tangentType):
|
||||
return (tangentType != "flow" and tangentType != "bounce")
|
||||
|
||||
def tangType(self, keyVal, keyTimes, index):
|
||||
|
||||
keyValTmp = utilMod.dupList(keyVal)
|
||||
|
||||
keyLocation = self.getKeyLocation(keyValTmp, index)
|
||||
nKeys = len(keyValTmp)
|
||||
|
||||
if keyLocation == "first":
|
||||
if keyValTmp[index] == keyValTmp[index+1] == keyValTmp[index+2]:
|
||||
return "Zero"
|
||||
elif keyLocation == "last":
|
||||
if keyValTmp[index] == keyValTmp[index-1] == keyValTmp[index-2]:
|
||||
return "Zero"
|
||||
else:
|
||||
index += 2
|
||||
for x in range(2):
|
||||
keyValTmp.insert(0, keyValTmp[0])
|
||||
keyValTmp.append(keyValTmp[-1])
|
||||
|
||||
if keyValTmp[index] == keyValTmp[index+1] == keyValTmp[index+2] or keyValTmp[index] == keyValTmp[index-1] == keyValTmp[index-2] or keyValTmp[index] == keyValTmp[index+1] == keyValTmp[index-1]:
|
||||
return "Zero"
|
||||
|
||||
#or....
|
||||
return "Average"
|
||||
|
||||
|
||||
def getAverageAngle(self, keyVal, keyTimes, index):
|
||||
|
||||
keyLocation = self.getKeyLocation(keyVal, index)
|
||||
|
||||
if keyLocation == "mid":
|
||||
|
||||
relTimeInA = keyTimes[index] - keyTimes[index-1]
|
||||
relValInA = keyVal[index-1] - keyVal[index]
|
||||
relTimeOutA = keyTimes[index+1] - keyTimes[index]
|
||||
relValOutA = keyVal[index+1] - keyVal[index]
|
||||
outAngleA = math.degrees(math.atan(relValOutA/relTimeOutA))
|
||||
outOpp = relTimeInA*math.tan(math.radians(outAngleA))
|
||||
|
||||
return -math.degrees(math.atan(((relValInA-outOpp)/2)/relTimeInA))
|
||||
|
||||
return 0
|
||||
|
||||
# end getAverageAngle
|
||||
|
||||
def getKeyLocation(self, keyVal, index):
|
||||
if index == 0:
|
||||
return "first"
|
||||
elif index == len(keyVal)-1:
|
||||
return "last"
|
||||
else:
|
||||
return "mid"
|
||||
|
||||
def fixTangentOvershoot(self, aCurve, keyVal, index, tangentType, curTangType, keysIndexSelN, *args):
|
||||
|
||||
#print "qual index? ", index
|
||||
if index == None: return
|
||||
|
||||
#fix tangent limit ----------------------------------------------------------------------------
|
||||
applied = False
|
||||
|
||||
|
||||
power = .8
|
||||
|
||||
#get in values
|
||||
iy = cmds.keyTangent(aCurve, query=True, index=(index, index), iy=True)[0]/3*power #in tangent handle y position
|
||||
oy = cmds.keyTangent(aCurve, query=True, index=(index, index), oy=True)[0]/3*power #out tangent handle y position
|
||||
|
||||
prevVal = keyVal[index-1]
|
||||
currVal = keyVal[index]
|
||||
nextVal = keyVal[index+1]
|
||||
|
||||
|
||||
#convert to radians if rotate
|
||||
isRotate = animMod.isAnimCurveRotate(aCurve)
|
||||
if isRotate:
|
||||
prevVal = math.radians(prevVal)
|
||||
currVal = math.radians(currVal)
|
||||
nextVal = math.radians(nextVal)
|
||||
|
||||
|
||||
|
||||
difNext = (nextVal-currVal)*power
|
||||
difPrev = (currVal-prevVal)*power
|
||||
|
||||
if (difNext < 0 and oy < difNext) or (difNext > 0 and oy > difNext):
|
||||
cmds.keyTangent(aCurve, edit=True, index=(index, index), inTangentType="auto", outTangentType="auto")
|
||||
|
||||
cmds.keyTangent(aCurve, edit=True, index=(index, index), oy=difNext*3)
|
||||
applied = True
|
||||
|
||||
|
||||
if (difPrev < 0 and iy < difPrev) or (difPrev > 0 and iy > difPrev):
|
||||
cmds.keyTangent(aCurve, edit=True, index=(index, index), inTangentType="auto", outTangentType="auto")
|
||||
|
||||
cmds.keyTangent(aCurve, edit=True, index=(index, index), iy=difPrev*3)
|
||||
|
||||
#print "aplicou index:", index
|
||||
|
||||
if index-1 in keysIndexSelN:
|
||||
cmds.keyTangent(aCurve, edit=True, index=(index-1, index-1), inTangentType="auto", outTangentType="auto")
|
||||
|
||||
self.flowTangent(aCurve, keyVal, index-1, tangentType)
|
||||
applied = True
|
||||
|
||||
#print "flow index:", index-1
|
||||
"""
|
||||
print "--------------------------------"
|
||||
print "index", index
|
||||
print "iy",iy
|
||||
print "oy",oy
|
||||
print "difPrev",difPrev
|
||||
print "prevVal",prevVal
|
||||
print "nextVal",nextVal
|
||||
print "currVal",currVal
|
||||
"""
|
||||
|
||||
|
||||
return applied
|
||||
|
||||
def fixTangentOpposite(self, aCurve, keyVal, index, tangentType, curTangType, keysIndexSelN, *args):
|
||||
|
||||
if index == None: return
|
||||
|
||||
currVal = keyVal[index]
|
||||
nextVal = keyVal[index+1]
|
||||
currTime = cmds.keyframe(aCurve, query=True, index=(index,index), timeChange=True)[0]#current time value
|
||||
nextTime = cmds.keyframe(aCurve, query=True, index=(index+1,index+1), timeChange=True)[0]#current time value
|
||||
|
||||
power = 2
|
||||
|
||||
|
||||
#get in values for next key
|
||||
ix = cmds.keyTangent(aCurve, query=True, index=(index+1,index+1), ix=True)[0] #in tangent handle x position
|
||||
iy = cmds.keyTangent(aCurve, query=True, index=(index+1,index+1), iy=True)[0] #in tangent handle y position
|
||||
|
||||
#get out values
|
||||
ox = cmds.keyTangent(aCurve, query=True, index=(index,index), ox=True)[0] #out tangent handle x position
|
||||
oy = cmds.keyTangent(aCurve, query=True, index=(index,index), oy=True)[0] #out tangent handle y position
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#curve position at handle
|
||||
valIn = nextVal - cmds.keyframe(aCurve, query=True, eval=True, time=(nextTime-ix/.125,nextTime-ix/.125), valueChange=True)[0]
|
||||
valOut = cmds.keyframe(aCurve, query=True, eval=True, time=(currTime+ox/.125,currTime+ox/.125), valueChange=True)[0] - currVal
|
||||
|
||||
#convert to radians if rotate
|
||||
isRotate = animMod.isAnimCurveRotate(aCurve)
|
||||
if isRotate:
|
||||
currVal = math.radians(currVal)
|
||||
nextVal = math.radians(nextVal)
|
||||
valIn = math.radians(valIn)
|
||||
valOut = math.radians(valOut)
|
||||
|
||||
#difference btw val and y
|
||||
difIn = iy/3 - valIn
|
||||
difOut = oy/3 - valOut
|
||||
|
||||
|
||||
|
||||
|
||||
#detect
|
||||
if (difIn > 0 and difOut > 0) or (difIn < 0 and difOut < 0):
|
||||
|
||||
if abs(difIn) > abs(difOut):
|
||||
inOut = "in"
|
||||
|
||||
else:
|
||||
inOut = "out"
|
||||
|
||||
|
||||
for x in range(5):
|
||||
currVal = keyVal[index]
|
||||
nextVal = keyVal[index+1]
|
||||
#get in values for next key
|
||||
ix = cmds.keyTangent(aCurve, query=True, index=(index+1,index+1), ix=True)[0] #in tangent handle x position
|
||||
iy = cmds.keyTangent(aCurve, query=True, index=(index+1,index+1), iy=True)[0] #in tangent handle y position
|
||||
|
||||
#get out values
|
||||
ox = cmds.keyTangent(aCurve, query=True, index=(index,index), ox=True)[0] #out tangent handle x position
|
||||
oy = cmds.keyTangent(aCurve, query=True, index=(index,index), oy=True)[0] #out tangent handle y position
|
||||
|
||||
#curve position at handle
|
||||
valIn = nextVal - cmds.keyframe(aCurve, query=True, eval=True, time=(nextTime-ix/.125,nextTime-ix/.125), valueChange=True)[0]
|
||||
valOut = cmds.keyframe(aCurve, query=True, eval=True, time=(currTime+ox/.125,currTime+ox/.125), valueChange=True)[0] - currVal
|
||||
|
||||
#convert to radians if rotate
|
||||
isRotate = animMod.isAnimCurveRotate(aCurve)
|
||||
if isRotate:
|
||||
currVal = math.radians(currVal)
|
||||
nextVal = math.radians(nextVal)
|
||||
valIn = math.radians(valIn)
|
||||
valOut = math.radians(valOut)
|
||||
|
||||
#difference btw val and y
|
||||
difIn = iy/3 - valIn
|
||||
difOut = oy/3 - valOut
|
||||
|
||||
if inOut == "in":
|
||||
#print"IN"
|
||||
|
||||
#if next key is is array
|
||||
if index+1 in keysIndexSelN:
|
||||
|
||||
newY = (iy/3) + (valOut-(oy/3))*power
|
||||
cmds.keyTangent(aCurve, edit=True, index=(index+1, index+1), iy=newY*3, oy=newY*3, ox=ix)
|
||||
|
||||
|
||||
else:
|
||||
#print"OUT"
|
||||
newY = (oy/3) + (valIn-(iy/3))*power
|
||||
cmds.keyTangent(aCurve, edit=True, index=(index, index), iy=newY*3, oy=newY*3, ix=ox)
|
||||
|
||||
|
||||
|
||||
"""
|
||||
print "index",index
|
||||
print "difIn",difIn
|
||||
print "difOut",difOut
|
||||
print "iy",iy
|
||||
print "oy",oy
|
||||
print "iy/3",iy/3
|
||||
print "oy/3",oy/3
|
||||
print "valIn",valIn
|
||||
print "valOut",valOut
|
||||
print "currVal",currVal
|
||||
print "nextVal",nextVal
|
||||
print "------------------------------"
|
||||
"""
|
||||
|
||||
def averageTangent(self, aCurve, keyVal, index, tangentType, curTangType, keysIndexSelN, keyTimes, *args):
|
||||
# average
|
||||
|
||||
cmds.keyTangent(aCurve, edit=True, index=(index, index), inTangentType="linear", outTangentType="linear")
|
||||
|
||||
if tangentType == "flow":
|
||||
if curTangType == "Zero":
|
||||
mAngle = 0
|
||||
else:
|
||||
mAngle = self.getAverageAngle(keyVal, keyTimes, index)
|
||||
|
||||
if index == 0:
|
||||
cmds.keyTangent(aCurve, edit=True, index=(index, index), outTangentType="linear")
|
||||
return
|
||||
if index == len(keyVal)-1:
|
||||
cmds.keyTangent(aCurve, edit=True, index=(index, index), inTangentType="linear")
|
||||
return
|
||||
|
||||
cmds.keyTangent(aCurve, edit=True, index=(index, index), inAngle=mAngle, outAngle=mAngle)
|
||||
|
||||
|
||||
#if tangentType == "bounce":
|
||||
#cmds.keyTangent(aCurve, edit=True, index=(index, index), inTangentType="linear", outTangentType="linear")
|
||||
|
||||
def flowTangent(self, aCurve, keyVal, index, tangentType, curTangType, *args):
|
||||
|
||||
if curTangType == "Zero" and tangentType == "flow": return
|
||||
|
||||
if index == None: return
|
||||
|
||||
#is it first or last key?
|
||||
keyLocation = self.getKeyLocation(keyVal, index)
|
||||
|
||||
if keyLocation != "mid" and tangentType != "bounce": return
|
||||
|
||||
currVal = keyVal[index]
|
||||
currTime = cmds.keyframe(aCurve, query=True, index=(index,index), timeChange=True)[0]#current time value
|
||||
|
||||
#get in values
|
||||
ix = cmds.keyTangent(aCurve, query=True, index=(index,index), ix=True)[0] #in tangent handle x position
|
||||
iy = cmds.keyTangent(aCurve, query=True, index=(index,index), iy=True)[0] #in tangent handle y position
|
||||
|
||||
#get out values
|
||||
ox = cmds.keyTangent(aCurve, query=True, index=(index,index), ox=True)[0] #out tangent handle x position
|
||||
oy = cmds.keyTangent(aCurve, query=True, index=(index,index), oy=True)[0] #out tangent handle y position
|
||||
|
||||
cmds.undoInfo(stateWithoutFlush=False)
|
||||
cmds.keyTangent(aCurve, index=(index,index), lock=False)
|
||||
cmds.undoInfo(stateWithoutFlush=True)
|
||||
if tangentType == "flow":
|
||||
if ox>ix:
|
||||
ox = ix
|
||||
oy = iy
|
||||
cmds.keyTangent(aCurve, edit=True, index=(index, index), ox=ox, oy=oy)
|
||||
else:
|
||||
ix = ox
|
||||
iy = oy
|
||||
cmds.keyTangent(aCurve, edit=True, index=(index, index), ix=ix, iy=iy)
|
||||
|
||||
|
||||
#curve position at handle
|
||||
valIn = cmds.keyframe(aCurve, query=True, eval=True, time=(currTime-ix/.125,currTime-ix/.125), valueChange=True)[0]
|
||||
valOut = cmds.keyframe(aCurve, query=True, eval=True, time=(currTime+ox/.125,currTime+ox/.125), valueChange=True)[0]
|
||||
|
||||
|
||||
#if the anim curve is rotate, convert to radians
|
||||
isRotate = animMod.isAnimCurveRotate(aCurve)
|
||||
if isRotate:
|
||||
currVal = math.radians(currVal)
|
||||
valIn = math.radians(valIn)
|
||||
valOut = math.radians(valOut)
|
||||
#print "isrotate"
|
||||
|
||||
#distance between the curve position and the key value
|
||||
distValueIn = (valIn-currVal)
|
||||
distValueOut = (valOut-currVal)
|
||||
|
||||
#distance between the curve position and the tangent y position
|
||||
distTangIn = distValueIn+(iy/3)
|
||||
distTangOut = distValueOut-(oy/3)
|
||||
|
||||
|
||||
if tangentType == "flow":
|
||||
|
||||
# calculate the difference btween the distances between the curve position and the tangent y position
|
||||
dif = (distTangIn-distTangOut)
|
||||
|
||||
newOy = (oy/3)-dif
|
||||
|
||||
#newIy = (iy/3)-dif
|
||||
newIy = newOy
|
||||
|
||||
#print "newIy",newIy,"(iy/3)",(iy/3),"(oy/3)",(oy/3),"currVal",currVal,"valOut",valOut,"distIn",distTangIn,"distOut",distTangOut,"dif",dif,"distValueIn",distValueIn,"distValueOut",distValueOut
|
||||
|
||||
elif tangentType == "bounce":
|
||||
newIy = -distValueIn+(-distValueIn-(iy/3))
|
||||
newOy = distValueOut+(distValueOut-(oy/3))
|
||||
|
||||
"""
|
||||
print "---------------------------"
|
||||
print "newIy",newIy
|
||||
print "newOy",newOy
|
||||
print "(iy/3)",(iy/3)
|
||||
print "(oy/3)",(oy/3)
|
||||
print "currVal",currVal
|
||||
print "valOut",valOut
|
||||
print "distIn",distTangIn
|
||||
print "distOut",distTangOut
|
||||
print "distValueIn",distValueIn
|
||||
print "distValueOut",distValueOut
|
||||
"""
|
||||
|
||||
#apply
|
||||
|
||||
cmds.keyTangent(aCurve, edit=True, index=(index, index), iy=newIy*3, oy=newOy*3)
|
||||
|
Reference in New Issue
Block a user