escapeEnable = true if ((RSanimSaveLoad != undefined) and (RSanimSaveLoad.isDisplayed)) do (destroyDialog RSanimSaveLoad) filein "rockstar/export/settings.ms" -- This is fast -- Figure out the project theProjectRoot = RsConfigGetProjRootDir() theProject = RSConfigGetProjectName() theWildWest = RsConfigGetWildWestDir() theProjectConfig = RsConfigGetProjBinConfigDir() -- 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_UI.ms") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ fn RSTA_loadAnimFile = ( input_name = getOpenFileName caption:"Save RS anim file" types:"RsAnimData (*.RsAnim)|*.RsAnim|All Files (*.*)|*.*|" if input_name != undefined then ( startTime = timestamp() suspendEditing() with redraw off ( undo off ( frameArray = #() AnimData = #( #(),--frame #(), -- bone name #(), --pos #(), --rot #() --scale ) f = openfile input_name inputData = #() -- define as array while not eof f do ( -- append inputData (filterstring (readLine f) "¬") thisData = (filterstring (readLine f) "¬") if thisData.count == 5 then ( -- format ("thisData: "+(thisData as string)+"\n") frameVal = stringstream thisData[1] frameVal = readvalue frameVal appendIfUnique frameArray frameVal -- nameVal = stringStream thisData[2] -- nameVal = readValue nameVal nameVal = thisData[2] posVal = stringStream thisData[3] posVal = readValue posVal rotVal = stringStream thisData[4] rotVal = readValue rotVal sclVal = stringStream thisData[5] sclVal = readValue sclVal append AnimData[1] frameVal --frame append AnimData[2] nameVal --name append AnimData[3] posVal --pos append AnimData[4] rotVal --rot append AnimData[5] sclVal --scale ) else ( close f resumeEditing() exit() ) ) close f format ((AnimData[1][1] as string)+" "+(AnimData[2][1] as string)+" "+(AnimData[3][1] as string)+" "+(AnimData[4][1] as string)+" "+(AnimData[5][1] as string)+"\n") --now we'll set the frame range startFrame = frameArray[1] endFrame = frameArray[frameArray.count] animationRange = interval startFrame endFrame max tool animmode set animate on for f = 1 to AnimData[1].count do ( if animData[1][f] != slidertime do ( sliderTime = (animData[1][f] as time) ) thisNode = getNodeByName AnimData[2][f] if thisNode != undefined do ( in coordsys parent thisNode.rotation = animData[4][f] in coordsys parent thisNode.position = animData[3][f] in coordsys parent thisNode.scale = animData[5][f] ) ) max tool animmode set animate off format ("AnimData[1].count: "+(AnimData[1].count as string)+"\n") ) ) resumeEditing() endTime = timestamp() format "Processing RSTA_loadAnimFile took % seconds\n" ((endTime - startTime) / 1000.0) ) ) fn RSTA_saveOutAnimFile boneDataArray outputFileName = ( output_file = createfile outputFileName with redraw off bdCount = boneDataArray[1].count bdPc = bdCOunt / 100 initProgBar() for frame = 1 to bdCount do ( if boneDataArray[2][frame] != undefined do ( sliderTime = boneDataArray[1][frame][1] progBar.prog.value = (frame / bdPc) if boneDataArray[2][frame] != undefined do ( for boneNode in boneDataArray[2][frame] do ( posi = in coordsys parent boneNode.position rot = in coordsys parent boneNode.rotation scl = in coordsys parent boneNode.scale outputData = ((sliderTime as string)+"¬"+boneNode.name+"¬"+(posi as string)+"¬"+(rot as string)+"¬"+(scl as string)+"\n") format ((outputData)) to:output_file ) ) ) ) destroyDialog progBar close output_file format (outputFileName+" saved!\n") ) fn RSTA_queryControllerKeys boneArray = ( local keyDataArray = #() initProgBar() for obj in boneArray do ( local keyArray = #( #(), --objName #(), --pos #(), --rot #() -- scale ) local storeMe = false if ((classof obj.position.controller) as string) == "position_list" then ( local posContCount = obj.position.controller.count if posContCOunt != 0 then ( --this may fuck up if we have diffeing keys in for cc = 1 to posContCount do ( local posKeys = obj.position.controller[cc].keys for key in posKeys do ( --later use key.time to acces the time of the key appendIfUnique keyArray[2] key ) ) storeMe = true ) ) else ( local posKeys = obj.position.controller.keys for key in posKeys do ( --later use key.time to acces the time of the key appendIfUnique keyArray[2] key storeMe = true ) ) if ((classof obj.rotation.controller) as string) == "rotation_list" then ( local rotContCount = obj.rotation.controller.count if rotContCount != 0 then ( for cc = 1 to rotContCount do ( local rotKeys = obj.rotation.controller[cc].keys for key in rotKeys do ( appendIfUnique keyArray[3] key ) ) storeMe = true ) ) else ( local rotKeys = obj.rotation.controller.keys for key in rotKeys do ( --later use key.time to acces the time of the key appendIfUnique keyArray[2] key storeMe = true ) ) if ((classof obj.scale.controller) as string) == "scale_list" then ( local sclContCount = obj.scale.controller.count if sclContCount != 0 then ( for cc = 1 to sclContCount do ( local sclKeys = obj.scale.controller[cc].keys for key in sclKeys do ( appendIfUnique keyArray[4] key ) ) storeMe = true ) ) else ( local sclKeys = obj.scale.controller.keys for key in sclKeys do ( --later use key.time to acces the time of the key appendIfUnique keyArray[2] key storeMe = true ) ) if storeMe == true do ( append keyArray[1] obj --only append this if we have stored the object (which means weve stored some keys) append keyDataArray keyArray ) iVal = findItem boneArray obj progBar.prog.value = (100.*iVal/boneArray.count) ) -- destroyDialog progbar -- initProgBar() returnArray = #() --now what we'll do is go through the keys and only store when the next one is different kdACount = keyDataArray.count kdaPc = kdACount / 100.0 for ind = 1 to kdACount do ( local obj = keyDataArray[ind][1] local posKeys = keyDataArray[ind][2] local rotKeys = keyDataArray[ind][3] local sclKeys = keyDataArray[ind][4] local keyArray = #( -- #(),--obj -- #() --key array ) local tmpKeyArray = #() --temp storage local storeMe = undefined local posKeysCount = posKeys.count for key = 1 to posKeysCount do ( if key > 1 do ( if posKeys[key] != posKeys[(key - 1)] do ( local keyTime = posKeys[key].time --may need to flip this appendIfUnique tmpKeyArray keyTime storeMe = true ) ) if key != posKeysCount do ( if posKeys[key] != posKeys[(key + 1)] do ( local keyTime = posKeys[key].time --may need to flip this appendIfUnique tmpKeyArray keyTime storeMe = true ) ) ) local rotKeysCount = rotKeys.count for key = 1 to rotKeysCount do ( if key > 1 do ( if rotKeys[key] != rotKeys[(key - 1)] do ( keyTime = rotKeys[key].time --may need to flip this appendIfUnique tmpKeyArray keyTime storeMe = true ) ) if key != rotKeysCount do ( if rotKeys[key] != rotKeys[(key + 1)] do ( keyTime = rotKeys[key].time --may need to flip this appendIfUnique tmpKeyArray keyTime storeMe = true ) ) ) local sclKeysCount = sclKeys.count for key = 1 to sclKeysCount do ( if key > 1 do ( if sclKeys[key] != sclKeys[(key - 1)] do ( keyTime = sclKeys[key].time --may need to flip this appendIfUnique tmpKeyArray keyTime storeMe = true ) ) if key != sclKeysCount do ( if sclKeys[key] != sclKeys[(key + 1)] do ( keyTime = sclKeys[key].time --may need to flip this appendIfUnique tmpKeyArray keyTime storeMe = true ) ) ) if storeMe == true do ( append keyArray obj[1] for i in tmpKeyArray do ( appendIfUnique keyArray i ) append returnArray keyArray ) progBar.prog.value = ind / kdaPc ) -- destroyDialog progBar --now what we'll do is find all frames and then store which objects need keys at said frame frameArray = #( #(), --frame #() --objects needing keys at frame ) --first build the list of all key frames tempFrames = #() for i in returnArray do ( iCount = i.count for frame = 2 to iCount do ( appendIfUnique tempFrames i[frame] ) ) --now sort the tempFrames array sort tempFrames for f in tempFrames do ( append frameArray[1] #(f) append frameArray[2] #() ) -- initProgBar() frameArrayCount = frameArray[1].count faCPc = frameArrayCount / 100 for m = 1 to frameArrayCount do ( mainFrame = (frameArray[1][m][1]) racCount = returnArray.count for i in returnArray do ( iCount = i.count for frame = 2 to iCount do ( if i[frame] == mainFrame do ( appendIfUnique frameArray[2][m] i[1] ) ) ) progbar.prog.value = (m / faCPc) ) destroyDialog progBar return frameArray ) fn RSTA_saveAnim sela = ( currentFrame = slidertime output_name = getSaveFileName caption:"Save RS anim file" types:"RsAnimData (*.RsAnim)|*.RsAnim|All Files (*.*)|*.*|" if output_name != undefined then ( startTime = timestamp() output_file = createfile output_name suspendEditing() with redraw off ( undo off ( boneArray = selection as array format ("Saving animation for "+(boneArray.count as string)+" objects..."+"\n") boneDataArray = RSTA_queryControllerKeys boneArray RSTA_saveOutAnimFile boneDataArray output_name ) ) resumeEditing() endTime = timestamp() format "Processing RSTA_saveAnim took % seconds\n" ((endTime - startTime) / 1000.0) ) sliderTime = currentFrame ) ------------------------------------------------------------------------------------------------------------------------- rollout rs_animSaveLoad "RS Anim" ( button btnSaveANim "Save Anim" width:120 height:25 tooltip:"Save animation from selected objects" button btnLoadANim "Load Anim" width:120 height:25 tooltip:"Load animation from selected file" on btnSaveANim pressed do ( sela = selection as array RSTA_saveAnim sela -- RSTA_storeBoneAnimKeyFrames boneArray ) on btnLoadANim pressed do ( RSTA_loadAnimFile() ) ) CreateDialog rs_animSaveLoad width:125 pos:[1450, 100]