ScriptSpot

Forum topic · Scripts Wanted

pls help! Dummy/Helper animated on spline needs xyz Keys!!!!!

By net_ralf · 2008-10-24

Description

Hi all,

i am desperate! I have a dummy/helper animated over a spline. So there are two keys 0 and 100 percent on the spline. As i want to import that Dummy to Eyon Fusion (there is a camera attached) via FBX i guess i need to convert the animation to xyz coordinates in space. Because Fusion does not get the ani that is defined by the spline!
Is there some script or hidden tool in Max that will do that conversion?
Or is it a simple import/export failure that comes with FBX?

please pretty please i need that clue! :-)

all the best,
Michael

Comments (15)

nycwtorres · 2009-01-29

perfect! thanks!

Anton Berg · 2009-01-28

from a quick glance a find one miss in the script.
if you do this:
-----
(
$.rotation.controller = Euler_XYZ ()
$.pos.controller = Position_XYZ ()
)
---
then max will reset the position controller for the current selection, ALL objects initially selected. Do you want that?

$ is a symbol for the current selection.

you should probably comment out that line...

if you want to change the controller on the original bone then you could reach it in this script by typing:
-------
item.rotation.controller = Euler_XYZ ()
item.pos.controller = Position_XYZ ()
---------

nycwtorres · 2009-01-28

OK that execute helped big time. I'm sooo close! But if I run the script below there are no errors. But the bones go wacky. HOWEVER. if I only select one bone at a time it works. I'm trying to figure out why. Maybe you see something.

--begin script
select # (
$Bone_Shoulder_Left_SK
, $Bone_ArmTwist_Left_SK
, $Bone_Arm_Left_SK
, $Bone_Elbow_Left_SK
, $Bone_ElbowTwist_Left_SK
, $Bone_Hand_Left_SK
)

myObjectsArray =selection as array

startFrame = 0
endFrame = 20
byFrame = 5

for item in myObjectsArray do
(
newObj = copy item
--newObj.controller = PRS()
newObj.rotation.controller = Euler_XYZ ()
newObj.pos.controller = Position_XYZ ()
newObj.name += "_Bakeanim"
newObj.parent = undefined

for i = startFrame to endFrame by byFrame do
(
with animate on
(
at time i newObj.transform = item.transform
)
)
(
--$.controller = PRS()
$.rotation.controller = Euler_XYZ ()
$.pos.controller = Position_XYZ ()
)

myBakeObj = execute ("$" + item.name + "01_Bakeanim")

(
for i = startFrame to endFrame by byFrame do
(
with animate on
(

at time i item.transform = myBakeObj.transform
--at time i item.transform = $(item.name + "01_Bakeanim.transform" )
)
)
)
)
--END script

Anton Berg · 2009-01-28

just saw a thing you need to fix.
If you need to construct a link to an existing object there is sometimes a need to use the execute command.

so your script has this row:
-----
at time i item.transform = (item.name + "01_Bakeanim.transform" )
------

change to:

------ start script
myBakeObj = execute ("$" + item.name + "01_Bakeanim")
at time i item.transform = myBakeObj.transform
-------

this should work better. There is one problem with this and that is if there exist two objects with the SAME NAME... then 3dsmax chooses the first one (in its own order).

Anton Berg · 2009-01-28

I removed this script it didn´t work...

Anton Berg · 2009-01-27

Hmm the trajectories is only the position of the objects it wont include any rotations. I guess you mean the collapse transform feature.

Could you please explain what you are trying to do since a copy of the bones doesn´t work.

nycwtorres · 2009-01-28

yes collapse transform.. sorry for the misinformation.

My goal is to "bake" keys into a skinned skeleton so that I can delete all control objects such as ik controllers, spline controllers, wire parameters, etc. This way I can cleanly export a clean and organized bone hierarchy and it's mesh to a game engine. The game engine wont recognize all those controllers. Does that make sense.

I have a good path.. I'm just not familiar with maxscript syntax etc.. I very proficient in MEL. sigh

--BEGIN
myObjectsArray =selection as array

startFrame = 0
endFrame = 100
byFrame = 1 --set a keyframe for every frame

for item in myObjectsArray do
(
newObj = copy item
newObj.controller = PRS()
newObj.name += "_Bakeanim"
newObj.parent = undefined

for i = startFrame to endFrame by byFrame do
(
with animate on
(
at time i newObj.transform = item.transform
)
)
)
--EVERYTHING ABOVE WORKS GREAT
--This next part is where it all goes bad

myObjectsArray =selection as array

startFrame = 0
endFrame = 100
byFrame = 1 --set a keyframe for every frame

for item in myObjectsArray do

(
for i = startFrame to endFrame by byFrame do
(
with animate on
(
at time i item.transform = (item.name + "01_Bakeanim.transform" )
)
)
)

--END
the feed back of the second part says:

-- Error occurred in i loop
-- Frame:
-- i: 0
-- called in item loop
-- Frame:
-- item: $Bone_FootToes_Left_SK
-- Unable to convert: "Bone_FootToes_Left_SK01_Bakeanim.transform" to type: Matrix

So it is not associating the variable's name of Sequence_Node_SK01_Bakeanim with the obj of the same name (which does exist in this file.)

nycwtorres · 2009-01-27

This is close to what I want.. but now all I have to do is get the keys back onto the original.. sigh.. I wonder why I can't just write a script that selects my bones and collapses the trajectories. If max can do it, why can't it be scripted. Thanks again.

Anton Berg · 2009-01-27

Ok I did a new version that should include the rotation as well. But I still need to make a copy of the original object and "collapse" the animation there. The reason is if their exist any linkage between the selected objects then the childrens positions are dependent on their parent position. And if I remove the IK link controller (if this bone object has that) then its childrens animations will be wrongly positioned.

So instead I make a copy of the selected objects and bake the animation on them. I then have a question in the end that asks if you want to delete your original objects!

PLEASE SAVE your maxfile BEFORE trying this. I am pretty sure you want to keep your original scene before baking the animation instead of the baked endresult. Especially if you need to change something.

-------start snippet
-- Grab my current viewport selection into an array
myObjectsArray =selection as array

startFrame = 0
endFrame = 100
byFrame = 1 --set a keyframe for every frame

for item in myObjectsArray do
(
newObj = copy item
newObj.controller = PRS()
newObj.name += "_Bakeanim"
newObj.parent = undefined

for i = startFrame to endFrame by byFrame do
(
with animate on
(
at time i newObj.transform = item.transform
)
)
)

del = (queryBox "Do you want to delete the original objects?" beep:false)
if del == true then ( delete myObjectsArray )
------end snippet

Attachments

nycwtorres · 2009-01-27

actually I figured it out.. that is with your original guidance. Thanks. I wanted to automate a similar function to collapsing trajectories.. here is what I have to so far, thanks for your help!

rotObj = dummy name:(uniquename "FollowObj")
yourObj = $Bone_Arm_Left_SK
startFrame = 0
endFrame = 100
byFrame = 5

for i = startFrame to endFrame by byFrame do
(with animate on
(
at time i rotobj.rotation = yourObj.rotation
))

for i = startFrame to endFrame by byFrame do
(with animate on
(
at time i yourObj.rotation = rotobj.rotation
))

reduceKeys yourObj.rotation.controller 0.5 1f

Anton Berg · 2009-01-27

Are you trying to collapse an IK rig with animation on it?

just for tryout purpose. You could you please create a simple example of what you want to do and attach it here. Then It would be easier for us to know how to help you and be sure the script works.

Anton Berg · 2009-01-27

here is a small code snippet that takes the position from one object following a spline and pasting them to another object.
You could the copy the position controller from the new object to the old object if you want to replace the path controller. But I did not do that. Let me know if you need it.

----snippet start
--create dummy object to hold
--the position of your object
posObj = dummy name:(uniquename "FollowObj")
-- I have a test object called "box01"
yourObj = $box01
startFrame = 0
endFrame = 100
byFrame = 1 --set a keyframe for every frame

for i = startFrame to endFrame by byFrame do
(
with animate on
(
-- at time i, set the dummy position to your
--object position
at time i posobj.pos = yourObj.pos
)
)
-- if you want to you can use this little extra function
-- to reduce the amount of keframes so you only get
-- the ones nececcary..
reduceKeys posObj.pos.controller 0.5 1f
----end snippet

--- I have attached the code snippet to this post.

Attachments

nycwtorres · 2009-01-27

This def a step in the right direction. I do need the keys back on the original object ..but also need the rotation values too since some bones rotate but don't move.

Thanks!!

nycwtorres · 2009-01-26

yeah but what is the maxscript for that process? I can't seem to find any. Is it common that 3ds Max has procedures that can't be done by maxscript?

Hani Tiby · 2008-10-26

go to the motion panel> trajectories
then in the collapse transform , choose which transforms you want to transfer then press collapse