Exporting Collision Geometry from Maya (and other editors)

I found people asking about this on the forums but I never found a solution so I thought I’d post a solution I came up with in a group project recently. The code is by no means ideal but hopefully it’ll help anyone get started with trying to do the same thing as we were.

The code is here: gist.github.com/AWhetter/4dee6698e96b335f238d

The main functions are calcCollisionShape and calcSize.
calcCollisionShape takes two strings. ‘shape’ represents the shape of the collision geometry to generate and is one of “box”, “sphere”, “cylinder”, “cone”, “hull”, “mesh”, or “geometry”. All bar “geometry” will create one shape over the entire model. “geometry” will use calcCollisionGeometryShapes to create collision geometry from what’s been exported from Maya.
‘model’ is a string representing the location of the model to make the geometry for. It’s fed straight into loader.loadModel so accepts the same strings as that.
It returns a list of tuples. Each tuple contains the collision shape and the TransformState representing the shape offset so that the model doesn’t need to be centred in Maya for the collision shape to be generated properly. We were using these lists like this:

for shape, transform in self.calcCollisionShape(collision_shape, model_loc):
    rigid_body_node.addShape(shape, transform)

In Maya collision geometry is created by naming the object collision_x_name, where ‘x’ is one of the collision shapes mentioned above excluding “geometry” (so “box”, “sphere”, “cylinder”, “cone”, “hull”, or “mesh”). ‘name’ is any name you want to give the object. (eg collision_box_crate or collision_cone_icecream). The collision geometry needs to be visible, but it can be removed in code (mentioned later).
Any model with collision geometry will need to have been converted using ‘-a pose’ in maya2egg (eg maya2egg -a pose -o model.egg model.mb). This means that the geometry nodes won’t be flattened automatically by the model loader and we can use them to generate collision geometry. It also means that you’ll need to do flattening yourself. We were using this code in a server-client game where the server only needed the collision geometry and the client only needed the model. Therefore calcCollisionShape doesn’t return the model and we were doing the flattening on the client. We did this with the following code:

model = loader.loadModel(model_loc)
for node in model.findAllMatches('**/collision*'):
    node.removeNode()
model.flattenStrong()

Currently the code does not allow the collision geometry in Maya to be rotated. We only needed this a couple of times so just used hulls. You could tag the collision object in Maya so that the transform gets exported into the egg file and extend the code to look for that as well.