-----------------------------------------------------------------------------
-- gets keyframes from the controllers animation
-----------------------------------------------------------------------------
function getTimeList obj firstframe lastframe =
(
local list,rotContr,posContr, ;
list = #(firstframe) ;
list2 = #() ; -- this is the list which will be returned.
-- Biped_Objects and Bones don't have the same properties
-- Biped_Objets
if (isKindOf obj Biped_Object) then (
for e in obj.controller.keys do (
t =e.time ;
if (t>firstFrame and t<=lastFrame) then
append list t ;
)
)
-- Bones
else (
rotContr = obj.rotation.controller ;
posContr = obj.pos.controller ;
for e in rotContr.keys do (
t = e.time ;
if (t>firstFrame and t<=lastFrame) then
append list t ;
)
for e in posContr.keys do (
t = e.time ;
if (t>firstFrame and t<=lastFrame) then
append list t ;
)
)
-- if several keyframes have the same value, we keep just one
keepLoneValues list list2 ;
list2 ;
)
-----------------------------------------------------------------------------
-- write
-- Selected keys belongs to [firstframe,lastFrame]
-- time = (key.time - firstFrame)*length/(lastFrame-firstFrame)
-- (e.g. first key has time 0.)
-----------------------------------------------------------------------------
function writeTrack sk boneId firstframe lastframe length scale flipYZ outFile=
(
local angle,timef,i,bname,d,mref,mparent ;
-- displays information in the maxscript listener
format "retrieving key information for % ...\n" (skinOps.GetBoneName sk boneId 1) ;
-- gets bone acording to the parameter boneId
bname= skinOps.GetBoneName sk boneId 1 ;
replaceSpaces bname ;
d = execute ("$" + bname) ;
-- gets keyframe list
timelist = getTimeList d firstframe lastframe ;
-- track header
format("\t\t\t\t\n") d.name to: outFile ;
)
-------------------------------------------------------------------------------------------------
------------------------------------------- WRITE SKELETON --------------------------------------
-------------------------------------------------------------------------------------------------
-- Nota :
-- A vertex 0 and a bone 0 are added because 3dsmax starts with vertex 1 and bone 1.
------------------
-- write
------------------
function writeB sk id scale flipYZ outFile =
(
-- gets bone acording to the parameter boneId
bname= skinOps.GetBoneName sk id 1 ;
replaceSpaces bname ;
d = execute ("$" + bname) ;
-- gets initial transform at frame 0f
format("\t\t\n") id (replaceSpaces d.name) to:outFile ;
slidertime = 0f ;
Tform = d.transform ;
if (not isRoot d) then (
mparent = d.parent.transform ;
Tform = Tform*inverse(mparent) ;
)
Tform.pos = Tform.pos * scale ;
if ((isRoot d) and flipYZ) then (
format "- Flipping root bone... \n" ;
Tform = flipYZTransform Tform ;
)
pos = Tform.pos ;
rot = Tform.rotation as angleaxis ;
angle = - degToRad (rot.angle) ; -- don't know why there must be this minus :((((((
format("\t\t\t\n") pos.x pos.y pos.z to:outFile ;
format("\t\t\t\n") angle to:outFile ;
format("\t\t\t\t\n") rot.axis.x rot.axis.y rot.axis.z to:outFile ;
format("\t\t\t\n") to:outFile ;
format("\t\t\n") to:outFile ;
)
-----------------------------
-- write Bones (using writeB)
-----------------------------
function writeBones sk scale flipYZ outFile =
(
local i ;
format("\t\n") to:outFile;
-- we create a virtual bone number 0.
format("\t\t\n") to:outFile ;
format("\t\t\t\n") to:outFile ;
format("\t\t\t\n") to:outFile ;
format("\t\t\t\t\n") to:outFile ;
format("\t\t\t\n") to:outFile ;
format("\t\t\n") to:outFile ;
i = 0 ;
for i=1 to (skinOps.GetNumberBones sk) do
(
writeB sk i scale flipYZ outFile ;
)
format("\t\n") to:outFile;
)
-----------------------------------
-- recursive fun to write hierarchy
-----------------------------------
function writeH b outFile =
(
if ( b.parent != undefined and (isKindOf b.parent BoneGeometry or iskindOf b.parent Biped_Object)) then
(
p = b.parent ;
format("\t\t\n") (replaceSpaces b.name) (replaceSpaces p.name) to:outFile ;
)
childrenArray = b.children ;
for i=1 to childrenArray.count do
(
if (isKindOf b BoneGeometry or iskindOf b Biped_Object) then
writeH childrenArray[i] outFile ;
)
)
--------------------------
-- write
--------------------------
function writeHierarchy sk outFile =
(
format("\t\n") to:outFile ;
roots = getRoots sk ;
-- ecriture de la track pour le bone 0.
format("\t\t\n") roots[1].name to:outFile ;
for b in roots do
(
writeH b outFile;
)
format("\t\n") to:outFile ;
)
-----------------------
-- write
-----------------------
function writeAnim sk firstFrame lastFrame length scale flipYZ name outFile =
(
local i,n ;
format("\t\n") to: outFile ;
format("\t\t\n") name length to:outFile ;
format("\t\t\t\n") to:outFile
-- ecriture track 0
format("\t\t\t\t\n") to: outFile ;
n = skinOps.GetNumberBones sk ;
liste = #(0,20,30,40) ;
for i = 1 to n do
writeTrack sk i firstframe lastframe length scale flipYZ outFile ;
format("\t\t\t\n") to:outFile
format("\t\t\n") to: outFile ;
format("\t\n") to: outFile ;
)
-------------------------------------------------------------
-- write main function
-- write the animation in the file out_name + ".skeleton.xml"
-- between the frame firstFrame and lastFrame
-- and scale time according to length
-------------------------------------------------------------
function writeSkeleton pmesh exportOptions out_name =
(
local sk,n,keys,initialKeys,messages ;
sk = getSkin pmesh ;
if (sk == undefined) then
(
MessageBox "There is no skin modifier for this object" ;
)
else
(
-- in order to perform, skin should be opened
max modify mode ;
modPanel.setCurrentObject pmesh.modifiers[#Skin] ;
format "------------------------------------------\n"
format "------ OGRE skeleton Exporter Log ------\n"
format "------------------------------------------\n"
format "Exporter options :\n"
format "- firstFrame: % \n- lastFrame: %\n" exportOptions.firstFrame exportOptions.lastFrame ;
-- creates the output file
outFile = createfile (out_name + ".skeleton.xml") ;
-- writes header
format("\n") to:outFile ;
format "Writing bones :\n" ;
writeBones sk exportOptions.scale exportOptions.flipYZ outFile ;
format "Writing bone hierarchy.\n" ;
writeHierarchy sk outFile ;
format "Writing bone tracks.\n" ;
writeAnim sk exportOptions.firstFrame exportOptions.lastFrame exportOptions.length exportOptions.scale exportOptions.flipYZ exportOptions.animName outFile ;
-- ecriture, fin des balises
format("\n") to: outFile ;
format "------------------------------------------\n"
format "---------- END ---------\n"
format "------------------------------------------\n"
close outFile ;
messageBox "Exporting skeleton successful !"
)
)