Notifications
Clear all

[Closed] Scripting Export of Biped Animations

How can I do this? I can’t seem to access any key information from the
individual biped part’s animation controllers. The animation controller
keys have no ‘.value’, and the subanim object is just a float with a value
of 0.

Is this right? Am I supposed to loop through setting the animation time and
extract the rotation/position information from the transform for the object
for each frame?

Thanks!

5 Replies

I would check each object for where its key frames are then save its transform at that frame. You can get what keys each object has with just ($.controller.keys) Each key has a time property which tells you what frame its on.

-RyanT

1 Reply
(@raeldor)
Joined: 10 months ago

Posts: 0

Thanks Ryan. Now I just need to get my head around 3ds transform setup (this object-offset stuff is a bit alien to me). I am exporting the mesh in local co-ordinates, so I assume when I am writing out my transformations which I want to be local to the parent, that I should multiply the transform by the inverse of it’s parent’s transform?

Doing some tests, I find…

myhip=$bip01_pelvis
$Biped_Object:Bip01 Pelvis @ [-0.139269,1.408870,26.587803]
myspine=$bip01_spine
$Biped_Object:Bip01 Spine @ [-0.197272,1.539500,29.388330]
invparent=inverse myhip.parent.transform
(matrix3 [0.379317,0.925089,-0.0181145] [-0.924036,0.37975,0.0441279] [0.0477012,0,0.998862] [-1.52292,0,-26.6222])
(myspine.transform*invparent).position
[-1.61844,0.40213,2.80415]
myspine.transform.position-myhip.transform.position
[-0.0580025,0.130629,2.80053]

This to me is strange. I was expecting the last two statements to return the same result. Am I missing something here?

Also, I am a little concerned about getting the translation, position and scale from the matrix object. I thought math-wise this was only safe to do if the scaling was uniform?

Thanks

I havent tried it that way. I dont really understand how the biped controllers work as far as getting the local transform out of them. If you have max 7 there is a helper called expose Tm. Here is a script I wrote awile back just to see if I could save off the animation for a biped. I only tested it on the simplest case of taking a snapshot of the entire biped and transfering the animation onto the snapshot. If you come up with a better solution I would love to see it.

 
fn char_bipclipfile theNode =

(

TestTransform = ExposeTm pos:[0,0,0] name:"TestRotation"



q = slidertime

startrange = animationrange.start

endrange = animationrange.end

firstTest = theNode.isSelected



if firstTest == true then

(

--Create node to test the transform of a biped node.

TestTransform.exposeNode = theNode

TestTransform.localReferenceNode = theNode.parent



format "%
" theNode.name to:charCreate



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

--Find the keycount in every node, test for COM create array of COM's seperate controllers 

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

testResult = findstring theNode.name " "

if testResult != undefined do

(

roottest = substring theNode.name 1 (testResult-1)

root = getNodeByName roottest

)

if testResult == undefined do

(

roottest = theNode.name

root = getNodeByName roottest

)



if theNode == root then

(

COMKeys = #()



x = theNode.controller.vertical.controller.keys

y = theNode.controller.horizontal.controller.keys

z = theNode.controller.turning.controller.keys



for i in x do

(

testKey = i.time

testArray = finditem COMKeys testKey

if testArray == 0 then

(

append COMKeys testKey

) 

)



for i in y do

(

testKey = i.time

testArray = finditem COMKeys testKey

if testArray == 0 then

(

append COMKeys testKey

) 

)



for i in z do

(

testKey = i.time

testArray = finditem COMKeys testKey

if testArray == 0 then

(

append COMKeys testKey

) 

)



keycount = COMKeys.count

)



else

(

testClass = classof theNode



if testClass == Biped_Object then

(

testNode = theNode.controller.keys

keycount = testNode.count

)



else

(

keycount = 0

)

)



format "%
" keycount to:charCreate

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

--formate rotation keys for biped

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

for q = 1 to keycount do

(

if theNode == root then

(frame = COMKeys [q])



if theNode != root then

(frame = getKeyTime theNode.controller q)



at time frame

(

XRot = TestTransform.worldEulerX 

YRot = TestTransform.worldEulerY 

ZRot = TestTransform.worldEulerZ



format "%
" frame to:charCreate

format "%
" XRot to:charCreate

format "%
" YRot to:charCreate

format "%
" ZRot to:charCreate

)

)



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

--formate position keys for biped

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

if theNode == root then -- This is the only bone that needs to move.

(

format "%
" keycount to:charCreate



for q = 1 to keycount do

( 

frame = COMKeys [q]



at time frame

( 

BipPos = TestTransform.worldPosition



format "%
" frame to: charCreate

format "%
" bipPos to: charCreate

)

)

)

)

else ()



--Delete node to test the transform of a biped node.

delete TestTransform



--Call function untill all nodes in hierarchy are sorted through.

testResult = theNode.children

for i in testResult do

(

char_bipclipfile i

)

) --End char_bipclipfile


Thanks again Ryan. I was playing with this helper a little, and noticed this…

testtransform=exposetm pos:[0,0,0]
$ExposeTransformHelper:ExposeTransform01 @ [0.000000,0.000000,0.000000]
testtransform.exposenode=mymesh
$Biped_Object:Bip01 Spine @ [-0.888108,1.167596,27.686647]
testtransform.localreferencenode=mymesh.parent
$Biped_Object:Bip01 Pelvis @ [-0.756745,1.046813,24.887947]
testtransform.localeuler
[0.180706,-0.0137388,-0.096129]
testtransform.localeulerx
-20.5945

What’s up with that? Is the localeuler returning something other than angles? The localuserx is correct based on what I am seeing in the scene.

Thanks

Hmmm, I agree that doesnt make sense. I wouldnt use the localEuler property then. Biped is a pain as you have noticed when trying to do this stuff.

-RyanT