def _longName( obj ): if type(obj) not in [types.StringType,types.UnicodeType]: return obj.longName() if unicode(obj[0]) != unicode('|'): objs = maya.cmds.ls(obj,long=True) if len(objs)>1: logger.warn( maya.stringTable[ 'y_BulletUtils.kLongNameAmbiguity' ] % obj ) return objs[0] return obj
def getRigidBodyFromTransform(transform): """ Given a transform (by name), return the rigid body. This method encapsulates the logic behind the RB hierarchies. Currently that hierarchy looks like: init_xform rb_xform rb_shape """ logger.debug(maya.stringTable['y_BulletUtils.kGettingRB'] % transform) if transform: xformNode = _longName(transform) else: return None # first check if this is a rigid body xform... shapeNodes = _getChildren(xformNode, type=("bulletRigidBodyShape", "bulletSoftBodyShape", "bulletSolverShape", "bulletRigidBodyConstraintShape", "bulletSoftConstraintShape")) if (len(shapeNodes) > 1): logger.warn(maya.stringTable['y_BulletUtils.kExceptedShapeUnder'] % xformNode) if (len(shapeNodes) > 0): return shapeNodes[0] # no match? check if the xform was the init xform... for childXformNode in _getChildren(xformNode, type="transform"): shapeNodes = _getChildren( childXformNode, type=("bulletRigidBodyShape", "bulletSoftBodyShape", "bulletSolverShape", "bulletRigidBodyConstraintShape", "bulletSoftConstraintShape")) if (len(shapeNodes) > 1): logger.warn( maya.stringTable['y_BulletUtils.kExceptedShapeUnder2'] % childXformNode) if (len(shapeNodes) > 0): return shapeNodes[0] # end-for # didn't find any RB shapes in the expected places return None
def addCapsulesToSkeleton(rootJointName=None, capsuleBoneRatio=DEFAULT_CAPSULE_LENGTH, capsuleRadiusRatio=DEFAULT_CAPSULE_RADIUS): """ This method traverses a joint hierarchy, adding kinematic rigid body capsules to the bones. If the name of the root joint is provided, the traversal will begin at that joint. Otherwise, the currently selected joint(s) will be used. """ initialSelection = maya.cmds.ls(long=True, selection=True) nodesToVisit = deque(_getNodesToVisit(rootJointName)) if not nodesToVisit or len(nodesToVisit) < 1: maya.OpenMaya.MGlobal.displayError( maya.stringTable['y_Ragdoll.kAddCollidersSelectJoint']) return while (len(nodesToVisit) > 0): currentJoint = nodesToVisit.popleft() logger.debug(maya.stringTable['y_Ragdoll.kVisiting'] % currentJoint) # within the current iteration, we will consider only other # joints attached to the current joint children = [ child for child in _getChildren(currentJoint) \ if _isJoint(child) ] # future iterations need only consider joints with children nodesToVisit.extend( [child for child in children \ if _numChildren(child) > 0] ) prevCapsules = [child for child in _getChildren(currentJoint) \ if RB_XFORM_PREFIX in _name(child)] # examine the bones between this joint and its child joints... for childJoint in children: logger.debug(maya.stringTable['y_Ragdoll.kBoneFromTo'] % (currentJoint, childJoint)) boneVector = _getTranslation(childJoint) bCapsuleExists = False for prevCapsuleXform in prevCapsules: if _getTranslation(prevCapsuleXform) == boneVector * 0.5: bCapsuleExists = True break # end-if # end-for if (bCapsuleExists): logger.warn(maya.stringTable['y_Ragdoll.kSkippingBone']) continue # end-if _createCapsule( currentJoint, childJoint, bAttachToJoint=True, # colliders for animation should be kinematic, # with zero mass bodyType=eBodyType.kKinematicRigidBody, mass=0.0, boneLengthRatio=capsuleBoneRatio, lengthRadiusRatio=capsuleRadiusRatio) # end-for # end-while # restore the initial selection maya.cmds.select(initialSelection, replace=True)