def getAlignedBoundsForJoint(joint, threshold=0.65, onlyVisibleMeshes=True): ''' looks at the verts the given joint/s and determines a local space (local to the first joint in the list if multiple are given) bounding box of the verts, and positions the hitbox accordingly if onlyVisibleMeshes is True, then only meshes that are visible in the viewport will contribute to the bounds ''' theJoint = joint verts = [] #so this is just to deal with the input arg being a tuple, list or string. you can pass in a list #of joint names and the verts affected just get accumulated into a list, and the resulting bound #should be the inclusive bounding box for the given joints if isinstance(joint, (tuple, list)): theJoint = joint[0] for joint in joint: verts += jointVertsForMaya(joint, threshold, onlyVisibleMeshes) else: verts += jointVertsForMaya(joint, threshold, onlyVisibleMeshes) jointDag = api.getMDagPath(theJoint) jointMatrix = jointDag.inclusiveMatrix() vJointPos = OpenMaya.MTransformationMatrix(jointMatrix).rotatePivot( OpenMaya.MSpace.kWorld) + OpenMaya.MTransformationMatrix( jointMatrix).getTranslation(OpenMaya.MSpace.kWorld) vJointPos = Vector([vJointPos.x, vJointPos.y, vJointPos.z]) vJointBasisX = OpenMaya.MVector(-1, 0, 0) * jointMatrix vJointBasisY = OpenMaya.MVector(0, -1, 0) * jointMatrix vJointBasisZ = OpenMaya.MVector(0, 0, -1) * jointMatrix bbox = OpenMaya.MBoundingBox() for vert in verts: #get the position relative to the joint in question vPos = Vector(xform(vert, query=True, ws=True, t=True)) vPos = vJointPos - vPos #now transform the joint relative position into the coordinate space of that joint #we do this so we can get the width, height and depth of the bounds of the verts #in the space oriented along the joint vPosInJointSpace = Vector((vPos.x, vPos.y, vPos.z)) vPosInJointSpace = vPosInJointSpace.change_space( vJointBasisX, vJointBasisY, vJointBasisZ) bbox.expand(OpenMaya.MPoint(*vPosInJointSpace)) minB, maxB = bbox.min(), bbox.max() return minB[0], minB[1], minB[2], maxB[0], maxB[1], maxB[2]
def getAlignedBoundsForJoint(joint, threshold=0.65, onlyVisibleMeshes=True): """ looks at the verts the given joint/s and determines a local space (local to the first joint in the list if multiple are given) bounding box of the verts, and positions the hitbox accordingly if onlyVisibleMeshes is True, then only meshes that are visible in the viewport will contribute to the bounds """ theJoint = joint verts = [] # so this is just to deal with the input arg being a tuple, list or string. you can pass in a list # of joint names and the verts affected just get accumulated into a list, and the resulting bound # should be the inclusive bounding box for the given joints if isinstance(joint, (tuple, list)): theJoint = joint[0] for joint in joint: verts += jointVertsForMaya(joint, threshold, onlyVisibleMeshes) else: verts += jointVertsForMaya(joint, threshold, onlyVisibleMeshes) jointDag = api.getMDagPath(theJoint) jointMatrix = jointDag.inclusiveMatrix() vJointPos = OpenMaya.MTransformationMatrix(jointMatrix).rotatePivot( OpenMaya.MSpace.kWorld ) + OpenMaya.MTransformationMatrix(jointMatrix).getTranslation(OpenMaya.MSpace.kWorld) vJointPos = Vector([vJointPos.x, vJointPos.y, vJointPos.z]) vJointBasisX = OpenMaya.MVector(-1, 0, 0) * jointMatrix vJointBasisY = OpenMaya.MVector(0, -1, 0) * jointMatrix vJointBasisZ = OpenMaya.MVector(0, 0, -1) * jointMatrix bbox = OpenMaya.MBoundingBox() for vert in verts: # get the position relative to the joint in question vPos = Vector(xform(vert, query=True, ws=True, t=True)) vPos = vJointPos - vPos # now transform the joint relative position into the coordinate space of that joint # we do this so we can get the width, height and depth of the bounds of the verts # in the space oriented along the joint vPosInJointSpace = Vector((vPos.x, vPos.y, vPos.z)) vPosInJointSpace = vPosInJointSpace.change_space(vJointBasisX, vJointBasisY, vJointBasisZ) bbox.expand(OpenMaya.MPoint(*vPosInJointSpace)) minB, maxB = bbox.min(), bbox.max() return minB[0], minB[1], minB[2], maxB[0], maxB[1], maxB[2]