ScriptSpot

Forum topic · General Scripting

AutoKey - Animation Converter(Dev)

By DolVai · 2013-09-09

Description

Hi, i'm trying to remake AutoKey script, it's currently able to copy from one object to another - exact same XYZ position key's.
But problem is that i have a rigged skeleton with animation and it has about 30+ bones and script can't work with more then 2 objects( 1 without anim and 2 with anim)
This is what i was able to do


on alignSource pressed do
	(	
		(
		sticks = #()
		append sticks $ 
		)
		for i = 1 to sticks.count do
			
		(global object1 = sticks[i]
		 objNames = for obj in selection collect obj.name
		objNames = makeUniqueArray objNames
		uniObjs = objNames as string
			AlignSource.text = uniObjs
			


		
		
		)
	)
	on alignDest pressed  do
		(	
		(
		vecs = #()
		append vecs $ 
		)
		for i = 1 to vecs.count do
			
		(global object2 = vecs[i]
		 objNames = for obj in selection collect obj.name
		objNames = makeUniqueArray objNames
		uniObjs = objNames as string
		alignDest.text = uniObjs
		
		)
	)
	
)

The result is same(working with 1 selecetion on each menu) only change is that http://i.shotnes.com/a/09/zw1rkbus.ko3_522e5062a76e4.png
object's that where seleceted are displaying in text box.

But if there is more then 2 objects selected i get this error.

If you can help with it please, i waisted a lot of time on this issue and ruined a project because of time it taked.

Comments (25)

DolVai · 2013-09-24

Seems transform function can't be used because it's transform with position of an object and after that it deletes anim keys, but i need just to rotate along the object(to be able properly transfer animation).

Anyway guys thx for help, but big thx goes to http://www.scriptspot.com/forums/3ds-max/general-scripting/aligning-boxe…

I just figured it out how to use that for my script and here is result.

Rotation Result - far from

Attachments

Budi G · 2013-09-27

hi DolVai ...

hmm...
do you need to keep the original position after baking keys ?

it's still using transform function... :


originalpos = object1.pos -- append original position
------------------------------------------ start process ...

-- baking keys process ... such a using my scipt in bottom

------------------------------------------ end process ...
object1.pos = originalpos -- back to original pos

anyway, if you found the best code as you need than this method... just use that ;)

goodluck

DolVai · 2013-09-19

barigazy

Any update on this ?
Only problem is remains in this part
coordsys local object1.rotation = y - x

I can simply make counter for object1[i].rotation = object2[i].rotation, but because it's not in world local, the result is far from what it should be like.

Budi G · 2013-09-19

hi ...

try this one:


object1[i].rotation.controller.value = object2[i].rotation.controller.value

it's great for the rotation technique ;)

another ways..
you can put a rotation first then a pos if need it, such:


object1[i].rotation = object2[i].rotation
object1[i].position = object2[i].position

barigazy · 2013-09-19

Hey Budi
The main problem is that bones have X-axis for normal direction and other object have Z-axis for dir.
BTW shorter version of your code wil be

object1[i][3][2].track.value = object2[i][3][2].track.value

Budi G · 2013-09-22

yep, you're right ...
I did not look into the whole case before :)

Thx but if you look in script

DolVai · 2013-09-22

Hello, Thx for reply, but if you look in script controller functin allready is used,

if selRotation.checked do( 
							for object1 in arr1 do 
	(
		addNewKey object1.rotation.controller startFrame.value 
	)

Here is what i have


	if arr1.count == arr2.count do
				(
			in coordsys world x = arr1
			in coordsys world y = arr2
				for i = 1 to arr1.count do
				(
					
		x[i].rotation = y[i].rotation

				)
			)

Rotation Result - far from

but its far from what i should be

Attachments

Budi G · 2013-09-22

just wondering, your goal is align dummy to bone. is it right ?
hmm.. the case is similiar with baking animation tools

I have some method, a snipet from my old script


(
position_checked = true -- such as checkbox
rotation_checked = true -- such as checkbox
scale_checked = false -- such as checkbox

object1 = $ -- ie: dummy as target
object2 = $bone002 -- ie: the bone have a motion as source

startfrm = 0
endfrm = 50

----------------------------------- align first
with animate on
(
	for T=startfrm to endfrm by 1 do
	(
	   at time T object1.transform = object2.transform
	)
)
------------------------------------------------------ user option
if position_checked == false then deleteKeys object1.pos.controller #allKeys
if rotation_checked == false then deleteKeys object1.rotation.controller #allKeys
if scale_checked == false then deleteKeys object1.scale.controller #allKeys
	
)

you can apply it into dummy to dummy, box to dummy or etc...
without making you dizzy thinking about PRS controller
:)

Thx will try.

DolVai · 2013-09-22

Thx a lot i think it works just perfect

arr1[i].transform

Only issue is that - it deletes not all objects in selection.

DolVai · 2013-09-16

Here is result

Autokeyr For multy objects

But i still can't figure out how to make same thing for orientation, maybe someone will help me out again ?


---this is what in header - first button

global arr1 = for obj in selection collect obj
					
		
		for i = 1 to arr1.count do
			
		(global object1 = arr1[i]


--scnd button is same but is arr2
--------
-- The orientatin script itself

		set animate on
		startValue = ( startFrame.value )	
	
				prevRot = object2t.rotation

	-------------------------------------------------------------------
		while startFrame.value <= endFrame.value do
		(
		
			
			if selRotation.checked do
			(
			in coordsys world x = object1.rotation
			in coordsys world y = object2.rotation
			in coordsys local object1.rotation = y - x
			)

	-------------------------------------------------------------------

If i try to add arr count'er to object1[i].rotation = y -x i get error
-- Unknown property: "rotation" in SubAnim:Visibility

If i i add counter for arr1

like here

for i = 1 to arr1.count do arr1[i].rotation = y - x
the result give me for example Box001 orientation transferred to both box003 and box004, but should be Box1 to box3, box2 to box4, like for translation.

Autokeyr For multy objects orientation

How to make this working ?, it would be realy good tool for animation transfering , if it would has this option.

Attachments

barigazy · 2013-09-16

First of all to collect objects in arr1 or arr2 u cal simply use


local arr1 = selection as array 
-- or 
local arr1 = getCurrentSelection()

Now check if arr1 and arr2 count is greater then zero and if both count are equal.
Then you can use this fn to copy separately pos, rot or scale keys.
This is your tool

try(destroyDialog ::bgaRoll)catch()
rollout bgaRoll "transferKeys"
(
local animObjs = #(), statObjs = #()
button btn_animO "Collect Animated Objects" pos:[5,5] width:140 height:18
progressBar pb_ao color:black value:100 pos:[5,24] width:140 height:5
button btn_statO "Collect Static Objects" pos:[5,30] width:140 height:18
progressBar pb_so color:black value:100 pos:[5,49] width:140 height:5
checkbox cb_pos "Pos" pos:[5,55] fieldwidth:20
checkbox cb_rot "Rot" pos:[52,55] fieldwidth:20
checkbox cb_scal "Scale" pos:[100,55] fieldwidth:20
button btn_trans "Transfer Keys" pos:[5,72] width:140

fn transferKeys arr1 arr2 pos:cb_pos.checked rot:cb_rot.checked scal:cb_scal.checked =
(
if arr1.count != 0 and arr2.count != 0 and arr1.count == arr2.count do
(
local ctrl = #()
if pos do append ctrl 1 ; if rot do append ctrl 2 ; if scal do append ctrl 3
if ctrl.count != 0 do for a in 1 to arr1.count do
(
for c in ctrl do
(
for i = 1 to 3 do
(
if arr1[a][3][c][i].track.keys.count != 0 do
arr2[a][3][c][i].track = copy arr1[a][3][c][i].track
)
)
)
)
)
on btn_animO pressed do
(
animObjs = getCurrentSelection()
if animObjs.count != 0 do pb_ao.color = red
format "Animated Objects Count = %\n" animObjs.count
)
on btn_statO pressed do
(
statObjs = getCurrentSelection()
if statObjs.count != 0 do pb_so.color = green
format "Static Objects Count = %\n" statObjs.count
)
on btn_trans pressed do
(
transferKeys animObjs statObjs
pb_ao.color = pb_so.color = black
free animObjs ; free statObjs
)
)
createDialog bgaRoll 150 100 10 110 style:#(#style_titlebar, #style_sysmenu, #style_toolwindow)

barigazy · 2013-09-16

How it works:
Select in order all animated objects in the scene and press "Collect Animated Objects". The same rule applies to static objects. Red and green progresbar shows that you are collected all objs that you need for now.
Check which controller keys you need to transfer (pos , rot , scale checkboxes) and press "Transfer Keys" button.
NOTE: Only controllers that contains animated keys will be transfered. Open Track Editor and see for yourself.
Cheers!

DolVai · 2013-09-17

Thx a lot barigazy, unfortunately it doesnt work for bones http://i.shotnes.com/a/17/orxbtoyj.io3_5237e7c744b44.png
these bones doesnt show keys in track view.
I'm trying to adopt your script for old one, which aligns pos and create keys, will give you video if i'l make it - thx a lot.

barigazy · 2013-09-17

I know. I created the tool for your last example. Bones will never works with this method.

DolVai · 2013-09-17

Is it hard to make some count'er for this part of code

if selRotation.checked do
(
in coordsys world x = object1.rotation
in coordsys world y = object2.rotation
in coordsys local object1.rotation = y - x
)
I tried to change object1 to what you said - getCurrentSelection, i get same result =(.

I figure it out anyway( By

DolVai · 2013-09-13

I figured it out anyway( By myself)


--- add in sourcebutton;   global arr1 = for obj in selection collect obj
--- add in destbutton; 	global arr2 = for obj in selection collect obj

			if selPosition.checked do(
				for object1 in arr1 do 

(
  local pc = object1.position.controller
  for startFrame in object1.rotation.controller.keys do
    addNewKey pc startFrame.value
)
 

-----

if selPosition.checked do
			(
				if arr1.count == arr2.count do
				(
					for i = 1 to arr1.count do
	
					arr1[i].pos = arr2[i].pivot 
				)
			)
	

And thx barigazy, your script example rly help me out, now script is fully working.

[code]

So any advise ?script is

DolVai · 2013-09-11

So any advise ?

script is working for arr2[i].pos = arr1[i].pos with for i = 1 to arr1.count do.

IT is not working with

startFrame.value = (startFrame.value - 1 )
		endFrame.value = endFrame.value
		done.text = "computing..."
		sliderTime = startFrame.value
		------------------------------------------------------------
			if selPosition.checked do addNewKey object1.position.controller startFrame.value
			if selRotation.checked do addNewKey object1.rotation.controller startFrame.value
			if selScale.checked do addNewKey object1.scale.controller startFrame.value
			startFrame.value += 1
			sliderTime += 1
			progress.value = ( 100 * startFrame.value ) / endFrame.value			

And i have no idea how to make it work with multiple objects in selection(X) to (Selection X)
The addkey animation feature is stoping after first object got keys(script won't addkey to second obj), any help ??

DolVai · 2013-09-10

Thx i understand this for a bit the script that you send me, the thing i dont understand is that what do i need to make - an count'er, for amount of selected object,
so script would be appled to all of the objects in selection variable "A" to selection var "B" ?

and if it so how i need to make it properly in that script ?
like here



		if selPosition.checked do
			( 
                          for i = 1 to object1.count do
			
                         (object1.pos = object2.pivot)

			)

And here


if selPosition.checked then for i = 1 to object1.count do addNewKey object1.position.controller startFrame.value

? rly taked a lot of time on this =(.

The script itself for properly for 1 to 1 objects, it doesnt work if there is 2 to 1 or more.

barigazy · 2013-09-10

Here another example

-- array of animated objects
arr1 = #($Source001,$Source002,$Source003,$Source004,$Source005)
-- array of objects that you need to copy animations
arr2 = #($Target001,$Target002,$Target003,$Target004,$Target005)
if arr1.count == arr2.count do
(
for i = 1 to arr1.count do
(
arr2[i].pos = arr1[i].pos
arr2[i].parent = arr1[i].parent
(arr2[i])[3].track = (arr1[i])[3].track

)
)

barigazy · 2013-09-10

U can add many objects in array but theses array need to have same number of items ei. same count.

Thx,but for my

DolVai · 2013-09-11

Thx,
but for my script
http://i.shotnes.com/a/11/k12fylci.2fz_522fb49888740.png

this solutin cant be appled(For this script, the only reason i use it - it make perfect position and anim keys), it has 2 buttons, for storing selection for array 1 and array 2.

Then it has add key function http://i.shotnes.com/a/11/ymob5bxi.zh0_522fb558bc135.png

That is problem i guess, because it designed only to add key for 1 object(that where selected on alignObjects button.

Barigazy

Could you give me hint(script Code) how to add keys for bouth objects in selection 1 array.

If i'm wrong correct me, i'm less skilled in script writing.

draging · 2013-09-10

Hi..
if I look at your picture, I just thought ...you may need motion mapping, map track to track.
but it already exists on the save and load animations in the main menu.

DolVai · 2013-09-10

Thx for reply, script is working with 1 object to another without any erros, problem accure when i try apply animation from 2 object's( In list, like on screenshot) on other 2(from second menu)
Here is some code, and if you dont want to download i attached whole script,



		startFrame.value = (startFrame.value - 1 )
		endFrame.value = endFrame.value
		done.text = "computing..."
		sliderTime = startFrame.value
		------------------------------------------------------------
			if selPosition.checked do addNewKey object1.position.controller startFrame.value
			if selRotation.checked do addNewKey object1.rotation.controller startFrame.value
			if selScale.checked do addNewKey object1.scale.controller startFrame.value
			startFrame.value += 1
			sliderTime += 1
			progress.value = ( 100 * startFrame.value ) / endFrame.value			
		------------------------------------------------------------

		if selPosition.checked do
			(
			object1.pos = object2.pivot
			)
			
			if selPosition.checked do addNewKey object1.position.controller startFrame.value

The problem is i dont understand which module i should create instead of object1.position.controller
object1.pos = object2.pivot

so script could be applyed for more then 2 objects(from selection).

I Would be very glad if someone could write some cod and help me out.

P.S. Sorry for my broken english

Attachments

barigazy · 2013-09-10

Are you try this tool
http://www.scriptspot.com/3ds-max/scripts/key-transfer
I think that your main problem is parent coordinate space of the bones.
Open the file in attachment. The scene contains two teapots and box.
Velvet Teapot is parented to box and animated. Run this code if you want to mach
animation of two teapots


t1 = $Teapot001
t2 = $Teapot002
t2.pos = t1.pos
t2.parent = t1.parent
t2[3].track = t1[3].track

Also this is useful thread for you
http://forums.cgsociety.org/showthread.php?f=98&t=1076519&highlight=copy…

Attachments

DolVai · 2013-09-10

So any Help, i need to make this script usable for multy objects, like shown on screenshot http://i.shotnes.com/a/09/zw1rkbus.ko3_522e5062a76e4.png
Animatin From LeftArm is assigning to dummy017, anim from Leftforearm is assigned to dummy018.
I'm not so sure how to do this, i'm less skilled in max scripting.