def getJointBounds(joints, threshold=0.65, space=SPACE_OBJECT): ''' if the joints are skinned, then the influenced verts that have weights greater than the given influenced are transformed into the space specified (if SPACE_OBJECT is used, the space of the first joint is used), and the bounds of the verts in this space are returned as a 2-tuple of bbMin, bbMax ''' global MVector, MTransformationMatrix, Vector if not isinstance(joints, (list, tuple)): joints = [joints] theJoint = joints[0] verts = [] for j in joints: verts += meshUtils.jointVertsForMaya(j, threshold) jointDag = apiExtensions.asMDagPath(theJoint) if space == SPACE_OBJECT: jointMatrix = jointDag.inclusiveMatrix() elif space == SPACE_LOCAL: jointMatrix = jointDag.exclusiveMatrix() elif space == SPACE_WORLD: jointMatrix = OpenMaya.MMatrix() else: raise TypeError("Invalid space specified") vJointPos = MTransformationMatrix(jointMatrix).rotatePivot( kWorld) + MTransformationMatrix(jointMatrix).getTranslation(kWorld) vJointPos = Vector([vJointPos.x, vJointPos.y, vJointPos.z]) vJointBasisX = MVector(-1, 0, 0) * jointMatrix vJointBasisY = MVector(0, -1, 0) * jointMatrix vJointBasisZ = MVector(0, 0, -1) * jointMatrix bbox = 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) vPosInJointSpace = vPosInJointSpace.change_space( vJointBasisX, vJointBasisY, vJointBasisZ) bbox.expand(MPoint(*vPosInJointSpace)) bbMin, bbMax = bbox.min(), bbox.max() bbMin = Vector([bbMin.x, bbMin.y, bbMin.z]) bbMax = Vector([bbMax.x, bbMax.y, bbMax.z]) return bbMin, bbMax
def getJointBounds( joints, threshold=0.65, space=SPACE_OBJECT ): ''' if the joints are skinned, then the influenced verts that have weights greater than the given influenced are transformed into the space specified (if SPACE_OBJECT is used, the space of the first joint is used), and the bounds of the verts in this space are returned as a 2-tuple of bbMin, bbMax ''' global MVector, MTransformationMatrix, Vector if not isinstance( joints, (list, tuple) ): joints = [ joints ] theJoint = joints[ 0 ] verts = [] for j in joints: verts += meshUtils.jointVertsForMaya( j, threshold ) jointDag = apiExtensions.asMDagPath( theJoint ) if space == SPACE_OBJECT: jointMatrix = jointDag.inclusiveMatrix() elif space == SPACE_LOCAL: jointMatrix = jointDag.exclusiveMatrix() elif space == SPACE_WORLD: jointMatrix = OpenMaya.MMatrix() else: raise TypeError( "Invalid space specified" ) vJointPos = MTransformationMatrix( jointMatrix ).rotatePivot( kWorld ) + MTransformationMatrix( jointMatrix ).getTranslation( kWorld ) vJointPos = Vector( [vJointPos.x, vJointPos.y, vJointPos.z] ) vJointBasisX = MVector(-1,0,0) * jointMatrix vJointBasisY = MVector(0,-1,0) * jointMatrix vJointBasisZ = MVector(0,0,-1) * jointMatrix bbox = 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 ) vPosInJointSpace = vPosInJointSpace.change_space( vJointBasisX, vJointBasisY, vJointBasisZ ) bbox.expand( MPoint( *vPosInJointSpace ) ) bbMin, bbMax = bbox.min(), bbox.max() bbMin = Vector( [bbMin.x, bbMin.y, bbMin.z] ) bbMax = Vector( [bbMax.x, bbMax.y, bbMax.z] ) return bbMin, bbMax
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 = apiExtensions.asMDagPath(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 = apiExtensions.asMDagPath( 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]