clearListener() filein "rockstar/export/settings.ms" -- This is fast -- Figure out the project theProjectRoot = RsConfigGetProjRootDir() theProject = RSConfigGetProjectName() theWildWest = RsConfigGetWildWestDir() theProjectConfig = RsConfigGetProjBinConfigDir() toolsRoot = RsConfigGetToolsRootDir() -- filein (RsConfigGetWildWestDir() + "script\\max\\Rockstar_North\\character\\Includes\\FN_Rigging.ms") filein (theWildWest + "script/3dsMax/_config_files/Wildwest_header.ms") filein (theWildWest + "script/3dsMax/_common_functions/FN_RSTA_Rigging.ms") filein (theWildWest + "script/3dsMax/_common_functions/FN_RSTA_UI.ms") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- geoArray = #( #($Geo_Pelvis, $SKEL_Pelvis), #($Geo_Spine0, $SKEL_Spine0), #($Geo_Spine1, $SKEL_Spine1), #($Geo_Spine2, $SKEL_Spine2), #($Geo_Spine3, $SKEL_Spine3), #($Geo_Neck_1, $SKEL_Neck_1), #($Geo_RB_Neck_1, $RB_Neck_1), #($Geo_Head, $Skel_Head), #($Geo_L_Clavicle, $Skel_L_Clavicle), #($Geo_RB_L_ArmRoll, $RB_L_ArmRoll), #($Geo_L_UpperArm, $SKEL_L_UpperArm), #($Geo_L_Forearm, $SKEL_L_Forearm), #($Geo_RB_L_ForeArmRoll, $RB_L_ForeArmRoll), #($Geo_L_Hand, $SKEL_L_Hand), #($Geo_L_Finger00, $SKEL_L_Finger00), #($Geo_L_Finger01, $SKEL_L_Finger01), #($Geo_L_Finger02, $SKEL_L_Finger02), #($Geo_L_Finger10, $SKEL_L_Finger10), #($Geo_L_Finger11, $SKEL_L_Finger11), #($Geo_L_Finger12, $SKEL_L_Finger12), #($Geo_L_Finger20, $SKEL_L_Finger20), #($Geo_L_Finger21, $SKEL_L_Finger21), #($Geo_L_Finger22, $SKEL_L_Finger22), #($Geo_L_Finger30, $SKEL_L_Finger30), #($Geo_L_Finger31, $SKEL_L_Finger31), #($Geo_L_Finger32, $SKEL_L_Finger32), #($Geo_L_Finger40, $SKEL_L_Finger40), #($Geo_L_Finger41, $SKEL_L_Finger41), #($Geo_L_Finger42, $SKEL_L_Finger42), #($Geo_R_Clavicle, $SKEL_R_Clavicle), #($Geo_RB_R_ArmRoll, $RB_R_ArmRoll), #($Geo_R_UpperArm, $SKEL_R_UpperArm), #($Geo_R_Forearm, $SKEL_R_Forearm), #($Geo_RB_R_ForeArmRoll, $RB_R_ForeArmRoll), #($Geo_R_Hand, $SKEL_R_Hand), #($Geo_R_Finger00, $SKEL_R_Finger00), #($Geo_R_Finger01, $SKEL_R_Finger01), #($Geo_R_Finger02, $SKEL_R_Finger02), #($Geo_R_Finger10, $SKEL_R_Finger10), #($Geo_R_Finger11, $SKEL_R_Finger11), #($Geo_R_Finger12, $SKEL_R_Finger12), #($Geo_R_Finger20, $SKEL_R_Finger20), #($Geo_R_Finger21, $SKEL_R_Finger21), #($Geo_R_Finger22, $SKEL_R_Finger22), #($Geo_R_Finger30, $SKEL_R_Finger30), #($Geo_R_Finger31, $SKEL_R_Finger31), #($Geo_R_Finger32, $SKEL_R_Finger32), #($Geo_R_Finger40, $SKEL_R_Finger40), #($Geo_R_Finger41, $SKEL_R_Finger41), #($Geo_R_Finger42, $SKEL_R_Finger42), #($Geo_RB_L_ThighRoll, $RB_L_ThighRoll), #($Geo_L_Thigh, $SKEL_L_Thigh), #($Geo_L_Calf, $Skel_L_Calf), #($Geo_L_Foot, $SKEL_L_Foot), #($Geo_L_Toe0, $SKEL_L_Toe0), #($Geo_RB_R_ThighRoll, $RB_R_ThighRoll), #($Geo_R_Thigh, $SKEL_R_Thigh), #($Geo_R_Calf, $SKEL_R_Calf), #($Geo_R_Foot, $SKEL_R_Foot), #($Geo_R_Toe0, $SKEL_R_Toe0) ) -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- fn rstaSkinHardWeightMesh meshToSkinArray skinDataArray = ( -- for i = 1 to skinDataArray.count do -- ( -- format (skinDataArray[i] as string+"\n") -- ) for meshToSkin in meshToSkinArray do ( if meshToSkin.modifiers.count >= 1 do ( for m = meshToSkin.modifiers.count to 1 by -1 do ( deleteModifier meshToSkin m ) ) addModifier meshToSkin (Skin()) max modify mode modPanel.setCurrentObject meshToSkin.modifiers[#Skin] local skinMOd = meshToSkin.modifiers[#Skin] skinMOd.bone_limit = 1 for i = 1 to skinDataArray.count do --add the bones into the skin modifier ( --format ((skinDataArray[i][1] as string)+" skinDataArray["+(i as string)+"][3]: "+(skinDataArray[i][3] as string)+"\n") if skinDataArray[i][3] == meshToSkin do ( local boneToAdd = skinDataArray[i][1] --format ("Adding "+(boneToAdd as string)+" to "+meshToSkin.name+"\n") local boneUpdateInt = undefined if i != skinDataArray.count then ( boneUpdateInt = 0 ) else ( --ok we're at the count so we need to refresh boneUpdateInt = 1 ) if boneToAdd != undefined do ( skinOps.addbone skinMod boneToAdd boneUpdateInt ) ) ) completeRedraw () local boneCount = skinOps.GetNumberBones skinMod local gbg = ClassOf meshToSkin --hacky way to try and stop the Runtime error: Exceeded the vertex count error -- local skinnedThis = false for thisData in skinDataArray do ( if thisData[3] == meshToSkin do ( local thisBone = thisData[1] local thisVertArray = thisData[2] --find the skin modifier index for thisBone for b = 1 to boneCount do ( local tb = skinOps.GetBoneName skinMod b 0 if tb == thisBone.name do ( --format ("Setting weights for "+thisBone.name+"\n") --ok we need to skin all the verts in thisVertArray to this bone for v in thisVertArray do ( --format ("Setting vert "+(v as string)+" for bone "+(b as string)+" "+thisBone.name+"\n") skinOps.SetVertexWeights skinMod v b 1.0 -- skinnedThis = true ) ) ) ) ) -- if skinnedThis == true do -- ( -- format ("Weights applied to "+meshToSkin.name+"\n") -- ) ) ) fn RSTA_getBoundingBoxSize bbOx = ( local xVal = undefined local yVal = undefined local zVal = undefined if bBox[1][1] < bBox[2][1] then ( xVal = (bBox[1][1] * -1) + bBox[2][1] ) else ( xVal = (bBox[2][1] * -1) + bBox[1][1] ) if bBox[1][2] < bBox[2][2] then ( yVal = (bBox[1][2] * -1) + bBox[2][2] ) else ( yVal = (bBox[2][2] * -1) + bBox[1][2] ) if bBox[1][3] < bBox[2][3] then ( zVal = (bBox[1][3] * -1) + bBox[2][3] ) else ( zVal = (bBox[2][3] * -1) + bBox[1][3] ) [xVal,yVal,zVal] ) fn RSTA_VoxelizeMesh meshObj maxVoxels boneIndex meshToSkinArray skinDataArray geoArray = ( local startA = timeStamp() --IT IS ESSENTIAL THAT THE PIVOTPOINT OF THE GEO IS ALIGNED TO ITS CORRESPOONDING JOINT --first get the boundingbox of the meshObj --divide the sides by maxVoxels to get the number of iterations --build a cube volume of voxels then use a meshselect to get the ones that actual fill the meshObj and delete the others outside its volume if meshObj.scale != [1,1,1] do ( format ("WARNING! "+meshObj.name+" does not have valid scale. Voxels may be wrong.\n") ) local realBbox = nodeGetBoundingBox meshObj meshObj.transform local meshBbox = RSTA_getBoundingBoxSize realBbox --format ("meshBbox: "+(meshBbox as string)+"\n") --divide the x y z by maxVoxels and then create the cub based off maxvoxels * largest value local divX = meshBBox[1] / maxVoxels --format ("divX: "+(divX as string)+"\n") local divY = meshBBox[2] / maxVoxels --format ("divY: "+(divY as string)+"\n") local divZ = meshBBox[3] / maxVoxels --format ("divZ: "+(divZ as string)+"\n") local newVoxelSize = undefined if divX > divY then ( if divX > divZ then ( --divX is biggest newVoxelSize = divX ) else ( --divZ is biggest newVoxelSize = divZ ) ) else ( --divX < divY if divY > divZ then ( --divY is biggest newVoxelSize = divY ) else ( --divZ is biggest newVoxelSize = divZ ) ) --we need to find the top left most position for the first voxel then iterate across --we need to build the voxels in the space of the meshObj local prevX = realBbox[1][1] - (newVoxelSize / 2) --this gets iterated over local prevY = realBbox[1][2] - (newVoxelSize / 2) local prevZ = realBbox[1][3] - (newVoxelSize / 2) local initX = prevX --used to store the initial X position local initY = prevY local initZ = prevZ -- local thisVox = Box length:newVoxelSize width:newVoxelSize height:newVoxelSize pos:[0,0,0] name:"voxName" lengthSegs:1 widthsegs:1 heightsegs:1 for xIt = 1 to maxVoxels do ( local x = preVx + newVoxelSize for yIt = 1 to maxVoxels do ( local y = prevY + newVoxelSize for zIt = 1 to maxVoxels do ( local z = prevZ + newVoxelsize local voxName = ("Vox_"+(substring meshObj.name 5 -1)+"_"+(xIt as string)+"_"+(yIt as string)+"_"+(zIt as string)) local pos = [x,y,z] local thisVox = Box length:newVoxelSize width:newVoxelSize height:newVoxelSize pos:pos name:voxName lengthSegs:1 widthsegs:1 heightsegs:1 in coordsys meshObj thisVox.position = pos addModifier thisVox (Vol__Select()) thisVox.modifiers[#Vol__Select].volume = 3 thisVox.modifiers[#Vol__Select].level = 1 thisVox.modifiers[#Vol__Select].node = meshObj local deleteThis = false if thisVox.mesh.selectedVerts.count == 0 do ( deleteThis = true ) if deleteThis == true then ( delete thisVox ) else ( for meshToSkin in meshToSkinArray do ( local weSetVert = false --NEED TO FIND A WAY HERE TO STORE DATA FOR MULTIPLE MESHTOSKIN OBJECTS --OTHERWISE WE WILL HAVE TO GENERATE THE VOXELS MULTIPLE TIMES --CAN I DO IT VIA A STRUCT PERHAPS? if meshToSkin.modifiers[#Vol__Select] == undefined then ( addModifier meshToSkin (Vol__Select()) meshToSkin.modifiers[#Vol__Select].volume = 3 meshToSkin.modifiers[#Vol__Select].level = 1 meshToSkin.modifiers[#Vol__Select].node = thisVox ) else ( meshToSkin.modifiers[#Vol__Select].node = thisVox ) if meshToSkin.mesh.selectedVerts.count != 0 then ( local selVerts = meshToSkin.mesh.selectedVerts as bitarray --format (voxName+" has "+(thisVox.mesh.selectedVerts.count as string)+" verts: "+(selVerts as string)+".\n") for b = 1 to skinDataArray.count do ( if skinDataArray[b][1] == geoArray[boneIndex][2] do ( if skinDataArray[b][3] == meshToSkin do --this is used to track which mesh object in the meshes to skin array these weights are for ( for v in selVerts do ( appendIfUnique skinDataArray[b][2] v weSetVert = true ) ) ) ) ) ) ) -- if meshObj.name != "Geo_R_Thigh" do -- ( try( delete thisVox )catch() -- ) if xIt == maxVoxels then ( prevX = initX ) else ( prevX = x ) if yIt == maxVoxels then ( prevY = initY ) else ( prevY = y ) if zIt == maxVoxels then ( prevZ = initZ ) else ( prevZ = z ) ) ) ) gc() local endA = timeStamp() format ("Processing voxel generation for "+meshObj.name+" took "+(((endA - startA) / 1000.0) as string)+" seconds\n") skinDataArray ) fn voxeliseBasedOfSkeletalGeo geoArray meshesToSkinArray = ( enableSceneRedraw() --just in case we've previously had a crash local start = timestamp() with undo off( if meshesToSkinArray.count > 0 then ( disableSceneRedraw() max create mode skinDataArray = #() createDialog progBar width:300 height:30 local geoArrayCount = geoArray.count for s = 1 to geoArrayCount do ( local sourceObj = geoArray[s][1] if sourceObj != undefined then ( local maxVoxels = 8 for meshToSkin in meshesToSkinArray do ( local tmpData = #(geoArray[s][2], #(), meshToSkin) appendIfUnique skinDataArray tmpData ) skinDataArray = RSTA_VoxelizeMesh sourceObj maxVoxels s meshesToSkinArray skinDataArray geoArray ) else ( format ("Source obj (geo) was undefined.\n") ) progBar.prog.value = (100.*s/geoArrayCount) ) destroyDialog progbar enableSceneRedraw() local end = timestamp() format ("Completing voxel generation took "+(((end - start) / 1000.0) as string)+" seconds in total.\n") --now we can actually skin this shit start = timestamp() rstaSkinHardWeightMesh meshesToSkinArray skinDataArray end = timestamp() format ("Processing hardskinning took "+(((end - start) / 1000.0) as string)+" seconds\n") ) else ( format "WARNING meshToSkin was undefined!\n" ) ) ) meshesToSkinArray = #( $Uppr_000_R, $lowr_000_r ) voxeliseBasedOfSkeletalGeo geoArray meshesToSkinArray