-- filein "rockstar/export/settings.ms" -- This is fast -- --Figure out the project -- theProjectRoot = RsConfigGetProjRootDir() -- theProject = RSConfigGetProjectName() -- theWildWest = RsConfigGetWildWestDir() -- theProjectConfig = RsConfigGetProjBinConfigDir() -- filein (theWildWest + "script/3dsMax/_config_files/Wildwest_header.ms") -- filein (theWildWest + "script/3dsMax/_common_functions/FN_RSTA_Rigging.ms") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ fn RSTA_oldStyleMuscleExpression muscleMesh msMuscle = ( -- local exposeNode = CreateExposeTransformNode target1 target2 local Handle1_X = muscleMesh.pos.controller[2][1] local Handle1_Y = muscleMesh.pos.controller[2][2] local Handle1_Z = muscleMesh.pos.controller[2][3] local Handle2_X = msMuscle.localPositionX.controller local Handle2_Y = msMuscle.localPositionY.controller local Handle2_Z = msMuscle.localPositionZ.controller local squashVal = msMuscle.modifiers[#Muscle_Settings].muscleAttrs.squashAndStretchMult.controller muscleMesh.scale.controller[2][1].controller = Float_expression() muscleMesh.scale.controller[2][1].controller.AddScalarTarget "Handle1_X" Handle1_X muscleMesh.scale.controller[2][1].controller.AddScalarTarget "Handle1_Y" Handle1_Y muscleMesh.scale.controller[2][1].controller.AddScalarTarget "Handle1_Z" Handle1_Z muscleMesh.scale.controller[2][1].controller.AddScalarTarget "Handle2_X" Handle2_X muscleMesh.scale.controller[2][1].controller.AddScalarTarget "Handle2_Y" Handle2_Y muscleMesh.scale.controller[2][1].controller.AddScalarTarget "Handle2_Z" Handle2_Z local relativeValue = length ( [Handle2_X.value,Handle2_Y.value,Handle2_Z.value] - [Handle1_X.value,Handle1_Y.value,Handle1_Z.value] ) local exprStr = "( length ( [Handle2_X,Handle2_Y,Handle2_Z] - [Handle1_X,Handle1_Y,Handle1_Z] ) ) / " + ( relativeValue as string ) muscleMesh.scale.controller[2][1].controller.setExpression exprStr -- if ( muscleMesh.modifiers["Muscle Settings"].squashAndStretch ) then -- ( -- for i = 2 to 3 do -- ( muscleMesh.scale.controller[2][i].controller = Float_expression() muscleMesh.scale.controller[2][i].controller.AddScalarTarget "Handle1_X" Handle1_X muscleMesh.scale.controller[2][i].controller.AddScalarTarget "Handle1_Y" Handle1_Y muscleMesh.scale.controller[2][i].controller.AddScalarTarget "Handle1_Z" Handle1_Z muscleMesh.scale.controller[2][i].controller.AddScalarTarget "Handle2_X" Handle2_X muscleMesh.scale.controller[2][i].controller.AddScalarTarget "Handle2_Y" Handle2_Y muscleMesh.scale.controller[2][i].controller.AddScalarTarget "Handle2_Z" Handle2_Z muscleMesh.scale.controller[2][i].controller.AddScalarTarget "squashAndStretch" squashVal -- local mult = target1.modifiers["Muscle Settings"].muscleAttrs["squashAndStretchMult"] -- obj.scale.controller[2][i].controller.AddScalarTarget "Multiplier" mult local exprStr = "(1 / ( ( length ( [Handle2_X,Handle2_Y,Handle2_Z] - [Handle1_X,Handle1_Y,Handle1_Z] ) / " + (RelativeValue as string) + " ) )) * squashAndStretch" -- local exprStr = "1 + ( ( " + (RelativeValue as string) + " - length( [Handle2_X,Handle2_Y,Handle2_Z] - [Handle1_X,Handle1_Y,Handle1_Z] ) ) * Multiplier )" muscleMesh.scale.controller[2][i].controller.setExpression exprStr -- ) -- ) ) fn RSTA_addMuscleScaleExpressions markers = ( local muscleMesh = markers[4] local msMuscle = markers[1] local mcMuscle = markers[3] format ("muscleMesh: "+(muscleMesh as string)+"\n") format ("msMuscle: "+(msMuscle as string)+"\n") format ("mcMuscle: "+(mcMuscle as string)+"\n") --UNTIL AUTODESK GIVE US A FIX WE HAVE TO USE THE OLD HARDCODED MUSCLES DUE TO UPDATES NEEDING KEYED OTHERWISE RSTA_oldStyleMuscleExpression muscleMesh msMuscle -- local Handle2_X = msMuscle.localPositionX.controller -- -- local squashy = msMuscle.modifiers[#Muscle_Settings].muscleAttrs.squashAndStretchMult.controller -- -- muscleMesh.scale.controller[2][1].controller = Float_expression() -- -- local defaultDist = distance msMuscle mcMuscle -- -- muscleMesh.scale.controller[2][1].controller.AddScalarConstant "defaultDist" defaultDist -- muscleMesh.scale.controller[2][1].controller.AddScalarTarget "distX" Handle2_X -- local exprStr = ("( 1 / defaultDist) * distX") -- muscleMesh.scale.controller[2][1].controller.setExpression exprStr -- -- muscleMesh.scale.controller[2][2].controller = Float_expression() -- muscleMesh.scale.controller[2][3].controller = Float_expression() -- muscleMesh.scale.controller[2][2].controller.AddScalarConstant "defaultDist" defaultDist -- muscleMesh.scale.controller[2][3].controller.AddScalarConstant "defaultDist" defaultDist -- muscleMesh.scale.controller[2][2].controller.AddScalarTarget "distX" Handle2_X -- muscleMesh.scale.controller[2][3].controller.AddScalarTarget "distX" Handle2_X -- -- muscleMesh.scale.controller[2][2].controller.AddScalarTarget "squashAndStretch" squashy -- muscleMesh.scale.controller[2][3].controller.AddScalarTarget "squashAndStretch" squashy -- -- local exprStr = ("if\n(\n\tsquashAndStretch = 0,\n\t1,\n\t((1 - (1 / defaultDist) * distX) + 1) * squashAndStretch\n)") -- muscleMesh.scale.controller[2][2].controller.setExpression exprStr -- muscleMesh.scale.controller[2][3].controller.setExpression exprStr if ( msMuscle.modifiers["Muscle Settings"].useRSSpring ) then ( local RsSprg = muscleMesh.position.controller[#Available].controller = (RsSpring ()) RsSprg.xLimitMin = -0.001 RsSprg.yLimitMin = -0.001 RsSprg.zLimitMin = -0.001 RsSprg.xLimitMax = 0.001 RsSprg.yLimitMax = 0.001 RsSprg.zLimitMax = 0.001 ) ) fn rsta_addMuscleSettingsAttributes markers markerSquashVal = ( local msMuscle = markers[1] local meMuscle = markers[2] muscleMainDef = attributes muscleAttrs ( parameters markerP rollout:markerR ( squashAndStretchMult type:#float ui:spn_squashAndStretchMult default:1 useRSSpring type:#boolean ui:cbx_useRSSpring ) rollout markerR "Marker Attributes" ( spinner spn_squashAndStretchMult "Squash and Stretch" align:#right fieldWidth:30 range:[ 0, 20, 1 ] checkBox cbx_useRSSpring "RS Spring" on spn_squashAndStretchMult changed arg do ( squashAndStretchMult = arg ) on cbx_useRSSpring changed arg do ( useRSSpring = arg ) ) ) local aHMod = EmptyModifier() aHMod.name = "Muscle Settings" addModifier msMuscle aHMod custAttributes.add aHMod muscleMainDef --now we need to add a bezier controller to the squash attr msMuscle.modifiers[#Muscle_Settings].muscleAttrs.squashAndStretchMult.controller = bezier_float () if markerSquashVal != undefined do ( msMuscle.modifiers[#Muscle_Settings].muscleAttrs.squashAndStretchMult = markerSquashVal ) ) fn rsta_addMuscleMarkerSettingsAttributes marker markerSquashVal = ( muscleMarkerMainDef = attributes muscleMarkerAttrs ( parameters markerP rollout:markerR ( squashAndStretchVal type:#float ui:spn_squashAndStretchVal default:1 ) rollout markerR "Marker Attributes" ( spinner spn_squashAndStretchVal "Squash and Stretch" align:#right fieldWidth:30 range:[ 0, 20, 1 ] on spn_squashAndStretchVal changed arg do ( squashAndStretchVal = arg ) ) ) local modExistsAlready = false for m = 1 to marker.modifiers.count do ( if marker.modifiers[m].name == "muscleMarker Settings" do ( modExistsAlready = true ) ) if modExistsAlready == false do ( local aHMod = EmptyModifier() aHMod.name = "muscleMarker Settings" addModifier marker aHMod custAttributes.add aHMod muscleMarkerMainDef --now we need to add a bezier controller to the squash attr marker.modifiers[#muscleMarker_Settings].muscleMarkerAttrs.squashAndStretchVal.controller = bezier_float () ) if markerSquashVal != undefined do ( marker.modifiers[#muscleMarker_Settings].muscleMarkerAttrs.squashAndStretchVal = markerSquashVal ) ) -- fn rsta_makeMuscleMesh msMuscle = fn rsta_makeMuscleMesh muscleNodes = ( local msMuscle = muscleNodes[1] local meMuscle = muscleNodes[2] -- meMuscle = getNodeByName ("ME_"+(substring msMuscle.name 4 -1)) local mcName = substituteString msMuscle.name "_MS_" "_MC_" local mbName = substituteString msMuscle.name "_MS_" "_MB_" -- mcMuscle = point pos:meMuscle.position isSelected:on name:("MC_"+(substring msMuscle.name 4 -1)) size:0.05 centerMarker:false axisTripod:false cross:true box:false constantScreenSize:false drawontop:false mcMuscle = point pos:meMuscle.position isSelected:on name:mcName size:0.05 centerMarker:false axisTripod:false cross:true box:false constantScreenSize:false drawontop:false mcMuscle.transform = meMuscle.transform mcMuscle.parent = msMuscle msMuscle.exposeNode = mcMuscle select mcMuscle rsta_FreezeTransform() RSTA_createPosConstraint mcMuscle meMuscle --now we can build the muscle geo local markers = #(msMuscle,meMuscle,mcMuscle) local rad = 0.03 local mStart = markers[1] local mEnd = markers[2] local tempTForm = mStart.transform tempTForm.pos = mEnd.pos local fwdVec = mEnd.pos - mStart.pos local midPoint = ( ( length fwdVec ) / 2 ) local normVec = normalize fwdVec local worldVec = [0,0,1] local sideVec = normalize( cross normVec worldVec ) local upVec = normalize( cross normVec sideVec ) local muscMatrix = matrix3 normVec sideVec upVec mStart.pos local muscMesh = sphere() muscMesh.radius = rad muscMesh.segments = 16 -- local muscName = trimLeft mStart.name "MS" -- muscName = "MB" + muscName -- muscMesh.name = muscName muscMesh.name = mbName muscMesh.wirecolor = (color 224 86 86) muscMesh.rotation = ( quat 0 1 0 1 ) resetXForm muscMesh convertToMesh muscMesh muscMesh.transform = muscMatrix in coordsys local( muscMesh.pos.x += midPoint ) select muscMesh setCommandPanelTaskMode #modify subObjectLevel = 1 meshop.setSoftSel muscMesh true meshop.setFalloff muscMesh 0.08 meshop.setSSUseEdgeDist muscMesh true meshop.setSSEdgeDist muscMesh 3 update muscMesh local offsetVal = midPoint - rad muscMesh.selectedVerts = #{1} meshop.moveVert muscMesh.mesh #all [offsetVal,0,0] node:muscMesh.mesh useSoftSel:true muscMesh.selectedVerts = #{muscMesh.verts.count} meshop.moveVert muscMesh.mesh #all [-offsetVal,0,0] node:muscMesh.mesh useSoftSel:true muscMesh.pivot = muscMesh.verts[muscMesh.verts.count].pos muscMesh.parent = mStart subObjectLevel = 0 select muscMesh rsta_FreezeTransform() append markers muscMesh RSTA_addMuscleScaleExpressions markers for x in markers do ( if ( matchPattern x.name pattern:"MS_*" ) then ( tag = ("exportTrans = false" + "\r\n" + "translateTrackType=TRACK_BONE_TRANSLATION" + "\r\n" + "exportRot = true") setUserPropBuffer x tag ) else if ( matchPattern x.name pattern:"ME_*" ) then ( tag = ("exportTrans=true\r\ntranslateTrackType=TRACK_BONE_TRANSLATION") setUserPropBuffer x tag ) else if ( matchPattern x.name pattern:"MB_*" ) then ( tag = "exportScale = true" setUserPropBuffer x tag ) ) ) fn RSTA_createMuscleSystem index parNode chiNode nodeNames = ( /** index PARAM IS THE NUMBER WE WANT TO ADD TO THE MUSCLE SYSTEM posNode IS AN ABOJECT WE WANT TO USE AS SOURCEPOSITION WILL CREATE 3 NODES FIRST OF ALL 1) MS_Muscle -- A EXPOSE TRANSFORM HELPER THIS WILL GET PARENTED BY USER THIS IS THE START 2) ME_Muscle --AN END NODE WHICH GETS PARENTED BY USER. THIS IS THE END 3) MC_Muscle --A CONSTRAINED NODE. THIS IS A CHILD OF (1) AND IS POSITION CONSTRAINED TO (2) . THIS IS USED TO TRACK THE DISTANCES BETWEEN 1 AND 2 */ local ind = "" if index != -1 then ( ind = index as string ) msName = ("Muscle_MS_"+(ind as string)) meName = ("Muscle_ME_"+(ind as string)) if nodeNames != undefined do ( msName = nodeNames[1] meName = nodeNames[2] ) markerSquashVal = 1.0 -- if parNode. msMuscle = ExposeTm pos:parNode.position isSelected:on name:msName size:0.05 centerMarker:false axisTripod:false cross:true box:false constantScreenSize:false drawontop:false meMuscle = point pos:chiNode.position isSelected:on name:meName size:0.05 centerMarker:false axisTripod:false cross:false box:true constantScreenSize:false drawontop:false msMuscle.wirecolor = color 228 184 152 meMuscle.wirecolor = color 228 184 152 format ("parNode: "+(parNode.name)+"\n") format ("chiNode: "+(chiNode.name)+"\n") format ("msMuscle: "+(msMuscle.name)+"\n") format ("meMuscle: "+(meMuscle.name)+"\n") msMuscle.transform = parNode.transform meMuscle.transform = chiNode.transform msParName = (substring parNode.parent.name 8 -1) format ("Attempting to parent "+msMuscle.name+" to "+msParName+"\n") msParNode = (getNodeByName msParName) if msParNode == undefined do (break()) msMuscle.parent = msParNode meParName = (substring chiNode.parent.name 8 -1) format ("Attempting to parent "+meMuscle.name+" to "+meParName+"\n") meParNode = getNodeByName meParName if meParNode == undefined do (break()) meMuscle.parent = meParNode select msMuscle rsta_FreezeTransform() select meMuscle rsta_FreezeTransform() markerSquashVal = 1.0 if parNode.modifiers[#muscleMarker_Settings] != undefined do ( markerSquashVal = parNode.modifiers[#muscleMarker_Settings].muscleMarkerAttrs.squashAndStretchVal ) rsta_addMuscleSettingsAttributes #(msMuscle, meMuscle) markerSquashVal --now we need to put a lookat on msMuscle RSTA_createAimConstraint msMuscle meMuscle meMuscle.parent msMuscle.rotation.controller[#LookAt_Constraint].upnode_world = false msMuscle.rotation.controller[#LookAt_Constraint].upNodeAxis = 0 select meMuscle --now we need to get the user to position this shit! if msMuscle.position != parNode.position do ( format (msMuscle.name+" in wrong place!\n") ) if meMuscle.position != chiNode.position do ( format (meMuscle.name+" in wrong place!\n") ) madeMuscleNodes = #(msMuscle, meMuscle) return madeMuscleNodes )