522 lines
12 KiB
Plaintext
Executable File
522 lines
12 KiB
Plaintext
Executable File
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] |