Skip to content

Commit

Permalink
adding ballisticAnimation tool, minor bug fixes for puppet and utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
morganloomis committed Oct 1, 2016
1 parent 695b18e commit 63d000b
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 8 deletions.
131 changes: 131 additions & 0 deletions ml_ballisticAnimation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#
# -= ml_ballisticAnimation.py =-
# __ by Morgan Loomis
# ____ ___ / / http://morganloomis.com
# / __ `__ \/ / Licensed under Creative Commons BY-SA
# / / / / / / / http://creativecommons.org/licenses/by-sa/3.0/
# /_/ /_/ /_/_/ _________
# /_________/ Revision 1, 2016-10-01
# _______________________________
# - -/__ Installing Python Scripts __/- - - - - - - - - - - - - - - - - - - -
#
# Copy this file into your maya scripts directory, for example:
# C:/Documents and Settings/user/My Documents/maya/scripts/ml_ballisticAnimation.py
#
# Run the tool by importing the module, and then calling the primary function.
# From python, this looks like:
# import ml_ballisticAnimation
# ml_ballisticAnimation.main()
# From MEL, this looks like:
# python("import ml_ballisticAnimation;ml_ballisticAnimation.main()");
# _________________
# - -/__ Description __/- - - - - - - - - - - - - - - - - - - - - - - - - - -
#
# Runs very simple gravity physics on the translation of an object, taking into account
# initial velocity.
# ___________
# - -/__ Usage __/- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
# Simply select a static or animated object, highlight or set your frame range, and run the script.
# If your object is already animated, the initial velocity will be calculated based
# on the position one frame before the frirst frame of the frame range.
# __________________
# - -/__ Requirements __/- - - - - - - - - - - - - - - - - - - - - - - - - -
#
# This script requires the ml_utilities module, which can be downloaded here:
# http://morganloomis.com/wiki/tools.html#ml_utilities
# __________
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /_ Enjoy! _/- - -
__author__ = 'Morgan Loomis'
__license__ = 'Creative Commons Attribution-ShareAlike'
__category__ = 'animationScripts'
__revision__ = 1


import maya.cmds as mc
try:
import ml_utilities as utl
utl.upToDateCheck(22)
except ImportError:
result = mc.confirmDialog( title='Module Not Found',
message='This tool requires the ml_utilities module. Once downloaded you will need to restart Maya.',
button=['Download Module','Cancel'],
defaultButton='Cancel', cancelButton='Cancel', dismissString='Cancel' )

if result == 'Download Module':
mc.showHelp('http://morganloomis.com/download/animationScripts/ml_utilities.py',absolute=True)


def main():

sel = mc.ls(sl=True)

if not sel:
raise RuntimeError('Please select an object.')

if [x for x in sel if not mc.attributeQuery('translate', exists=True, node=x)]:
raise RuntimeError('Only works on transform nodes, please adjust your selection.')

frameRate = utl.getFrameRate()
timeFactor = 1.0/frameRate

unit = mc.currentUnit(query=True, linear=True)

#default is meters
distFactor = 1

if unit == 'mm':
distFactor = 1000
elif unit == 'cm':
distFactor = 100
elif unit == 'km':
distFactor = 0.001
elif unit == 'in':
distFactor = 39.3701
elif unit == 'ft':
distFactor = 3.28084
elif unit == 'yd':
distFactor = 1.09361
elif unit == 'mi':
distFactor = 0.000621371

g = 9.8 * distFactor

start, end = utl.frameRange()
start = int(start)
end = int(end)

mc.currentTime(start)

for each in sel:

mc.setKeyframe(each+'.translate')
startTrans = mc.getAttr(each+'.translate')[0]
prevTrans = [mc.keyframe(each, query=True, attribute=x, eval=True, time=(start-1,))[0] for x in ('tx','ty','tz')]

xInit = startTrans[0]-prevTrans[0]
yInit = startTrans[1]-prevTrans[1]
zInit = startTrans[2]-prevTrans[2]

mc.cutKey(each, attribute='translate', time=(start+0.1,end+0.5))
mc.setKeyframe(each, attribute='translateX', time=start+1, value=startTrans[0]+xInit)
mc.setKeyframe(each, attribute='translateZ', time=start+1, value=startTrans[2]+zInit)
mc.setKeyframe(each, attribute='translateX', time=end-1, value=startTrans[0]+(xInit*(end-start-1)))
mc.setKeyframe(each, attribute='translateZ', time=end-1, value=startTrans[2]+(zInit*(end-start-1)))
mc.setKeyframe(each, attribute='translateX', time=end, value=startTrans[0]+(xInit*(end-start)))
mc.setKeyframe(each, attribute='translateZ', time=end, value=startTrans[2]+(zInit*(end-start)))

for i,f in enumerate(range(start,end+1)):
t = i * timeFactor
y = startTrans[1] + (i * yInit) - (g * t * t)/2

mc.setKeyframe(each, attribute='translateY', time=f, value=y)


if __name__ == '__main__':
main()

# ______________________
# - -/__ Revision History __/- - - - - - - - - - - - - - - - - - - - - - - -
#
# Revision 1: 2016-10-01 : First publish.
10 changes: 6 additions & 4 deletions ml_puppet.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# / __ `__ \/ / Licensed under Creative Commons BY-SA
# / / / / / / / http://creativecommons.org/licenses/by-sa/3.0/
# /_/ /_/ /_/_/ _________
# /_________/ Revision 9, 2015-11-18
# /_________/ Revision 10, 2016-09-25
# _______________________________
# - -/__ Installing Python Scripts __/- - - - - - - - - - - - - - - - - - - -
#
Expand Down Expand Up @@ -44,7 +44,7 @@
__author__ = 'Morgan Loomis'
__license__ = 'Creative Commons Attribution-ShareAlike'
__category__ = 'animationScripts'
__revision__ = 9
__revision__ = 10

import maya.cmds as mc
import maya.mel as mm
Expand All @@ -53,7 +53,7 @@

try:
import ml_utilities as utl
utl.upToDateCheck(15)
utl.upToDateCheck(21)
except ImportError:
result = mc.confirmDialog( title='Module Not Found',
message='This tool requires the ml_utilities module. Once downloaded you will need to restart Maya.',
Expand Down Expand Up @@ -503,7 +503,7 @@ def fkIkSwitch(nodes=None, switchTo=None, switchRange=False, bakeOnOnes=False):
matchControls.extend(data['fkChain'])

if switchRange:
keytimes = mc.keyframe([data['ikControl'],data['pvControl']], time=(start,end), query=True, timeChange=True)
keytimes = mc.keyframe([data['ikControls'],data['pvControl']], time=(start,end), query=True, timeChange=True)
if keytimes:
elemDict[elem]['keytimes'] = list(set(keytimes))
else:
Expand Down Expand Up @@ -962,3 +962,5 @@ def convertRotateOrderUI(nodes, *args):
# Revision 8: 2015-06-23 : puppet context menu fix for windows paths
#
# Revision 9: 2015-11-18 : Updated fk ik switching code for latest puppeteer
#
# Revision 10: 2016-09-25 : Minor KeyError bug fix.
44 changes: 40 additions & 4 deletions ml_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# / __ `__ \/ / Licensed under Creative Commons BY-SA
# / / / / / / / http://creativecommons.org/licenses/by-sa/3.0/
# /_/ /_/ /_/_/ _________
# /_________/ Revision 21, 2016-08-11
# /_________/ Revision 22, 2016-10-01
# _______________________________
# - -/__ Installing Python Scripts __/- - - - - - - - - - - - - - - - - - - -
#
Expand Down Expand Up @@ -34,7 +34,7 @@
__author__ = 'Morgan Loomis'
__license__ = 'Creative Commons Attribution-ShareAlike'
__category__ = 'animationScripts'
__revision__ = 21
__revision__ = 22

import maya.cmds as mc
import maya.mel as mm
Expand Down Expand Up @@ -329,7 +329,8 @@ def frameRange(start=None, end=None):
gPlayBackSlider = mm.eval('$temp=$gPlayBackSlider')
if mc.timeControl(gPlayBackSlider, query=True, rangeVisible=True):
frameRange = mc.timeControl(gPlayBackSlider, query=True, rangeArray=True)
return frameRange
start = frameRange[0]
end = frameRange[1]-1
else:
start = mc.playbackOptions(query=True, min=True)
end = mc.playbackOptions(query=True, max=True)
Expand Down Expand Up @@ -1739,7 +1740,7 @@ def buildWindow(self):

mc.text(label=self.info)
mc.setParent('..')
mc.separator(height=8, style='single')
mc.separator(height=8, style='single', horizontal=True)


def finish(self):
Expand Down Expand Up @@ -1858,6 +1859,39 @@ def hotkeyMenuItem(self, command=None, annotation='', menuLabel='Create Hotkey')
command='import ml_utilities;ml_utilities.createHotkey(\"'+melCommand+'\", \"'+self.name+'\", description=\"'+annotation+'\")',
enableCommandRepeat=True,
image='commandButton')


def selectionField(self, label='', annotation='', channel=False):
'''
Create a field with a button that adds the selection to the field.
'''
field = mc.textFieldButtonGrp(label=label, text='',
buttonLabel='Set Selected',
buttonCommand=self.setCorrectiveDriverPlug)
mc.textFieldButtonGrp(field, edit=True, buttonCommand=partial(self._populateSelectionField, channel, field))


def _populateSelectionField(self, channel, field, *args):

selectedChannels = None
if channel:
selectedChannels = getSelectedChannels()
if not selectedChannels:
raise RuntimeError('Please select an attribute in the channelBox.')
if len(selectedChannels) > 1:
raise RuntimeError('Please select only one attribute.')

sel = mc.ls(sl=True)
if not sel:
raise RuntimeError('Please select a node.')
if len(sel) > 1:
raise RuntimeError('Please select only one node.')

selection = sel[0]
if selectedChannels:
selection = selection+'.'+selectedChannels[0]

mc.textFieldButtonGrp(field, edit=True, text=selection)


class ButtonWithPopup():
Expand Down Expand Up @@ -2068,3 +2102,5 @@ def __exit__(self, *args):
# Revision 21: 2016-07-31 : MlUi bug fixes.
#
# Revision 21: 2016-08-11 : windows support for icons
#
# Revision 22: 2016-10-01 : changing frameRange to return consistent results when returning timeline or selection.

0 comments on commit 63d000b

Please sign in to comment.