[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!
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
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