Script for å kopiere animasjonskeys

Max scripts

Moderatorer: Super Moderatorer, Admins


Trådstarter
hardrock_ram
Innlegg: 1502
Registrert: ons 07 feb, 2007
Sted: Kristiansand

Script for å kopiere animasjonskeys

Legg innav hardrock_ram » tor 28 nov, 2013

EDIT: Dette scriptet får snart en liten fiks

Som dere sikkert vet så har 3dsmax dårlige muligheter for å overføre keyframes fra en animasjonskontroller til en annen. Såvidt jeg kan huske så må man kopiere selve kontrolleren, noe som i mange tilfeller ikke er brukbart. Dette scriptet skal ta seg av den saken. Det er også noen basis "redigeringsmuligheter" for keys.

Øverst er det en knapp for å velge objekt, samt en drop-down meny for å velge kontroller. Merk at denne menyen kun fungerer på de vanligste kontrollerne, for eks. posisjon, rotasjon, list, sliderValue og parametre laget med parameter editor. For animasjonskontrollere som ikke vises eller ved bugs, så kan man taste kontrollerbanen manuelt i tekstfeltet "current controller".
Videre håper jeg at scriptet er stort sett selvforklarende, men det er bare å spørre :).

Jeg må poengetere at dette er laget i arbeidstiden min for å brukes på jobb. Jeg har full tillatelse til å publisere script, men det er hyggelig om den lille teksten "By Cameron Sense AS Norway" blir stående selv om det tas i bruk hos andre bedrifter ;)

[spoiler]

Kode: Velg alt

(--START SCRIPT
   rollout rollout_transferKeys "Transfer keys from one controller to another"
   (--START Interface
      group "Choose controller"
      (
         pickbutton pBtn_pickedObject "Pick object" autoDisplay:true
         dropDownList drDwnLst_originalController "Choose controller"
         editText txt_fromController "Current controller:"
         
         editText txt_classOfController "Current controller class" bold:true readOnly:true
         editText txt_keyableController "Current controller is keyable" bold:true readOnly:true
         editText txt_keysOnController "Number of keys on current controller" bold:true readOnly:true
         
         button btn_originalPath "Save as original controller path"
         button btn_receivingPath "Save as receiving controller path"
         button btn_resetControllers "Reset lists and text fields"
         editText txt_originalPath "Current original controller: " bold:true readOnly:true
         editText txt_receivingPath "Current receiving controller: " bold:true readOnly:true
      )
      group "Append Receiving objects"
      (
         label lbl_info_1 "Objects must have identical controller hierarchy as the receiving path, exepth object name" align:#left
         label lbl_info_2 "If a modifier has a different placement in the stack, the modifier name instead of stack index must be used in the path" align:#left
         label lbl_info_3 "If stair models is used in offset or scale, the objects will be in the same order as they where picked" align:#left
         label lbl_info_4 "The receiving list must consist of ALL objects that should be included, exept the original object that is copied from" align:#left
         label lbl_info_5 "By including the original object, it to will receive new animation on the choosen controller" align:#left
         label lbl_info_6 "" align:#left
         button btn_receivingObjects "Append selected objects to the receiving list"
         button btn_removeObjectFromReceivingList "Remove selected objects from receiving list"
         button btn_printReceivingListOrder "Print receiving objects order in listener"
         button btn_emptyReceivingObjectsList "Empty receiving objects list"
      )
      group "Original frames"
      (
         spinner spn_fromFrame "From frame" type: #integer range:[-999999,999999,0]
         spinner spn_toFrame "To frame" type: #integer range:[-999999,999999,0]
      )
      group "Key displacement"
      (
         spinner spn_timeOffset "Time offset from original frames" type: #integer range:[-999999,999999,0]
         spinner spn_valueOffset "Value offset from original frames" type: #float range:[-999999,999999,0]
         checkBox chkBox_timeStairOffset "Stair offset model for time. (Time is added for each object)"
         checkBox chkBox_exponentialTimeStairOffset "Time between each object increases at an exponential rate" enabled:false
         checkBox chkBox_valueStairOffset "Stair offset model for value. (Value is added for each object)"
         checkBox chkBox_exponentialValueStairOffset "Value between each object increases at an exponential rate" enabled:false
         checkBox chkBox_mirrorAnimationValues "Mirror animation values"
         checkBox chkBox_relativeValues "Use relative values: The current value on the receiving object is added. (Try to use a new controller instead)"
      )
      group "Scale"
      (
         spinner spn_scaleTime "Time scale" type: #float range:[-999999,999999,1]
         spinner spn_scaleValue "Value scale" type: #float range:[-999999,999999,1]
         spinner spn_scaleTimeCenterValue "Scale center frame" type: #integer range:[-999999,999999,0]
         spinner spn_scaleValueCenterValue "Scale center value" type: #float range:[-999999,999999,0]
         checkBox chkBox_timeStairScale "Stair scale model for time. (the time scale will increase with set value for every object)"
         checkBox chkBox_valueStairScale "Stair scale model for value. (the value scale will increase with set value for every object)"
      )
      group "Execute"
      (
         button btn_TransferKeys "Transfer keys"
      )
      group "Information"
      (
         label lbl_info_7 "By Cameron Sense AS Norway" --Please keep this :)
      )
      
      --Variables
      local currentObject
      local listController = false
      
      --Arrays:
      local array_currentControllers = #()
      local Array_dropDownListItems = #()
      local array_custAttribute = #()
      local array_parameters = #()
      local array_modifiers = #()
      
      --Paths
      local pickedObject
      local originalPath
      local receivingPath
      local originalObject
      local receivingObject
      
      --Receiving objects
      local array_receivingObjects = #()
      
      ------------------------------------------------------------------------------------
      --START  pickButton function
      fn fn_pickObject Obj textField =
      (
         --Empties arrays and variables
         array_custAttribute = #()
         array_modifiers = #()
         
         currentObject= Obj
         
         textField.text = "$" + Obj.name
         
         if classOf Obj.controller == prs do
         (
            append array_currentControllers Obj.controller
            append Array_dropDownListItems (Obj.controller as string)
            append array_custAttribute 0
            append array_modifiers 0
         )
         
         if classOf Obj == sliderManipulator do
         (
            append array_currentControllers Obj.value.controller
            append Array_dropDownListItems ("Value" + Obj.value.controller as string)
            append array_custAttribute 0
            append array_modifiers 0
         )
         
         for i = 1 to Obj.modifiers.count do
         (
            if classOf Obj.modifiers[i] == EmptyModifier and (custAttributes.count Obj.modifiers[i]) >0 then
            (
               append array_modifiers i
               
               for j = 1 to (custAttributes.getDefs Obj.modifiers[i]).count do
               (
                  append array_currentControllers (custAttributes.get Obj.modifiers[i] j)
                  append Array_dropDownListItems (Obj.modifiers[i].name as string + ": " + (custAttributes.get Obj.modifiers[i] j).name)
                  append array_custAttribute j
               )
            )
            else
            (
               append array_custAttribute 0
               append array_modifiers 0
            )
         )
         drDwnLst_originalController.items = Array_dropDownListItems
      )
      ------------------------------------------------------------------------------
      --START pickButton events
      on pBtn_pickedObject picked Obj do
      (
         --Reset variables and arrays
         currentObject = undefined
         listController = false
         free array_currentControllers
         free Array_dropDownListItems
         free array_custAttribute
         free array_parameters
         free array_modifiers
         
         --Reset interface
         drDwnLst_originalController.items = #()
         
         --Object is put in its own variable and in the text field
         pickedObject = Obj
         txt_fromController.text = ""
         
         --Run function for new object
         fn_pickObject Obj txt_fromController
         
         --Update class of controller text field
         txt_classOfController.text = try (classOf (execute txt_fromController.text)) as string catch "undefined"
         txt_keyableController.text = try (execute txt_fromController.text).keyable as string catch "undefined"
         txt_keysOnController.text = try (execute txt_fromController.text).keys.count as string catch "undefined"
      )
      ------------------------------------------------------------------------------
      --START DropDownList function
      fn fn_addText textField currentObject currentModifierIndex controller index custAttribute param =
      (
         if classof controller == prs do
         (
            textField.text += "." + "controller"
            
            array_currentControllers = #(currentObject.controller.position.controller, currentObject.controller.rotation.controller, currentObject.controller.scale.controller)
            Array_dropDownListItems = #((classOf currentObject.controller.position.controller) as string, (classOf currentObject.controller.rotation.controller) as string, (classOf currentObject.controller.scale.controller) as string)
            
            drDwnLst_originalController.items = Array_dropDownListItems
         )
         -----------------------------------------------------------------------------
         if classOf controller == Position_XYZ or classOf controller == Euler_XYZ or classOf controller == ScaleXYZ do
         (
            textField.text += "."
            if classOf controller == Position_XYZ  do textField.text += "position"
            if classOf controller == Euler_XYZ  do textField.text += "rotation"
               if classOf controller == ScaleXYZ  do textField.text += "scale"
            textField.text += "." + "controller"
            if listController == true do textField.text += "[" + index as string + "]"
            listController = false
            
            array_currentControllers = #(array_currentControllers[index][1] as string, array_currentControllers[index][2] as string, array_currentControllers[index][3] as string)
            Array_dropDownListItems = #(array_currentControllers[1] as string, array_currentControllers[2] as string, array_currentControllers[3] as string)
            drDwnLst_originalController.items = Array_dropDownListItems
         )
         
         if controller == "SubAnim:X_Position" do textField.text += "." + "x_position" + "." + "controller"
         if controller == "SubAnim:Y_Position" do textField.text += "." + "y_position" + "." + "controller"
         if controller == "SubAnim:Z_Position" do textField.text += "." + "z_position" + "." + "controller"
         
         if controller == "SubAnim:X_Rotation" do textField.text += "." + "x_rotation" + "." + "controller"
         if controller == "SubAnim:Y_Rotation" do textField.text += "." + "y_rotation" + "." + "controller"
         if controller == "SubAnim:Z_Rotation" do textField.text += "." + "z_rotation" + "." + "controller"
         
         if controller == "SubAnim:X_Scale" do textField.text += "." + "x_scale" + "." + "controller"
         if controller == "SubAnim:Y_Scale" do textField.text += "." + "y_scale" + "." + "controller"
         if controller == "SubAnim:Z_Scale" do textField.text += "." + "z_scale" + "." + "controller"
         
         -----------------------------------------------------------------------------
         if classOf controller == position_List or classOf controller == rotation_list or classOf controller == scale_list do
         (
            listController = true
            array_currentControllers = #()
            Array_dropDownListItems = #()
            for i = 1 to (controller.getCount()) do append array_currentControllers controller[i].controller
            for i = 1 to (controller.getCount()) do append Array_dropDownListItems (controller.getName i as string)
            drDwnLst_originalController.items = Array_dropDownListItems
         )
         ------------------------------------------------------------------------
         if classOf controller == bezier_float and classOf currentObject == sliderManipulator do textField.text += "." + "value" + "." + "controller"
         ------------------------------------------------------------------------
         if classOf controller as string == "<AttributeDef:Custom_Attributes>" do
         (
            textField.text = "(" + "custAttributes.get " + "$" + (currentObject.name as string) + "." + "modifiers" + "[" + currentModifierIndex as string + "]" + " " + (custAttribute as string) + ")"
            
            array_currentControllers = #()
            Array_dropDownListItems = #()
            array_parameters = #()
            paramNr = 1
            while controller[paramNr] != undefined do
            (
               append array_currentControllers controller[paramNr]
               append array_parameters controller[paramNr].name
               append Array_dropDownListItems (controller[paramNr] as string)
               drDwnLst_originalController.items = Array_dropDownListItems
               
               --VIKTIG:
               paramNr += 1
            )
         )
         
         if param != undefined do
         (
            textField.text += "[" + index as string + "]" + "." + "controller"
            param = undefined
         )
      )
      --END DropDownList function
      ------------------------------------------------------------------------
      --START dropDownList events
      on drDwnLst_originalController selected itemNr do
      (
         fn_addText txt_fromController currentObject array_modifiers[itemNr] array_currentControllers[itemNr] itemNr array_custAttribute[itemNr] array_parameters[itemNr]
         txt_classOfController.text = try (classOf (execute txt_fromController.text)) as string catch "undefined"
         txt_keyableController.text = try (execute txt_fromController.text).keyable as string catch "undefined"
         txt_keysOnController.text = try (execute txt_fromController.text).keys.count as string catch "undefined"
      )
      ---------------------------------------------------------------------------------------
      --START supporting function events
      on txt_fromController changed txt do
      (
         txt_classOfController.text = try (classOf (execute txt_fromController.text)) as string catch "undefined"
         txt_keyableController.text = try (execute txt_fromController.text).keyable as string catch "undefined"
         txt_keysOnController.text = try (execute txt_fromController.text).keys.count as string catch "undefined"
      )
      
      on btn_resetControllers pressed do
      (
         pBtn_pickedObject.object = undefined
         
         --Reset variables and arrays
         currentObject = undefined
         listController = false
         free array_currentControllers
         free Array_dropDownListItems
         free array_custAttribute
         free array_parameters
         free array_modifiers
         
         --Reset interface
         drDwnLst_originalController.items = #()
         txt_fromController.text = ""
         txt_classOfController.text = try (classOf (execute txt_fromController.text)) as string catch "undefined"
         txt_keyableController.text = try (execute txt_fromController.text).keyable as string catch "undefined"
         txt_keysOnController.text = try (execute txt_fromController.text).keys.count as string catch "undefined"
      )
      
      on chkBox_timeStairOffset changed state do if state == true then chkBox_exponentialTimeStairOffset.enabled = true else chkBox_exponentialTimeStairOffset.enabled = false
      on chkBox_valueStairOffset changed state do if state == true then chkBox_exponentialValueStairOffset.enabled = true else chkBox_exponentialValueStairOffset.enabled = false
      --END supporting function events
      ------------------------------------------------------------------------------------------------
      --START save path events
      on btn_originalPath pressed do
      (
         originalPath = txt_fromController.text
         txt_originalPath.text = txt_fromController.text
         
         --Spinners get suggested range from original path
         spn_fromFrame.value = \
         try ((((getTimeRange (execute originalPath) #allKeys).start as float)/4800)*frameRate) as integer
         catch (((animationRange.start as float)/4800)*frameRate) as integer
         
         spn_toFrame.value = \
         try ((((getTimeRange (execute originalPath) #allKeys).end as float)/4800)*frameRate) as integer
         catch (((animationRange.end as float)/4800)*frameRate) as integer
         
         spn_scaleTimeCenterValue.value = \
         try ((((getTimeRange (execute originalPath) #allKeys).start as float)/4800)*frameRate) as integer
         catch (((animationRange.start as float)/4800)*frameRate) as integer
      )
      on btn_receivingPath pressed do
      (
         receivingPath = txt_fromController.text
         txt_receivingPath.text = txt_fromController.text
      )
      --END save path events
      -----------------------------------------------------------------------------------------------
      --START receiving objects array
      on btn_receivingObjects pressed do for i = selection do appendIfUnique array_receivingObjects i
      on btn_removeObjectFromReceivingList pressed do
      (
         for i = selection where (findItem array_receivingObjects i != 0) do deleteItem array_receivingObjects (findItem array_receivingObjects i)
      )
      on btn_emptyReceivingObjectsList pressed do free array_receivingObjects
      on btn_printReceivingListOrder pressed do for i = array_receivingObjects do print i.name
      --END receiving objects array
      ----------------------------------------------------------------------------------------------------
      --START execute
      on btn_TransferKeys pressed do
      (
         undo "Transfer Keys script" on
         (
            local receivingObject = undefined --Contains primary receiving object
            local stringIndex = 0 --The string index number where the name of the object starts
            local nameCount = 0 -- number of digits in name
            local originalPathAsController = execute originalPath
            local receivingPathCopy = undefined --A copy of receiving path. This contains the right path for each receiving object
            local receivingPathCopyAsController = undefined
            
            --Variables and arrays for key values
            local originalTrackKeyable = false
            local receivingTrackKeyable = false
            
            local array_originalFrames = #()
            local array_originalFramesAsFloat = #()
            local array_originalKeyValues = #()
            
            --Variables for scaling and offset
            local originalTimeOffset = spn_timeOffset.value
            local originalValueOffset = spn_valueOffset.value
            local originalScaleTimeOffset = spn_scaleTime.value
            local originalScaleValueOffset = spn_scaleValue.value
            
            local timeOffset = spn_timeOffset.value
            local valueOffset = spn_valueOffset.value
            local scaleTimeOffset = spn_scaleTime.value
            local scaleValueOffset = spn_scaleValue.value
            
            if originalPath != undefined and receivingPath != undefined do
            (
               --------------------------------------------------------------------------------------------------------------------
               --Gather keys from original controller path
               if try originalPathAsController.keyable catch false do
               (
                  originalTrackKeyable = true
                  
                  for i = 1 to (numKeys originalPathAsController) do
                  (
                     append array_originalFrames (getKeyTime originalPathAsController i)
                     append array_originalFramesAsFloat (((getKeyTime originalPathAsController i) as string) as float)
                  )
                  
                  animate on (for i = array_originalFramesAsFloat do at time i (append array_originalKeyValues originalPathAsController.value))
                  animate off()
               )
               --------------------------------------------------------------------------------------------------------------------
               --Operation to prepare replacement of object name in controller path
               for i = array_receivingObjects do if (findString receivingPath i.name) != undefined do
               (
                  receivingObject = i
                  stringIndex = (findString receivingPath i.name)
                  nameCount = i.name.count
               )
               --------------------------------------------------------------------------------------------------------------------
            )
            --Start change key time and values
            for currentObject = array_receivingObjects while receivingObject != undefined and originalTrackKeyable == true do
            (
               --Replace object name in controller path
               receivingPathCopy = replace receivingPath stringIndex nameCount currentObject.name
               receivingPathCopyAsController = execute receivingPathCopy
               ----------------------------------------------------------------------------------------------------
               if receivingPathCopyAsController.keyable == true then receivingTrackKeyable = true else receivingTrackKeyable = false
               ----------------------------------------------------------------------------------------------------
               if receivingTrackKeyable == true do
               (
                  --Delete keys that might exist on the receiving controller
                  deleteKeys receivingPathCopyAsController #allKeys
                  ----------------------------------------------------------------------------------------------------
                  --Transfer keys to new controller
                  for i = 1 to array_originalFramesAsFloat.count where array_originalFramesAsFloat[i]>=spn_fromFrame.value and array_originalFramesAsFloat[i]<=spn_toFrame.value do
                  (
                     --Sets keyframe at correct time
                     local moveTime = ((array_originalFramesAsFloat[i]+timeOffset - spn_scaleTimeCenterValue.value) * scaleTimeOffset)
                     local absoluteTime = spn_scaleTimeCenterValue.value + moveTime
                     addNewKey receivingPathCopyAsController absoluteTime
                     
                     
                     --Sets value at current keyframe
                     local mirrorValue = if chkBox_mirrorAnimationValues.checked != true then array_originalKeyValues[i]+valueOffset else -(array_originalKeyValues[i])+valueOffset
                     local relativeValue = if chkBox_relativeValues.checked == true then receivingPathCopyAsController.value else 0
                     
                     local moveValue = ((mirrorValue+relativeValue - spn_scaleValueCenterValue.value) * scaleValueOffset)
                     local absoluteValue = spn_scaleValueCenterValue.value + moveValue
                     
                     
                     with animate on (at time absoluteTime receivingPathCopyAsController.value = absoluteValue)
                  )
               )
               ----------------------------------------------------------------------------------------------------
               --Sets correct offset for next object
               if chkBox_timeStairOffset.checked == true do if chkBox_exponentialTimeStairOffset.checked == true then timeOffset += timeOffset else timeOffset += originalTimeOffset
               if chkBox_valueStairOffset.checked == true do if chkBox_exponentialValueStairOffset.checked == true then valueOffset += valueOffset else valueOffset += originalValueOffset
               if chkBox_timeStairScale.checked == true do scaleTimeOffset *= originalScaleTimeOffset
               if chkBox_valueStairScale.checked == true do scaleValueOffset *= originalScaleValueOffset
               ----------------------------------------------------------------------------------------------------
            )--END change key time and values
         )--END undo
      )--END execute
      ----------------------------------------------------------------------------------------------------
   )--END Interface
   createDialog rollout_transferKeys 600 1050
)--END script
[/spoiler]
if your not living on a killing ground, you better make your own

Gå tilbake til «Max scripts»

Hvem er online

Brukere i dette forumet: Ingen registrerte brukere og 2 gjester

cron