Tuesday 12 September 2017

Working with multiple Bullet solvers in a scene

When creating a Bullet body in a Maya scene in which there are multiple Bullet solvers, Maya simply picks the first solver it encounters and assigns that to the new body. This is almost always not the one you actually need. Unfortunately there are no tools to assign a different solver to a body.
In order to get around this issue, I modified the Bullet scripts that come with Maya. It's a quick hack, but it allows me to get on with things.
The part of code responsible for picking the solver is found in C:\Program Files\Autodesk\Maya2016\Python\Lib\site-packages\maya\app\mayabullet\BulletUtils.py in a function named getSolver. As you will see if you read it, it simply picks the first solver found in the scene. I have added the following bit of code:
try: if maya.cmds.optionVar( exists='preferredBulletSolver' ) :
preferedSolverName = maya.cmds.optionVar( q='preferredBulletSolver' )
preferedSolvers = maya.cmds.ls(preferedSolverName, type='bulletSolverShape',long=True)
if len(preferedSolvers)>0:
solvers = preferedSolvers
except:
pass
 This gets inserted from the third line of code in the function, right after the line that reads solvers = maya.cmds.ls(type='bulletSolverShape',long=True). What it does is it checks for an optionVar named preferredBulletSolver. An optionVar is Maya's way of storing user settings which are persistent and accessible to scripts. We can store the name of a solver in it, and when we come to create a new rigid body, the script will pick up on it and use that solver. Here is a piece of code that creates or updates the optionVar:
import maya.cmds as mc
selectedSolvers = mc.ls(sl=True, typ='bulletSolverShape')
if len(selectedSolvers) == 0 :
selectedSolvers = mc.listRelatives(mc.ls(sl=True), typ='bulletSolverShape')
if selectedSolvers is None or len(selectedSolvers) == 0 :
mc.warning( "Select a Bullet solver." )
else :
mc.optionVar( stringValue=('preferredBulletSolver', selectedSolvers[0]) )
mc.warning( "New Bullet rigid bodies will use the solver: " + selectedSolvers[0] )
I keep it as a shelf button. It is used by selecting the desired solver, then clicking the shelf button. From then on, newly created Bullet bodies will use the solver I selected, rather then some random one.